+- update to post 2.6.3-rc1 20040209
authorOlaf Hering <olh@suse.de>
Mon, 9 Feb 2004 10:02:00 +0000 (10:02 +0000)
committerOlaf Hering <olh@suse.de>
Mon, 9 Feb 2004 10:02:00 +0000 (10:02 +0000)
suse-commit: 7fe33ba10771b9d5849f3f6710bf35fa73cf40db

734 files changed:
CREDITS
Documentation/Changes
Documentation/SubmittingPatches
Documentation/cciss.txt
Documentation/networking/8139too.txt [deleted file]
Documentation/networking/bonding.txt
Documentation/networking/ethertap.txt
Documentation/networking/ifenslave.c
Documentation/networking/ip-sysctl.txt
Documentation/sound/alsa/ALSA-Configuration.txt
TODO [deleted file]
arch/alpha/defconfig
arch/arm/Kconfig
arch/arm/common/amba.c
arch/arm/configs/footbridge_defconfig
arch/arm/configs/iq80321_defconfig
arch/arm/configs/netwinder_defconfig
arch/arm/kernel/calls.S
arch/arm/kernel/vmlinux.lds.S
arch/arm/mach-integrator/Kconfig
arch/arm/mach-integrator/Makefile
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/cpu.c
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c [new file with mode: 0644]
arch/arm/mach-integrator/leds.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/neponset.c
arch/i386/defconfig
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/cpu/cpufreq/acpi.c
arch/ia64/configs/generic_defconfig
arch/ia64/configs/sn2_defconfig
arch/ia64/defconfig
arch/ia64/kernel/acpi.c
arch/ia64/kernel/iosapic.c
arch/ia64/sn/io/hwgfs/hcl.c
arch/ia64/sn/io/hwgfs/hcl_util.c
arch/ia64/sn/io/io.c
arch/ia64/sn/io/sn2/klgraph.c
arch/ia64/sn/io/sn2/module.c
arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
arch/ia64/sn/io/sn2/pciio.c
arch/ia64/sn/io/sn2/pic.c
arch/ia64/sn/io/sn2/xtalk.c
arch/mips/defconfig-lasat200
arch/parisc/configs/a500_defconfig [new file with mode: 0644]
arch/parisc/configs/c3000_defconfig [new file with mode: 0644]
arch/parisc/hpux/fs.c
arch/parisc/hpux/ioctl.c
arch/parisc/hpux/sys_hpux.c
arch/parisc/kernel/asm-offsets.c
arch/parisc/kernel/drivers.c
arch/parisc/kernel/firmware.c
arch/parisc/kernel/head.S
arch/parisc/kernel/head64.S
arch/parisc/kernel/hpmc.S
arch/parisc/kernel/init_task.c
arch/parisc/kernel/inventory.c
arch/parisc/kernel/pacache.S
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/pci-dma.c
arch/parisc/kernel/pci.c
arch/parisc/kernel/pdc_chassis.c
arch/parisc/kernel/pdc_cons.c
arch/parisc/kernel/perf_asm.S
arch/parisc/kernel/perf_images.h
arch/parisc/kernel/process.c
arch/parisc/kernel/ptrace.c
arch/parisc/kernel/signal32.c
arch/parisc/kernel/signal32.h
arch/parisc/kernel/sys32.h
arch/parisc/kernel/sys_parisc.c
arch/parisc/kernel/syscall_table.S
arch/parisc/kernel/unaligned.c
arch/parisc/kernel/vmlinux.lds.S
arch/parisc/lib/lusercopy.S
arch/parisc/math-emu/cnv_float.h
arch/parisc/math-emu/dbl_float.h
arch/parisc/math-emu/decode_exc.c
arch/parisc/math-emu/denormal.c
arch/parisc/math-emu/dfadd.c
arch/parisc/math-emu/dfcmp.c
arch/parisc/math-emu/dfdiv.c
arch/parisc/math-emu/dfmpy.c
arch/parisc/math-emu/dfrem.c
arch/parisc/math-emu/dfsqrt.c
arch/parisc/math-emu/dfsub.c
arch/parisc/math-emu/driver.c
arch/parisc/math-emu/fcnvff.c
arch/parisc/math-emu/fcnvfu.c
arch/parisc/math-emu/fcnvfut.c
arch/parisc/math-emu/fcnvfx.c
arch/parisc/math-emu/fcnvfxt.c
arch/parisc/math-emu/fcnvuf.c
arch/parisc/math-emu/fcnvxf.c
arch/parisc/math-emu/float.h
arch/parisc/math-emu/fmpyfadd.c
arch/parisc/math-emu/fpbits.h
arch/parisc/math-emu/fpu.h
arch/parisc/math-emu/fpudispatch.c
arch/parisc/math-emu/frnd.c
arch/parisc/math-emu/hppa.h
arch/parisc/math-emu/math-emu.h
arch/parisc/math-emu/sfadd.c
arch/parisc/math-emu/sfcmp.c
arch/parisc/math-emu/sfdiv.c
arch/parisc/math-emu/sfmpy.c
arch/parisc/math-emu/sfrem.c
arch/parisc/math-emu/sfsqrt.c
arch/parisc/math-emu/sfsub.c
arch/parisc/math-emu/sgl_float.h
arch/parisc/mm/kmap.c
arch/ppc/configs/common_defconfig
arch/ppc/configs/pmac_defconfig
arch/ppc/defconfig
arch/ppc/kernel/pci.c
arch/ppc/syslib/prom_init.c
arch/ppc64/Kconfig
arch/ppc64/kernel/idle.c
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/rtas-proc.c
arch/ppc64/kernel/setup.c
arch/ppc64/kernel/smp.c
arch/ppc64/kernel/time.c
arch/ppc64/kernel/vio.c
arch/ppc64/mm/numa.c
arch/ppc64/xmon/start.c
arch/ppc64/xmon/xmon.c
arch/sparc/kernel/Makefile
arch/sparc/kernel/sparc_ksyms.c
arch/sparc64/defconfig
arch/v850/kernel/bug.c
arch/v850/kernel/setup.c
arch/v850/kernel/v850e_cache.c
arch/x86_64/defconfig
arch/x86_64/kernel/acpi/boot.c
crypto/sha256.c
crypto/sha512.c
drivers/acpi/asus_acpi.c
drivers/acpi/numa.c
drivers/acpi/pci_irq.c
drivers/acpi/processor.c
drivers/acpi/tables.c
drivers/acpi/toshiba_acpi.c
drivers/atm/atmtcp.c
drivers/atm/idt77252.c
drivers/base/bus.c
drivers/block/cciss.c
drivers/block/cciss.h
drivers/block/cciss_cmd.h
drivers/block/genhd.c
drivers/block/paride/Transition-notes [new file with mode: 0644]
drivers/block/paride/bpck6.c
drivers/block/paride/frpw.c
drivers/block/paride/paride.c
drivers/block/paride/paride.h
drivers/block/paride/pd.c
drivers/block/ps2esdi.c
drivers/char/hvc_console.c
drivers/char/keyboard.c
drivers/char/mxser.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/sonypi.h
drivers/char/synclink.c
drivers/char/synclinkmp.c
drivers/i2c/busses/i2c-keywest.c
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/arm/icside.c
drivers/ide/arm/rapide.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-generic.c
drivers/ide/ide-iops.c
drivers/ide/ide-taskfile.c
drivers/ide/ide-tcq.c
drivers/ide/ide.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cs5520.c
drivers/ide/pci/cs5530.c
drivers/ide/pci/cy82c693.c
drivers/ide/pci/generic.c
drivers/ide/pci/hpt34x.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/it8172.c
drivers/ide/pci/ns87415.c
drivers/ide/pci/opti621.c
drivers/ide/pci/pdc202xx_new.c
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/rz1000.c
drivers/ide/pci/sc1200.c
drivers/ide/pci/serverworks.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/siimage.c
drivers/ide/pci/sis5513.c
drivers/ide/pci/sl82c105.c
drivers/ide/pci/slc90e66.c
drivers/ide/pci/triflex.c
drivers/ide/pci/triflex.h
drivers/ide/pci/trm290.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/pmac.c
drivers/ieee1394/eth1394.c
drivers/input/evdev.c
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/turbografx.c
drivers/input/serio/i8042.c
drivers/input/serio/parkbd.c
drivers/macintosh/Makefile
drivers/macintosh/via-pmu.c
drivers/media/video/Kconfig
drivers/media/video/bw-qcam.c
drivers/media/video/meye.c
drivers/media/video/meye.h
drivers/media/video/msp3400.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/tda9887.c
drivers/media/video/tuner.c
drivers/media/video/tvaudio.c
drivers/media/video/tvmixer.c
drivers/message/fusion/mptscsih.c
drivers/net/3c501.c
drivers/net/3c501.h
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c527.c
drivers/net/8139too.c
drivers/net/82596.c
drivers/net/8390.c
drivers/net/8390.h
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/Space.c
drivers/net/a2065.c
drivers/net/ac3200.c
drivers/net/acenic.c
drivers/net/apne.c
drivers/net/appletalk/ipddp.c
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/arc-rimi.c
drivers/net/arcnet/arcnet.c
drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com20020-pci.c
drivers/net/arcnet/com20020.c
drivers/net/arcnet/com90io.c
drivers/net/arcnet/com90xx.c
drivers/net/ariadne.c
drivers/net/arm/am79c961a.c
drivers/net/arm/ether00.c
drivers/net/arm/ether1.c
drivers/net/arm/ether3.c
drivers/net/arm/etherh.c
drivers/net/at1700.c
drivers/net/atari_bionet.c
drivers/net/atari_pamsnet.c
drivers/net/atarilance.c
drivers/net/atp.c
drivers/net/au1000_eth.c
drivers/net/bagetlance.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.h
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_alb.h
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/cs89x0.c
drivers/net/de600.c
drivers/net/de600.h
drivers/net/de620.c
drivers/net/declance.c
drivers/net/defxx.c
drivers/net/depca.c
drivers/net/dummy.c
drivers/net/e2100.c
drivers/net/eepro.c
drivers/net/eexpress.c
drivers/net/eql.c
drivers/net/es3210.c
drivers/net/eth16i.c
drivers/net/ethertap.c
drivers/net/ewrk3.c
drivers/net/fc/iph5526.c
drivers/net/fc/iph5526_scsi.h
drivers/net/fmv18x.c
drivers/net/forcedeth.c
drivers/net/gt96100eth.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/baycom_par.c
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/dmascc.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/hamradio/mkiss.c
drivers/net/hamradio/mkiss.h
drivers/net/hamradio/scc.c
drivers/net/hamradio/yam.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/hp100.c
drivers/net/hplance.c
drivers/net/hydra.c
drivers/net/ibmlana.c
drivers/net/ibmlana.h
drivers/net/irda/sa1100_ir.c
drivers/net/ixgb/ixgb_main.c
drivers/net/jazzsonic.c
drivers/net/lance.c
drivers/net/lasi_82596.c
drivers/net/lne390.c
drivers/net/lp486e.c
drivers/net/mac8390.c
drivers/net/mac89x0.c
drivers/net/macmace.c
drivers/net/macsonic.c
drivers/net/meth.c
drivers/net/mvme147.c
drivers/net/ne.c
drivers/net/ne2.c
drivers/net/ne2k_cbus.c
drivers/net/ne2k_cbus.h
drivers/net/ne3210.c
drivers/net/net_init.c
drivers/net/ni5010.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/ns83820.c
drivers/net/oaknet.c
drivers/net/pci-skeleton.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/com20020_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/ibmtr_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/pcnet32.c
drivers/net/plip.c
drivers/net/ppp_generic.c
drivers/net/pppoe.c
drivers/net/saa9730.c
drivers/net/sb1250-mac.c
drivers/net/seeq8005.c
drivers/net/sgiseeq.c
drivers/net/shaper.c
drivers/net/sk98lin/skge.c
drivers/net/sk_g16.c
drivers/net/sk_mca.c
drivers/net/sk_mca.h
drivers/net/skfp/skfddi.c
drivers/net/smc-mca.c
drivers/net/smc-ultra.c
drivers/net/smc-ultra32.c
drivers/net/smc9194.c
drivers/net/stnic.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/tc35815.c
drivers/net/tg3.c
drivers/net/tokenring/3c359.c
drivers/net/tokenring/abyss.c
drivers/net/tokenring/ibmtr.c
drivers/net/tokenring/madgemc.c
drivers/net/tokenring/olympic.c
drivers/net/tokenring/proteon.c
drivers/net/tokenring/skisa.c
drivers/net/tokenring/smctr.c
drivers/net/tokenring/tms380tr.c
drivers/net/tokenring/tmspci.c
drivers/net/tulip/Kconfig
drivers/net/tulip/de2104x.c
drivers/net/tulip/dmfe.c
drivers/net/tulip/interrupt.c
drivers/net/tulip/tulip.h
drivers/net/tulip/tulip_core.c
drivers/net/tulip/winbond-840.c
drivers/net/tulip/xircom_tulip_cb.c
drivers/net/tun.c
drivers/net/typhoon-firmware.h
drivers/net/typhoon.c
drivers/net/typhoon.h
drivers/net/wan/cosa.c
drivers/net/wan/lmc/lmc_main.c
drivers/net/wan/lmc/lmc_var.h
drivers/net/wan/x25_asy.c
drivers/net/wd.c
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/airo.c
drivers/net/wireless/arlan-main.c
drivers/net/wireless/arlan.h
drivers/net/wireless/atmel.c
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/atmel_pci.c [new file with mode: 0644]
drivers/net/wireless/orinoco_pci.c
drivers/net/wireless/orinoco_plx.c
drivers/net/wireless/orinoco_tmd.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/strip.c
drivers/net/wireless/wavelan.c
drivers/net/wireless/wavelan.p.h
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wavelan_cs.p.h
drivers/net/wireless/wl3501_cs.c
drivers/net/znet.c
drivers/net/zorro8390.c
drivers/parisc/Kconfig
drivers/parisc/ccio-dma.c
drivers/parisc/dino.c
drivers/parisc/eisa_eeprom.c
drivers/parisc/iosapic.c
drivers/parisc/iosapic_private.h
drivers/parisc/lba_pci.c
drivers/parisc/led.c
drivers/parisc/sba_iommu.c
drivers/parisc/superio.c
drivers/parport/daisy.c
drivers/parport/parport_gsc.c
drivers/parport/share.c
drivers/pnp/Kconfig
drivers/pnp/card.c
drivers/pnp/isapnp/Kconfig [new file with mode: 0644]
drivers/pnp/isapnp/core.c
drivers/pnp/pnpbios/Kconfig [new file with mode: 0644]
drivers/pnp/pnpbios/Makefile
drivers/pnp/pnpbios/core.c
drivers/pnp/pnpbios/pnpbios.h
drivers/s390/net/qeth.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/imm.c
drivers/scsi/imm.h
drivers/scsi/libata-core.c
drivers/scsi/ppa.c
drivers/scsi/ppa.h
drivers/scsi/qla2xxx/Kconfig
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qlogicfc.c [new file with mode: 0644]
drivers/scsi/qlogicfc.h [new file with mode: 0644]
drivers/scsi/qlogicfc_asm.c [new file with mode: 0644]
drivers/scsi/sg.c
drivers/serial/8250_pnp.c
drivers/serial/mux.c
drivers/usb/gadget/ether.c
drivers/video/Makefile
drivers/video/console/sticore.c
drivers/video/fbcmap.c
drivers/video/fbmem.c
drivers/video/fbsysfs.c [new file with mode: 0644]
drivers/video/radeonfb.c
drivers/video/riva/fbdev.c
drivers/video/stifb.c
drivers/video/vga16fb.c
fs/eventpoll.c
fs/ext2/namei.c
fs/ext2/xattr.c
fs/hfs/mdb.c
fs/hfsplus/wrapper.c
fs/xattr.c
include/acpi/processor.h
include/asm-alpha/byteorder.h
include/asm-arm/arch-integrator/cm.h [new file with mode: 0644]
include/asm-arm/arch-integrator/irqs.h
include/asm-arm/arch-integrator/system.h
include/asm-arm/arch-integrator/time.h
include/asm-arm/hardware/amba.h
include/asm-arm/hardware/sa1111.h
include/asm-arm/pci.h
include/asm-arm/semaphore.h
include/asm-arm/unistd.h
include/asm-ia64/iosapic.h
include/asm-ia64/sn/alenlist.h [deleted file]
include/asm-ia64/sn/hcl.h
include/asm-ia64/sn/pci/pcibr.h
include/asm-ia64/sn/pci/pciio.h
include/asm-ia64/sn/sn2/shubio.h
include/asm-ia64/sn/xtalk/xtalk.h
include/asm-parisc/cache.h
include/asm-parisc/compat.h
include/asm-parisc/compat_rt_sigframe.h [new file with mode: 0644]
include/asm-parisc/compat_signal.h [new file with mode: 0644]
include/asm-parisc/compat_ucontext.h [new file with mode: 0644]
include/asm-parisc/pci.h
include/asm-parisc/pdc.h
include/asm-parisc/posix_types.h
include/asm-parisc/rt_sigframe.h
include/asm-parisc/siginfo.h
include/asm-parisc/superio.h
include/asm-parisc/uaccess.h
include/asm-ppc/open_pic.h
include/asm-ppc64/eeh.h
include/asm-ppc64/io.h
include/asm-ppc64/paca.h
include/asm-ppc64/pci.h
include/asm-ppc64/vio.h
include/asm-sparc/unistd.h
include/asm-sparc64/unistd.h
include/asm-v850/delay.h
include/asm-v850/module.h
include/linux/acpi.h
include/linux/arcdevice.h
include/linux/com20020.h
include/linux/fb.h
include/linux/ide.h
include/linux/if_bonding.h
include/linux/if_vlan.h
include/linux/in6.h
include/linux/inetdevice.h
include/linux/input.h
include/linux/ioport.h
include/linux/ipv6.h
include/linux/kernel.h
include/linux/mod_devicetable.h
include/linux/netdevice.h
include/linux/netfilter_ipv4/ip_conntrack_core.h
include/linux/parport.h
include/linux/pci_ids.h
include/linux/pkt_sched.h
include/linux/pnp.h
include/linux/ptrace.h
include/linux/scc.h
include/linux/sctp.h
include/linux/string.h
include/linux/sysctl.h
include/linux/tcp.h
include/net/arp.h
include/net/atmclip.h
include/net/ip6_route.h
include/net/ipv6.h
include/net/irda/irlmp_frame.h
include/net/irda/timer.h
include/net/ndisc.h
include/net/neighbour.h
include/net/pkt_sched.h
include/net/sctp/constants.h
include/net/sctp/structs.h
include/net/tcp.h
include/sound/ac97_codec.h
include/sound/sndmagic.h
include/sound/tea575x-tuner.h [new file with mode: 0644]
include/sound/version.h
ipc/util.c
ipc/util.h
kernel/exit.c
kernel/printk.c
kernel/resource.c
lib/bitmap.c
lib/string.c
lib/vsprintf.c
mm/filemap.c
net/8021q/vlan_dev.c
net/Kconfig
net/appletalk/ddp.c
net/atm/clip.c
net/ax25/af_ax25.c
net/bridge/br_if.c
net/core/dev.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/utils.c
net/decnet/Kconfig
net/decnet/af_decnet.c
net/decnet/dn_neigh.c
net/decnet/dn_route.c
net/econet/af_econet.c
net/ipv4/Kconfig
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/igmp.c
net/ipv4/ipvs/Kconfig
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_ftp.c
net/ipv4/netfilter/ip_conntrack_proto_generic.c
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
net/ipv4/netfilter/ip_conntrack_proto_udp.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_conntrack_tftp.c
net/ipv4/netfilter/ip_fw_compat.c
net/ipv4/netfilter/ip_fw_compat_masq.c
net/ipv4/netfilter/ip_fw_compat_redir.c
net/ipv4/netfilter/ip_nat_core.c
net/ipv4/netfilter/ip_nat_ftp.c
net/ipv4/netfilter/ip_nat_helper.c
net/ipv4/netfilter/ip_nat_proto_icmp.c
net/ipv4/netfilter/ip_nat_proto_tcp.c
net/ipv4/netfilter/ip_nat_proto_udp.c
net/ipv4/netfilter/ip_nat_proto_unknown.c
net/ipv4/netfilter/ip_nat_rule.c
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/ip_nat_tftp.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLASSIFY.c
net/ipv4/netfilter/ipt_DSCP.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/ipt_MARK.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_NETMAP.c
net/ipv4/netfilter/ipt_REDIRECT.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_SAME.c
net/ipv4/netfilter/ipt_TCPMSS.c
net/ipv4/netfilter/ipt_TOS.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_ah.c
net/ipv4/netfilter/ipt_conntrack.c
net/ipv4/netfilter/ipt_dscp.c
net/ipv4/netfilter/ipt_ecn.c
net/ipv4/netfilter/ipt_esp.c
net/ipv4/netfilter/ipt_helper.c
net/ipv4/netfilter/ipt_iprange.c
net/ipv4/netfilter/ipt_length.c
net/ipv4/netfilter/ipt_limit.c
net/ipv4/netfilter/ipt_mac.c
net/ipv4/netfilter/ipt_mark.c
net/ipv4/netfilter/ipt_multiport.c
net/ipv4/netfilter/ipt_owner.c
net/ipv4/netfilter/ipt_physdev.c
net/ipv4/netfilter/ipt_pkttype.c
net/ipv4/netfilter/ipt_state.c
net/ipv4/netfilter/ipt_tcpmss.c
net/ipv4/netfilter/ipt_tos.c
net/ipv4/netfilter/ipt_ttl.c
net/ipv4/netfilter/iptable_filter.c
net/ipv4/netfilter/iptable_mangle.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv6/Kconfig
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/anycast.c
net/ipv6/datagram.c
net/ipv6/exthdrs.c
net/ipv6/ipv6_sockglue.c
net/ipv6/mcast.c
net/ipv6/ndisc.c
net/ipv6/netfilter/Kconfig
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_MARK.c
net/ipv6/netfilter/ip6t_ah.c
net/ipv6/netfilter/ip6t_dst.c
net/ipv6/netfilter/ip6t_esp.c
net/ipv6/netfilter/ip6t_eui64.c
net/ipv6/netfilter/ip6t_frag.c
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/netfilter/ip6t_hl.c
net/ipv6/netfilter/ip6t_ipv6header.c
net/ipv6/netfilter/ip6t_length.c
net/ipv6/netfilter/ip6t_limit.c
net/ipv6/netfilter/ip6t_mac.c
net/ipv6/netfilter/ip6t_mark.c
net/ipv6/netfilter/ip6t_multiport.c
net/ipv6/netfilter/ip6t_owner.c
net/ipv6/netfilter/ip6t_rt.c
net/ipv6/netfilter/ip6table_filter.c
net/ipv6/netfilter/ip6table_mangle.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/udp.c
net/ipx/af_ipx.c
net/irda/af_irda.c
net/key/af_key.c
net/llc/llc_conn.c
net/netlink/af_netlink.c
net/netrom/af_netrom.c
net/packet/af_packet.c
net/rose/af_rose.c
net/sched/Kconfig
net/sched/sch_hfsc.c [new file with mode: 0644]
net/sctp/Kconfig
net/sctp/Makefile
net/sctp/adler32.c [deleted file]
net/sctp/associola.c
net/sctp/endpointola.c
net/sctp/protocol.c
net/sctp/sysctl.c
net/sctp/ulpqueue.c
net/sunrpc/sched.c
net/unix/af_unix.c
net/wanrouter/wanmain.c
net/x25/af_x25.c
net/xfrm/xfrm_policy.c
scripts/file2alias.c
scripts/modpost.c
sound/core/Makefile
sound/core/oss/mixer_oss.c
sound/core/rawmidi.c
sound/core/sound.c
sound/i2c/other/Makefile
sound/i2c/other/tea575x-tuner.c [new file with mode: 0644]
sound/isa/es1688/es1688.c
sound/isa/gus/interwave.c
sound/oss/ad1889.c
sound/oss/dmasound/tas3004.c
sound/oss/dmasound/trans_16.c
sound/oss/harmony.c
sound/pci/Kconfig
sound/pci/Makefile
sound/pci/ac97/ac97_codec.c
sound/pci/bt87x.c [new file with mode: 0644]
sound/pci/cs46xx/dsp_spos_scb_lib.c
sound/pci/emu10k1/emufx.c
sound/pci/fm801.c
sound/pci/ice1712/aureon.h
sound/pci/ice1712/delta.c
sound/pci/ice1712/delta.h
sound/pci/ice1712/ice1724.c
sound/pci/intel8x0.c
sound/pci/via82xx.c
sound/pci/vx222/vx222_ops.c

diff --git a/CREDITS b/CREDITS
index 07a7a0d..13eba32 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -818,6 +818,11 @@ S: 1382 Bordeaux Drive
 S: Sunnyvale, CA 94087
 S: USA
 
+N: Bruno Ducrot
+E: ducrot@poupinou.org
+D: CPUFreq and ACPI bugfixes.
+S: Mougin, France
+
 N: Don Dugger
 E: n0ano@valinux.com
 D: Linux/IA-64
@@ -897,8 +902,8 @@ E: bj0rn@blox.se
 W: http://www.pi.se/blox/
 D: Extended support for loadable modules
 D: D-Link pocket adapter drivers
-S: Grevgatan 11
-S: S-114 53 Stockholm
+S: Brevia 1043
+S: S-114 79 Stockholm
 S: Sweden
 
 N: Michael Engel
index 1618de5..fe1bf8b 100644 (file)
@@ -236,13 +236,15 @@ Networking
 General changes
 ---------------
 
-The IP firewalling and NAT code has been replaced again.  The new
-netfilter software (including ipfwadm and ipchains backwards-
-compatible modules) is currently distributed separately.
-
 If you have advanced network configuration needs, you should probably
 consider using the network tools from ip-route2.
 
+Packet Filter / NAT
+-------------------
+The packet filtering and NAT code uses the same tools like the previous 2.4.x
+kernel series (iptables).  It still includes backwards-compatibility modules
+for 2.2.x-style ipchains and 2.0.x-style ipfwadm.
+
 PPP
 ---
 
@@ -399,15 +401,13 @@ NFS-utils
 ---------
 o  <http://sourceforge.net/project/showfiles.php?group_id=14>
 
-Netfilter
----------
-o  <http://netfilter.filewatcher.org/iptables-1.2.tar.bz2>
-o  <http://netfilter.samba.org/iptables-1.2.tar.bz2>
-o  <http://netfilter.kernelnotes.org/iptables-1.2.tar.bz2>
+Iptables
+--------
+o  <http://www.iptables.org/downloads.html>
 
 Ip-route2
 ---------
-o  <ftp://ftp.inr.ac.ru/ip-routing/iproute2-2.2.4-now-ss991023.tar.gz>
+o  <ftp://ftp.tux.org/pub/net/ip-routing/iproute2-2.2.4-now-ss991023.tar.gz>
 
 OProfile
 --------
index c08521b..d77a5dc 100644 (file)
@@ -241,7 +241,7 @@ Let the compiler optimize away the "no-op" case.
 
 Simple example, of poor code:
 
-       dev = init_etherdev (NULL, 0);
+       dev = alloc_etherdev (sizeof(struct funky_private));
        if (!dev)
                return -ENODEV;
        #ifdef CONFIG_NET_FUNKINESS
@@ -256,7 +256,7 @@ Cleaned-up example:
        #endif
 
 (in the code itself)
-       dev = init_etherdev (NULL, 0);
+       dev = alloc_etherdev (sizeof(struct funky_private));
        if (!dev)
                return -ENODEV;
        init_funky_net(dev);
index d0e9602..fef7413 100644 (file)
@@ -13,6 +13,7 @@ This driver is known to work with the following cards:
        * SA 642
        * SA 6400
        * SA 6400 U320 Expansion Module
+       * SA 6i
 
 If nodes are not already created in the /dev/cciss directory
 
diff --git a/Documentation/networking/8139too.txt b/Documentation/networking/8139too.txt
deleted file mode 100644 (file)
index c73effc..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-
-               "8139too" Fast Ethernet driver for Linux
-        RTL-8139, -8129, and -8130 10/100 Fast Ethernet adapters
-
-       Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
-
-                http://sourceforge.net/projects/gkernel/
-
-
-             Architectures supported (all PCI platforms):
-                   x86, Alpha AXP, PowerPC, Sparc64
-
-                   Kernel versions supported: 2.4.x
-
-
-
-Disclaimer
-----------
-
-DO NOT CONTACT DONALD BECKER FOR SUPPORT OF THIS DRIVER, his driver is
-completely different and maintained independently of the 8139too code base.
-
-
-
-Requirements
-------------
-Kernel 2.4.3 or later.
-A Fast Ethernet adapter containing an RTL8139-based chip.
-
-
-
-Introduction
-------------
-
-The "8139too" Fast Ethernet driver for Linux 2.4.0 is a substantial
-modification of the experimental rtl8139 driver from Donald Becker,
-some versions of which appeared in 2.2.x and 2.3.x kernels.  The
-RTL-8139 is a very low-cost Fast Ethernet chip, which makes it very
-popular.
-
-The step from 2.2.x to 2.4.x kernels brings many new features to Linux
-device drivers.  Features for MMIO resources, a standard hot-plug API,
-and other interfaces are now becoming requirements, as drivers move
-off the x86 platform.  With that in mind, I have begun updating the
-RTL-8139 driver to current 2.3.x (2.4) kernel standards and APIs, and
-fixing the problems that users have been encountering.
-
-
-
-Features of 8139too
--------------------
-[note - this list intended for people familiar with kernel drivers]
-
-** 100% MMIO, for full speed operation.  All users (so far) have
-reported performance increases over their existing RTL drivers.
-
-** Multi-platform support:  x86, Alpha, PPC, ...
-
-** Use proper SMP spinlocking, fixing SMP interrupt bugs, making the
-driver portable to non-x86 SMP platforms in the process.
-
-** Use new PCI driver API for seamless, low-maintenance hot-plug support
-
-** Several bugs fixes from original rtl8139 1.08r (October 5, 1999),
-including the very common "transmit timeout" problem.
-
-* Use new resource allocation API, required for hot-plug support
-* Use new register read/write macros
-* initcall support (module_init/exit)
-* vastly improved debug tracing support
-* code formatting in many places for readability
-* use new init_etherdev() facilities
-
-...and probably some other less important changes which I forgot.
-
-
-
-Installation
-------------
-
-OPTION 1: Build inside kernel tree (into kernel image, or as module)
-
-       (overwrite 8139too driver in kernel tree with different version)
-       1) cp 8139too.c $my_source_tree/drivers/net/8139too.c
-
-OPTION 2: Build outside kernel tree
-
-       Use the included Makefile.
-
-
-
-Tested Adapters
----------------
-AOpen ALN-325C
-AT-2500TX 10/100 PCI Fast Ethernet Network Adapter Card
-D-Link DFE-530TX
-Cnet CNF401 'SinglePoint' 10/100 Base-TX
-Genius GF 100TXR4 Fast Ethernet 10/100M PCI Network Card
-KTI KF-230TX
-KTI KF-230TX/2
-Lantech FastNet TX
-Ovislink Fast Ethernet
-Planet ENW-9504 (V.4) 10/100
-SDT Jeoun Fast PCI-TX
-SMC EZNET 10/100
-UNEX NexNIC ND012C
-
-(please add your adapter model to this list)
-
-
-
-Status of Platform Support
---------------------------
-
-(see errata below for details)
-
-x86:           tested, stable
-Alpha AXP:     tested, stable
-PowerPC:       tested, unstable
-Sparc64:       not tested
-
-
-
-Special Thanks
---------------
-The following people contributed invaluable testing time, feedback
-and/or patches during the development of this driver.  Thanks to all
-of them.
-
-Donald Becker, Alan Cox, Richard Stallman, Linus Torvalds - inspiration
-
-Alan Cox, Gerard Roudier - insight on posted MMIO writes
-
-Martin Mares - code review
-
-Tigran Aivazian - testing, code review, and a bug fix
-
-Chmouel Boudjnah, Alexander Dietrich, Oleg Drokin,
-James Fidell, Taso Hatzi, Peter K - intrepid test team
-
-And thanks to every supporter free software.
-
-(see top of 8139too.c for further credits and kudos)
-
-
-
-Submitting Bug Reports
-----------------------
-Obtain and compile the modified rtl8139-diag source code from the
-8139too driver Web site, http://sourceforge.net/projects/gkernel/
-This diagnostics programs, originally from Donald Becker, has been
-modified to display all registers on your RTL8139 chip, not just the
-first 0x80.
-
-If possible, send the output of a working and broken driver with
-       rtl8139-diag -mmaaavvveefN > my-output-file.txt
-
-Send "lspci -vvv" or "cat /proc/pci" output for PCI information.
-
-
-
-Known Bugs / Errata / To-Do
----------------------------
-The following issues are known, and are actively being pursued.  Patches
-to resolve these issues is welcome.  If a problem occurs which is not in
-the list, please report it.  That's why we do beta releases, after all...
-
-
-
-1) Work with Donald to merge fixes and updates into his driver.
-
-2) ETHTOOL_SSET support
-
-3) PPC platform has stability problems. (XXX: verify this is still true)
-
-4) Sparc64 platform not tested at all.
-
-8) Much improved command line / module parameter setup.  (patches and
-suggestions welcome)  (WIP)
-
-9) Better documentation.  (patches welcome)
-
-12) 10base-T support flaky or slow (todo: verify this is still true)
-
-
-
-
-Change History
---------------
-
-Version 0.9.26 - August 9, 2002
-
-* Fix MII ioctl phy id corruption.
-* Fix big-endian multicast bug.
-* Support register dumps via ethtool.
-* Fix several uses of 'len' after potential skb free, in dev->hard_start_xmit
-* Replace several "magic numbers" with their proper representation
-  constants in linux/mii.h.
-* Support ethtool media interface via generic kernel MII API
-* Export NIC-specific statistics via ethtool.
-* Proper support for RTL8139 rev K. (can be disabled via
-  compile-time conditional)
-* Add PCI ids for new 8139 boards.
-* Use ethernet crc via generic linux/crc32.h kernel API.
-* Better RX reset.  Old rx-reset method still available via
-  a compile-time conditional.
-* Only account specific RX errors if rx_status is !OK
-
-
-Version 0.9.22 - November 8, 2001
-
-* Additional retries before aborting Tx
-* Do not write other TxConfig bits when writing clear-abort bit.
-* Ack TxErr intr status after each Tx abort, too.
-* Fix oops in interface restart
-
-
-Version 0.9.21 - November 1, 2001
-
-* Disable early Rx, it hurts performance and creates races.
-* Remove DPRINTK macro function tracing.
-* Better interrupt sharing behavior.
-* Acknowledge PCI errors.
-* Remove early-Rx acknowledgement, unnecessary
-* Remove code for uncommon case where Tx packets are
-  properly aligned, and do not need to be copied.
-  Tx packets are now always copied into a static DMA buffer,
-  which is allocated at interface open.
-* Fix problems with kernel thread exit.
-
-
-Version 0.9.20 - October 18, 2001
-
-* Print out notice when 8139C+ chip is detected
-* Add id for D-Link DFE690TXD pcmcia cardbus card (Gert Dewit)
-
-
-Version 0.9.19 - October 9, 2001
-
-* Eliminate buffer copy for unaligned Tx's (manfred)
-* Better RX error recovery (manfred)
-* Wake-On-LAN and ETHTOOL_GSET support (Kalle Niemitalo)
-* Fix assertion in PIO mode (various)
-
-
-Version 0.9.18 - July 6, 2001
-
-* Fix race leading to crashes on some machines.
-* Minimize race leading to low performance.
-* Correct interrupt acknowledgement to cover all three
-  relevant Rx events.
-* Add ethtool driver info support.
-* Collect additional driver-internal statistics.
-* Add descriptions for module parameters.
-* Support new SIOCxMIIxxx ioctls added in kernel 2.4.6.
-* Multicast filter big endian fix.
-* Support new PCI PM API added in kernel 2.4.6.
-
-
-Version 0.9.17 - May 7, 2001
-
-* Fix chipset wakeup bug which prevent media connection for 8139B
-* Print out "media is unconnected..." instead of
-  "partner ability 0000"
-
-
-Version 0.9.16 - April 14, 2001
-
-* Complete MMIO audit, disable read-after-every-write
-* Update Rx interrupt handling
-* Enable Early Rx thresholds, highly recommended to reduce
-  Rx FIFO overflow
-* Make 8129 support conditional
-* Support for new 2.4.3 kernel APIs
-* More correct PIO/MMIO PCI BAR region size checking
-* Add check for totally dead/missing hardware
-* Disable media timer code to "set full duplex"
-* s/spin_lock_irq/spin_lock_irqsave/
-* Only set AcceptMulticast if more than one mc address
-* Only set rx_mode if changed, in set_rx_mode
-* Only suspend/resume if interface is up
-* Always print out version upon module load, even if no devices found
-
-
-Version 0.9.15 - February 20, 2001
-
-* Call pci_enable_device to wake up/assign resource to device,
-  before actually using it.
-* Support wacky clone PCI ids (report from Norival Toniato Junior)
-* Text spelling corrections
-* Make sure tp->phys[] is signed
-* Always wake queue after hw restart, in tx_timeout
-* Record time of last received packet
-
-
-Version 0.9.14 - January 11, 2001
-
-* Merge some changes from Becker version 1.13:
-       * Add DFE 538TX PCI id
-       * MII read/write functions updated
-       * Cfg93[45]6 lock/unlock fix
-       * RTL-8129 (MII) support
-* Clean up spinlocking
-
-
-Version 0.9.13 - December, 2000
-
-* Clear blocked signals, avoid buffer overrun setting current->comm
-* Remove bogus PCI BAR length assertions
-* Remove unused 'debug' module parameter
-
-
-Version 0.9.12 - November 23, 2000
-
-* Kill major Tx stop/wake queue race
-* Use SET_MODULE_OWNER and fix module unload race
-* Fix cable length ("Twister") tuning
-* Proper media[] array length checking
-* Replace timer with kernel thread for twister tuning state machine
-  and media checking.  Fixes mdio_xxx locking, now mdio_xxx is always
-  protected by rtnl_lock semaphore.
-* Correct some sledgehammer a.k.a. overzealous spin-locks
-* Performance: Eliminate atomic_t for Tx counters, we don't need it
-* Performance: Don't copy Tx buffer if the rare case occurs where it
-  is aligned perfectly for us.
-* Eliminate needless casting of dev->priv
-* PIO mode selection and Twister tuning are now CONFIG_xxx options
-  (though purposefully not in net/Config.in... yet)
-
-
-Version 0.9.11 - October 28, 2000
-
-* Do not fail when PIO and MMIO region lengths do not match.
-  (They don't on some CardBus models, at least)
-* Sanity check Rx packet status and size (Tobias)
-* When handling a Tx timeout, disable Tx ASAP if not already.
-* Do not inline Tx interrupt handler (better register usage)
-* Handle dirty_tx signed integer wrap
-* Do not abort Rx processing on lack of memory, keep going
-  until the current Rx ring is completely handling. (Tobias)
-* Clean up rtl8139_close
-* Whitespace correction for dev_kfree_skb_irq call
-
-
-Version 0.9.10 - September 12, 2000
-
-* Never wrap an Rx packet (faster Rx interrupt handling)
-* Clear all TxAborted conditions (bug fix)
-* Correct copyright
-* More credits
-* Update NWay doc URL
-* Clean up commonly used ifdef switches
-* Reorg info displayed at bootup/modprobe time
-* Remove some unneeded spinlocks
-* Misc cosmetic code cleanup
-* Always print interrupt status for abnormal interrupts
-* Use RealTek-recommended FIFO and DMA burst settings (1024 bytes)
-
-
-Version 0.9.9 - September 9, 2000
-
-* Fix oops-able bug in Rx ring wrap calculation (David Ford)
-* Use PIO instead of MMIO when USE_IO_OPS is defined
-* Move Rx error handling out of Rx interrupt handler, resulting in
-  tighter Rx interrupt processing
-
-
-Version 0.9.8 - September 7, 2000
-
-* Propagate request_irq error value (andrew morton)
-* Correct potential oops bug in PCI DMA unmap code
-* Fix bugs related to counting/discounting of 32-bit CRC in each Rx packet
-* Fix 16/32-bit bug in interrupt status check
-* Timer cleanups (andrew morton)
-
-
-Version 0.9.7 - June 11, 2000
-
-* Fix support for older chips (RTL8139 early chips should now work again)
-
-
-Version 0.9.6 - May 30, 2000
-
-* Fix 4-extra-bytes bug
-  (thanks to Markus Westergren, via Santiago Garcia Mantinan)
-* Yet more improved chip recognition
-
-
-Version 0.9.5 - May 17, 2000
-
-* Improved chip version recognition
-* Continue banging away at receiver hang problem
-* Use spin_lock_irq in another spot
-* Don't print anything on pci_enable_device, it does so for us
-* Disable buggy NWay code
-* Define TxConfig bitmasks
-
-
-Version 0.9.4.1 - April 27, 2000 - third public beta release
-
-* Replace several "magic numbers" with symbolic constants
-* Differentiate between board-specific info and chip-specific info
-  (allows for easier support of specific boards or chips)
-* Move some of the transmit side outside of the spinlock
-  by using atomic variables.  Use spin_lock_irq instead of
-  spin_lock_irq{save,restore} in select places, for better performance.
-* New module option "media" for forcing media selection.  Functions the
-  same as "options" in other drivers, and will soon be renamed
-  'options' to be homogeneous.
-* New power management wake-up code
-* Slightly more verbose chip id messages in kernel log
-* Add/correct chip register constant list
-* New chipset wake up (open) logic
-* No longer locks CONFIGx updates
-* Do not set Interfame Gap (IFG) bits in TxConfig
-* Better Rx reset logic in case of Rx FIFO Overflow
-* For chips which support it, enable bit to automatically clear Rx
-  FIFO overflow
-* No longer enable and disable interrupts in interrupt handler
-  (technique borrowed from BSD driver, appears to have problems
-   with some chips)
-* H/W spinlock now protects ioctl
-* Chipset-dependent RxConfig settings
-
-
-Version 0.9.3.3.2 - Feb 22, 2000 - second public beta release
-
-* Begin integration of Daniel Kobras' MMIO flush patch (disabled for now)
-* Softnet logic updates to fix bugs and improve performance
-* Dynamic sizing of I/O resources (0x80 for older chips, 0xFF for newer ones)
-* Remove bogus SiS entries from PCI probe table
-* Add support for cards
-       "Delta Electronics 8139 10/100BaseTX"
-       "Addtron Technolgy 8139 10/100BaseTX"
-* Fix major bug with rx ring buffer size (also present in rtl8139.c 1.08r)
-* PCI DMA mapping by Dave Miller
-* Complete rewrite of SMP locking logic
-* Hotplug support
-* Call rtl8139_hw_start from rtl8139_open, and remove duplicated code
-  from rtl8139_open
-* Reset NWay registers to sane defaults on rtl8139_open/hw_start
-* Miscellaneous code cleanup
-
-
-Version 0.7.0 - Feb 7, 2000 - first public beta release
-* Initial public version, derived from Donald Becker's rtl8139.c v1.08r
-
-[EOF]
-
index 32acbb0..372b6f5 100644 (file)
@@ -21,7 +21,7 @@ userspace tools, please follow the links at the end of this file.
 
 Table of Contents
 =================
+
 Installation
 Bond Configuration
 Module Parameters
@@ -66,7 +66,7 @@ of the -I option on the ifenslave compile line is to make sure it uses
 /usr/include/linux.
 
 To install ifenslave.c, do:
-    # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave 
+    # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave
     # cp ifenslave /sbin/ifenslave
 
 
@@ -74,10 +74,10 @@ Bond Configuration
 ==================
 
 You will need to add at least the following line to /etc/modules.conf
-so the bonding driver will automatically load when the bond0 interface is 
-configured. Refer to the modules.conf manual page for specific modules.conf 
-syntax details. The Module Parameters section of this document describes each 
-bonding driver parameter. 
+so the bonding driver will automatically load when the bond0 interface is
+configured. Refer to the modules.conf manual page for specific modules.conf
+syntax details. The Module Parameters section of this document describes each
+bonding driver parameter.
 
        alias bond0 bonding
 
@@ -113,7 +113,7 @@ bonding interface (bond1), use MASTER=bond1 in the config file to make the
 network interface be a slave of bond1.
 
 Restart the networking subsystem or just bring up the bonding device if your
-administration tools allow it. Otherwise, reboot. On Red Hat distros you can 
+administration tools allow it. Otherwise, reboot. On Red Hat distros you can
 issue `ifup bond0' or `/etc/rc.d/init.d/network restart'.
 
 If the administration tools of your distribution do not support
@@ -128,30 +128,30 @@ manually configure the bonding device with the following commands:
 
 (use appropriate values for your network above)
 
-You can then create a script containing these commands and place it in the 
+You can then create a script containing these commands and place it in the
 appropriate rc directory.
 
 If you specifically need all network drivers loaded before the bonding driver,
-adding the following line to modules.conf will cause the network driver for 
+adding the following line to modules.conf will cause the network driver for
 eth0 and eth1 to be loaded before the bonding driver.
 
 probeall bond0 eth0 eth1 bonding
 
-Be careful not to reference bond0 itself at the end of the line, or modprobe 
+Be careful not to reference bond0 itself at the end of the line, or modprobe
 will die in an endless recursive loop.
 
-To have device characteristics (such as MTU size) propagate to slave devices, 
-set the bond characteristics before enslaving the device.  The characteristics 
+To have device characteristics (such as MTU size) propagate to slave devices,
+set the bond characteristics before enslaving the device.  The characteristics
 are propagated during the enslave process.
 
-If running SNMP agents, the bonding driver should be loaded before any network 
-drivers participating in a bond. This requirement is due to the the interface 
-index (ipAdEntIfIndex) being associated to the first interface found with a 
-given IP address. That is, there is only one ipAdEntIfIndex for each IP 
-address. For example, if eth0 and eth1 are slaves of bond0 and the driver for 
-eth0 is loaded before the bonding driver, the interface for the IP address 
-will be associated with the eth0 interface. This configuration is shown below, 
-the IP address 192.168.1.1 has an interface index of 2 which indexes to eth0 
+If running SNMP agents, the bonding driver should be loaded before any network
+drivers participating in a bond. This requirement is due to the the interface
+index (ipAdEntIfIndex) being associated to the first interface found with a
+given IP address. That is, there is only one ipAdEntIfIndex for each IP
+address. For example, if eth0 and eth1 are slaves of bond0 and the driver for
+eth0 is loaded before the bonding driver, the interface for the IP address
+will be associated with the eth0 interface. This configuration is shown below,
+the IP address 192.168.1.1 has an interface index of 2 which indexes to eth0
 in the ifDescr table (ifDescr.2).
 
      interfaces.ifTable.ifEntry.ifDescr.1 = lo
@@ -189,10 +189,10 @@ functions such as Interface_Scan_Next will report that association.
 Module Parameters
 =================
 
-Optional parameters for the bonding driver can be supplied as command line 
-arguments to the insmod command. Typically, these parameters are specified in 
-the file /etc/modules.conf (see the manual page for modules.conf). The 
-available bonding driver parameters are listed below. If a parameter is not 
+Optional parameters for the bonding driver can be supplied as command line
+arguments to the insmod command. Typically, these parameters are specified in
+the file /etc/modules.conf (see the manual page for modules.conf). The
+available bonding driver parameters are listed below. If a parameter is not
 specified the default value is used. When initially configuring a bond, it
 is recommended "tail -f /var/log/messages" be run in a separate window to
 watch for bonding driver error messages.
@@ -202,19 +202,19 @@ parameters be specified, otherwise serious network degradation will occur
 during link failures.
 
 arp_interval
-        Specifies the ARP monitoring frequency in milli-seconds. 
-        If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the 
-        switch should be configured in a mode that evenly distributes packets 
-        across all links - such as round-robin. If the switch is configured to 
-        distribute the packets in an XOR fashion, all replies from the ARP 
-        targets will be received on the same link which could cause the other 
+
+        Specifies the ARP monitoring frequency in milli-seconds.
+        If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the
+        switch should be configured in a mode that evenly distributes packets
+        across all links - such as round-robin. If the switch is configured to
+        distribute the packets in an XOR fashion, all replies from the ARP
+        targets will be received on the same link which could cause the other
         team members to fail. ARP monitoring should not be used in conjunction
-        with miimon. A value of 0 disables ARP monitoring. The default value 
+        with miimon. A value of 0 disables ARP monitoring. The default value
         is 0.
+
 arp_ip_target
+
        Specifies the ip addresses to use when arp_interval is > 0. These
        are the targets of the ARP request sent to determine the health of
        the link to the targets. Specify these values in ddd.ddd.ddd.ddd
@@ -223,8 +223,8 @@ arp_ip_target
        maximum number of targets that can be specified is set at 16.
 
 downdelay
-        Specifies the delay time in milli-seconds to disable a link after a 
+
+        Specifies the delay time in milli-seconds to disable a link after a
         link failure has been detected. This should be a multiple of miimon
         value, otherwise the value will be rounded. The default value is 0.
 
@@ -247,7 +247,7 @@ max_bonds
        and bond2 will be created.  The default value is 1.
 
 miimon
+
         Specifies the frequency in milli-seconds that MII link monitoring
         will occur. A value of zero disables MII link monitoring. A value
         of 100 is a good starting point. See High Availability section for
@@ -258,7 +258,7 @@ mode
        Specifies one of the bonding policies. The default is
        round-robin (balance-rr).  Possible values are (you can use
        either the text or numeric option):
+
        balance-rr or 0
 
                Round-robin policy: Transmit in a sequential order
@@ -273,7 +273,7 @@ mode
                externally visible on only one port (network adapter)
                to avoid confusing the switch.  This mode provides
                fault tolerance.
+
        balance-xor or 2
 
                XOR policy: Transmit based on [(source MAC address
@@ -293,7 +293,7 @@ mode
                groups that share the same speed and duplex settings.
                Transmits and receives on all slaves in the active
                aggregator.
+
                Pre-requisites:
 
                1. Ethtool support in the base drivers for retrieving the
@@ -317,7 +317,7 @@ mode
                Ethtool support in the base drivers for retrieving the
                speed of each slave.
 
-       balance-alb or 6 
+       balance-alb or 6
 
                Adaptive load balancing: includes balance-tlb + receive
                load balancing (rlb) for IPV4 traffic and does not require
@@ -327,7 +327,7 @@ mode
                overwrites the src hw address with the unique hw address of
                one of the slaves in the bond such that different clients
                use different hw addresses for the server.
-               
+
                Receive traffic from connections created by the server is
                also balanced. When the server sends an ARP Request the
                bonding driver copies and saves the client's IP information
@@ -363,25 +363,11 @@ mode
                2. Base driver support for setting the hw address of a
                device also when it is open. This is required so that there
                will always be one slave in the team using the bond hw
-               address (the current_slave) while having a unique hw
-               address for each slave in the bond. If the current_slave
-               fails it's hw address is swapped with the new current_slave
+               address (the curr_active_slave) while having a unique hw
+               address for each slave in the bond. If the curr_active_slave
+               fails it's hw address is swapped with the new curr_active_slave
                that was chosen.
 
-multicast
-
-        Option specifying the mode of operation for multicast support.
-        Possible values are:
-
-       disabled or 0
-               Disabled (no multicast support)
-
-        active or 1
-               Enabled on active slave only, useful in active-backup mode
-
-       all or 2
-               Enabled on all slaves, this is the default
-
 primary
 
         A string (eth0, eth2, etc) to equate to a primary device. If this
@@ -397,11 +383,11 @@ primary
         primary is only valid in active-backup mode.
 
 updelay
-        Specifies the delay time in milli-seconds to enable a link after a 
+
+        Specifies the delay time in milli-seconds to enable a link after a
         link up status has been detected. This should be a multiple of miimon
         value, otherwise the value will be rounded. The default value is 0.
+
 use_carrier
 
         Specifies whether or not miimon should use MII or ETHTOOL
@@ -529,20 +515,20 @@ Verifying Bond Configuration
 ----------------------------
 The bonding driver information files reside in the /proc/net/bonding directory.
 
-Sample contents of /proc/net/bonding/bond0 after the driver is loaded with 
+Sample contents of /proc/net/bonding/bond0 after the driver is loaded with
 parameters of mode=0 and miimon=1000 is shown below.
+
         Bonding Mode: load balancing (round-robin)
         Currently Active Slave: eth0
         MII Status: up
         MII Polling Interval (ms): 1000
         Up Delay (ms): 0
         Down Delay (ms): 0
+
         Slave Interface: eth1
         MII Status: up
         Link Failure Count: 1
+
         Slave Interface: eth0
         MII Status: up
         Link Failure Count: 1
@@ -550,34 +536,34 @@ parameters of mode=0 and miimon=1000 is shown below.
 2) Network verification
 -----------------------
 The network configuration can be verified using the ifconfig command. In
-the example below, the bond0 interface is the master (MASTER) while eth0 and 
-eth1 are slaves (SLAVE). Notice all slaves of bond0 have the same MAC address 
+the example below, the bond0 interface is the master (MASTER) while eth0 and
+eth1 are slaves (SLAVE). Notice all slaves of bond0 have the same MAC address
 (HWaddr) as bond0 for all modes except TLB and ALB that require a unique MAC
 address for each slave.
 
 [root]# /sbin/ifconfig
-bond0     Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4  
+bond0     Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4
           inet addr:XXX.XXX.XXX.YYY  Bcast:XXX.XXX.XXX.255  Mask:255.255.252.0
           UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
           RX packets:7224794 errors:0 dropped:0 overruns:0 frame:0
           TX packets:3286647 errors:1 dropped:0 overruns:1 carrier:0
-          collisions:0 txqueuelen:0 
+          collisions:0 txqueuelen:0
 
-eth0      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4  
+eth0      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4
           inet addr:XXX.XXX.XXX.YYY  Bcast:XXX.XXX.XXX.255  Mask:255.255.252.0
           UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
           RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0
           TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0
-          collisions:0 txqueuelen:100 
-          Interrupt:10 Base address:0x1080 
+          collisions:0 txqueuelen:100
+          Interrupt:10 Base address:0x1080
 
-eth1      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4  
+eth1      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4
           inet addr:XXX.XXX.XXX.YYY  Bcast:XXX.XXX.XXX.255  Mask:255.255.252.0
           UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
           RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0
           TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0
-          collisions:0 txqueuelen:100 
-          Interrupt:9 Base address:0x1400 
+          collisions:0 txqueuelen:100
+          Interrupt:9 Base address:0x1400
 
 
 Frequently Asked Questions
@@ -605,9 +591,9 @@ Frequently Asked Questions
 
 5.  What happens when a slave link dies?
 
-       If your ethernet cards support MII or ETHTOOL link status monitoring 
-        and the MII monitoring has been enabled in the driver (see description 
-        of module parameters), there will be no adverse consequences. This 
+       If your ethernet cards support MII or ETHTOOL link status monitoring
+        and the MII monitoring has been enabled in the driver (see description
+        of module parameters), there will be no adverse consequences. This
         release of the bonding driver knows how to get the MII information and
        enables or disables its slaves according to their link status.
        See section on High Availability for additional information.
@@ -622,8 +608,8 @@ Frequently Asked Questions
         slave.
 
        If neither mii_monitor and arp_interval is configured, the bonding
-       driver will not handle this situation very well. The driver will 
-       continue to send packets but some packets will be lost. Retransmits 
+       driver will not handle this situation very well. The driver will
+       continue to send packets but some packets will be lost. Retransmits
        will cause serious degradation of performance (in the case when one
        of two slave links fails, 50% packets will be lost, which is a serious
        problem for both TCP and UDP).
@@ -636,9 +622,9 @@ Frequently Asked Questions
 
 7.  Which switches/systems does it work with?
 
-       In round-robin and XOR mode, it works with systems that support 
+       In round-robin and XOR mode, it works with systems that support
        trunking:
-       
+
        * Many Cisco switches and routers (look for EtherChannel support).
        * SunTrunking software.
        * Alteon AceDirector switches / WebOS (use Trunks).
@@ -646,7 +632,7 @@ Frequently Asked Questions
          models (450) can define trunks between ports on different physical
          units.
        * Linux bonding, of course !
-       
+
        In 802.3ad mode, it works with with systems that support IEEE 802.3ad
        Dynamic Link Aggregation:
 
@@ -667,21 +653,21 @@ Frequently Asked Questions
        is then passed to all following slaves and remains persistent (even if
        the the first slave is removed) until the bonding device is brought
        down or reconfigured.
-       
+
        If you wish to change the MAC address, you can set it with ifconfig:
 
          # ifconfig bond0 hw ether 00:11:22:33:44:55
 
        The MAC address can be also changed by bringing down/up the device
        and then changing its slaves (or their order):
-       
+
          # ifconfig bond0 down ; modprobe -r bonding
          # ifconfig bond0 .... up
          # ifenslave bond0 eth...
 
        This method will automatically take the address from the next slave
        that will be added.
-       
+
        To restore your slaves' MAC addresses, you need to detach them
        from the bond (`ifenslave -d bond0 eth0'), set them down
        (`ifconfig eth0 down'), unload the drivers (`rmmod 3c59x', for
@@ -729,27 +715,27 @@ High Availability
 =================
 
 To implement high availability using the bonding driver, the driver needs to be
-compiled as a module, because currently it is the only way to pass parameters 
+compiled as a module, because currently it is the only way to pass parameters
 to the driver. This may change in the future.
 
-High availability is achieved by using MII or ETHTOOL status reporting. You 
-need to verify that all your interfaces support MII or ETHTOOL link status 
-reporting.  On Linux kernel 2.2.17, all the 100 Mbps capable drivers and 
-yellowfin gigabit driver support MII. To determine if ETHTOOL link reporting 
-is available for interface eth0, type "ethtool eth0" and the "Link detected:" 
-line should contain the correct link status. If your system has an interface 
-that does not support MII or ETHTOOL status reporting, a failure of its link 
-will not be detected! A message indicating MII and ETHTOOL is not supported by 
-a network driver is logged when the bonding driver is loaded with a non-zero 
+High availability is achieved by using MII or ETHTOOL status reporting. You
+need to verify that all your interfaces support MII or ETHTOOL link status
+reporting.  On Linux kernel 2.2.17, all the 100 Mbps capable drivers and
+yellowfin gigabit driver support MII. To determine if ETHTOOL link reporting
+is available for interface eth0, type "ethtool eth0" and the "Link detected:"
+line should contain the correct link status. If your system has an interface
+that does not support MII or ETHTOOL status reporting, a failure of its link
+will not be detected! A message indicating MII and ETHTOOL is not supported by
+a network driver is logged when the bonding driver is loaded with a non-zero
 miimon value.
 
 The bonding driver can regularly check all its slaves links using the ETHTOOL
-IOCTL (ETHTOOL_GLINK command) or by checking the MII status registers. The 
-check interval is specified by the module argument "miimon" (MII monitoring). 
-It takes an integer that represents the checking time in milliseconds. It 
-should not come to close to (1000/HZ) (10 milli-seconds on i386) because it 
-may then reduce the system interactivity. A value of 100 seems to be a good 
-starting point. It means that a dead link will be detected at most 100 
+IOCTL (ETHTOOL_GLINK command) or by checking the MII status registers. The
+check interval is specified by the module argument "miimon" (MII monitoring).
+It takes an integer that represents the checking time in milliseconds. It
+should not come to close to (1000/HZ) (10 milli-seconds on i386) because it
+may then reduce the system interactivity. A value of 100 seems to be a good
+starting point. It means that a dead link will be detected at most 100
 milli-seconds after it goes down.
 
 Example:
@@ -761,7 +747,7 @@ Or, put the following lines in /etc/modules.conf:
    alias bond0 bonding
    options bond0 miimon=100
 
-There are currently two policies for high availability. They are dependent on 
+There are currently two policies for high availability. They are dependent on
 whether:
 
    a) hosts are connected to a single host or switch that support trunking
@@ -811,7 +797,7 @@ Example 2 : host to switch at twice the speed
      # ifenslave bond0 eth0 eth1
 
 
-2) High Availability on two or more switches (or a single switch without 
+2) High Availability on two or more switches (or a single switch without
    trunking support)
 ---------------------------------------------------------------------------
 This mode is more problematic because it relies on the fact that there
@@ -870,10 +856,10 @@ by another external mechanism, it is good to have host1's active interface
 connected to one switch and host2's to the other. Such system will survive
 a failure of a single host, cable, or switch. The worst thing that may happen
 in the case of a switch failure is that half of the hosts will be temporarily
-unreachable until the other switch expires its tables. 
+unreachable until the other switch expires its tables.
 
 Example 2: Using multiple ethernet cards connected to a switch to configure
-           NIC failover (switch is not required to support trunking). 
+           NIC failover (switch is not required to support trunking).
 
 
           +----------+                          +----------+
@@ -957,7 +943,7 @@ The main limitations are :
     servers, but may be useful when the front switches send multicast
     information on their links (e.g. VRRP), or even health-check the servers.
     Use the arp_interval/arp_ip_target parameters to count incoming/outgoing
-    frames.  
+    frames.
 
 
 
@@ -973,13 +959,12 @@ Donald Becker's Ethernet Drivers and diag programs may be found at :
 You will also find a lot of information regarding Ethernet, NWay, MII, etc. at
 www.scyld.com.
 
-For new versions of the driver, patches for older kernels and the updated
-userspace tools, take a look at Willy Tarreau's site :
+Patches for 2.2 kernels are at Willy Tarreau's site :
  - http://wtarreau.free.fr/pub/bonding/
- - http://www-miaif.lip6.fr/willy/pub/bonding/
+ - http://www-miaif.lip6.fr/~tarreau/pub/bonding/
 
 To get latest informations about Linux Kernel development, please consult
 the Linux Kernel Mailing List Archives at :
-   http://boudicca.tux.org/hypermail/linux-kernel/latest/
+   http://www.ussg.iu.edu/hypermail/linux/kernel/
 
 -- END --
index 7f3b529..337f650 100644 (file)
@@ -47,7 +47,7 @@ This allows the kernel to exchange data with userspace applications. There
 are two ways of doing this, the new way works with netlink sockets and I
 have no experience with that yet. ANK uses it in his excellent iproute2
 package, see for example rtmon.c. iproute2 can be found on
-ftp://ftp.inr.ac.ru/ip-routing/iproute2*
+ftp://ftp.tux.org/pub/net/ip-routing/iproute2*
 
 The new way is described, partly in netlink(7), available on 
 http://www.europe.redhat.com/documentation/man-pages/man7/netlink.7.php3
index a4b44df..b88d625 100644 (file)
@@ -4,8 +4,6 @@
  *     This program controls the Linux implementation of running multiple
  *     network interfaces in parallel.
  *
- * Usage:      ifenslave [-v] master-interface < slave-interface [metric <N>] > ...
- *
  * Author:     Donald Becker <becker@cesdis.gsfc.nasa.gov>
  *             Copyright 1994-1996 Donald Becker
  *
  *      - For opt_c: slave should not be set to the master's setting
  *        while it is running. It was already set during enslave. To
  *        simplify things, it is now handeled separately.
+ *
+ *    - 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
+ *      - Code cleanup and style changes
+ *        set version to 1.1.0
  */
 
-#define APP_VERSION    "1.0.12"
-#define APP_RELDATE    "June 30, 2003"
+#define APP_VERSION    "1.1.0"
+#define APP_RELDATE    "Septemer 24, 2003"
 #define APP_NAME       "ifenslave"
 
 static char *version =
-APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ") "  "\nDonald Becker (becker@cesdis.gsfc.nasa.gov).\n"
-"detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n"
-"2.4 kernel support added on 2001/02/16 by Chad N. Tindel (ctindel at ieee dot org.\n";
+APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ")\n"
+"o Donald Becker (becker@cesdis.gsfc.nasa.gov).\n"
+"o Detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n"
+"o 2.4 kernel support added on 2001/02/16 by Chad N. Tindel\n"
+"  (ctindel at ieee dot org).\n";
 
 static const char *usage_msg =
-"Usage: ifenslave [-adfrvVh] <master-interface> < <slave-if> [metric <N>] > ...\n"
-"       ifenslave -c master-interface slave-if\n";
+"Usage: ifenslave [-f] <master-if> <slave-if> [<slave-if>...]\n"
+"       ifenslave -d   <master-if> <slave-if> [<slave-if>...]\n"
+"       ifenslave -c   <master-if> <slave-if>\n"
+"       ifenslave --help\n";
 
-static const char *howto_msg =
-"Usage: ifenslave [-adfrvVh] <master-interface> < <slave-if> [metric <N>] > ...\n"
-"       ifenslave -c master-interface slave-if\n"
+static const char *help_msg =
 "\n"
 "       To create a bond device, simply follow these three steps :\n"
 "       - ensure that the required drivers are properly loaded :\n"
@@ -115,18 +119,32 @@ static const char *howto_msg =
 "       - assign an IP address to the bond device :\n"
 "         # ifconfig bond0 <addr> netmask <mask> broadcast <bcast>\n"
 "       - attach all the interfaces you need to the bond device :\n"
-"         # ifenslave bond0 eth0 eth1 eth2\n"
+"         # ifenslave [{-f|--force}] bond0 eth0 [eth1 [eth2]...]\n"
 "         If bond0 didn't have a MAC address, it will take eth0's. Then, all\n"
 "         interfaces attached AFTER this assignment will get the same MAC addr.\n"
-"\n"
-"       To detach a dead interface without setting the bond device down :\n"
-"         # ifenslave -d bond0 eth1\n"
+"         (except for ALB/TLB modes)\n"
 "\n"
 "       To set the bond device down and automatically release all the slaves :\n"
 "         # ifconfig bond0 down\n"
 "\n"
+"       To detach a dead interface without setting the bond device down :\n"
+"         # ifenslave {-d|--detach} bond0 eth0 [eth1 [eth2]...]\n"
+"\n"
 "       To change active slave :\n"
-"         # ifenslave -c bond0 eth0\n"
+"         # ifenslave {-c|--change-active} bond0 eth0\n"
+"\n"
+"       To show master interface info\n"
+"         # ifenslave bond0\n"
+"\n"
+"       To show all interfaces info\n"
+"       # ifenslave {-a|--all-interfaces}\n"
+"\n"
+"       To be more verbose\n"
+"       # ifenslave {-v|--verbose} ...\n"
+"\n"
+"       # ifenslave {-u|--usage}   Show usage\n"
+"       # ifenslave {-V|--version} Show version\n"
+"       # ifenslave {-h|--help}    This message\n"
 "\n";
 
 #include <unistd.h>
@@ -153,476 +171,332 @@ typedef __uint8_t u8;           /* ditto */
 #include <linux/ethtool.h>
 
 struct option longopts[] = {
- /* { name  has_arg  *flag  val } */
-    {"all-interfaces", 0, 0, 'a'},     /* Show all interfaces. */
-    {"force",       0, 0, 'f'},                /* Force the operation. */
-    {"help",           0, 0, '?'},             /* Give help */
-       {"howto",       0, 0, 'h'},     /* Give some more help */
-    {"receive-slave", 0, 0, 'r'},      /* Make a receive-only slave.  */
-    {"verbose",        0, 0, 'v'},             /* Report each action taken.  */
-    {"version",        0, 0, 'V'},             /* Emit version information.  */
-    {"detach",       0, 0, 'd'},       /* Detach a slave interface. */
-    {"change-active", 0, 0, 'c'},      /* Change the active slave.  */
-    { 0, 0, 0, 0 }
+       /* { name  has_arg  *flag  val } */
+       {"all-interfaces",      0, 0, 'a'},     /* Show all interfaces. */
+       {"change-active",       0, 0, 'c'},     /* Change the active slave.  */
+       {"detach",              0, 0, 'd'},     /* Detach a slave interface. */
+       {"force",               0, 0, 'f'},     /* Force the operation. */
+       {"help",                0, 0, 'h'},     /* Give help */
+       {"usage",               0, 0, 'u'},     /* Give usage */
+       {"verbose",             0, 0, 'v'},     /* Report each action taken. */
+       {"version",             0, 0, 'V'},     /* Emit version information. */
+       { 0, 0, 0, 0}
 };
 
 /* Command-line flags. */
 unsigned int
-opt_a = 0,                                     /* Show-all-interfaces flag. */
-opt_f = 0,                                     /* Force the operation. */
-opt_r = 0,                                     /* Set up a Rx-only slave. */
-opt_d = 0,                                     /* detach a slave interface. */
-opt_c = 0,                                     /* change-active-slave flag. */
-verbose = 0,                                   /* Verbose flag. */
-opt_version = 0,
-opt_howto = 0;
-int skfd = -1;                                 /* AF_INET socket for ioctl() calls.    */
+opt_a = 0,     /* Show-all-interfaces flag. */
+opt_c = 0,     /* Change-active-slave flag. */
+opt_d = 0,     /* Detach a slave interface. */
+opt_f = 0,     /* Force the operation. */
+opt_h = 0,     /* Help */
+opt_u = 0,     /* Usage */
+opt_v = 0,     /* Verbose flag. */
+opt_V = 0;     /* Version */
+
+int skfd = -1;         /* AF_INET socket for ioctl() calls.*/
+int abi_ver = 0;       /* userland - kernel ABI version */
+int hwaddr_set = 0;    /* Master's hwaddr is set */
+int saved_errno;
+
+struct ifreq master_mtu, master_flags, master_hwaddr;
+struct ifreq slave_mtu, slave_flags, slave_hwaddr;
+
+struct dev_ifr {
+       struct ifreq *req_ifr;
+       char *req_name;
+       int req_type;
+};
 
-static void if_print(char *ifname);
-static int get_abi_ver(char *master_ifname);
+struct dev_ifr master_ifra[] = {
+       {&master_mtu,     "SIOCGIFMTU",     SIOCGIFMTU},
+       {&master_flags,   "SIOCGIFFLAGS",   SIOCGIFFLAGS},
+       {&master_hwaddr,  "SIOCGIFHWADDR",  SIOCGIFHWADDR},
+       {NULL, "", 0}
+};
+
+struct dev_ifr slave_ifra[] = {
+       {&slave_mtu,     "SIOCGIFMTU",     SIOCGIFMTU},
+       {&slave_flags,   "SIOCGIFFLAGS",   SIOCGIFFLAGS},
+       {&slave_hwaddr,  "SIOCGIFHWADDR",  SIOCGIFHWADDR},
+       {NULL, "", 0}
+};
 
-int
-main(int argc, char **argv)
+static void if_print(char *ifname);
+static int get_drv_info(char *master_ifname);
+static int get_if_settings(char *ifname, struct dev_ifr ifra[]);
+static int get_slave_flags(char *slave_ifname);
+static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr);
+static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr);
+static int set_slave_mtu(char *slave_ifname, int mtu);
+static int set_if_flags(char *ifname, short flags);
+static int set_if_up(char *ifname, short flags);
+static int set_if_down(char *ifname, short flags);
+static int clear_if_addr(char *ifname);
+static int set_if_addr(char *master_ifname, char *slave_ifname);
+static int change_active(char *master_ifname, char *slave_ifname);
+static int enslave(char *master_ifname, char *slave_ifname);
+static int release(char *master_ifname, char *slave_ifname);
+#define v_print(fmt, args...)  \
+       if (opt_v)              \
+               fprintf(stderr, fmt, ## args )
+
+int main(int argc, char *argv[])
 {
-       struct ifreq  ifr2, if_hwaddr, if_ipaddr, if_metric, if_mtu, if_dstaddr;
-       struct ifreq  if_netmask, if_brdaddr, if_flags;
-       int rv, goterr = 0;
-       int c, errflag = 0;
-       sa_family_t master_family;
        char **spp, *master_ifname, *slave_ifname;
-       int hwaddr_notset;
-       int abi_ver = 0;
+       int c, i, rv;
+       int res = 0;
+       int exclusive = 0;
 
-       while ((c = getopt_long(argc, argv, "acdfrvV?h", longopts, 0)) != EOF)
+       while ((c = getopt_long(argc, argv, "acdfhuvV", longopts, 0)) != EOF) {
                switch (c) {
-               case 'a': opt_a++; break;
-               case 'f': opt_f++; break;
-               case 'r': opt_r++; break;
-               case 'd': opt_d++; break;
-               case 'c': opt_c++; break;
-               case 'v': verbose++;            break;
-               case 'V': opt_version++;        break;
-               case 'h': opt_howto++;  break;
-               case '?': errflag++;
-               }
-
-       /* option check */
-       if (opt_c)
-               if(opt_a || opt_f || opt_r || opt_d || verbose || opt_version ||
-                  opt_howto || errflag ) {
+               case 'a': opt_a++; exclusive++; break;
+               case 'c': opt_c++; exclusive++; break;
+               case 'd': opt_d++; exclusive++; break;
+               case 'f': opt_f++; exclusive++; break;
+               case 'h': opt_h++; exclusive++; break;
+               case 'u': opt_u++; exclusive++; break;
+               case 'v': opt_v++; break;
+               case 'V': opt_V++; exclusive++; break;
+
+               case '?':
                        fprintf(stderr, usage_msg);
-                       return 2;
+                       res = 2;
+                       goto out;
                }
+       }
 
-       if (errflag) {
+       /* options check */
+       if (exclusive > 1) {
                fprintf(stderr, usage_msg);
-               return 2;
+               res = 2;
+               goto out;
        }
 
-       if (opt_howto) {
-               fprintf(stderr, howto_msg);
-               return 0;
+       if (opt_v || opt_V) {
+               printf(version);
+               if (opt_V) {
+                       res = 0;
+                       goto out;
+               }
        }
 
-       if (verbose || opt_version) {
-               printf(version);
-               if (opt_version)
-                       exit(0);
+       if (opt_u) {
+               printf(usage_msg);
+               res = 0;
+               goto out;
        }
 
-       /* Open a basic socket. */
-       if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
-               perror("socket");
-               exit(-1);
+       if (opt_h) {
+               printf(usage_msg);
+               printf(help_msg);
+               res = 0;
+               goto out;
        }
 
-       if (verbose)
-               fprintf(stderr, "DEBUG: argc=%d, optind=%d and argv[optind] is %s.\n",
-                               argc, optind, argv[optind]);
+       /* Open a basic socket */
+       if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               perror("socket");
+               res = 1;
+               goto out;
+       }
 
-       /* No remaining args means show all interfaces. */
-       if (optind == argc) {
-               if_print((char *)NULL);
-               (void) close(skfd);
-               exit(0);
+       if (opt_a) {
+               if (optind == argc) {
+                       /* No remaining args */
+                       /* show all interfaces */
+                       if_print((char *)NULL);
+                       goto out;
+               } else {
+                       /* Just show usage */
+                       fprintf(stderr, usage_msg);
+                       res = 2;
+                       goto out;
+               }
        }
 
-       /* Copy the interface name. */
+       /* Copy the interface name */
        spp = argv + optind;
        master_ifname = *spp++;
-       slave_ifname = *spp++;
 
-       /* Check command line. */
-       if (opt_c) {
-               char **tempp = spp;
-               if ((master_ifname == NULL)||(slave_ifname == NULL)||(*tempp++ != NULL)) {
-                       fprintf(stderr, usage_msg);
-                       (void) close(skfd);
-                       return 2;
-               }
+       if (master_ifname == NULL) {
+               fprintf(stderr, usage_msg);
+               res = 2;
+               goto out;
        }
 
-       /* A single args means show the configuration for this interface. */
-       if (slave_ifname == NULL) {
-               if_print(master_ifname);
-               (void) close(skfd);
-               exit(0);
-       }
-
-       /* exchange abi version with bonding driver */
-       abi_ver = get_abi_ver(master_ifname);
-       if (abi_ver < 0) {
-               (void) close(skfd);
-               exit(1);
-       }
-
-       /* Get the vitals from the master interface. */
-       {
-               struct ifreq *ifra[7] = { &if_ipaddr, &if_mtu, &if_dstaddr,
-                                                                 &if_brdaddr, &if_netmask, &if_flags,
-                                                                 &if_hwaddr };
-               const char *req_name[7] = {
-                       "IP address", "MTU", "destination address",
-                       "broadcast address", "netmask", "status flags",
-                       "hardware address" };
-               const int ioctl_req_type[7] = {
-                       SIOCGIFADDR, SIOCGIFMTU, SIOCGIFDSTADDR,
-                       SIOCGIFBRDADDR, SIOCGIFNETMASK, SIOCGIFFLAGS,
-                       SIOCGIFHWADDR };
-               int i;
-
-               for (i = 0; i < 7; i++) {
-                       strncpy(ifra[i]->ifr_name, master_ifname, IFNAMSIZ);
-                       if (ioctl(skfd, ioctl_req_type[i], ifra[i]) < 0) {
-                               fprintf(stderr,
-                                               "Something broke getting the master's %s: %s.\n",
-                                               req_name[i], strerror(errno));
-                       }
-               }
+       /* exchange abi version with bonding module */
+       res = get_drv_info(master_ifname);
+       if (res) {
+               fprintf(stderr,
+                       "Master '%s': Error: handshake with driver failed. "
+                       "Aborting\n",
+                       master_ifname);
+               goto out;
+       }
 
-               /* check if master is up; if not then fail any operation */
-               if (!(if_flags.ifr_flags & IFF_UP)) {
-                       fprintf(stderr, "Illegal operation; the specified master interface '%s' is not up.\n", master_ifname);
-                       (void) close(skfd);
-                       exit (1);
-               }
+       slave_ifname = *spp++;
 
-               hwaddr_notset = 1; /* assume master's address not set yet */
-               for (i = 0; hwaddr_notset && (i < 6); i++) {
-                       hwaddr_notset &= ((unsigned char *)if_hwaddr.ifr_hwaddr.sa_data)[i] == 0;
+       if (slave_ifname == NULL) {
+               if (opt_d || opt_c) {
+                       fprintf(stderr, usage_msg);
+                       res = 2;
+                       goto out;
                }
 
-               /* The family '1' is ARPHRD_ETHER for ethernet. */
-               if (if_hwaddr.ifr_hwaddr.sa_family != 1 && !opt_f) {
-                       fprintf(stderr, "The specified master interface '%s' is not"
-                                       " ethernet-like.\n  This program is designed to work"
-                                       " with ethernet-like network interfaces.\n"
-                                       " Use the '-f' option to force the operation.\n",
-                                       master_ifname);
-                       (void) close(skfd);
-                       exit (1);
-               }
-               master_family = if_hwaddr.ifr_hwaddr.sa_family;
-               if (verbose) {
-                       unsigned char *hwaddr = (unsigned char *)if_hwaddr.ifr_hwaddr.sa_data;
-                       printf("The current hardware address (SIOCGIFHWADDR) of %s is type %d  "
-                                  "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", master_ifname,
-                                  if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
-                                  hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
-               }
+               /* A single arg means show the
+                * configuration for this interface
+                */
+               if_print(master_ifname);
+               goto out;
        }
 
+       res = get_if_settings(master_ifname, master_ifra);
+       if (res) {
+               /* Probably a good reason not to go on */
+               fprintf(stderr,
+                       "Master '%s': Error: get settings failed: %s. "
+                       "Aborting\n",
+                       master_ifname, strerror(res));
+               goto out;
+       }
 
-       /* do this when enslaving interfaces */
-       do {
-               if (opt_d) {  /* detach a slave interface from the master */
-                       strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
-                       strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
-                       if ((ioctl(skfd, SIOCBONDRELEASE, &if_flags) < 0) &&
-                               (ioctl(skfd, BOND_RELEASE_OLD, &if_flags) < 0)) {
-                                       fprintf(stderr, "SIOCBONDRELEASE: cannot detach %s from %s. errno=%s.\n",
-                                                       slave_ifname, master_ifname, strerror(errno));
-                       }
-                       else if (abi_ver < 1) {
-                               /* The driver is using an old ABI, so we'll set the interface
-                                * down to avoid any conflicts due to same IP/MAC
-                                */
-                               strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
-                               if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
-                                       int saved_errno = errno;
-                                       fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
-                                               strerror(saved_errno));
-                               }
-                               else {
-                                       ifr2.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
-                                       if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
-                                               int saved_errno = errno;
-                                               fprintf(stderr, "Shutting down interface %s failed: %s\n",
-                                                       slave_ifname, strerror(saved_errno));
-                                       }
-                               }
-                       }
-               } else if (opt_c) { /* change primary slave */
-                       strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
-                       strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
-                       if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &if_flags) < 0) &&
-                           (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &if_flags) < 0)) {
-                               fprintf(stderr, "SIOCBONDCHANGEACTIVE: %s.\n", strerror(errno));
-                       }
-               } else {  /* attach a slave interface to the master */
-
-                       strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
-                       if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
-                               int saved_errno = errno;
-                               fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
-                                               strerror(saved_errno));
-                               (void) close(skfd);
-                               return 1;
-                       }
-
-                       if ((ifr2.ifr_flags & IFF_SLAVE) && !opt_r) {
-                               fprintf(stderr, "%s is already a slave\n", slave_ifname);
-                               (void) close(skfd);
-                               return 1;
-                       }
-
-                       /* if hwaddr_notset, assign the slave hw address to the master */
-                       if (hwaddr_notset) {
-                               /* assign the slave hw address to the
-                                * master since it currently does not
-                                * have one; otherwise, slaves may
-                                * have different hw addresses in
-                                * active-backup mode as seen when enslaving
-                                * using "ifenslave bond0 eth0 eth1" because
-                                * hwaddr_notset is set outside this loop.
-                                * TODO: put this and the "else" portion in
-                                *       a function.
-                                */
-                               /* get the slaves MAC address */
-                               strncpy(if_hwaddr.ifr_name, slave_ifname,
-                                       IFNAMSIZ);
-                               rv = ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr);
-                               if (-1 == rv) {
-                                       fprintf(stderr, "Could not get MAC "
-                                               "address of %s: %s\n",
-                                               slave_ifname,
-                                               strerror(errno));
-                                       strncpy(if_hwaddr.ifr_name,
-                                               master_ifname, IFNAMSIZ);
-                                       goterr = 1;
-                               }
-
-                               if (!goterr) {
-                                       if (abi_ver < 1) {
-                                               /* In ABI versions older than 1, the
-                                                * master's set_mac routine couldn't
-                                                * work if it was up, because it
-                                                * used the default ethernet set_mac
-                                                * function.
-                                                */
-                                               /* bring master down */
-                                               if_flags.ifr_flags &= ~IFF_UP;
-                                               if (ioctl(skfd, SIOCSIFFLAGS,
-                                                               &if_flags) < 0) {
-                                                       goterr = 1;
-                                                       fprintf(stderr,
-                                                               "Shutting down "
-                                                               "interface %s failed: "
-                                                               "%s\n",
-                                                               master_ifname,
-                                                               strerror(errno));
-                                               }
-                                       }
-
-                                       strncpy(if_hwaddr.ifr_name,
-                                               master_ifname, IFNAMSIZ);
-                                       if (ioctl(skfd, SIOCSIFHWADDR,
-                                                       &if_hwaddr) < 0) {
-                                               fprintf(stderr,
-                                                       "Could not set MAC "
-                                                       "address of %s: %s\n",
-                                                       master_ifname,
-                                                       strerror(errno));
-                                               goterr=1;
-                                       } else {
-                                               hwaddr_notset = 0;
-                                       }
-
-                                       if (abi_ver < 1) {
-                                               /* bring master back up */
-                                               if_flags.ifr_flags |= IFF_UP;
-                                               if (ioctl(skfd, SIOCSIFFLAGS,
-                                                         &if_flags) < 0) {
-                                                       fprintf(stderr,
-                                                               "Bringing up interface "
-                                                               "%s failed: %s\n",
-                                                               master_ifname,
-                                                               strerror(errno));
-                                               }
-                                       }
-                               }
-                       } else if (abi_ver < 1) { /* if (hwaddr_notset) */
-
-                               /* The driver is using an old ABI, so we'll set the interface
-                                * down and assign the master's hwaddr to it
-                                */
-                               if (ifr2.ifr_flags & IFF_UP) {
-                                       ifr2.ifr_flags &= ~IFF_UP;
-                                       if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
-                                               int saved_errno = errno;
-                                               fprintf(stderr, "Shutting down interface %s failed: %s\n",
-                                                       slave_ifname, strerror(saved_errno));
-                                       }
-                               }
-
-                               strncpy(if_hwaddr.ifr_name, slave_ifname, IFNAMSIZ);
-                               if (ioctl(skfd, SIOCSIFHWADDR, &if_hwaddr) < 0) {
-                                       int saved_errno = errno;
-                                       fprintf(stderr, "SIOCSIFHWADDR on %s failed: %s\n", if_hwaddr.ifr_name,
-                                               strerror(saved_errno));
-                                       if (saved_errno == EBUSY)
-                                               fprintf(stderr, "  The slave device %s is busy: it must be"
-                                                       " idle before running this command.\n", slave_ifname);
-                                       else if (saved_errno == EOPNOTSUPP)
-                                               fprintf(stderr, "  The slave device you specified does not support"
-                                                       " setting the MAC address.\n  Your kernel likely does not"
-                                                       " support slave devices.\n");
-                                       else if (saved_errno == EINVAL)
-                                               fprintf(stderr, "  The slave device's address type does not match"
-                                                       " the master's address type.\n");
-                               } else {
-                                       if (verbose) {
-                                               unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
-                                               printf("Slave's (%s) hardware address set to "
-                                                          "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", slave_ifname,
-                                                          hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
-                                       }
-                               }
-                       }
+       /* check if master is indeed a master;
+        * if not then fail any operation
+        */
+       if (!(master_flags.ifr_flags & IFF_MASTER)) {
+               fprintf(stderr,
+                       "Illegal operation; the specified interface '%s' "
+                       "is not a master. Aborting\n",
+                       master_ifname);
+               res = 1;
+               goto out;
+       }
 
-                       if (*spp  &&  !strcmp(*spp, "metric")) {
-                               if (*++spp == NULL) {
-                                       fprintf(stderr, usage_msg);
-                                       (void) close(skfd);
-                                       exit(2);
-                               }
-                               if_metric.ifr_metric = atoi(*spp);
-                               strncpy(if_metric.ifr_name, slave_ifname, IFNAMSIZ);
-                               if (ioctl(skfd, SIOCSIFMETRIC, &if_metric) < 0) {
-                                       fprintf(stderr, "SIOCSIFMETRIC on %s: %s\n", slave_ifname,
-                                                       strerror(errno));
-                                       goterr = 1;
-                               }
-                               spp++;
-                       }
+       /* check if master is up; if not then fail any operation */
+       if (!(master_flags.ifr_flags & IFF_UP)) {
+               fprintf(stderr,
+                       "Illegal operation; the specified master interface "
+                       "'%s' is not up.\n",
+                       master_ifname);
+               res = 1;
+               goto out;
+       }
 
-                       if (strncpy(if_ipaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-                               || ioctl(skfd, SIOCSIFADDR, &if_ipaddr) < 0) {
-                               fprintf(stderr,
-                                               "Something broke setting the slave's address: %s.\n",
-                                               strerror(errno));
-                       } else {
-                               if (verbose) {
-                                       unsigned char *ipaddr = if_ipaddr.ifr_addr.sa_data;
-                                       printf("Set the slave's (%s) IP address to %d.%d.%d.%d.\n",
-                                                  slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
-                               }
-                       }
+       /* Only for enslaving */
+       if (!opt_c && !opt_d) {
+               sa_family_t master_family = master_hwaddr.ifr_hwaddr.sa_family;
+               unsigned char *hwaddr =
+                       (unsigned char *)master_hwaddr.ifr_hwaddr.sa_data;
 
-                       if (strncpy(if_mtu.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-                               || ioctl(skfd, SIOCSIFMTU, &if_mtu) < 0) {
-                               fprintf(stderr, "Something broke setting the slave MTU: %s.\n",
-                                               strerror(errno));
-                       } else {
-                               if (verbose)
-                                       printf("Set the slave's (%s) MTU to %d.\n", slave_ifname, if_mtu.ifr_mtu);
-                       }
+               /* The family '1' is ARPHRD_ETHER for ethernet. */
+               if (master_family != 1 && !opt_f) {
+                       fprintf(stderr,
+                               "Illegal operation: The specified master "
+                               "interface '%s' is not ethernet-like.\n "
+                               "This program is designed to work with "
+                               "ethernet-like network interfaces.\n "
+                               "Use the '-f' option to force the "
+                               "operation.\n",
+                               master_ifname);
+                       res = 1;
+                       goto out;
+               }
 
-                       if (strncpy(if_dstaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-                               || ioctl(skfd, SIOCSIFDSTADDR, &if_dstaddr) < 0) {
-                               fprintf(stderr, "Error setting the slave (%s) with SIOCSIFDSTADDR: %s.\n",
-                                               slave_ifname, strerror(errno));
-                       } else {
-                               if (verbose) {
-                                       unsigned char *ipaddr = if_dstaddr.ifr_dstaddr.sa_data;
-                                       printf("Set the slave's (%s) destination address to %d.%d.%d.%d.\n",
-                                                  slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
-                               }
+               /* Check master's hw addr */
+               for (i = 0; i < 6; i++) {
+                       if (hwaddr[i] != 0) {
+                               hwaddr_set = 1;
+                               break;
                        }
+               }
 
-                       if (strncpy(if_brdaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-                               || ioctl(skfd, SIOCSIFBRDADDR, &if_brdaddr) < 0) {
-                               fprintf(stderr,
-                                               "Something broke setting the slave (%s) broadcast address: %s.\n",
-                                               slave_ifname, strerror(errno));
-                       } else {
-                               if (verbose) {
-                                       unsigned char *ipaddr = if_brdaddr.ifr_broadaddr.sa_data;
-                                       printf("Set the slave's (%s) broadcast address to %d.%d.%d.%d.\n",
-                                                  slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
-                               }
-                       }
+               if (hwaddr_set) {
+                       v_print("current hardware address of master '%s' "
+                               "is %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
+                               "type %d\n",
+                               master_ifname,
+                               hwaddr[0], hwaddr[1],
+                               hwaddr[2], hwaddr[3],
+                               hwaddr[4], hwaddr[5],
+                               master_family);
+               }
+       }
 
-                       if (strncpy(if_netmask.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-                               || ioctl(skfd, SIOCSIFNETMASK, &if_netmask) < 0) {
-                               fprintf(stderr,
-                                               "Something broke setting the slave (%s) netmask: %s.\n",
-                                               slave_ifname, strerror(errno));
-                       } else {
-                               if (verbose) {
-                                       unsigned char *ipaddr = if_netmask.ifr_netmask.sa_data;
-                                       printf("Set the slave's (%s) netmask to %d.%d.%d.%d.\n",
-                                                  slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+       /* Accepts only one slave */
+       if (opt_c) {
+               /* change active slave */
+               res = get_slave_flags(slave_ifname);
+               if (res) {
+                       fprintf(stderr,
+                               "Slave '%s': Error: get flags failed. "
+                               "Aborting\n",
+                               slave_ifname);
+                       goto out;
+               }
+               res = change_active(master_ifname, slave_ifname);
+               if (res) {
+                       fprintf(stderr,
+                               "Master '%s', Slave '%s': Error: "
+                               "Change active failed\n",
+                               master_ifname, slave_ifname);
+               }
+       } else {
+               /* Accept multiple slaves */
+               do {
+                       if (opt_d) {
+                               /* detach a slave interface from the master */
+                               rv = get_slave_flags(slave_ifname);
+                               if (rv) {
+                                       /* Can't work with this slave. */
+                                       /* remember the error and skip it*/
+                                       fprintf(stderr,
+                                               "Slave '%s': Error: get flags "
+                                               "failed. Skipping\n",
+                                               slave_ifname);
+                                       res = rv;
+                                       continue;
                                }
-                       }
-
-                       if (abi_ver < 1) {
-
-                               /* The driver is using an old ABI, so we'll set the interface
-                                * up before enslaving it
-                                */
-                               ifr2.ifr_flags |= IFF_UP;
-                               if ((ifr2.ifr_flags &= ~(IFF_SLAVE | IFF_MASTER)) == 0
-                                       || strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-                                       || ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
-                                               fprintf(stderr,
-                                                       "Something broke setting the slave (%s) flags: %s.\n",
-                                                       slave_ifname, strerror(errno));
-                               } else {
-                                       if (verbose)
-                                               printf("Set the slave's (%s) flags %4.4x.\n",
-                                                       slave_ifname, if_flags.ifr_flags);
+                               rv = release(master_ifname, slave_ifname);
+                               if (rv) {
+                                       fprintf(stderr,
+                                               "Master '%s', Slave '%s': Error: "
+                                               "Release failed\n",
+                                               master_ifname, slave_ifname);
+                                       res = rv;
                                }
                        } else {
-                               /* the bonding module takes care of setting the slave's mac address
-                                * and opening its interface
-                                */
-                               if (ifr2.ifr_flags & IFF_UP) { /* the interface will need to be down */
-                                       ifr2.ifr_flags &= ~IFF_UP;
-                                       if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
-                                               int saved_errno = errno;
-                                               fprintf(stderr, "Shutting down interface %s failed: %s\n",
-                                                       slave_ifname, strerror(saved_errno));
-                                       }
+                               /* attach a slave interface to the master */
+                               rv = get_if_settings(slave_ifname, slave_ifra);
+                               if (rv) {
+                                       /* Can't work with this slave. */
+                                       /* remember the error and skip it*/
+                                       fprintf(stderr,
+                                               "Slave '%s': Error: get "
+                                               "settings failed: %s. "
+                                               "Skipping\n",
+                                               slave_ifname, strerror(rv));
+                                       res = rv;
+                                       continue;
                                }
-                       }
-
-                       /* Do the real thing */
-                       if (!opt_r) {
-                               strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
-                               strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
-                               if ((ioctl(skfd, SIOCBONDENSLAVE, &if_flags) < 0) &&
-                                   (ioctl(skfd, BOND_ENSLAVE_OLD, &if_flags) < 0)) {
-                                       fprintf(stderr, "SIOCBONDENSLAVE: %s.\n", strerror(errno));
+                               rv = enslave(master_ifname, slave_ifname);
+                               if (rv) {
+                                       fprintf(stderr,
+                                               "Master '%s', Slave '%s': Error: "
+                                               "Enslave failed\n",
+                                               master_ifname, slave_ifname);
+                                       res = rv;
                                }
                        }
-               }
-       } while ( (slave_ifname = *spp++) != NULL);
+               } while ((slave_ifname = *spp++) != NULL);
+       }
 
-       /* Close the socket. */
-       (void) close(skfd);
+out:
+       if (skfd >= 0) {
+               close(skfd);
+       }
 
-       return(goterr);
+       return res;
 }
 
 static short mif_flags;
@@ -631,35 +505,34 @@ static short mif_flags;
 static int if_getconfig(char *ifname)
 {
        struct ifreq ifr;
-       int metric, mtu;                        /* Parameters of the master interface. */
+       int metric, mtu;        /* Parameters of the master interface. */
        struct sockaddr dstaddr, broadaddr, netmask;
+       unsigned char *hwaddr;
 
        strcpy(ifr.ifr_name, ifname);
        if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
                return -1;
        mif_flags = ifr.ifr_flags;
        printf("The result of SIOCGIFFLAGS on %s is %x.\n",
-                  ifname, ifr.ifr_flags);
+              ifname, ifr.ifr_flags);
 
        strcpy(ifr.ifr_name, ifname);
        if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0)
                return -1;
        printf("The result of SIOCGIFADDR is %2.2x.%2.2x.%2.2x.%2.2x.\n",
-                  ifr.ifr_addr.sa_data[0], ifr.ifr_addr.sa_data[1],
-                  ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3]);
+              ifr.ifr_addr.sa_data[0], ifr.ifr_addr.sa_data[1],
+              ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3]);
 
        strcpy(ifr.ifr_name, ifname);
        if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
                return -1;
 
-       {
-               /* Gotta convert from 'char' to unsigned for printf().  */
-               unsigned char *hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data;
-               printf("The result of SIOCGIFHWADDR is type %d  "
-                          "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
-                          ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
-                          hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
-       }
+       /* Gotta convert from 'char' to unsigned for printf(). */
+       hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data;
+       printf("The result of SIOCGIFHWADDR is type %d  "
+              "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
+              ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
+              hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
 
        strcpy(ifr.ifr_name, ifname);
        if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) {
@@ -691,7 +564,7 @@ static int if_getconfig(char *ifname)
        } else
                netmask = ifr.ifr_netmask;
 
-       return(0);
+       return 0;
 }
 
 static void if_print(char *ifname)
@@ -705,15 +578,16 @@ static void if_print(char *ifname)
                ifc.ifc_len = sizeof(buff);
                ifc.ifc_buf = buff;
                if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
-                       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
+                       perror("SIOCGIFCONF failed");
                        return;
                }
 
                ifr = ifc.ifc_req;
                for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
                        if (if_getconfig(ifr->ifr_name) < 0) {
-                               fprintf(stderr, "%s: unknown interface.\n",
-                                               ifr->ifr_name);
+                               fprintf(stderr,
+                                       "%s: unknown interface.\n",
+                                       ifr->ifr_name);
                                continue;
                        }
 
@@ -721,16 +595,18 @@ static void if_print(char *ifname)
                        /*ife_print(&ife);*/
                }
        } else {
-               if (if_getconfig(ifname) < 0)
-                       fprintf(stderr, "%s: unknown interface.\n", ifname);
+               if (if_getconfig(ifname) < 0) {
+                       fprintf(stderr,
+                               "%s: unknown interface.\n", ifname);
+               }
        }
 }
 
-static int get_abi_ver(char *master_ifname)
+static int get_drv_info(char *master_ifname)
 {
        struct ifreq ifr;
        struct ethtool_drvinfo info;
-       int abi_ver = 0;
+       char *endptr;
 
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
@@ -739,24 +615,487 @@ static int get_abi_ver(char *master_ifname)
        info.cmd = ETHTOOL_GDRVINFO;
        strncpy(info.driver, "ifenslave", 32);
        snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
-       if (ioctl(skfd, SIOCETHTOOL, &ifr) >= 0) {
-               char *endptr;
-
-               abi_ver = strtoul(info.fw_version, &endptr, 0);
-               if (*endptr) {
-                       fprintf(stderr, "Error: got invalid string as an ABI "
-                               "version from the bonding module\n");
-                       return -1;
+
+       if (ioctl(skfd, SIOCETHTOOL, &ifr) < 0) {
+               if (errno == EOPNOTSUPP) {
+                       goto out;
                }
+
+               saved_errno = errno;
+               v_print("Master '%s': Error: get bonding info failed %s\n",
+                       master_ifname, strerror(saved_errno));
+               return 1;
+       }
+
+       abi_ver = strtoul(info.fw_version, &endptr, 0);
+       if (*endptr) {
+                v_print("Master '%s': Error: got invalid string as an ABI "
+                       "version from the bonding module\n",
+                       master_ifname);
+               return 1;
+       }
+
+out:
+       v_print("ABI ver is %d\n", abi_ver);
+
+       return 0;
+}
+
+static int change_active(char *master_ifname, char *slave_ifname)
+{
+       struct ifreq ifr;
+       int res = 0;
+
+       if (!(slave_flags.ifr_flags & IFF_SLAVE)) {
+               fprintf(stderr,
+                       "Illegal operation: The specified slave interface "
+                       "'%s' is not a slave\n",
+                       slave_ifname);
+               return 1;
        }
 
-       if (verbose) {
-               printf("ABI ver is %d\n", abi_ver);
+       strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+       strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
+       if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &ifr) < 0) &&
+           (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &ifr) < 0)) {
+               saved_errno = errno;
+               v_print("Master '%s': Error: SIOCBONDCHANGEACTIVE failed: "
+                       "%s\n",
+                       master_ifname, strerror(saved_errno));
+               res = 1;
        }
-       return abi_ver;
+
+       return res;
 }
 
+static int enslave(char *master_ifname, char *slave_ifname)
+{
+       struct ifreq ifr;
+       int res = 0;
+
+       if (slave_flags.ifr_flags & IFF_SLAVE) {
+               fprintf(stderr,
+                       "Illegal operation: The specified slave interface "
+                       "'%s' is already a slave\n",
+                       slave_ifname);
+               return 1;
+       }
 
+       res = set_if_down(slave_ifname, slave_flags.ifr_flags);
+       if (res) {
+               fprintf(stderr,
+                       "Slave '%s': Error: bring interface down failed\n",
+                       slave_ifname);
+               return res;
+       }
+
+       if (abi_ver < 2) {
+               /* Older bonding versions would panic if the slave has no IP
+                * address, so get the IP setting from the master.
+                */
+               res = set_if_addr(master_ifname, slave_ifname);
+               if (res) {
+                       fprintf(stderr,
+                               "Slave '%s': Error: set address failed\n",
+                               slave_ifname);
+                       return res;
+               }
+       } else {
+               res = clear_if_addr(slave_ifname);
+               if (res) {
+                       fprintf(stderr,
+                               "Slave '%s': Error: clear address failed\n",
+                               slave_ifname);
+                       return res;
+               }
+       }
+
+       if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) {
+               res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu);
+               if (res) {
+                       fprintf(stderr,
+                               "Slave '%s': Error: set MTU failed\n",
+                               slave_ifname);
+                       return res;
+               }
+       }
+
+       if (hwaddr_set) {
+               /* Master already has an hwaddr
+                * so set it's hwaddr to the slave
+                */
+               if (abi_ver < 1) {
+                       /* The driver is using an old ABI, so
+                        * the application sets the slave's
+                        * hwaddr
+                        */
+                       res = set_slave_hwaddr(slave_ifname,
+                                              &(master_hwaddr.ifr_hwaddr));
+                       if (res) {
+                               fprintf(stderr,
+                                       "Slave '%s': Error: set hw address "
+                                       "failed\n",
+                                       slave_ifname);
+                               goto undo_mtu;
+                       }
+
+                       /* For old ABI the application needs to bring the
+                        * slave back up
+                        */
+                       res = set_if_up(slave_ifname, slave_flags.ifr_flags);
+                       if (res) {
+                               fprintf(stderr,
+                                       "Slave '%s': Error: bring interface "
+                                       "down failed\n",
+                                       slave_ifname);
+                               goto undo_slave_mac;
+                       }
+               }
+               /* The driver is using a new ABI,
+                * so the driver takes care of setting
+                * the slave's hwaddr and bringing
+                * it up again
+                */
+       } else {
+               /* No hwaddr for master yet, so
+                * set the slave's hwaddr to it
+                */
+               if (abi_ver < 1) {
+                       /* For old ABI, the master needs to be
+                        * down before setting it's hwaddr
+                        */
+                       res = set_if_down(master_ifname, master_flags.ifr_flags);
+                       if (res) {
+                               fprintf(stderr,
+                                       "Master '%s': Error: bring interface "
+                                       "down failed\n",
+                                       master_ifname);
+                               goto undo_mtu;
+                       }
+               }
+
+               res = set_master_hwaddr(master_ifname,
+                                       &(slave_hwaddr.ifr_hwaddr));
+               if (res) {
+                       fprintf(stderr,
+                               "Master '%s': Error: set hw address "
+                               "failed\n",
+                               master_ifname);
+                       goto undo_mtu;
+               }
+
+               if (abi_ver < 1) {
+                       /* For old ABI, bring the master
+                        * back up
+                        */
+                       res = set_if_up(master_ifname, master_flags.ifr_flags);
+                       if (res) {
+                               fprintf(stderr,
+                                       "Master '%s': Error: bring interface "
+                                       "up failed\n",
+                                       master_ifname);
+                               goto undo_master_mac;
+                       }
+               }
+
+               hwaddr_set = 1;
+       }
+
+       /* Do the real thing */
+       strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+       strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
+       if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) &&
+           (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) {
+               saved_errno = errno;
+               v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n",
+                       master_ifname, strerror(saved_errno));
+               res = 1;
+       }
+
+       if (res) {
+               goto undo_master_mac;
+       }
+
+       return 0;
+
+/* rollback (best effort) */
+undo_master_mac:
+       set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr));
+       hwaddr_set = 0;
+       goto undo_mtu;
+undo_slave_mac:
+       set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr));
+undo_mtu:
+       set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu);
+       return res;
+}
+
+static int release(char *master_ifname, char *slave_ifname)
+{
+       struct ifreq ifr;
+       int res = 0;
+
+       if (!(slave_flags.ifr_flags & IFF_SLAVE)) {
+               fprintf(stderr,
+                       "Illegal operation: The specified slave interface "
+                       "'%s' is not a slave\n",
+                       slave_ifname);
+               return 1;
+       }
+
+       strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+       strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
+       if ((ioctl(skfd, SIOCBONDRELEASE, &ifr) < 0) &&
+           (ioctl(skfd, BOND_RELEASE_OLD, &ifr) < 0)) {
+               saved_errno = errno;
+               v_print("Master '%s': Error: SIOCBONDRELEASE failed: %s\n",
+                       master_ifname, strerror(saved_errno));
+               return 1;
+       } else if (abi_ver < 1) {
+               /* The driver is using an old ABI, so we'll set the interface
+                * down to avoid any conflicts due to same MAC/IP
+                */
+               res = set_if_down(slave_ifname, slave_flags.ifr_flags);
+               if (res) {
+                       fprintf(stderr,
+                               "Slave '%s': Error: bring interface "
+                               "down failed\n",
+                               slave_ifname);
+               }
+       }
+
+       /* set to default mtu */
+       set_slave_mtu(slave_ifname, 1500);
+
+       return res;
+}
+
+static int get_if_settings(char *ifname, struct dev_ifr ifra[])
+{
+       int i;
+       int res = 0;
+
+       for (i = 0; ifra[i].req_ifr; i++) {
+               strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ);
+               res = ioctl(skfd, ifra[i].req_type, ifra[i].req_ifr);
+               if (res < 0) {
+                       saved_errno = errno;
+                       v_print("Interface '%s': Error: %s failed: %s\n",
+                               ifname, ifra[i].req_name,
+                               strerror(saved_errno));
+
+                       return saved_errno;
+               }
+       }
+
+       return 0;
+}
+
+static int get_slave_flags(char *slave_ifname)
+{
+       int res = 0;
+
+       strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ);
+       res = ioctl(skfd, SIOCGIFFLAGS, &slave_flags);
+       if (res < 0) {
+               saved_errno = errno;
+               v_print("Slave '%s': Error: SIOCGIFFLAGS failed: %s\n",
+                       slave_ifname, strerror(saved_errno));
+       } else {
+               v_print("Slave %s: flags %04X.\n",
+                       slave_ifname, slave_flags.ifr_flags);
+       }
+
+       return res;
+}
+
+static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr)
+{
+       unsigned char *addr = (unsigned char *)hwaddr->sa_data;
+       struct ifreq ifr;
+       int res = 0;
+
+       strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+       memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
+       res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
+       if (res < 0) {
+               saved_errno = errno;
+               v_print("Master '%s': Error: SIOCSIFHWADDR failed: %s\n",
+                       master_ifname, strerror(saved_errno));
+               return res;
+       } else {
+               v_print("Master '%s': hardware address set to "
+                       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
+                       master_ifname, addr[0], addr[1], addr[2],
+                       addr[3], addr[4], addr[5]);
+       }
+
+       return res;
+}
+
+static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr)
+{
+       unsigned char *addr = (unsigned char *)hwaddr->sa_data;
+       struct ifreq ifr;
+       int res = 0;
+
+       strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
+       memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
+       res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
+       if (res < 0) {
+               saved_errno = errno;
+
+               v_print("Slave '%s': Error: SIOCSIFHWADDR failed: %s\n",
+                       slave_ifname, strerror(saved_errno));
+
+               if (saved_errno == EBUSY) {
+                       v_print("  The device is busy: it must be idle "
+                               "before running this command.\n");
+               } else if (saved_errno == EOPNOTSUPP) {
+                       v_print("  The device does not support setting "
+                               "the MAC address.\n"
+                               "  Your kernel likely does not support slave "
+                               "devices.\n");
+               } else if (saved_errno == EINVAL) {
+                       v_print("  The device's address type does not match "
+                               "the master's address type.\n");
+               }
+               return res;
+       } else {
+               v_print("Slave '%s': hardware address set to "
+                       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
+                       slave_ifname, addr[0], addr[1], addr[2],
+                       addr[3], addr[4], addr[5]);
+       }
+
+       return res;
+}
+
+static int set_slave_mtu(char *slave_ifname, int mtu)
+{
+       struct ifreq ifr;
+       int res = 0;
+
+       ifr.ifr_mtu = mtu;
+       strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
+
+       res = ioctl(skfd, SIOCSIFMTU, &ifr);
+       if (res < 0) {
+               saved_errno = errno;
+               v_print("Slave '%s': Error: SIOCSIFMTU failed: %s\n",
+                       slave_ifname, strerror(saved_errno));
+       } else {
+               v_print("Slave '%s': MTU set to %d.\n", slave_ifname, mtu);
+       }
+
+       return res;
+}
+
+static int set_if_flags(char *ifname, short flags)
+{
+       struct ifreq ifr;
+       int res = 0;
+
+       ifr.ifr_flags = flags;
+       strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+       res = ioctl(skfd, SIOCSIFFLAGS, &ifr);
+       if (res < 0) {
+               saved_errno = errno;
+               v_print("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n",
+                       ifname, strerror(saved_errno));
+       } else {
+               v_print("Interface '%s': flags set to %04X.\n", ifname, flags);
+       }
+
+       return res;
+}
+
+static int set_if_up(char *ifname, short flags)
+{
+       return set_if_flags(ifname, flags | IFF_UP);
+}
+
+static int set_if_down(char *ifname, short flags)
+{
+       return set_if_flags(ifname, flags & ~IFF_UP);
+}
+
+static int clear_if_addr(char *ifname)
+{
+       struct ifreq ifr;
+       int res = 0;
+
+       strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+       ifr.ifr_addr.sa_family = AF_INET;
+       memset(ifr.ifr_addr.sa_data, 0, sizeof(ifr.ifr_addr.sa_data));
+
+       res = ioctl(skfd, SIOCSIFADDR, &ifr);
+       if (res < 0) {
+               saved_errno = errno;
+               v_print("Interface '%s': Error: SIOCSIFADDR failed: %s\n",
+                       ifname, strerror(saved_errno));
+       } else {
+               v_print("Interface '%s': address cleared\n", ifname);
+       }
+
+       return res;
+}
+
+static int set_if_addr(char *master_ifname, char *slave_ifname)
+{
+       struct ifreq ifr;
+       int res;
+       unsigned char *ipaddr;
+       int i;
+       struct {
+               char *req_name;
+               char *desc;
+               int g_ioctl;
+               int s_ioctl;
+       } ifra[] = {
+               {"IFADDR", "addr", SIOCGIFADDR, SIOCSIFADDR},
+               {"DSTADDR", "destination addr", SIOCGIFDSTADDR, SIOCSIFDSTADDR},
+               {"BRDADDR", "broadcast addr", SIOCGIFBRDADDR, SIOCSIFBRDADDR},
+               {"NETMASK", "netmask", SIOCGIFNETMASK, SIOCSIFNETMASK},
+               {NULL, NULL, 0, 0},
+       };
+
+       for (i = 0; ifra[i].req_name; i++) {
+               strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+               res = ioctl(skfd, ifra[i].g_ioctl, &ifr);
+               if (res < 0) {
+                       int saved_errno = errno;
+
+                       v_print("Interface '%s': Error: SIOCG%s failed: %s\n",
+                               master_ifname, ifra[i].req_name,
+                               strerror(saved_errno));
+
+                       ifr.ifr_addr.sa_family = AF_INET;
+                       memset(ifr.ifr_addr.sa_data, 0,
+                              sizeof(ifr.ifr_addr.sa_data));
+               }
+
+               strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
+               res = ioctl(skfd, ifra[i].s_ioctl, &ifr);
+               if (res < 0) {
+                       int saved_errno = errno;
+
+                       v_print("Interface '%s': Error: SIOCS%s failed: %s\n",
+                               slave_ifname, ifra[i].req_name,
+                               strerror(saved_errno));
+
+                       return res;
+               }
+
+               ipaddr = ifr.ifr_addr.sa_data;
+               v_print("Interface '%s': set IP %s to %d.%d.%d.%d\n",
+                       slave_ifname, ifra[i].desc,
+                       ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+       }
+
+       return 0;
+}
 
 /*
  * Local variables:
@@ -768,3 +1107,4 @@ static int get_abi_ver(char *master_ifname)
  *  compile-command: "gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave"
  * End:
  */
+
index f2b360b..c283059 100644 (file)
@@ -294,6 +294,19 @@ tcp_low_latency - BOOLEAN
        changed would be a Beowulf compute cluster.
        Default: 0
 
+tcp_westwood - BOOLEAN
+        Enable TCP Westwood+ congestion control algorithm.
+       TCP Westwood+ is a sender-side only modification of the TCP Reno 
+       protocol stack that optimizes the performance of TCP congestion 
+       control. It is based on end-to-end bandwidth estimation to set 
+       congestion window and slow start threshold after a congestion 
+       episode. Using this estimation, TCP Westwood+ adaptively sets a 
+       slow start threshold and a congestion window which takes into 
+       account the bandwidth used  at the time congestion is experienced. 
+       TCP Westwood+ significantly increases fairness wrt TCP Reno in 
+       wired networks and throughput over wireless links.   
+        Default: 0
+
 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 
index 8eeed04..01d9495 100644 (file)
@@ -203,6 +203,15 @@ Module parameters
 
     Module supports up to 8 cards.
 
+  Module snd-bt87x
+  ----------------
+
+    Module for video cards based on Bt87x chips.
+
+    digital_rate - Override the default digital rate (Hz)
+
+    Module supports up to 8 cards.
+
   Module snd-cmi8330
   ------------------
 
@@ -562,6 +571,7 @@ Module parameters
                         * Hoontech SoundTrack DSP 24
                         * Hoontech SoundTrack DSP 24 Value
                         * Hoontech SoundTrack DSP 24 Media 7.1
+                        * Digigram VX442
 
     omni       - Omni I/O support for MidiMan M-Audio Delta44/66
 
@@ -592,8 +602,15 @@ Module parameters
     ac97_clock   - AC'97 codec clock base (0 = auto-detect)
     joystick      - Enable joystick (default off)
     mpu_port      - MPU401 port # (0 = disabled, 0x330,0x300)
+    ac97_quirk    - AC'97 workaround for strange hardware (-1 = default)
+                    -1 = default, don't override
+                     0 = disable
+                     1 = use headphone control as master
+                     2 = swap headphone and master controls
+                     3 = for AD1985, turn on OMS bit and use headphone
 
     Module supports autoprobe and multiple bus-master chips (max 8).
+
     Note: the latest driver supports auto-detection of chip clock.
     if you still encounter too fast playback, specify the clock
     explicitly via the module option "ac97_clock=41194".
@@ -601,6 +618,13 @@ Module parameters
     The joystick and MPU-401 are supported only certain hardwares.
     MPU401 is experimental,  It doesn't work perfectly.
 
+    The ac97_quirk option is used to enable/override the workaround
+    for specific devices.  Some hardware have swapped output pins
+    between Master and Headphone, or Surround.  The driver provides
+    the auto-detection of known problematic devices, but some might
+    be unknown or wrongly detected.  In such a case, pass the proper
+    value with this option.
+
     The power-management is supported.
     
   Module snd-interwave
@@ -659,6 +683,7 @@ Module parameters
                        others) 
 
     Module supports autoprobe and multiple chips (max 8).
+
     Note: the binding of amplifier is dependent on hardware.
     If there is no sound even though all channels are unmuted, try to
     specify other gpio connection via amp_gpio option. 
@@ -702,6 +727,7 @@ Module parameters
     vaio_hack        - alias buffer_top=0x25a800
 
     Module supports autoprobe and multiple chips (max 8).
+
     Note: on some notebooks the buffer address cannot be detected
     automatically, or causes hang-up during initialization.
     In such a case, specify the buffer top address explicity via
@@ -788,6 +814,7 @@ Module parameters
     enable_beep     - enable beep using PCM (enabled as default)
 
     Module supports autoprobe a chip.
+
     Note: the driver may have problems regarding endianess.
 
     The power-management is supported.
@@ -1006,6 +1033,8 @@ Module parameters
                  0 = auto (defalut), 1 = enable, 2 = disable,
                  3 = 48k only, 4 = no VRA
                  [VIA8233/C,8235 only]
+    ac97_quirk  - AC'97 workaround for strange hardware
+                  See the description of intel8x0 module for details.
 
     Module supports autoprobe and multiple bus-master chips (max 8).
 
diff --git a/TODO b/TODO
deleted file mode 100644 (file)
index 64e3d50..0000000
--- a/TODO
+++ /dev/null
@@ -1,61 +0,0 @@
-(*=done, not submited)
-
-- fbdev: use a new activate flag to tell drivers to apply a mode even if it didn't
-  change. Call set_var() with this flag when switching from KD_GRAPHICS back to
-  text mode. That should fix most of the problems of apps banging the HW and
-  leaving it in an incorrect state. (XFree still should be shot for banging the
-  HW on exit when it's not the front VT)
-
-* fbdev: add a couple of routines to suspend/resume display on a framebuffer.
-  Resume will additionally restore the screen. To be called by the drivers when
-  they are power managed
-
-- fbdev: make fbset work properly again ! stty isn't a solution for lots of
-  cases (supposedly done in jsimmons tree)
-
-- look at scsi P.M (hrm....)
-
-- get rid of "pre-parsed" fields in the device-tree. Everything should come
-  from properties. PCI drivers don't need addr parsing, mac-io based drivers
-  can parse "reg" (or it can be done by macio_asic and stored as resources),
-  etc... As far as interrupts are concerned, I need to think about it, we
-  shall either have an helper that walks the interrupt tree to get the
-  vector, or we still do a one-time parsing and store those in linux,irq
-  properties. The later is probably better at first.
-  We probably also want to factor the strings in the device tree memory
-  representation when building it from OF.
-  -> partially done, macio drivers now have resource management
-
-* figure out breakage of release_OF_resource on macio devices (probably
-  getting to the wrong resource)
-
-- Implement DMA api instead of using generic stuff
-
-- Move more of arch/ppc/platforms/pmac* to drivers/macintosh. I want to
-  rework the way "features" are done, but I still can't find a new design
-  that would please me while not copying what Apple did in darwin ...
-  I probably want to split that file in per-chipset files (gc, ohare,
-  heathrow/paddington, keylargo, uninorth, etc...) though the way those
-  would "advertise" their routines still need to be defined. What about
-  hooking function pointers to the device-tree ?
-
-- Use device-tree values to fill the PCI latency setting and add fixups
-  for the values of uninorth devices like darwin does
-
-- Rework swim3 using BIO properly, dealing with hotswap (should be rmmod'able
-  as well), and including paulus latest fixes. Also adapt it to new model
-
-- Port ADB to new driver model, add various settings (trackpad tap, kbd Fn
-  key behaviour etc...) to sysfs attribute files
-
-- Add PHY layer & ethtool support to bmac driver
-
-- G5 sound drivers (probably want a complete rewrite of dmasound if we decide
-  to keep that driver around, or just base on Alsa)
-
-- While we are at sound: proper refcounting of KeyLargo clocks for better PM
-  and separate I2S channel configuration
-
-- Rework PPC arch whole interrupt management to finally deal with cascaded
-  controllers properly, also get rid of the linar irq_desc array
-
index 32a8530..1013d70 100644 (file)
@@ -155,7 +155,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 CONFIG_BLK_DEV_ALI15X3=y
index 76fd0d9..f670baf 100644 (file)
@@ -616,6 +616,8 @@ source "drivers/ide/Kconfig"
 
 source "drivers/scsi/Kconfig"
 
+source "drivers/message/fusion/Kconfig"
+
 source "drivers/ieee1394/Kconfig"
 
 source "drivers/message/i2o/Kconfig"
@@ -629,6 +631,10 @@ source "drivers/input/Kconfig"
 
 source "drivers/char/Kconfig"
 
+source "drivers/i2c/Kconfig"
+
+source "drivers/l3/Kconfig"
+
 source "drivers/media/Kconfig"
 
 source "fs/Kconfig"
index 0947c1b..cdfc26e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/hardware/amba.h>
 #include <asm/sizes.h>
 
@@ -41,6 +42,23 @@ static int amba_match(struct device *dev, struct device_driver *drv)
        return amba_lookup(pcdrv->id_table, pcdev) != NULL;
 }
 
+#ifdef CONFIG_HOTPLUG
+static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
+{
+       struct amba_device *pcdev = to_amba_device(dev);
+
+       if (nr_env < 2)
+               return -ENOMEM;
+
+       snprintf(buf, bufsz, "AMBA_ID=%08lx", pcdev->periphid);
+       *envp++ = buf;
+       *envp++ = NULL;
+       return 0;
+}
+#else
+#define amba_hotplug NULL
+#endif
+
 static int amba_suspend(struct device *dev, u32 state)
 {
        struct amba_driver *drv = to_amba_driver(dev->driver);
@@ -68,6 +86,7 @@ static int amba_resume(struct device *dev)
 static struct bus_type amba_bustype = {
        .name           = "amba",
        .match          = amba_match,
+       .hotplug        = amba_hotplug,
        .suspend        = amba_suspend,
        .resume         = amba_resume,
 };
@@ -149,27 +168,19 @@ static void amba_device_release(struct device *dev)
        kfree(d);
 }
 
-static ssize_t show_id(struct device *_dev, char *buf)
-{
-       struct amba_device *dev = to_amba_device(_dev);
-       return sprintf(buf, "%08x\n", dev->periphid);
-}
-static DEVICE_ATTR(id, S_IRUGO, show_id, NULL);
+#define amba_attr(name,fmt,arg...)                             \
+static ssize_t show_##name(struct device *_dev, char *buf)     \
+{                                                              \
+       struct amba_device *dev = to_amba_device(_dev);         \
+       return sprintf(buf, fmt, arg);                          \
+}                                                              \
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
 
-static ssize_t show_irq(struct device *_dev, char *buf)
-{
-       struct amba_device *dev = to_amba_device(_dev);
-       return sprintf(buf, "%u\n", dev->irq);
-}
-static DEVICE_ATTR(irq, S_IRUGO, show_irq, NULL);
-
-static ssize_t show_res(struct device *_dev, char *buf)
-{
-       struct amba_device *dev = to_amba_device(_dev);
-       return sprintf(buf, "\t%08lx\t%08lx\t%08lx\n",
-                       dev->res.start, dev->res.end, dev->res.flags);
-}
-static DEVICE_ATTR(resource, S_IRUGO, show_res, NULL);
+amba_attr(id, "%08x\n", dev->periphid);
+amba_attr(irq0, "%u\n", dev->irq[0]);
+amba_attr(irq1, "%u\n", dev->irq[1]);
+amba_attr(resource, "\t%08lx\t%08lx\t%08lx\n",
+         dev->res.start, dev->res.end, dev->res.flags);
 
 /**
  *     amba_device_register - register an AMBA device
@@ -208,10 +219,17 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
                if (cid == 0xb105f00d)
                        dev->periphid = pid;
 
-               ret = device_register(&dev->dev);
+               if (dev->periphid)
+                       ret = device_register(&dev->dev);
+               else
+                       ret = -ENODEV;
+
                if (ret == 0) {
                        device_create_file(&dev->dev, &dev_attr_id);
-                       device_create_file(&dev->dev, &dev_attr_irq);
+                       if (dev->irq[0] != NO_IRQ)
+                               device_create_file(&dev->dev, &dev_attr_irq0);
+                       if (dev->irq[1] != NO_IRQ)
+                               device_create_file(&dev->dev, &dev_attr_irq1);
                        device_create_file(&dev->dev, &dev_attr_resource);
                } else {
  out:
@@ -237,7 +255,85 @@ void amba_device_unregister(struct amba_device *dev)
        device_unregister(&dev->dev);
 }
 
+
+struct find_data {
+       struct amba_device *dev;
+       struct device *parent;
+       const char *busid;
+       unsigned int id;
+       unsigned int mask;
+};
+
+static int amba_find_match(struct device *dev, void *data)
+{
+       struct find_data *d = data;
+       struct amba_device *pcdev = to_amba_device(dev);
+       int r;
+
+       r = (pcdev->periphid & d->mask) == d->id;
+       if (d->parent)
+               r &= d->parent == dev->parent;
+       if (d->busid)
+               r &= strcmp(dev->bus_id, d->busid) == 0;
+
+       if (r) {
+               get_device(dev);
+               d->dev = pcdev;
+       }
+
+       return r;
+}
+
+/**
+ *     amba_find_device - locate an AMBA device given a bus id
+ *     @busid: bus id for device (or NULL)
+ *     @parent: parent device (or NULL)
+ *     @id: peripheral ID (or 0)
+ *     @mask: peripheral ID mask (or 0)
+ *
+ *     Return the AMBA device corresponding to the supplied parameters.
+ *     If no device matches, returns NULL.
+ *
+ *     NOTE: When a valid device is found, its refcount is
+ *     incremented, and must be decremented before the returned
+ *     reference.
+ */
+struct amba_device *
+amba_find_device(const char *busid, struct device *parent, unsigned int id,
+                unsigned int mask)
+{
+       struct find_data data;
+
+       data.dev = NULL;
+       data.parent = parent;
+       data.busid = busid;
+       data.id = id;
+       data.mask = mask;
+
+       bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match);
+
+       return data.dev;
+}
+
+int amba_request_regions(struct amba_device *dev, const char *name)
+{
+       int ret = 0;
+
+       if (!request_mem_region(dev->res.start, SZ_4K, name))
+               ret = -EBUSY;
+
+       return ret;
+}
+
+void amba_release_regions(struct amba_device *dev)
+{
+       release_mem_region(dev->res.start, SZ_4K);
+}
+
 EXPORT_SYMBOL(amba_driver_register);
 EXPORT_SYMBOL(amba_driver_unregister);
 EXPORT_SYMBOL(amba_device_register);
 EXPORT_SYMBOL(amba_device_unregister);
+EXPORT_SYMBOL(amba_find_device);
+EXPORT_SYMBOL(amba_request_regions);
+EXPORT_SYMBOL(amba_release_regions);
index b9caaec..a2bdef2 100644 (file)
@@ -399,7 +399,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 CONFIG_BLK_DEV_OFFBOARD=y
 CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index c84b6b1..456dbbb 100644 (file)
@@ -441,7 +441,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index 33b0f9b..a974619 100644 (file)
@@ -439,7 +439,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index 7cf08c2..3da0b80 100644 (file)
@@ -285,6 +285,9 @@ __syscall_start:
                .long   sys_tgkill
                .long   sys_utimes
 /* 270 */      .long   sys_fadvise64_64
+               .long   sys_pciconfig_iobase
+               .long   sys_pciconfig_read
+               .long   sys_pciconfig_write
 __syscall_end:
 
                .rept   NR_syscalls - (__syscall_end - __syscall_start) / 4
index addbcb8..56af340 100644 (file)
@@ -102,6 +102,12 @@ SECTIONS
                 */
                *(.init.task)
 
+               . = ALIGN(4096);
+               __nosave_begin = .;
+               *(.data.nosave)
+               . = ALIGN(4096);
+               __nosave_end = .;
+
                /*
                 * then the cacheline aligned data
                 */
index dac0ad8..47f67a2 100644 (file)
@@ -7,6 +7,15 @@ config ARCH_INTEGRATOR_AP
          Include support for the ARM(R) Integrator/AP and
          Integrator/PP2 platforms.
 
+config ARCH_INTEGRATOR_CP
+       bool "Support Integrator/CP platform"
+       select ARCH_CINTEGRATOR
+       help
+         Include support for the ARM(R) Integrator CP platform.
+
+config ARCH_CINTEGRATOR
+       bool
+
 config INTEGRATOR_IMPD1
        tristate "Include support for Integrator/IM-PD1"
        depends on ARCH_INTEGRATOR_AP
index 6e2f5a2..34726a4 100644 (file)
@@ -6,6 +6,7 @@
 
 obj-y                                  := core.o lm.o time.o
 obj-$(CONFIG_ARCH_INTEGRATOR_AP)       += integrator_ap.o
+obj-$(CONFIG_ARCH_INTEGRATOR_CP)       += integrator_cp.o
 
 obj-$(CONFIG_LEDS)                     += leds.o
 obj-$(CONFIG_PCI)                      += pci_v3.o pci.o
index 5ca1a1d..8f30c11 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/spinlock.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
+#include <asm/io.h>
 #include <asm/hardware/amba.h>
+#include <asm/arch/cm.h>
 
 static struct amba_device rtc_device = {
        .dev            = {
@@ -25,7 +28,7 @@ static struct amba_device rtc_device = {
                .end    = INTEGRATOR_RTC_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
-       .irq            = IRQ_RTCINT,
+       .irq            = { IRQ_RTCINT, NO_IRQ },
        .periphid       = 0x00041030,
 };
 
@@ -38,7 +41,7 @@ static struct amba_device uart0_device = {
                .end    = INTEGRATOR_UART0_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
-       .irq            = IRQ_UARTINT0,
+       .irq            = { IRQ_UARTINT0, NO_IRQ },
        .periphid       = 0x0041010,
 };
 
@@ -51,7 +54,7 @@ static struct amba_device uart1_device = {
                .end    = INTEGRATOR_UART1_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
-       .irq            = IRQ_UARTINT1,
+       .irq            = { IRQ_UARTINT1, NO_IRQ },
        .periphid       = 0x0041010,
 };
 
@@ -64,7 +67,7 @@ static struct amba_device kmi0_device = {
                .end    = KMI0_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
-       .irq            = IRQ_KMIINT0,
+       .irq            = { IRQ_KMIINT0, NO_IRQ },
        .periphid       = 0x00041050,
 };
 
@@ -77,7 +80,7 @@ static struct amba_device kmi1_device = {
                .end    = KMI1_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
-       .irq            = IRQ_KMIINT1,
+       .irq            = { IRQ_KMIINT1, NO_IRQ },
        .periphid       = 0x00041050,
 };
 
@@ -102,3 +105,25 @@ static int __init integrator_init(void)
 }
 
 arch_initcall(integrator_init);
+
+#define CM_CTRL        IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET
+
+static spinlock_t cm_lock;
+
+/**
+ * cm_control - update the CM_CTRL register.
+ * @mask: bits to change
+ * @set: bits to set
+ */
+void cm_control(u32 mask, u32 set)
+{
+       unsigned long flags;
+       u32 val;
+
+       spin_lock_irqsave(&cm_lock, flags);
+       val = readl(CM_CTRL) & ~mask;
+       writel(val | set, CM_CTRL);
+       spin_unlock_irqrestore(&cm_lock, flags);
+}
+
+EXPORT_SYMBOL(cm_control);
index a33722e..f2c1567 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/hardware.h>
 #include <asm/io.h>
+#include <asm/mach-types.h>
 #include <asm/hardware/icst525.h>
 
 static struct cpufreq_driver integrator_driver;
@@ -98,7 +99,12 @@ static int integrator_set_target(struct cpufreq_policy *policy,
 
        /* get current setting */
        cm_osc = __raw_readl(CM_OSC);
-       vco.s = (cm_osc >> 8) & 7;
+
+       if (machine_is_integrator()) {
+               vco.s = (cm_osc >> 8) & 7;
+       } else if (machine_is_cintegrator()) {
+               vco.s = 1;
+       }
        vco.v = cm_osc & 255;
        vco.r = 22;
        freqs.old = icst525_khz(&cclk_params, vco);
@@ -107,7 +113,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
         * larger freq in case of CPUFREQ_RELATION_L.
         */
        if (relation == CPUFREQ_RELATION_L)
-               target_freq += 1999;
+               target_freq += 999;
        if (target_freq > policy->max)
                target_freq = policy->max;
        vco = icst525_khz_to_vco(&cclk_params, target_freq);
@@ -123,8 +129,14 @@ static int integrator_set_target(struct cpufreq_policy *policy,
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
        cm_osc = __raw_readl(CM_OSC);
-       cm_osc &= 0xfffff800;
-       cm_osc |= vco.v | vco.s << 8;
+
+       if (machine_is_integrator()) {
+               cm_osc &= 0xfffff800;
+               cm_osc |= vco.s << 8;
+       } else if (machine_is_cintegrator()) {
+               cm_osc &= 0xffffff00;
+       }
+       cm_osc |= vco.v;
 
        __raw_writel(0xa05f, CM_LOCK);
        __raw_writel(cm_osc, CM_OSC);
@@ -144,7 +156,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
 {
        unsigned long cpus_allowed;
        unsigned int cpu = policy->cpu;
-       u_int cm_osc, cm_stat, mem_freq_khz;
+       u_int cm_osc;
        struct icst525_vco vco;
 
        cpus_allowed = current->cpus_allowed;
@@ -153,18 +165,13 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
        BUG_ON(cpu != smp_processor_id());
 
        /* detect memory etc. */
-       cm_stat = __raw_readl(CM_STAT);
        cm_osc = __raw_readl(CM_OSC);
-       vco.s = (cm_osc >> 20) & 7;
-       vco.v = (cm_osc >> 12) & 255;
-       vco.r = 22;
-       mem_freq_khz = icst525_khz(&lclk_params, vco) / 2;
 
-       printk(KERN_INFO "CPU%d: Module id: %d\n", cpu, cm_stat & 255);
-       printk(KERN_INFO "CPU%d: Memory clock = %d.%03d MHz\n",
-              cpu, mem_freq_khz / 1000, mem_freq_khz % 1000);
-
-       vco.s = (cm_osc >> 8) & 7;
+       if (machine_is_integrator()) {
+               vco.s = (cm_osc >> 8) & 7;
+       } else if (machine_is_cintegrator()) {
+               vco.s = 1;
+       }
        vco.v = cm_osc & 255;
        vco.r = 22;
 
index 1fc9d95..dfdd5ec 100644 (file)
@@ -188,7 +188,8 @@ static int impd1_probe(struct lm_device *dev)
                d->res.start    = dev->resource.start + idev->offset;
                d->res.end      = d->res.start + SZ_4K - 1;
                d->res.flags    = IORESOURCE_MEM;
-               d->irq          = dev->irq;
+               d->irq[0]       = dev->irq;
+               d->irq[1]       = dev->irq;
                d->periphid     = idev->id;
 
                ret = amba_device_register(d, &dev->resource);
index bc48318..a803e80 100644 (file)
@@ -251,7 +251,7 @@ static struct platform_device cfi_flash_device = {
        .resource       = &cfi_flash_resource,
 };
 
-static int __init ap_init(void)
+static void __init ap_init(void)
 {
        unsigned long sc_dec;
        int i;
@@ -279,16 +279,13 @@ static int __init ap_init(void)
 
                lm_device_register(lmdev);
        }
-
-       return 0;
 }
 
-arch_initcall(ap_init);
-
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
        MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
        BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
        BOOT_PARAMS(0x00000100)
        MAPIO(ap_map_io)
        INITIRQ(ap_init_irq)
+       INIT_MACHINE(ap_init)
 MACHINE_END
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
new file mode 100644 (file)
index 0000000..7519410
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ *  linux/arch/arm/mach-integrator/integrator_cp.c
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/amba.h>
+#include <asm/hardware/amba_kmi.h>
+
+#include <asm/arch/lm.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/mmc.h>
+#include <asm/mach/map.h>
+
+#define INTCP_PA_MMC_BASE              0x1c000000
+#define INTCP_PA_AACI_BASE             0x1d000000
+
+#define INTCP_PA_FLASH_BASE            0x24000000
+#define INTCP_FLASH_SIZE               SZ_32M
+
+#define INTCP_VA_CIC_BASE              0xf1000040
+#define INTCP_VA_PIC_BASE              0xf1400000
+#define INTCP_VA_SIC_BASE              0xfca00000
+
+#define INTCP_PA_ETH_BASE              0xc8000000
+#define INTCP_ETH_SIZE                 0x10
+
+#define INTCP_VA_CTRL_BASE             0xfcb00000
+#define INTCP_FLASHPROG                        0x04
+#define CINTEGRATOR_FLASHPROG_FLVPPEN  (1 << 0)
+#define CINTEGRATOR_FLASHPROG_FLWREN   (1 << 1)
+
+/*
+ * Logical      Physical
+ * f1000000    10000000        Core module registers
+ * f1100000    11000000        System controller registers
+ * f1200000    12000000        EBI registers
+ * f1300000    13000000        Counter/Timer
+ * f1400000    14000000        Interrupt controller
+ * f1600000    16000000        UART 0
+ * f1700000    17000000        UART 1
+ * f1a00000    1a000000        Debug LEDs
+ * f1b00000    1b000000        GPIO
+ */
+
+static struct map_desc intcp_io_desc[] __initdata = {
+ { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
+ { 0xfc900000, 0xc9000000, SZ_4K, MT_DEVICE },
+ { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE },
+ { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE },
+};
+
+static void __init intcp_map_io(void)
+{
+       iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
+}
+
+#define cic_writel     __raw_writel
+#define cic_readl      __raw_readl
+#define pic_writel     __raw_writel
+#define pic_readl      __raw_readl
+#define sic_writel     __raw_writel
+#define sic_readl      __raw_readl
+
+static void cic_mask_irq(unsigned int irq)
+{
+       irq -= IRQ_CIC_START;
+       cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void cic_unmask_irq(unsigned int irq)
+{
+       irq -= IRQ_CIC_START;
+       cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET);
+}
+
+static struct irqchip cic_chip = {
+       .ack    = cic_mask_irq,
+       .mask   = cic_mask_irq,
+       .unmask = cic_unmask_irq,
+};
+
+static void pic_mask_irq(unsigned int irq)
+{
+       irq -= IRQ_PIC_START;
+       pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void pic_unmask_irq(unsigned int irq)
+{
+       irq -= IRQ_PIC_START;
+       pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET);
+}
+
+static struct irqchip pic_chip = {
+       .ack    = pic_mask_irq,
+       .mask   = pic_mask_irq,
+       .unmask = pic_unmask_irq,
+};
+
+static void sic_mask_irq(unsigned int irq)
+{
+       irq -= IRQ_SIC_START;
+       sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void sic_unmask_irq(unsigned int irq)
+{
+       irq -= IRQ_SIC_START;
+       sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET);
+}
+
+static struct irqchip sic_chip = {
+       .ack    = sic_mask_irq,
+       .mask   = sic_mask_irq,
+       .unmask = sic_unmask_irq,
+};
+
+static void
+sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+       unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS);
+
+       if (status == 0) {
+               do_bad_IRQ(irq, desc, regs);
+               return;
+       }
+
+       do {
+               irq = ffs(status) - 1;
+               status &= ~(1 << irq);
+
+               irq += IRQ_SIC_START;
+
+               desc = irq_desc + irq;
+               desc->handle(irq, desc, regs);
+       } while (status);
+}
+
+static void __init intcp_init_irq(void)
+{
+       unsigned int i;
+
+       /*
+        * Disable all interrupt sources
+        */
+       pic_writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
+       pic_writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
+
+       for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) {
+               if (i == 11)
+                       i = 22;
+               if (i == IRQ_CP_CPPLDINT)
+                       i++;
+               if (i == 29)
+                       break;
+               set_irq_chip(i, &pic_chip);
+               set_irq_handler(i, do_level_IRQ);
+               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+       }
+
+       cic_writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
+       cic_writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
+
+       for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) {
+               set_irq_chip(i, &cic_chip);
+               set_irq_handler(i, do_level_IRQ);
+               set_irq_flags(i, IRQF_VALID);
+       }
+
+       sic_writel(0x00000fff, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
+       sic_writel(0x00000fff, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
+
+       for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
+               set_irq_chip(i, &sic_chip);
+               set_irq_handler(i, do_level_IRQ);
+               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+       }
+
+       set_irq_handler(IRQ_CP_CPPLDINT, sic_handle_irq);
+       pic_unmask_irq(IRQ_CP_CPPLDINT);
+}
+
+/*
+ * Flash handling.
+ */
+static int intcp_flash_init(void)
+{
+       u32 val;
+
+       val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+       val |= CINTEGRATOR_FLASHPROG_FLWREN;
+       writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+
+       return 0;
+}
+
+static void intcp_flash_exit(void)
+{
+       u32 val;
+
+       val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+       val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN);
+       writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+}
+
+static void intcp_flash_set_vpp(int on)
+{
+       u32 val;
+
+       val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+       if (on)
+               val |= CINTEGRATOR_FLASHPROG_FLVPPEN;
+       else
+               val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN;
+       writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+}
+
+static struct flash_platform_data intcp_flash_data = {
+       .map_name       = "cfi_probe",
+       .width          = 4,
+       .init           = intcp_flash_init,
+       .exit           = intcp_flash_exit,
+       .set_vpp        = intcp_flash_set_vpp,
+};
+
+static struct resource intcp_flash_resource = {
+       .start          = INTCP_PA_FLASH_BASE,
+       .end            = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device intcp_flash_device = {
+       .name           = "armflash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &intcp_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &intcp_flash_resource,
+};
+
+static struct resource smc91x_resources[] = {
+       [0] = {
+               .start  = INTCP_PA_ETH_BASE,
+               .end    = INTCP_PA_ETH_BASE + INTCP_ETH_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_CP_ETHINT,
+               .end    = IRQ_CP_ETHINT,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device smc91x_device = {
+       .name           = "smc91x",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .resource       = smc91x_resources,
+};
+
+static struct platform_device *intcp_devs[] __initdata = {
+       &intcp_flash_device,
+       &smc91x_device,
+};
+
+/*
+ * It seems that the card insertion interrupt remains active after
+ * we've acknowledged it.  We therefore ignore the interrupt, and
+ * rely on reading it from the SIC.  This also means that we must
+ * clear the latched interrupt.
+ */
+static unsigned int mmc_status(struct device *dev)
+{
+       unsigned int status = readl(0xfca00004);
+       writel(8, 0xfcb00008);
+
+       return status & 8;
+}
+
+static struct mmc_platform_data mmc_data = {
+       .mclk           = 33000000,
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .status         = mmc_status,
+};
+
+static struct amba_device mmc_device = {
+       .dev            = {
+               .bus_id = "mb:1c",
+               .platform_data = &mmc_data,
+       },
+       .res            = {
+               .start  = INTCP_PA_MMC_BASE,
+               .end    = INTCP_PA_MMC_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq            = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 },
+       .periphid       = 0,
+};
+
+static struct amba_device aaci_device = {
+       .dev            = {
+               .bus_id = "mb:1d",
+       },
+       .res            = {
+               .start  = INTCP_PA_AACI_BASE,
+               .end    = INTCP_PA_AACI_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq            = { IRQ_CP_AACIINT, NO_IRQ },
+       .periphid       = 0,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+       &mmc_device,
+       &aaci_device,
+};
+
+static void __init intcp_init(void)
+{
+       int i;
+
+       platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
+
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+               struct amba_device *d = amba_devs[i];
+               amba_device_register(d, &iomem_resource);
+       }
+}
+
+MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
+       MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+       BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
+       BOOT_PARAMS(0x00000100)
+       MAPIO(intcp_map_io)
+       INITIRQ(intcp_init_irq)
+       INIT_MACHINE(intcp_init)
+MACHINE_END
index 8fe7df1..9d182b7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mach-integrator/leds.c
  *
- *  Integrator LED control routines
+ *  Integrator/AP and Integrator/CP LED control routines
  *
  *  Copyright (C) 1999 ARM Limited
  *  Copyright (C) 2000 Deep Blue Solutions Ltd
@@ -28,6 +28,7 @@
 #include <asm/leds.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
+#include <asm/arch/cm.h>
 
 static int saved_leds;
 
@@ -35,9 +36,6 @@ static void integrator_leds_event(led_event_t ledevt)
 {
        unsigned long flags;
        const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
-       const unsigned int hdr_ctrl = IO_ADDRESS(INTEGRATOR_HDR_BASE) +
-                                       INTEGRATOR_HDR_CTRL_OFFSET;
-       unsigned int ctrl;
        unsigned int update_alpha_leds;
        
        // yup, change the LEDs
@@ -46,15 +44,11 @@ static void integrator_leds_event(led_event_t ledevt)
 
        switch(ledevt) {
        case led_idle_start:
-               ctrl = __raw_readl(hdr_ctrl);
-               ctrl &= ~INTEGRATOR_HDR_CTRL_LED;
-               __raw_writel(ctrl, hdr_ctrl);
+               cm_control(CM_CTRL_LED, 0);
                break;
 
        case led_idle_end:
-               ctrl = __raw_readl(hdr_ctrl);
-               ctrl |= INTEGRATOR_HDR_CTRL_LED;
-               __raw_writel(ctrl, hdr_ctrl);
+               cm_control(CM_CTRL_LED, CM_CTRL_LED);
                break;
 
        case led_timer:
@@ -85,7 +79,7 @@ static void integrator_leds_event(led_event_t ledevt)
 
 static int __init leds_init(void)
 {
-       if (machine_is_integrator())
+       if (machine_is_integrator() || machine_is_cintegrator())
                leds_event = integrator_leds_event;
 
        return 0;
index 7983baf..6f214c7 100644 (file)
@@ -119,8 +119,34 @@ static struct platform_device sa1111_device = {
        .resource       = sa1111_resources,
 };
 
+static struct resource smc91x_resources[] = {
+       [0] = {
+               .start  = 0x0c000000,
+               .end    = 0x0c0fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = LUBBOCK_ETH_IRQ,
+               .end    = LUBBOCK_ETH_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = 0x0e000000,
+               .end    = 0x0e0fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device smc91x_device = {
+       .name           = "smc91x",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .resource       = smc91x_resources,
+};
+
 static struct platform_device *devices[] __initdata = {
        &sa1111_device,
+       &smc91x_device,
 };
 
 static void __init lubbock_init(void)
index b8312f4..dcd3245 100644 (file)
@@ -92,11 +92,8 @@ static void assabet_lcd_power(int on)
                ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
 }
 
-static int __init assabet_init(void)
+static void __init assabet_init(void)
 {
-       if (!machine_is_assabet())
-               return -EINVAL;
-
        /*
         * Ensure that the power supply is in "high power" mode.
         */
@@ -139,13 +136,8 @@ static int __init assabet_init(void)
                        "hasn't been configured in the kernel\n" );
 #endif
        }
-
-       return 0;
 }
 
-arch_initcall(assabet_init);
-
-
 /*
  * On Assabet, we must probe for the Neponset board _before_
  * paging_init() has occurred to actually determine the amount
@@ -332,4 +324,5 @@ MACHINE_START(ASSABET, "Intel-Assabet")
        FIXUP(fixup_assabet)
        MAPIO(assabet_map_io)
        INITIRQ(sa1100_init_irq)
+       INIT_MACHINE(assabet_init)
 MACHINE_END
index 76f6d09..4b6ad81 100644 (file)
@@ -256,9 +256,35 @@ static struct platform_device sa1111_device = {
        .resource       = sa1111_resources,
 };
 
+static struct resource smc91x_resources[] = {
+       [0] = {
+               .start  = SA1100_CS3_PHYS,
+               .end    = SA1100_CS3_PHYS + 0x01ffffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_NEPONSET_SMC9196,
+               .end    = IRQ_NEPONSET_SMC9196,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = SA1100_CS3_PHYS + 0x02000000,
+               .end    = SA1100_CS3_PHYS + 0x03ffffff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device smc91x_device = {
+       .name           = "smc91x",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .resource       = smc91x_resources,
+};
+
 static struct platform_device *devices[] __initdata = {
        &neponset_device,
        &sa1111_device,
+       &smc91x_device,
 };
 
 static int __init neponset_init(void)
index 8f2ebb7..7905c3f 100644 (file)
@@ -274,7 +274,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index b4feecc..8c24f7d 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/io_apic.h>
 #include <asm/apic.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/mpspec.h>
 
 #if defined (CONFIG_X86_LOCAL_APIC)
@@ -45,8 +46,8 @@
 int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */
 int acpi_ht __initdata = 1;    /* enable HT */
 
-int acpi_lapic = 0;
-int acpi_ioapic = 0;
+int acpi_lapic;
+int acpi_ioapic;
 
 /* --------------------------------------------------------------------------
                               Boot-time Configuration
@@ -471,7 +472,7 @@ acpi_boot_init (void)
         * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
         */
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
                return result;
@@ -479,7 +480,8 @@ acpi_boot_init (void)
 
        mp_register_lapic_address(acpi_lapic_addr);
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
+                                      MAX_APICS);
        if (!result) { 
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -491,7 +493,7 @@ acpi_boot_init (void)
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -528,8 +530,8 @@ acpi_boot_init (void)
                return 1;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
-       if (!result) { 
+       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS);
+       if (!result) {
                printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
                return -ENODEV;
        }
@@ -541,14 +543,14 @@ acpi_boot_init (void)
        /* Build a default routing table for legacy (ISA) interrupts. */
        mp_config_acpi_legacy_irqs();
 
-       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
+       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
index 7d77643..12ff2d1 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * acpi_processor_perf.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
+ * acpi-cpufreq-io.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2002, 2003 Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -42,7 +42,6 @@
 #define ACPI_PROCESSOR_CLASS           "processor"
 #define ACPI_PROCESSOR_DRIVER_NAME     "ACPI Processor P-States Driver"
 #define ACPI_PROCESSOR_DEVICE_NAME     "Processor"
-#define ACPI_PROCESSOR_FILE_PERFORMANCE        "performance"
 
 #define _COMPONENT             ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME               ("acpi_processor_perf")
@@ -52,184 +51,13 @@ MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
 MODULE_LICENSE("GPL");
 
 
-static struct acpi_processor_performance       *performance;
-
-
-static int 
-acpi_processor_get_performance_control (
-       struct acpi_processor_performance *perf)
-{
-       int                     result = 0;
-       acpi_status             status = 0;
-       struct acpi_buffer      buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       union acpi_object       *pct = NULL;
-       union acpi_object       obj = {0};
-       struct acpi_pct_register *reg = NULL;
-
-       ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
-
-       status = acpi_evaluate_object(perf->pr->handle, "_PCT", NULL, &buffer);
-       if(ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
-               return_VALUE(-ENODEV);
-       }
-
-       pct = (union acpi_object *) buffer.pointer;
-       if (!pct || (pct->type != ACPI_TYPE_PACKAGE) 
-               || (pct->package.count != 2)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
-               result = -EFAULT;
-               goto end;
-       }
-
-       /*
-        * control_register
-        */
-
-       obj = pct->package.elements[0];
-
-       if ((obj.type != ACPI_TYPE_BUFFER) 
-               || (obj.buffer.length < sizeof(struct acpi_pct_register)) 
-               || (obj.buffer.pointer == NULL)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-                       "Invalid _PCT data (control_register)\n"));
-               result = -EFAULT;
-               goto end;
-       }
-
-       reg = (struct acpi_pct_register *) (obj.buffer.pointer);
-
-       if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                       "Unsupported address space [%d] (control_register)\n",
-                       (u32) reg->space_id));
-               result = -EFAULT;
-               goto end;
-       }
-
-       perf->control_register = (u16) reg->address;
-       perf->control_register_bit_width = reg->bit_width;
-       /*
-        * status_register
-        */
-
-       obj = pct->package.elements[1];
-
-       if ((obj.type != ACPI_TYPE_BUFFER) 
-               || (obj.buffer.length < sizeof(struct acpi_pct_register)) 
-               || (obj.buffer.pointer == NULL)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-                       "Invalid _PCT data (status_register)\n"));
-               result = -EFAULT;
-               goto end;
-       }
-
-       reg = (struct acpi_pct_register *) (obj.buffer.pointer);
-
-       if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                       "Unsupported address space [%d] (status_register)\n",
-                       (u32) reg->space_id));
-               result = -EFAULT;
-               goto end;
-       }
-
-       perf->status_register = (u16) reg->address;
-       perf->status_register_bit_width = reg->bit_width;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-               "control_register[0x%04x] status_register[0x%04x]\n",
-               perf->control_register,
-               perf->status_register));
-
-end:
-       acpi_os_free(buffer.pointer);
-
-       return_VALUE(result);
-}
-
-
-static int 
-acpi_processor_get_performance_states (
-       struct acpi_processor_performance *     perf)
-{
-       int                     result = 0;
-       acpi_status             status = AE_OK;
-       struct acpi_buffer      buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       struct acpi_buffer      format = {sizeof("NNNNNN"), "NNNNNN"};
-       struct acpi_buffer      state = {0, NULL};
-       union acpi_object       *pss = NULL;
-       int                     i = 0;
-
-       ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
-
-       status = acpi_evaluate_object(perf->pr->handle, "_PSS", NULL, &buffer);
-       if(ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
-               return_VALUE(-ENODEV);
-       }
-
-       pss = (union acpi_object *) buffer.pointer;
-       if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
-               result = -EFAULT;
-               goto end;
-       }
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", 
-               pss->package.count));
-
-       if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) {
-               perf->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-                       "Limiting number of states to max (%d)\n", 
-                       ACPI_PROCESSOR_MAX_PERFORMANCE));
-       }
-       else
-               perf->state_count = pss->package.count;
-
-       if (perf->state_count > 1)
-               perf->pr->flags.performance = 1;
-
-       for (i = 0; i < perf->state_count; i++) {
-
-               struct acpi_processor_px *px = &(perf->states[i]);
-
-               state.length = sizeof(struct acpi_processor_px);
-               state.pointer = px;
-
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
-
-               status = acpi_extract_package(&(pss->package.elements[i]), 
-                       &format, &state);
-               if (ACPI_FAILURE(status)) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
-                       result = -EFAULT;
-                       goto end;
-               }
-
-               if (!px->core_frequency) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data: freq is zero\n"));
-                       result = -EFAULT;
-                       goto end;
-               }
-
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-                       "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
-                       i, 
-                       (u32) px->core_frequency, 
-                       (u32) px->power, 
-                       (u32) px->transition_latency, 
-                       (u32) px->bus_master_latency,
-                       (u32) px->control, 
-                       (u32) px->status));
-       }
+struct cpufreq_acpi_io {
+       struct acpi_processor_performance       acpi_data;
+       struct cpufreq_frequency_table          *freq_table;
+};
 
-end:
-       acpi_os_free(buffer.pointer);
+static struct cpufreq_acpi_io  *acpi_io_data[NR_CPUS];
 
-       return_VALUE(result);
-}
 
 static int
 acpi_processor_write_port(
@@ -270,7 +98,8 @@ acpi_processor_read_port(
 
 static int
 acpi_processor_set_performance (
-       struct acpi_processor_performance       *perf,
+       struct cpufreq_acpi_io  *data,
+       unsigned int            cpu,
        int                     state)
 {
        u16                     port = 0;
@@ -282,38 +111,19 @@ acpi_processor_set_performance (
 
        ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
 
-       if (!perf || !perf->pr)
-               return_VALUE(-EINVAL);
-
-       if (!perf->pr->flags.performance)
-               return_VALUE(-ENODEV);
-
-       if (state >= perf->state_count) {
-               ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
-                       "Invalid target state (P%d)\n", state));
-               return_VALUE(-ENODEV);
-       }
-
-       if (state < perf->pr->performance_platform_limit) {
-               ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
-                       "Platform limit (P%d) overrides target state (P%d)\n",
-                       perf->pr->performance_platform_limit, state));
-               return_VALUE(-ENODEV);
-       }
-
-       if (state == perf->state) {
+       if (state == data->acpi_data.state) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
                        "Already at target state (P%d)\n", state));
                return_VALUE(0);
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
-               perf->state, state));
+               data->acpi_data.state, state));
 
        /* cpufreq frequency struct */
-       cpufreq_freqs.cpu = perf->pr->id;
-       cpufreq_freqs.old = perf->states[perf->state].core_frequency;
-       cpufreq_freqs.new = perf->states[state].core_frequency;
+       cpufreq_freqs.cpu = cpu;
+       cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency;
+       cpufreq_freqs.new = data->freq_table[state].frequency;
 
        /* notify cpufreq */
        cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
@@ -323,9 +133,9 @@ acpi_processor_set_performance (
         * control_register.
         */
 
-       port = perf->control_register;
-       bit_width = perf->control_register_bit_width;
-       value = (u32) perf->states[state].control;
+       port = data->acpi_data.control_register.address;
+       bit_width = data->acpi_data.control_register.bit_width;
+       value = (u32) data->acpi_data.states[state].control;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
                "Writing 0x%08x to port 0x%04x\n", value, port));
@@ -344,12 +154,12 @@ acpi_processor_set_performance (
         * giving up.
         */
 
-       port = perf->status_register;
-       bit_width = perf->status_register_bit_width;
+       port = data->acpi_data.status_register.address;
+       bit_width = data->acpi_data.status_register.bit_width;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
                "Looking for 0x%08x from port 0x%04x\n",
-               (u32) perf->states[state].status, port));
+               (u32) data->acpi_data.states[state].status, port));
 
        for (i=0; i<100; i++) {
                ret = acpi_processor_read_port(port, bit_width, &value);
@@ -358,7 +168,7 @@ acpi_processor_set_performance (
                                "Invalid port width 0x%04x\n", bit_width));
                        return_VALUE(ret);
                }
-               if (value == (u32) perf->states[state].status)
+               if (value == (u32) data->acpi_data.states[state].status)
                        break;
                udelay(10);
        }
@@ -366,7 +176,7 @@ acpi_processor_set_performance (
        /* notify cpufreq */
        cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
 
-       if (value != (u32) perf->states[state].status) {
+       if (value != (u32) data->acpi_data.states[state].status) {
                unsigned int tmp = cpufreq_freqs.new;
                cpufreq_freqs.new = cpufreq_freqs.old;
                cpufreq_freqs.old = tmp;
@@ -380,169 +190,33 @@ acpi_processor_set_performance (
                "Transition successful after %d microseconds\n",
                i * 10));
 
-       perf->state = state;
+       data->acpi_data.state = state;
 
        return_VALUE(0);
 }
 
 
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-/* /proc/acpi/processor/../performance interface (DEPRECATED) */
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
-       .open           = acpi_processor_perf_open_fs,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
-{
-       struct acpi_processor   *pr = (struct acpi_processor *)seq->private;
-       int                     i = 0;
-
-       ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
-
-       if (!pr)
-               goto end;
-
-       if (!pr->flags.performance || !pr->performance) {
-               seq_puts(seq, "<not supported>\n");
-               goto end;
-       }
-
-       seq_printf(seq, "state count:             %d\n"
-                       "active state:            P%d\n",
-                       pr->performance->state_count,
-                       pr->performance->state);
-
-       seq_puts(seq, "states:\n");
-       for (i = 0; i < pr->performance->state_count; i++)
-               seq_printf(seq, "   %cP%d:                  %d MHz, %d mW, %d uS\n",
-                       (i == pr->performance->state?'*':' '), i,
-                       (u32) pr->performance->states[i].core_frequency,
-                       (u32) pr->performance->states[i].power,
-                       (u32) pr->performance->states[i].transition_latency);
-
-end:
-       return 0;
-}
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, acpi_processor_perf_seq_show,
-                                               PDE(inode)->data);
-}
-
-static int
-acpi_processor_write_performance (
-        struct file            *file,
-        const char             __user *buffer,
-        size_t                 count,
-        loff_t                 *data)
-{
-       int                     result = 0;
-       struct acpi_processor   *pr = (struct acpi_processor *) data;
-       char                    state_string[12] = {'\0'};
-       unsigned int            new_state = 0;
-       struct cpufreq_policy   policy;
-
-       ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
-
-       if (!pr || !pr->performance || (count > sizeof(state_string) - 1))
-               return_VALUE(-EINVAL);
-       
-       if (copy_from_user(state_string, buffer, count))
-               return_VALUE(-EFAULT);
-       
-       state_string[count] = '\0';
-       new_state = simple_strtoul(state_string, NULL, 0);
-
-       cpufreq_get_policy(&policy, pr->id);
-
-       policy.cpu = pr->id;
-       policy.max = pr->performance->states[new_state].core_frequency * 1000;
-
-       result = cpufreq_set_policy(&policy);
-       if (result)
-               return_VALUE(result);
-
-       return_VALUE(count);
-}
-
-static void
-acpi_cpufreq_add_file (
-       struct acpi_processor *pr)
-{
-       struct proc_dir_entry   *entry = NULL;
-       struct acpi_device      *device = NULL;
-
-       ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
-
-       if (acpi_bus_get_device(pr->handle, &device))
-               return_VOID;
-
-       /* add file 'performance' [R/W] */
-       entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-                 S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
-       if (!entry)
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                       "Unable to create '%s' fs entry\n",
-                       ACPI_PROCESSOR_FILE_PERFORMANCE));
-       else {
-               entry->proc_fops = &acpi_processor_perf_fops;
-               entry->proc_fops->write = acpi_processor_write_performance;
-               entry->data = acpi_driver_data(device);
-       }
-       return_VOID;
-}
-
-static void
-acpi_cpufreq_remove_file (
-       struct acpi_processor *pr)
-{
-       struct acpi_device      *device = NULL;
-
-       ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
-
-       if (acpi_bus_get_device(pr->handle, &device))
-               return_VOID;
-
-       /* remove file 'performance' */
-       remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-                 acpi_device_dir(device));
-
-       return_VOID;
-}
-
-#else
-static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
-static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
-#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
-
-
 static int
 acpi_cpufreq_target (
        struct cpufreq_policy   *policy,
        unsigned int target_freq,
        unsigned int relation)
 {
-       struct acpi_processor_performance *perf = &performance[policy->cpu];
+       struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
        unsigned int next_state = 0;
        unsigned int result = 0;
 
        ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
 
-       result = cpufreq_frequency_table_target(policy, 
-                       &perf->freq_table[perf->pr->limit.state.px],
+       result = cpufreq_frequency_table_target(policy,
+                       data->freq_table,
                        target_freq,
                        relation,
                        &next_state);
        if (result)
                return_VALUE(result);
 
-       result = acpi_processor_set_performance (perf, next_state);
+       result = acpi_processor_set_performance (data, policy->cpu, next_state);
 
        return_VALUE(result);
 }
@@ -553,119 +227,110 @@ acpi_cpufreq_verify (
        struct cpufreq_policy   *policy)
 {
        unsigned int result = 0;
-       struct acpi_processor_performance *perf = &performance[policy->cpu];
+       struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
 
        ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
 
        result = cpufreq_frequency_table_verify(policy, 
-                       &perf->freq_table[perf->pr->limit.state.px]);
-
-       cpufreq_verify_within_limits(
-               policy, 
-               perf->states[perf->state_count - 1].core_frequency * 1000,
-               perf->states[perf->pr->limit.state.px].core_frequency * 1000);
+                       data->freq_table);
 
        return_VALUE(result);
 }
 
 
 static int
-acpi_processor_get_performance_info (
-       struct acpi_processor_performance       *perf)
-{
-       int                     result = 0;
-       acpi_status             status = AE_OK;
-       acpi_handle             handle = NULL;
-
-       ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
-
-       if (!perf || !perf->pr || !perf->pr->handle)
-               return_VALUE(-EINVAL);
-
-       status = acpi_get_handle(perf->pr->handle, "_PCT", &handle);
-       if (ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-                       "ACPI-based processor performance control unavailable\n"));
-               return_VALUE(-ENODEV);
-       }
-
-       result = acpi_processor_get_performance_control(perf);
-       if (result)
-               return_VALUE(result);
-
-       result = acpi_processor_get_performance_states(perf);
-       if (result)
-               return_VALUE(result);
-
-       result = acpi_processor_get_platform_limit(perf->pr);
-       if (result)
-               return_VALUE(result);
-
-       return_VALUE(0);
-}
-
-
-static int
 acpi_cpufreq_cpu_init (
        struct cpufreq_policy   *policy)
 {
        unsigned int            i;
        unsigned int            cpu = policy->cpu;
-       struct acpi_processor   *pr = NULL;
-       struct acpi_processor_performance *perf = &performance[policy->cpu];
-       struct acpi_device      *device;
+       struct cpufreq_acpi_io  *data;
        unsigned int            result = 0;
 
        ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
 
-       acpi_processor_register_performance(perf, &pr, cpu);
+       data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
+       if (!data)
+               return_VALUE(-ENOMEM);
+       memset(data, 0, sizeof(struct cpufreq_acpi_io));
 
-       pr = performance[cpu].pr;
-       if (!pr)
-               return_VALUE(-ENODEV);
+       acpi_io_data[cpu] = data;
 
-       result = acpi_processor_get_performance_info(perf);
+       result = acpi_processor_register_performance(&data->acpi_data, cpu);
        if (result)
-               return_VALUE(-ENODEV);
+               goto err_free;
 
        /* capability check */
-       if (!pr->flags.performance)
-               return_VALUE(-ENODEV);
+       if (data->acpi_data.state_count <= 1) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No P-States\n"));
+               result = -ENODEV;
+               goto err_unreg;
+       }
+       if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) ||
+           (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported address space [%d, %d]\n",
+                                 (u32) (data->acpi_data.control_register.space_id),
+                                 (u32) (data->acpi_data.status_register.space_id)));
+               result = -ENODEV;
+               goto err_unreg;
+       }
+
+       /* alloc freq_table */
+       data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1), GFP_KERNEL);
+       if (!data->freq_table) {
+               result = -ENOMEM;
+               goto err_unreg;
+       }
 
        /* detect transition latency */
        policy->cpuinfo.transition_latency = 0;
-       for (i=0;i<perf->state_count;i++) {
-               if ((perf->states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency)
-                       policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000;
+       for (i=0; i<data->acpi_data.state_count; i++) {
+               if ((data->acpi_data.states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency)
+                       policy->cpuinfo.transition_latency = data->acpi_data.states[i].transition_latency * 1000;
        }
        policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-       policy->cur = perf->states[pr->limit.state.px].core_frequency * 1000;
+
+       /* 
+        * The current speed is unknown and not detectable by ACPI... argh! Assume 
+        * it's P0, it will be set to this value later during initialization.
+        */
+       policy->cur = data->acpi_data.states[0].core_frequency * 1000;
 
        /* table init */
-       for (i=0; i<=perf->state_count; i++)
+       for (i=0; i<=data->acpi_data.state_count; i++)
        {
-               perf->freq_table[i].index = i;
-               if (i<perf->state_count)
-                       perf->freq_table[i].frequency = perf->states[i].core_frequency * 1000;
+               data->freq_table[i].index = i;
+               if (i<data->acpi_data.state_count)
+                       data->freq_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000;
                else
-                       perf->freq_table[i].frequency = CPUFREQ_TABLE_END;
+                       data->freq_table[i].frequency = CPUFREQ_TABLE_END;
        }
 
-       result = cpufreq_frequency_table_cpuinfo(policy, &perf->freq_table[0]);
-
-       acpi_cpufreq_add_file(pr);
-
-       if (acpi_bus_get_device(pr->handle, &device))
-               device = NULL;
+       result = cpufreq_frequency_table_cpuinfo(policy, &data->freq_table[0]);
+       if (result) {
+               goto err_freqfree;
+       }
                
-       printk(KERN_INFO "cpufreq: %s - ACPI performance management activated.\n",
-               device ? acpi_device_bid(device) : "CPU??");
-       for (i = 0; i < pr->performance->state_count; i++)
+
+       printk(KERN_INFO "cpufreq: CPU%u - ACPI performance management activated.\n",
+              cpu);
+       for (i = 0; i < data->acpi_data.state_count; i++)
                printk(KERN_INFO "cpufreq: %cP%d: %d MHz, %d mW, %d uS\n",
-                       (i == pr->performance->state?'*':' '), i,
-                       (u32) pr->performance->states[i].core_frequency,
-                       (u32) pr->performance->states[i].power,
-                       (u32) pr->performance->states[i].transition_latency);
+                       (i == data->acpi_data.state?'*':' '), i,
+                       (u32) data->acpi_data.states[i].core_frequency,
+                       (u32) data->acpi_data.states[i].power,
+                       (u32) data->acpi_data.states[i].transition_latency);
+
+       return_VALUE(result);
+
+ err_freqfree:
+       kfree(data->freq_table);
+ err_unreg:
+       acpi_processor_unregister_performance(&data->acpi_data, cpu);
+ err_free:
+       kfree(data);
+       acpi_io_data[cpu] = NULL;
+
        return_VALUE(result);
 }
 
@@ -674,11 +339,16 @@ static int
 acpi_cpufreq_cpu_exit (
        struct cpufreq_policy   *policy)
 {
-       struct acpi_processor  *pr = performance[policy->cpu].pr;
+       struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
+
 
        ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_exit");
 
-       acpi_cpufreq_remove_file(pr);
+       if (data) {
+               acpi_io_data[policy->cpu] = NULL;
+               acpi_processor_unregister_performance(&data->acpi_data, policy->cpu);
+               kfree(data);
+       }
 
        return_VALUE(0);
 }
@@ -698,97 +368,11 @@ static int __init
 acpi_cpufreq_init (void)
 {
        int                     result = 0;
-       int                     current_state = 0;
-       int                     i = 0;
-       struct acpi_processor   *pr = NULL;
-       struct acpi_processor_performance *perf = NULL;
 
        ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
 
-       /* alloc memory */
-       if (performance)
-               return_VALUE(-EBUSY);
-
-       performance = kmalloc(NR_CPUS * sizeof(struct acpi_processor_performance), GFP_KERNEL);
-       if (!performance)
-               return_VALUE(-ENOMEM);
-       memset(performance, 0, NR_CPUS * sizeof(struct acpi_processor_performance));
-
-       /* register struct acpi_processor_performance performance */
-       for (i=0; i<NR_CPUS; i++) {
-               if (cpu_online(i))
-                       acpi_processor_register_performance(&performance[i], &pr, i);
-       }
-
-       /* initialize  */
-       for (i=0; i<NR_CPUS; i++) {
-               if (cpu_online(i) && performance[i].pr)
-                       result = acpi_processor_get_performance_info(&performance[i]);
-       }
-
-       /* test it on one CPU */
-       for (i=0; i<NR_CPUS; i++) {
-               if (!cpu_online(i))
-                       continue;
-               pr = performance[i].pr;
-               if (pr && pr->flags.performance)
-                       goto found_capable_cpu;
-       }
-       result = -ENODEV;
-       goto err0;
-
- found_capable_cpu:
-       
        result = cpufreq_register_driver(&acpi_cpufreq_driver);
-       if (result) 
-               goto err0;
        
-       perf = pr->performance;
-       current_state = perf->state;
-
-       if (current_state == pr->limit.state.px) {
-               result = acpi_processor_set_performance(perf, (perf->state_count - 1));
-               if (result) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
-                       result = -ENODEV;
-                       goto err1;
-               }
-       }
-
-       result = acpi_processor_set_performance(perf, pr->limit.state.px);
-       if (result) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
-               result = -ENODEV;
-               goto err1;
-       }
-       
-       if (current_state != 0) {
-               result = acpi_processor_set_performance(perf, current_state);
-               if (result) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
-                       result = -ENODEV;
-                       goto err1;
-               }
-       }
-
-       return_VALUE(0);
-
-       /* error handling */
- err1:
-       cpufreq_unregister_driver(&acpi_cpufreq_driver);
-       
- err0:
-       /* unregister struct acpi_processor_performance performance */
-       for (i=0; i<NR_CPUS; i++) {
-               if (performance[i].pr) {
-                       performance[i].pr->flags.performance = 0;
-                       performance[i].pr->performance = NULL;
-                       performance[i].pr = NULL;
-               }
-       }
-       kfree(performance);
-       
-       printk(KERN_INFO "cpufreq: No CPUs supporting ACPI performance management found.\n");
        return_VALUE(result);
 }
 
@@ -796,27 +380,9 @@ acpi_cpufreq_init (void)
 static void __exit
 acpi_cpufreq_exit (void)
 {
-       int                     i = 0;
-
        ACPI_FUNCTION_TRACE("acpi_cpufreq_exit");
 
-       for (i=0; i<NR_CPUS; i++) {
-               if (performance[i].pr)
-                       performance[i].pr->flags.performance = 0;
-       }
-
-        cpufreq_unregister_driver(&acpi_cpufreq_driver);
-
-       /* unregister struct acpi_processor_performance performance */
-       for (i=0; i<NR_CPUS; i++) {
-               if (performance[i].pr) {
-                       performance[i].pr->flags.performance = 0;
-                       performance[i].pr->performance = NULL;
-                       performance[i].pr = NULL;
-               }
-       }
-
-       kfree(performance);
+       cpufreq_unregister_driver(&acpi_cpufreq_driver);
 
        return_VOID;
 }
index 983d799..745a565 100644 (file)
@@ -191,7 +191,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index 5c755d7..719def0 100644 (file)
@@ -170,7 +170,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index 5456e54..bc4a1e3 100644 (file)
@@ -188,7 +188,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index 67da883..30f55df 100644 (file)
@@ -191,8 +191,6 @@ acpi_parse_lsapic (acpi_table_entry_header *header)
 
        if (!lsapic->flags.enabled)
                printk(" disabled");
-       else if (available_cpus >= NR_CPUS)
-               printk(" ignored (increase NR_CPUS)");
        else {
                printk(" enabled");
 #ifdef CONFIG_SMP
@@ -395,12 +393,6 @@ acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
        size = ma->length_hi;
        size = (size << 32) | ma->length_lo;
 
-       if (num_node_memblks >= NR_NODE_MEMBLKS) {
-               printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n",
-                      size/(1024*1024), paddr);
-               return;
-       }
-
        /* Ignore disabled entries */
        if (!ma->flags.enabled)
                return;
@@ -552,29 +544,29 @@ acpi_boot_init (void)
 
        /* Local APIC */
 
-       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1)
+       if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1)
                printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 
        /* I/O APIC */
 
-       if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1)
+       if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
                printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
 
        /* System-Level Interrupt Routing */
 
-       if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0)
                printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
   skip_madt:
 
index 983afbf..0957a01 100644 (file)
@@ -114,7 +114,7 @@ static struct iosapic {
        char            *addr;          /* base address of IOSAPIC */
        unsigned int    gsi_base;       /* first GSI assigned to this IOSAPIC */
        unsigned short  num_rte;        /* number of RTE in this IOSAPIC */
-} iosapic_lists[256];
+} iosapic_lists[NR_IOSAPICS];
 
 static int num_iosapic;
 
index 048b5fc..2c03714 100644 (file)
@@ -645,7 +645,7 @@ vertex_to_name(vertex_hdl_t vhdl, char *buf, unsigned int buflen)
 
 
 void
-hwgraph_debug(char *file, char * function, int line, vertex_hdl_t vhdl1, vertex_hdl_t vhdl2, char *format, ...)
+hwgraph_debug(char *file, const char * function, int line, vertex_hdl_t vhdl1, vertex_hdl_t vhdl2, char *format, ...)
 {
 
        int pos;
index 4bd13b4..d6aa26c 100644 (file)
@@ -151,7 +151,7 @@ mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid)
                (void)hwgraph_edge_add( hwgraph_all_cnodes,
                                        vhdl,
                                        cnodeid_buffer);
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hwgraph_all_cnodes, NULL, "Creating path vhdl1\n"));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hwgraph_all_cnodes, NULL, "Creating path vhdl1\n");
        }
 }
 
index cccb99d..fc29ddd 100644 (file)
@@ -471,38 +471,8 @@ hub_dmamap_addr(   hub_dmamap_t dmamap,    /* use these mapping resources */
 }
 
 /*
- * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc.
- * Return an appropriate crosstalk address list that maps to the specified physical 
- * address list.
- */
-/* ARGSUSED */
-alenlist_t
-hub_dmamap_list(hub_dmamap_t hub_dmamap,       /* use these mapping resources */
-               alenlist_t palenlist,           /* map this area of memory */
-               unsigned flags)
-{
-       vertex_hdl_t vhdl;
-
-       ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
-
-       if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
-           /* If the map is FIXED, re-use is OK. */
-           if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
-               char name[MAXDEVNAME];
-               vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
-               printk(KERN_WARNING  "%s: hub_dmamap_list re-uses dmamap\n", vertex_to_name(vhdl, name, MAXDEVNAME));
-           }
-       } else {
-               hub_dmamap->hdma_flags |= HUB_DMAMAP_USED;
-       }
-
-       /* There isn't actually any DMA mapping hardware on the hub.  */
-       return palenlist;
-}
-
-/*
  * Driver indicates that it has completed whatever DMA it may have started
- * after an earlier dmamap_addr or dmamap_list call.
+ * after an earlier dmamap_addr call.
  */
 void
 hub_dmamap_done(hub_dmamap_t hub_dmamap)       /* done with these mapping resources */
@@ -535,23 +505,6 @@ hub_dmatrans_addr( vertex_hdl_t dev,       /* translate for this device */
        return (PHYS_TO_DMA(paddr));
 }
 
-/*
- * Translate a list of IP27 addresses and lengths into a list of crosstalk 
- * addresses and lengths.  No actual hardware mapping takes place; the hub 
- * has no DMA mapping registers -- crosstalk addresses map directly.
- */
-/* ARGSUSED */
-alenlist_t
-hub_dmatrans_list(     vertex_hdl_t dev,       /* translate for this device */
-                       device_desc_t dev_desc, /* device descriptor */
-                       alenlist_t palenlist,   /* system address/length list */
-                       unsigned flags)         /* defined in dma.h */
-{
-       BUG();
-       /* no translation needed */
-       return palenlist;
-}
-
 /*ARGSUSED*/
 void
 hub_dmamap_drain(      hub_dmamap_t map)
@@ -568,15 +521,6 @@ hub_dmaaddr_drain( vertex_hdl_t vhdl,
     /* XXX- flush caches, if cache coherency WAR is needed */
 }
 
-/*ARGSUSED*/
-void
-hub_dmalist_drain(     vertex_hdl_t vhdl,
-                       alenlist_t list)
-{
-    /* XXX- flush caches, if cache coherency WAR is needed */
-}
-
-
 
 /* CONFIGURATION MANAGEMENT */
 
@@ -768,28 +712,25 @@ hub_widget_flags_set(nasid_t              nasid,
  * crosstalk bus provider.
  */
 xtalk_provider_t hub_provider = {
-       (xtalk_piomap_alloc_f *)        hub_piomap_alloc,
-       (xtalk_piomap_free_f *)         hub_piomap_free,
-       (xtalk_piomap_addr_f *)         hub_piomap_addr,
-       (xtalk_piomap_done_f *)         hub_piomap_done,
-       (xtalk_piotrans_addr_f *)       hub_piotrans_addr,
-
-       (xtalk_dmamap_alloc_f *)        hub_dmamap_alloc,
-       (xtalk_dmamap_free_f *)         hub_dmamap_free,
-       (xtalk_dmamap_addr_f *)         hub_dmamap_addr,
-       (xtalk_dmamap_list_f *)         hub_dmamap_list,
-       (xtalk_dmamap_done_f *)         hub_dmamap_done,
-       (xtalk_dmatrans_addr_f *)       hub_dmatrans_addr,
-       (xtalk_dmatrans_list_f *)       hub_dmatrans_list,
-       (xtalk_dmamap_drain_f *)        hub_dmamap_drain,
-       (xtalk_dmaaddr_drain_f *)       hub_dmaaddr_drain,
-       (xtalk_dmalist_drain_f *)       hub_dmalist_drain,
-
-       (xtalk_intr_alloc_f *)          hub_intr_alloc,
-       (xtalk_intr_alloc_f *)          hub_intr_alloc_nothd,
-       (xtalk_intr_free_f *)           hub_intr_free,
-       (xtalk_intr_connect_f *)        hub_intr_connect,
-       (xtalk_intr_disconnect_f *)     hub_intr_disconnect,
-       (xtalk_provider_startup_f *)    hub_provider_startup,
-       (xtalk_provider_shutdown_f *)   hub_provider_shutdown,
+       .piomap_alloc   = (xtalk_piomap_alloc_f *) hub_piomap_alloc,
+       .piomap_free    = (xtalk_piomap_free_f *) hub_piomap_free,
+       .piomap_addr    = (xtalk_piomap_addr_f *) hub_piomap_addr,
+       .piomap_done    = (xtalk_piomap_done_f *) hub_piomap_done,
+       .piotrans_addr  = (xtalk_piotrans_addr_f *) hub_piotrans_addr,
+
+       .dmamap_alloc   = (xtalk_dmamap_alloc_f *) hub_dmamap_alloc,
+       .dmamap_free    = (xtalk_dmamap_free_f *) hub_dmamap_free,
+       .dmamap_addr    = (xtalk_dmamap_addr_f *) hub_dmamap_addr,
+       .dmamap_done    = (xtalk_dmamap_done_f *) hub_dmamap_done,
+       .dmatrans_addr  = (xtalk_dmatrans_addr_f *) hub_dmatrans_addr,
+       .dmamap_drain   = (xtalk_dmamap_drain_f *) hub_dmamap_drain,
+       .dmaaddr_drain  = (xtalk_dmaaddr_drain_f *) hub_dmaaddr_drain,
+
+       .intr_alloc     = (xtalk_intr_alloc_f *) hub_intr_alloc,
+       .intr_alloc_nothd = (xtalk_intr_alloc_f *) hub_intr_alloc_nothd,
+       .intr_free      = (xtalk_intr_free_f *) hub_intr_free,
+       .intr_connect   = (xtalk_intr_connect_f *) hub_intr_connect,
+       .intr_disconnect = (xtalk_intr_disconnect_f *) hub_intr_disconnect,
+       .provider_startup = (xtalk_provider_startup_f *) hub_provider_startup,
+       .provider_shutdown = (xtalk_provider_shutdown_f *) hub_provider_shutdown,
 };
index 3bb59b9..0a8b925 100644 (file)
@@ -43,7 +43,7 @@ klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
 
        hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
 
-       HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, myhubv, NULL, "Created path for hub vertex for Shub node.\n"));
+       HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, myhubv, NULL, "Created path for hub vertex for Shub node.\n");
 
        rc = device_master_set(myhubv, node_vertex);
        if (rc) {
@@ -71,7 +71,7 @@ klhwg_add_disabled_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu,
                snprintf(name, 120, "%s/%s/%c", EDGE_LBL_DISABLED, EDGE_LBL_CPU, 'a' + cpu->cpu_info.physid);
                (void) hwgraph_path_add(node_vertex, name, &my_cpu);
 
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for disabled cpu slice.\n"));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for disabled cpu slice.\n");
 
                mark_cpuvertex_as_cpu(my_cpu, cpu_id);
                device_master_set(my_cpu, node_vertex);
@@ -98,7 +98,7 @@ klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
 
         (void) hwgraph_path_add(node_vertex, name, &my_cpu);
 
-       HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for active cpu slice.\n"));
+       HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for active cpu slice.\n");
 
        mark_cpuvertex_as_cpu(my_cpu, cpu_id);
         device_master_set(my_cpu, node_vertex);
@@ -107,7 +107,7 @@ klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
         if (hwgraph_edge_get(node_vertex, EDGE_LBL_CPU, &cpu_dir) == GRAPH_SUCCESS) {
                 snprintf(name, 120, "%c", 'a' + cpu->cpu_info.physid);
                 (void) hwgraph_edge_add(cpu_dir, my_cpu, name);
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, cpu_dir, my_cpu, "Created % from vhdl1 to vhdl2.\n", name));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, cpu_dir, my_cpu, "Created % from vhdl1 to vhdl2.\n", name);
         }
 }
 
@@ -166,7 +166,7 @@ klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
                        return;
                 }
 
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, xbow_v, NULL, "Created path for xtalk.\n"));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, xbow_v, NULL, "Created path for xtalk.\n");
 
                xswitch_vertex_init(xbow_v); 
 
@@ -212,7 +212,7 @@ klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode)
                return;
        }
 
-       HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created path for SHUB node.\n"));
+       HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created path for SHUB node.\n");
        hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
        ASSERT(hub);
        if(hub->hub_info.flags & KLINFO_ENABLE)
@@ -250,7 +250,7 @@ klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode)
                        printk("klhwg_add_node: Cannot create CPU directory\n");
                        return;
                }
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, cpu_dir, NULL, "Created cpu directiry on SHUB node.\n"));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, cpu_dir, NULL, "Created cpu directiry on SHUB node.\n");
 
        }
 
@@ -305,7 +305,7 @@ klhwg_add_all_routers(vertex_hdl_t hwgraph_root)
                                                  "failed.  Path == %s", path_buffer);
                                return;
                        }
-                       HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created router path.\n"));
+                       HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created router path.\n");
 
                /* Find the rest of the routers stored on this node. */
                } while ( (brd = find_lboard_class_any(KLCF_NEXT_ANY(brd),
@@ -400,7 +400,7 @@ klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd,
                                path_buffer, dest_path, (void *)dest_hndl, rc);
                        return;
                }
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, router_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", dest_path));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, router_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", dest_path);
                
        }
 }
@@ -492,14 +492,14 @@ klhwg_connect_hubs(vertex_hdl_t hwgraph_root)
 
                                rc = hwgraph_path_add(hub_hndl, EDGE_LBL_INTERCONNECT, &hub_hndl);
 
-                               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hub_hndl, NULL, "Created link path.\n"));
+                               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, NULL, "Created link path.\n");
 
                                sprintf(buf,"%s/%s",path_buffer,EDGE_LBL_INTERCONNECT);
                                rc = hwgraph_traverse(hwgraph_root, buf, &hub_hndl);
                                sprintf(buf,"%d",port);
                                rc = hwgraph_edge_add(hub_hndl, dest_hndl, buf);
 
-                               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hub_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", buf));
+                               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", buf);
 
                                if (rc != GRAPH_SUCCESS) {
                                        printk("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
@@ -533,7 +533,7 @@ klhwg_add_all_modules(vertex_hdl_t hwgraph_root)
                rc = hwgraph_path_add(hwgraph_root, name, &module_vhdl);
                ASSERT(rc == GRAPH_SUCCESS);
                rc = rc;
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, module_vhdl, NULL, "Created module path.\n"));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, module_vhdl, NULL, "Created module path.\n");
 
                hwgraph_fastinfo_set(module_vhdl, (arbitrary_info_t) modules[cm]);
 
@@ -545,7 +545,7 @@ klhwg_add_all_modules(vertex_hdl_t hwgraph_root)
                rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
                ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
                rc = rc;
-               HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, vhdl, NULL, "Created L1 path.\n"));
+               HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, vhdl, NULL, "Created L1 path.\n");
 
                hwgraph_info_add_LBL(vhdl, INFO_LBL_ELSC,
                                     (arbitrary_info_t)1);
index 2128672..67204d2 100644 (file)
@@ -200,7 +200,7 @@ io_module_init(void)
        board = find_lboard_nasid((lboard_t *) KL_CONFIG_INFO(nasid), nasid, KLTYPE_SNIA);
        ASSERT(board);
 
-       HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found Shub lboard 0x%lx nasid 0x%x cnode 0x%x \n", (unsigned long)board, (int)nasid, (int)node));
+       HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found Shub lboard 0x%lx nasid 0x%x cnode 0x%x \n", (unsigned long)board, (int)nasid, (int)node);
 
        m = module_add_node(board->brd_geoid, node);
        if (! m->snum_valid && module_probe_snum(m, nasid, nasid))
@@ -219,7 +219,7 @@ io_module_init(void)
                                nasid, KLTYPE_SNIA);
        ASSERT(board);
 
-       HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found headless/memless lboard 0x%lx node %d nasid %d cnode %d\n", (unsigned long)board, node, (int)nasid, (int)node));
+       HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found headless/memless lboard 0x%lx node %d nasid %d cnode %d\n", (unsigned long)board, node, (int)nasid, (int)node);
 
         m = module_add_node(board->brd_geoid, node);
 
index 53d0a25..3571229 100644 (file)
@@ -106,7 +106,6 @@ cnodeid_t           pcibr_get_dmatrans_node(vertex_hdl_t);
 iopaddr_t               pcibr_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
 void                    pcibr_dmamap_drain(pcibr_dmamap_t);
 void                    pcibr_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(vertex_hdl_t, alenlist_t);
 iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
 
 void                    pcibr_provider_startup(vertex_hdl_t);
@@ -2327,17 +2326,6 @@ pcibr_dmaaddr_drain(vertex_hdl_t pconn_vhdl,
     xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
 }
 
-void
-pcibr_dmalist_drain(vertex_hdl_t pconn_vhdl,
-                   alenlist_t list)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmalist_drain(xconn_vhdl, list);
-}
-
 /*
  * Get the starting PCIbus address out of the given DMA map.
  * This function is supposed to be used by a close friend of PCI bridge
index 6aaf86e..04d70e1 100644 (file)
@@ -304,13 +304,6 @@ pciio_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
        (dev, addr, size);
 }
 
-void
-pciio_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-       (dev, list);
-}
-
 /* =====================================================================
  *          INTERRUPT MANAGEMENT
  *
index 3c6979a..bbf07dd 100644 (file)
@@ -805,7 +805,6 @@ pciio_provider_t        pci_pic_provider =
     (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
     (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
     (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
-    (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
 
     (pciio_intr_alloc_f *) pcibr_intr_alloc,
     (pciio_intr_free_f *) pcibr_intr_free,
index 88104c7..4e9769c 100644 (file)
@@ -47,13 +47,10 @@ static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidg
 xtalk_dmamap_t          xtalk_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    xtalk_dmamap_free(xtalk_dmamap_t);
 iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
-alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
 void                    xtalk_dmamap_done(xtalk_dmamap_t);
 iopaddr_t               xtalk_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(vertex_hdl_t, device_desc_t, alenlist_t, unsigned);
 void                   xtalk_dmamap_drain(xtalk_dmamap_t);
 void                   xtalk_dmaaddr_drain(vertex_hdl_t, iopaddr_t, size_t);
-void                   xtalk_dmalist_drain(vertex_hdl_t, alenlist_t);
 xtalk_intr_t            xtalk_intr_alloc(vertex_hdl_t, device_desc_t, vertex_hdl_t);
 xtalk_intr_t            xtalk_intr_alloc_nothd(vertex_hdl_t, device_desc_t, vertex_hdl_t);
 void                    xtalk_intr_free(xtalk_intr_t);
@@ -352,16 +349,6 @@ xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap,     /* use these mapping resources */
 }
 
 
-alenlist_t
-xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */
-                 alenlist_t alenlist,  /* map this Address/Length List */
-                 unsigned flags)
-{
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
-       (CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
-}
-
-
 void
 xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
 {
@@ -382,16 +369,6 @@ xtalk_dmatrans_addr(vertex_hdl_t dev,      /* translate for this device */
 }
 
 
-alenlist_t
-xtalk_dmatrans_list(vertex_hdl_t dev,  /* translate for this device */
-                   device_desc_t dev_desc,     /* device descriptor */
-                   alenlist_t palenlist,       /* system address/length list */
-                   unsigned flags)
-{                              /* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-       (dev, dev_desc, palenlist, flags);
-}
-
 void
 xtalk_dmamap_drain(xtalk_dmamap_t map)
 {
@@ -406,13 +383,6 @@ xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
        (dev, addr, size);
 }
 
-void
-xtalk_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-       (dev, list);
-}
-
 /* =====================================================================
  *                    INTERRUPT MANAGEMENT
  *
index 38b02f2..0f2e950 100644 (file)
@@ -254,7 +254,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
new file mode 100644 (file)
index 0000000..8fb5158
--- /dev/null
@@ -0,0 +1,887 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_PARISC=y
+CONFIG_MMU=y
+CONFIG_STACK_GROWSUP=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+# CONFIG_STANDALONE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+# CONFIG_PA7000 is not set
+# CONFIG_PA7100LC is not set
+# CONFIG_PA7200 is not set
+CONFIG_PA8X00=y
+CONFIG_PA20=y
+CONFIG_PARISC64=y
+CONFIG_64BIT=y
+# CONFIG_PDC_NARROW is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+CONFIG_COMPAT=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, GSC, ISA)
+#
+# CONFIG_GSC is not set
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_PCI_LBA=y
+CONFIG_IOSAPIC=y
+CONFIG_IOMMU_SBA=y
+# CONFIG_SUPERIO is not set
+CONFIG_CHASSIS_LCD_LED=y
+# CONFIG_PDC_CHASSIS is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+CONFIG_YENTA=m
+CONFIG_CARDBUS=y
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=6144
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_REPORT_LUNS=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_IOMAPPED=y
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=m
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_QLOGIC_1280=m
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+CONFIG_SCSI_DEBUG=m
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_DM is not set
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_ISENSE=m
+CONFIG_FUSION_CTL=m
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+# CONFIG_INET_IPCOMP is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+# CONFIG_IP_NF_NAT_LOCAL is not set
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+CONFIG_PCMCIA_XIRCOM=m
+CONFIG_PCMCIA_XIRTULIP=m
+CONFIG_HP100=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=m
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+CONFIG_EPIC100=m
+# CONFIG_SUNDANCE is not set
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+CONFIG_ACENIC_OMIT_TIGON_I=y
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SK98LIN is not set
+CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+CONFIG_PCMCIA_WAVELAN=m
+CONFIG_PCMCIA_NETWAVE=m
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_AIRO is not set
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_PCI_HERMES=m
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+CONFIG_PCMCIA_HERMES=m
+CONFIG_AIRO_CS=m
+# CONFIG_PCMCIA_ATMEL is not set
+# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MUX is not set
+CONFIG_PDC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# I2C Algorithms
+#
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+CONFIG_GEN_RTC_X=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+# CONFIG_STI_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE_COLUMNS=160
+CONFIG_DUMMY_CONSOLE_ROWS=64
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+CONFIG_JFS_FS=m
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_GSS is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+CONFIG_NLS_CODEPAGE_863=m
+# CONFIG_NLS_CODEPAGE_864 is not set
+CONFIG_NLS_CODEPAGE_865=m
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_INFO is not set
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
new file mode 100644 (file)
index 0000000..e1a7a67
--- /dev/null
@@ -0,0 +1,1057 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_PARISC=y
+CONFIG_MMU=y
+CONFIG_STACK_GROWSUP=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+# CONFIG_STANDALONE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+# CONFIG_PA7000 is not set
+# CONFIG_PA7100LC is not set
+# CONFIG_PA7200 is not set
+CONFIG_PA8X00=y
+CONFIG_PA20=y
+# CONFIG_PARISC64 is not set
+# CONFIG_64BIT is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HPUX is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, GSC, ISA)
+#
+# CONFIG_GSC is not set
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_PCI_LBA=y
+CONFIG_IOSAPIC=y
+CONFIG_IOMMU_SBA=y
+CONFIG_SUPERIO=y
+# CONFIG_CHASSIS_LCD_LED is not set
+# CONFIG_PDC_CHASSIS is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+CONFIG_YENTA=m
+CONFIG_CARDBUS=y
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_FW_LOADER=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDEDISK_STROKE=y
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_IDE_TASKFILE_IO is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_PCI_WIP is not set
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_NS87415=y
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=m
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_REPORT_LUNS=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_MEGARAID is not set
+CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_VIA=m
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+CONFIG_SCSI_QLOGIC_FC=m
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA2XXX_CONFIG=y
+CONFIG_SCSI_QLA2XXX=m
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+CONFIG_SCSI_QLA23XX=m
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+CONFIG_SCSI_DEBUG=m
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+CONFIG_PCMCIA_QLOGIC=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_DM is not set
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_ISENSE=m
+CONFIG_FUSION_CTL=m
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+# CONFIG_INET_IPCOMP is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+# CONFIG_IP_NF_NAT_LOCAL is not set
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_IP_NF_COMPAT_IPCHAINS=m
+CONFIG_IP_NF_COMPAT_IPFWADM=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_HAPPYMEAL=m
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+# CONFIG_DM9102 is not set
+CONFIG_PCMCIA_XIRCOM=m
+CONFIG_PCMCIA_XIRTULIP=m
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_AMD8111_ETH is not set
+CONFIG_ADAPTEC_STARFIRE=m
+# CONFIG_ADAPTEC_STARFIRE_NAPI is not set
+CONFIG_B44=m
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=m
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SK98LIN is not set
+CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_IXGB=y
+CONFIG_IXGB_NAPI=y
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=m
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PCIPS2 is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_HIL_OLD is not set
+# CONFIG_KEYBOARD_HIL is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_HIL is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MUX is not set
+# CONFIG_PDC_CONSOLE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+CONFIG_GEN_RTC_X=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_STI=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE_COLUMNS=160
+CONFIG_DUMMY_CONSOLE_ROWS=64
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_PARISC_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_UHCI_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_MIDI is not set
+# CONFIG_USB_ACM is not set
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+# CONFIG_USB_STORAGE_ISD200 is not set
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_XPAD is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_SCANNER=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+CONFIG_USB_LEGOTOWER=m
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_INFO is not set
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
index 945ca1b..0800eb3 100644 (file)
@@ -1,7 +1,24 @@
 /*
- * linux/arch/parisc/kernel/sys_hpux.c
+ *    Implements HPUX syscalls.
  *
- * implements HPUX syscalls.
+ *    Copyright (C) 1999 Matthew Wilcox <willy with parisc-linux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2000 John Marvin <jsm with parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the 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/mm.h>
index 03d6300..755d3a4 100644 (file)
@@ -1,7 +1,21 @@
 /*
- * linux/arch/parisc/hpux/ioctl.c
+ *    Implements some necessary HPUX ioctls.
  *
- * implements some necessary HPUX ioctls.
+ *    Copyright (C) 1999-2002 Matthew Wilcox <willy with parisc-linux.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*
index 382124d..d6d2b3f 100644 (file)
@@ -1,7 +1,25 @@
 /*
- * linux/arch/parisc/kernel/sys_hpux.c
+ *    Implements HPUX syscalls.
  *
- * implements HPUX syscalls.
+ *    Copyright (C) 1999 Matthew Wilcox <willy with parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf
+ *    Copyright (C) 2000 John Marvin <jsm with parisc-linux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2001 Nathan Neulinger <nneul at umr.edu>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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/fs.h>
index 6b9af53..f4dac2e 100644 (file)
@@ -2,6 +2,29 @@
  * Generate definitions needed by assembly language modules.
  * This code generates raw asm output which is post-processed to extract
  * and format the required data.
+ *
+ *    Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
+ *    Copyright (C) 2000 Sam Creasey <sammy@sammy.net>
+ *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2001 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2001 Richard Hirst <rhirst at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *    Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/types.h>
index 976b9c7..bdb2af9 100644 (file)
@@ -286,7 +286,7 @@ void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path)
                path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
        }
 
-       padev = HBA_DATA(bus->dev->platform_data)->dev;
+       padev = HBA_DATA(bus->bridge->platform_data)->dev;
        while (padev != &root) {
                path->bc[i--] = padev->hw_path;
                padev = padev->parent;
index 8c733e0..da94aec 100644 (file)
@@ -1,10 +1,22 @@
-/* arch/parisc/kernel/pdc.c  - safe pdc access routines
+/*
+ * arch/parisc/kernel/firmware.c  - safe PDC access routines
+ *
+ *     PDC == Processor Dependent Code
+ *
+ * See http://www.parisc-linux.org/documentation/index.html
+ * for documentation describing the entry points and calling
+ * conventions defined below.
  *
  * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
- * portions Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ * Copyright 2003 Grant Grundler <grundler parisc-linux org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
  *
- * only these routines should be used out of the real kernel (i.e. everything
- * using virtual addresses) for obvious reasons */
+ */
 
 /*     I think it would be in everyone's best interest to follow this
  *     guidelines when writing PDC wrappers:
@@ -643,6 +655,49 @@ int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
 }
 
 
+#if 0  /* UNTEST CODE - left here in case someone needs it */
+
+/** 
+ * pdc_pci_config_read - read PCI config space.
+ * @hpa                token from PDC to indicate which PCI device
+ * @pci_addr   configuration space address to read from
+ *
+ * Read PCI Configuration space *before* linux PCI subsystem is running.
+ */
+unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
+{
+       int retval;
+       spin_lock_irq(&pdc_lock);
+       pdc_result[0] = 0;
+       pdc_result[1] = 0;
+       retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG, 
+                             __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL);
+       spin_unlock_irq(&pdc_lock);
+       return retval ? ~0 : (unsigned int) pdc_result[0];
+}
+
+
+/** 
+ * pdc_pci_config_write - read PCI config space.
+ * @hpa                token from PDC to indicate which PCI device
+ * @pci_addr   configuration space address to write
+ * @val                value we want in the 32-bit register
+ *
+ * Write PCI Configuration space *before* linux PCI subsystem is running.
+ */
+void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
+{
+       int retval;
+       spin_lock_irq(&pdc_lock);
+       pdc_result[0] = 0;
+       retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG, 
+                             __pa(pdc_result), hpa,
+                             cfg_addr&~3UL, 4UL, (unsigned long) val);
+       spin_unlock_irq(&pdc_lock);
+       return retval;
+}
+#endif /* UNTESTED CODE */
+
 /**
  * pdc_tod_read - Read the Time-Of-Day clock.
  * @tod: The return buffer:
index 5f2de99..d7aff5e 100644 (file)
 
        .level 1.1
 
-       .section        .initcall.init
-       .align          4
-       .export __initcall_start
-__initcall_start:
-       .export __initcall_end
-__initcall_end:
-       .export __setup_start
-__setup_start:
-       .export __setup_end
-__setup_end:
-
        .data
 
        .export boot_args
@@ -64,13 +53,13 @@ stext:
 
        /* Clear BSS (shouldn't the boot loader do this?) */
 
-       .import _edata,data
-       .import _end,data
+       .import __bss_start,data
+       .import __bss_stop,data
 
-       ldil            L%PA(_edata),%r3
-       ldo             R%PA(_edata)(%r3),%r3
-       ldil            L%PA(_end),%r4
-       ldo             R%PA(_end)(%r4),%r4
+       ldil            L%PA(__bss_start),%r3
+       ldo             R%PA(__bss_start)(%r3),%r3
+       ldil            L%PA(__bss_stop),%r4
+       ldo             R%PA(__bss_stop)(%r4),%r4
 $bss_loop:
        cmpb,<<,n       %r3,%r4,$bss_loop
        stw,ma          %r0,4(%r3)
index bfe99a3..d1b52dc 100644 (file)
 
        .level 2.0w
 
-       .section        .initcall.init
-       .align          4
-       .export __initcall_start
-__initcall_start:
-       .export __initcall_end
-__initcall_end:
-       .export __setup_start
-__setup_start:
-       .export __setup_end
-__setup_end:
-
        .data
 
        .export boot_args
@@ -64,13 +53,13 @@ stext:
 
        /* Clear BSS (shouldn't the boot loader do this?) */
 
-       .import _edata,data
-       .import _end,data
+       .import __bss_start,data
+       .import __bss_stop,data
 
-       ldil            L%PA(_edata),%r3
-       ldo             R%PA(_edata)(%r3),%r3
-       ldil            L%PA(_end),%r4
-       ldo             R%PA(_end)(%r4),%r4
+       ldil            L%PA(__bss_start),%r3
+       ldo             R%PA(__bss_start)(%r3),%r3
+       ldil            L%PA(__bss_stop),%r4
+       ldo             R%PA(__bss_stop)(%r4),%r4
 $bss_loop:
        cmpb,<<,n       %r3,%r4,$bss_loop
        stb,ma          %r0,1(%r3)
index aad7323..eeb3950 100644 (file)
@@ -17,7 +17,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 
index da0e9b9..6a61a95 100644 (file)
@@ -1,3 +1,27 @@
+/* 
+ *    Static declaration of "init" task data structure.
+ *
+ *    Copyright (C) 2000 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2001 Helge Deller <deller @ parisc-linux.org>
+ *    Copyright (C) 2002 Matthew Wilcox <willy with parisc-linux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/sched.h>
index 0262713..ff3b9fe 100644 (file)
@@ -526,20 +526,6 @@ static void __init system_map_inventory(void)
        int i;
        long status = PDC_OK;
     
-#if defined(CONFIG_IOMMU_SBA) && defined(CONFIG_SUPERIO)
-       /*
-        * Stop the suckyio usb controller on Astro based systems.
-        * Otherwise the machine might crash during iommu setup.
-        */
-       pdc_io_reset();
-
-       /*
-        * Unfortunately if we reset devices here, serial console
-        * stops working :-(
-        */
-       /* pdc_io_reset_devices(); */
-#endif
-
        for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
                struct parisc_device *dev;
                struct pdc_system_map_mod_info module_result;
index b9e7927..a6c20e7 100644 (file)
@@ -1,6 +1,8 @@
 /*
- *  Parisc tlb and cache flushing support
- *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
+ *  PARISC TLB and cache flushing support
+ *  Copyright (C) 2000-2001 Hewlett-Packard (John Marvin)
+ *  Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org)
+ *  Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org)
  *
  *    This program is free software; you can redistribute it and/or modify
  *    it under the terms of the GNU General Public License as published by
@@ -14,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*
index 2426626..5798e44 100644 (file)
@@ -1,5 +1,27 @@
 /*
- * Architecture-specific kernel symbols
+ *    Architecture-specific kernel symbols
+ *
+ *    Copyright (C) 2000-2001 Richard Hirst <rhirst with parisc-linux.org>
+ *    Copyright (C) 2001 Dave Kennedy
+ *    Copyright (C) 2001 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2001-2003 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2002-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq at parisc-linux.org>
+ *    Copyright (C) 2002-2003 Helge Deller <deller with parisc-linux.org>
+ * 
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/config.h>
index 13ddc47..7b0ede9 100644 (file)
@@ -261,11 +261,13 @@ pcxl_alloc_range(size_t size)
        } else if(pages_needed <= 32) {
                PCXL_FIND_FREE_MAPPING(res_idx, mask, 32);
        } else {
-               panic(__FILE__ ": pcxl_alloc_range() Too many pages to map.\n");
+               panic("%s: pcxl_alloc_range() Too many pages to map.\n",
+                     __FILE__);
        }
 
        dump_resmap();
-       panic(__FILE__ ": pcxl_alloc_range() out of dma mapping resources\n");
+       panic("%s: pcxl_alloc_range() out of dma mapping resources\n",
+             __FILE__);
        
 resource_found:
        
@@ -319,7 +321,8 @@ pcxl_free_range(unsigned long vaddr, size_t size)
        } else if(pages_mapped <= 32) {
                PCXL_FREE_MAPPINGS(res_idx, mask, 32);
        } else {
-               panic(__FILE__ ": pcxl_free_range() Too many pages to unmap.\n");
+               panic("%s: pcxl_free_range() Too many pages to unmap.\n",
+                     __FILE__);
        }
        
        pcxl_used_pages -= (pages_mapped ? pages_mapped : 1);
index c17ffa3..7b097b6 100644 (file)
@@ -229,7 +229,7 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
                struct pci_bus_region *region, struct resource *res)
 {
        struct pci_bus *bus = dev->bus;
-       struct pci_hba_data *hba = HBA_DATA(bus->dev->platform_data);
+       struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
 
        if (res->flags & IORESOURCE_IO) {
                /*
index dee2b91..d79c0a4 100644 (file)
@@ -1,23 +1,22 @@
-/*
- *             arch/parisc/kernel/pdc_chassis.c
+/* 
+ *    interfaces to log Chassis Codes via PDC (firmware)
  *
- *             Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
- *             Copyright (C) 2002-2003 Thibaut Varene <varenet@esiee.fr>
+ *    Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
+ *    Copyright (C) 2002-2003 Thibaut Varene <varenet@esiee.fr>
  *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the 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 free software; you can redistribute it and/or modify
- *             it under the terms of the GNU General Public License as published by
- *             the Free Software Foundation; either version 2, or (at your option)
- *             any later version.
- *      
- *             This program is distributed in the hope that it will be useful,
- *             but WITHOUT ANY WARRANTY; without even the implied warranty of
- *             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *             GNU General Public License for more details.
- *      
- *             You should have received a copy of the GNU General Public License
- *             along with this program; if not, write to the Free Software
- *             Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    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
  */
 
 #undef PDC_CHASSIS_DEBUG
index 04b8263..8072e38 100644 (file)
@@ -1,6 +1,35 @@
-/*
- *  linux/arch/parisc/kernel/pdc_console.c
+/* 
+ *    PDC Console support - ie use firmware to dump text via boot console
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000 Martin K Petersen <mkp at mkp.net>
+ *    Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
+ *    Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
+ *    Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
  *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
  *  The PDC console is a simple console, which can be used for debugging 
  *  boot related problems on HP PA-RISC machines.
  *
index aa0dd4d..884be87 100644 (file)
@@ -1,8 +1,22 @@
-; 
-;   Purpose:
-;      This file has the overall purpose of suppyling low-level
-;   assembly to program the intrigue portion of the cpu.
-; 
+
+/*    low-level asm for "intrigue" (PA8500-8700 CPU perf counters)
+ *
+ *    Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 
 #include <linux/config.h>
 #include <asm/assembly.h>
index d53ee4f..a8ed8d0 100644 (file)
@@ -1,12 +1,27 @@
+/* 
+ *    Imagine for use with the Onyx (PCX-U) CPU interface 
+ *
+ *    Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 #ifndef PERF_IMAGES_H
 #define PERF_IMAGES_H
 
 /* Magic numbers taken without modification from HPUX stuff */
 
-/*
- * Imagine for use with the Onyx cpu interface
- */
-
 #define PCXU_IMAGE_SIZE 584
 
 static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = {
index 465f679..447795e 100644 (file)
@@ -1,10 +1,35 @@
 /*
- *  linux/arch/parisc/kernel/process.c
- *     based on the work for i386
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
+ *    PARISC Architecture-dependent parts of process handling
+ *    based on the work for i386
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000 Martin K Petersen <mkp at mkp.net>
+ *    Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
+ *    Copyright (C) 2000 David Kennedy <dkennedy with linuxcare.com>
+ *    Copyright (C) 2000 Richard Hirst <rhirst with parisc-lixux.org>
+ *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
+ *    Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org>
+ *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
+ *    Copyright (C) 2001-2002 Helge Deller <deller at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #define __KERNEL_SYSCALLS__
index 2f484a0..514e8b5 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/user.h>
 #include <linux/personality.h>
 #include <linux/security.h>
+#include <linux/compat.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -36,8 +37,6 @@
 
 #ifdef __LP64__
 
-#define CHILD_IS_32BIT (child->personality == PER_LINUX_32BIT)
-
 /* This function is needed to translate 32 bit pt_regs offsets in to
  * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
  * will request offset 12 if it wants gr3, but the lower 32 bits of
@@ -130,7 +129,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
                int copied;
 
 #ifdef __LP64__
-               if (CHILD_IS_32BIT) {
+               if (is_compat_task(child)) {
                        unsigned int tmp;
 
                        addr &= 0xffffffffL;
@@ -162,7 +161,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
        case PTRACE_POKEDATA:
                ret = 0;
 #ifdef __LP64__
-               if (CHILD_IS_32BIT) {
+               if (is_compat_task(child)) {
                        unsigned int tmp = (unsigned int)data;
                        DBG(("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
                                request == PTRACE_POKETEXT ? "TEXT" : "DATA",
@@ -185,7 +184,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
        case PTRACE_PEEKUSR: {
                ret = -EIO;
 #ifdef __LP64__
-               if (CHILD_IS_32BIT) {
+               if (is_compat_task(child)) {
                        unsigned int tmp;
 
                        if (addr & (sizeof(int)-1))
@@ -244,7 +243,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
                        goto out_tsk;
                }
 #ifdef __LP64__
-               if (CHILD_IS_32BIT) {
+               if (is_compat_task(child)) {
                        if (addr & (sizeof(int)-1))
                                goto out_tsk;
                        if ((addr = translate_usr_offset(addr)) < 0)
index 08c1044..26eead2 100644 (file)
@@ -1,4 +1,25 @@
-/* mostly borrowed from kernel/signal.c */
+/*    Signal support for 32-bit kernel builds
+ *
+ *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
+ *    Code was mostly borrowed from kernel/signal.c.
+ *    See kernel/signal.c for additional Copyrights.
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 #include <linux/config.h>
 #include <linux/compat.h>
 #include <linux/slab.h>
index 9399b3b..9c29b63 100644 (file)
@@ -1,3 +1,21 @@
+/* 
+ *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2003 Carlos O'Donell <carlos at parisc-linux.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 #ifndef _PARISC64_KERNEL_SIGNAL32_H
 #define _PARISC64_KERNEL_SIGNAL32_H
 
index cdb196b..06c2090 100644 (file)
@@ -1,3 +1,22 @@
+/* 
+ *    Copyright (C) 2002 Richard Hirst <rhirst at parisc-linux.org>
+ *    Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
+ *    Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 #ifndef _PARISC64_KERNEL_SYS32_H
 #define _PARISC64_KERNEL_SYS32_H
 
index 42eeef0..de86953 100644 (file)
@@ -1,7 +1,25 @@
+
 /*
- * linux/arch/parisc/kernel/sys_parisc.c
+ *    PARISC specific syscalls
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
  *
- * this implements syscalls which are handled per-arch.
+ *    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 <asm/uaccess.h>
index 2ee2c7a..e418c25 100644 (file)
@@ -1,3 +1,35 @@
+/*    System Call Table
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000-2001 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 Alan Modra <amodra at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org>
+ *    Copyright (C) 2000 Grant Grundler <grundler at parisc-linux.org>
+ *    Copyright (C) 2001 Richard Hirst <rhirst with parisc-linux.org>
+ *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
+ *    Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
+ *    Copyright (C) 2000-2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 #undef ENTRY_SAME
 #undef ENTRY_DIFF
 #undef ENTRY_UHOH
index bb4fc35..530235c 100644 (file)
@@ -270,7 +270,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
     }
 #endif
 
-       DPRINTF("val = 0xllx\n", val);
+       DPRINTF("val = 0x%llx\n", val);
 
        if (flop)
                regs->fr[toreg] = val;
index 32c089a..e3ea3db 100644 (file)
@@ -1,5 +1,31 @@
+/*    Kernel link layout for various "sections"
+ *
+ *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
+ *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
+ *    Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
+ *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
+ *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
+ *    Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 #include <linux/config.h>
 #include <asm-generic/vmlinux.lds.h>
+/* needed for the processor specific cache alignment size */   
+#include <asm/cache.h>
        
 /* ld script to make hppa Linux kernel */
 #ifndef CONFIG_PARISC64
@@ -22,7 +48,7 @@ SECTIONS
   . = 0x10100000;
 
   _text = .;                   /* Text and read-only data */
-  .text BLOCK(16) : {
+  .text ALIGN(16) : {
        *(.text*)
        *(.PARISC.unwind)
        *(.fixup)
@@ -32,18 +58,42 @@ SECTIONS
 
   _etext = .;                  /* End of text section */
 
+  RODATA
+
+  /* writeable */
+  data_start = .;
+
   . = ALIGN(16);               /* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  RODATA
-
-  .data BLOCK(8192) : {                        /* Data without special */
-       data_start = .;
+  .data : {                    /* Data */
        *(.data)
+       CONSTRUCTORS
        }
 
+  . = ALIGN(4096);
+  /* nosave data is really only used for software suspend...it's here
+   * just in case we ever implement it */
+  __nosave_begin = .;
+  .data_nosave : { *(.data.nosave) }
+  . = ALIGN(4096);
+  __nosave_end = .;
+
+  . = ALIGN(L1_CACHE_BYTES);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  _edata = .;                  /* End of data section */
+
+  . = ALIGN(16384);            /* init_task */
+  .data.init_task : { *(.data.init_task) }
+
+  /* The interrupt stack is currently partially coded, but not yet
+   * implemented */
+  . = ALIGN(16384);    
+  init_istack : { *(init_istack) }
+
 #ifdef CONFIG_PARISC64
   . = ALIGN(16);               /* Linkage tables */
   .opd : { *(.opd) } PROVIDE (__gp = .); 
@@ -63,7 +113,7 @@ SECTIONS
   __setup_start = .;
   .init.setup : { *(.init.setup) }
   __setup_end = .;
-  __start___param =.; 
+  __start___param = .;
   __param : { *(__param) }
   __stop___param = .;
   __initcall_start = .;
@@ -81,6 +131,19 @@ SECTIONS
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
+  /* alternate instruction replacement.  This is a mechanism x86 uses
+   * to detect the CPU type and replace generic instruction sequences
+   * with CPU specific ones.  We don't currently do this in PA, but
+   * it seems like a good idea... */
+  . = ALIGN(4);
+  __alt_instructions = .;
+  .altinstructions : { *(.altinstructions) } 
+  __alt_instructions_end = .; 
+ .altinstr_replacement : { *(.altinstr_replacement) } 
+  /* .exit.text is discard at runtime, not link time, to deal with references
+     from .altinstructions and .eh_frame */
+  .exit.text : { *(.exit.text) }
+  .exit.data : { *(.exit.data) }
   . = ALIGN(4096);
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
@@ -91,17 +154,28 @@ SECTIONS
   __per_cpu_end = .;
   . = ALIGN(4096);
   __init_end = .;
-
-  init_task BLOCK(16384) : { *(init_task) }  /* The initial task and kernel stack */
-
-  _edata = .;                  /* End of data section */
-
-
-  .bss : { *(.bss) *(COMMON) }         /* BSS */
-
+  /* freed after init ends here */
+       
+  __bss_start = .;             /* BSS */
+  .bss : { *(.bss) *(COMMON) }
+  __bss_stop = .; 
 
   _end = . ;
 
+  /* Sections to be discarded */
+  /DISCARD/ : {
+       *(.exitcall.exit)
+#ifdef CONFIG_PARISC64
+       /* temporary hack until binutils is fixed to not emit these
+        for static binaries */
+       *(.interp)
+       *(.dynsym)
+       *(.dynstr)
+       *(.dynamic)
+       *(.hash)
+#endif
+       }
+
   /* Stabs debugging sections.  */
   .stab 0 : { *(.stab) }
   .stabstr 0 : { *(.stabstr) }
@@ -112,14 +186,4 @@ SECTIONS
   .comment 0 : { *(.comment) }
   .note 0 : { *(.note) }       
 
-#ifdef CONFIG_PARISC64
-  /* temporary hack until binutils is fixed to not emit these
-     for static binaries */
-  /DISCARD/ : {
-    *(.dynsym)
-    *(.dynstr)
-    *(.dynamic)
-    *(.hash)
-  }
-#endif
 }
index 4d65585..72c9615 100644 (file)
@@ -1,8 +1,11 @@
 /*
- * Linux/PA-RISC Project (http://www.parisc-linux.org/)
+ *    User Space Access Routines
+ *
+ *    Copyright (C) 2000-2002 Hewlett-Packard (John Marvin)
+ *    Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
+ *    Copyright (C) 2001 Matthieu Delahaye <delahaym at esiee.fr>
+ *    Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
  *
- * Assembly Language User Access Routines
- *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
  *
  *    This program is free software; you can redistribute it and/or modify
  *    it under the terms of the GNU General Public License as published by
@@ -16,7 +19,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*
index 653add4..9071e09 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifdef __NO_PA_HDRS
index 7b9740a..1570e2e 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #ifdef __NO_PA_HDRS
     PA header file -- do not include this header file for non-PA builds.
index 3cb8b42..f84f258 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
@@ -347,7 +347,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[])
                return SIGNALCODE(SIGFPE, FPE_FLTRES);
          default:
                update_trap_counts(Fpu_register, aflags, bflags, trap_counts);
-               printk(__FILE__ "(%d) Unknown FPU exception 0x%x\n",
+               printk("%s(%d) Unknown FPU exception 0x%x\n", __FILE__,
                        __LINE__, Excp_type(exception_index));
                return SIGNALCODE(SIGILL, ILL_COPROC);
          case NOEXCEPTION:     /* no exception */
index 8c23639..60687e1 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 97943b9..e147d7d 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index c0806c3..5952126 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index b37471a..d7d4bec 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 526f91c..4380f5a 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 75a4cc4..b983785 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index ff2d426..b6ed106 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index ba87b5e..87ebc60 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 5843cdf..e202c24 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  *  linux/arch/math-emu/driver.c.c
index 7821233..76c063f 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index a973c39..7e85655 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index c8b5fcb..4176a44 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 48292df..d6475bd 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index f54950c..8b9010c 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index f0b40e9..5e68189 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 06546ca..05c7fad 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 3d4de16..ce76f6d 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 782c028..5dd7f93 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 13df40b..cefad06 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifdef __NO_PA_HDRS
index a0ffc93..0af5c3c 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 3271a32..6e28f9f 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 8dc8087..904b384 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index cbe82d7..5d3d52f 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifdef __NO_PA_HDRS
index a5c436f..3a99f59 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #ifndef _PARISC_MATH_EMU_H
 #define _PARISC_MATH_EMU_H
index 0d81dc1..008d721 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 7aa3963..1466fb4 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 059e913..3e2a4d6 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 3c51b71..afa4069 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 4975584..3a1b7a3 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 030353b..cd3f6db 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index ffd77a0..24eef61 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 /*
  * BEGIN_DESC
index 8103f0a..82519a5 100644 (file)
@@ -16,7 +16,7 @@
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifdef __NO_PA_HDRS
index b4da595..20468fe 100644 (file)
@@ -1,3 +1,26 @@
+/* 
+ *    kmap/page table map and unmap support routines
+ *
+ *    Copyright 1999,2000 Hewlett-Packard Company
+ *    Copyright 2000 John Marvin <jsm at hp.com>
+ *    Copyright 2000 Grant Grundler <grundler at parisc-linux.org>
+ *    Copyright 2000 Philipp Rumpf <prumpf@tux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 /*
 ** Stolen mostly from arch/parisc/kernel/pci-dma.c
 */
index ac02449..c6ac04c 100644 (file)
@@ -210,7 +210,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index 1ccff4a..7a06e3d 100644 (file)
@@ -218,7 +218,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index b061b11..ec1e609 100644 (file)
@@ -218,7 +218,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index afb1a5e..240fd8b 100644 (file)
@@ -801,7 +801,12 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
 
        /* Fixup bus number according to what OF think it is. */
 #ifdef CONFIG_PPC_PMAC
-       /* Sorry about that, I need to find a best way to fix it.... */
+       /* The G5 need a special case here. Basically, we don't remap all
+        * busses on it so we don't create the pci-OF-map. However, we do
+        * remap the AGP bus and so have to deal with it. A future better
+        * fix has to be done by making the remapping per-host and always
+        * filling the pci_to_OF map. --BenH
+        */
        if (_machine == _MACH_Pmac && busnr >= 0xf0)
                busnr -= 0xf0;
        else
@@ -896,7 +901,7 @@ void __init
 pci_process_bridge_OF_ranges(struct pci_controller *hose,
                           struct device_node *dev, int primary)
 {
-       static unsigned int static_lc_ranges[1024] __initdata;
+       static unsigned int static_lc_ranges[256] __initdata;
        unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
        unsigned int size;
        int rlen = 0, orig_rlen;
@@ -913,9 +918,9 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
        if (!dt_ranges)
                return;
        /* Sanity check, though hopefully that never happens */
-       if (rlen > 1024) {
+       if (rlen > sizeof(static_lc_ranges)) {
                printk(KERN_WARNING "OF ranges property too large !\n");
-               rlen = 1024;
+               rlen = sizeof(static_lc_ranges);
        }
        lc_ranges = static_lc_ranges;
        memcpy(lc_ranges, dt_ranges, rlen);
index 5b071d0..e114c59 100644 (file)
@@ -501,11 +501,10 @@ setup_disp_fake_bi(ihandle dp)
        if (strcmp(name, "valkyrie") == 0)
                address += 0x1000;
 
-       prom_print("address:");
-       prom_print_hex(address);
-       prom_print("\n");
-
 #ifdef CONFIG_POWER4
+#if CONFIG_TASK_SIZE > 0x80000000
+#error CONFIG_TASK_SIZE cannot be above 0x80000000 with BOOTX_TEXT on G5
+#endif
        {
                extern boot_infos_t disp_bi;
                unsigned long va, pa, i, offset;
@@ -515,7 +514,8 @@ setup_disp_fake_bi(ihandle dp)
 
                for (i=0; i<0x4000; i++) {  
                        make_pte((unsigned long)Hash - KERNELBASE, Hash_size, va, pa, 
-                                _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX);
+                                _PAGE_ACCESSED | _PAGE_NO_CACHE |
+                                _PAGE_GUARDED | PP_RWXX);
                        va += 0x1000;
                        pa += 0x1000;
                }
@@ -855,8 +855,6 @@ prom_init(int r3, int r4, prom_entry pp)
         * loaded by an OF bootloader which did set a BAT for us.
         * This breaks OF translate so we force phys to be 0.
         */
-       prom_print("&stext=0x");
-       prom_print_hex(phys);
        if (offset == 0) {
                prom_print("(already at 0xc0000000) phys=0\n");
                phys = 0;
@@ -869,13 +867,6 @@ prom_init(int r3, int r4, prom_entry pp)
        } else {
                /* We assume the phys. address size is 3 cells */
                phys = (unsigned long)result[2];
-               prom_print(" phys=0x");
-               prom_print_hex(phys);
-               prom_print("(result[0]=0x");
-               prom_print_hex((unsigned long)result[0]);
-               prom_print(" result[1]=0x");
-               prom_print_hex((unsigned long)result[1]);
-               prom_print(")\n");
        }
 
        if (prom_disp_node != 0)
index e5c47d1..de235e3 100644 (file)
@@ -251,54 +251,10 @@ config CMDLINE
 
 endmenu
 
-source "drivers/base/Kconfig"
-
-source "drivers/mtd/Kconfig"
-
-source "drivers/parport/Kconfig"
-
-source "drivers/pnp/Kconfig"
-
-source "drivers/block/Kconfig"
-
-source "drivers/ide/Kconfig"
-
-source "drivers/scsi/Kconfig"
-
-source "drivers/md/Kconfig"
-
-source "drivers/message/fusion/Kconfig"
-
-source "drivers/ieee1394/Kconfig"
-
-source "drivers/message/i2o/Kconfig"
-
-source "net/Kconfig"
-
-source "drivers/isdn/Kconfig"
-
-source "drivers/telephony/Kconfig"
-
-#
-# input before char - char/joystick depends on it. As does USB.
-#
-source "drivers/input/Kconfig"
-
-source "drivers/char/Kconfig"
-
-source "drivers/i2c/Kconfig"
-
-source "drivers/media/Kconfig"
+source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "drivers/video/Kconfig"
-
-source "sound/Kconfig"
-
-source "drivers/usb/Kconfig"
-
-
 menu "iSeries device drivers"
        depends on PPC_ISERIES
 
index eb4655e..8c82ae5 100644 (file)
@@ -161,7 +161,7 @@ int dedicated_idle(void)
        struct paca_struct *lpaca = get_paca(), *ppaca;
        unsigned long start_snooze;
 
-       ppaca = &paca[(lpaca->xPacaIndex) ^ 1];
+       ppaca = &paca[smp_processor_id() ^ 1];
 
        while (1) {
                /* Indicate to the HV that we are idle.  Now would be
index fb15c0d..571b2c6 100644 (file)
@@ -1132,9 +1132,9 @@ smt_setup(void)
                                sizeof(option));
                        if (option[0] != 0) {
                                found = 1;
-                               if (!strcmp(option, "off"))     
+                               if (!strcmp(option, RELOC("off")))      
                                        my_smt_enabled = SMT_OFF;
-                               else if (!strcmp(option, "on")) 
+                               else if (!strcmp(option, RELOC("on")))  
                                        my_smt_enabled = SMT_ON;
                                else
                                        my_smt_enabled = SMT_DYNAMIC;
index d2c8e57..074596c 100644 (file)
@@ -333,7 +333,7 @@ static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
 {
        int sn, n = 0;
        char *tmpbuf;
-       
+
        if (progress_led == NULL) return 0;
 
        tmpbuf = kmalloc (MAX_LINELENGTH, GFP_KERNEL);
index 0f866d9..fde3591 100644 (file)
@@ -283,6 +283,10 @@ EXPORT_SYMBOL(machine_halt);
 unsigned long ppc_proc_freq;
 unsigned long ppc_tb_freq;
 
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(unsigned int, pvr);
+#endif
+
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
        unsigned long cpu_id = (unsigned long)v - 1;
@@ -302,7 +306,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                return 0;
 
 #ifdef CONFIG_SMP
-       pvr = paca[cpu_id].pvr;
+       pvr = per_cpu(pvr, cpu_id);
 #else
        pvr = _get_PVR();
 #endif
index ab93b3c..e069a45 100644 (file)
@@ -600,9 +600,11 @@ extern struct gettimeofday_struct do_gtod;
 
 struct thread_info *current_set[NR_CPUS];
 
+DECLARE_PER_CPU(unsigned int, pvr);
+
 static void __devinit smp_store_cpu_info(int id)
 {
-       paca[id].pvr = _get_PVR();
+       per_cpu(pvr, id) = _get_PVR();
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
index cd9745c..118c771 100644 (file)
@@ -267,7 +267,7 @@ int timer_interrupt(struct pt_regs * regs)
        int next_dec;
        unsigned long cur_tb;
        struct paca_struct *lpaca = get_paca();
-       unsigned long cpu = lpaca->xPacaIndex;
+       unsigned long cpu = smp_processor_id();
 
        irq_enter();
 
index 330be2f..b6ecf03 100644 (file)
 
 #define DBGENTER() pr_debug("%s entered\n", __FUNCTION__)
 
+/* just so vio_find_node() will always match vio_register_device() */
+#define KOBJNAME_FMT "%s@%lx"
+
+extern struct subsystem devices_subsys; /* needed for vio_find_name() */
+
 extern struct TceTable *build_tce_table(struct TceTable *tbl);
 
 extern dma_addr_t get_tces(struct TceTable *, unsigned order,
@@ -250,7 +255,7 @@ struct vio_dev * __devinit vio_register_device(struct device_node *of_node)
        /* init generic 'struct device' fields: */
        viodev->dev.parent = &vio_bus_device->dev;
        viodev->dev.bus = &vio_bus_type;
-       snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s@%lx",
+       snprintf(viodev->dev.bus_id, BUS_ID_SIZE, KOBJNAME_FMT,
                of_node->name, viodev->unit_address);
        viodev->dev.release = vio_dev_release;
 
@@ -274,6 +279,42 @@ void __devinit vio_unregister_device(struct vio_dev *viodev)
 }
 EXPORT_SYMBOL(vio_unregister_device);
 
+/* vio_find_name() - internal because only vio.c knows how we formatted the
+ * kobject name
+ * XXX once vio_bus_type.devices is actually used as a kset in
+ * drivers/base/bus.c, this function should be removed in favor of
+ * "device_find(kobj_name, &vio_bus_type)"
+ */
+static struct vio_dev *vio_find_name(const char *kobj_name)
+{
+       struct kobject *found;
+
+       found = kset_find_obj(&devices_subsys.kset, kobj_name);
+       if (!found)
+               return NULL;
+
+       return to_vio_dev(container_of(found, struct device, kobj));
+}
+
+/**
+ * vio_find_node - find an already-registered vio_dev
+ * @vnode: device_node of the virtual device we're looking for
+ */
+struct vio_dev *vio_find_node(struct device_node *vnode)
+{
+       unsigned long *unit_address;
+       char kobj_name[BUS_ID_SIZE];
+
+       /* construct the kobject name from the device node */
+       unit_address = (unsigned long *)get_property(vnode, "reg", NULL);
+       if (!unit_address)
+               return NULL;
+       snprintf(kobj_name, BUS_ID_SIZE, KOBJNAME_FMT, vnode->name, *unit_address);
+
+       return vio_find_name(kobj_name);
+}
+EXPORT_SYMBOL(vio_find_node);
+
 /**
  * vio_get_attribute: - get attribute for virtual device
  * @vdev:      The vio device to get property.
index ea2712a..5380606 100644 (file)
@@ -269,8 +269,8 @@ void __init do_init_bootmem(void)
                                        physbase = start_paddr;
                                }
 
-                               if (size > end_paddr - start_paddr)
-                                       size = end_paddr - start_paddr;
+                               if (size > end_paddr - physbase)
+                                       size = end_paddr - physbase;
 
                                dbg("free_bootmem %lx %lx\n", physbase, size);
                                free_bootmem_node(NODE_DATA(nid), physbase,
@@ -290,8 +290,8 @@ void __init do_init_bootmem(void)
                                        physbase = start_paddr;
                                }
 
-                               if (size > end_paddr - start_paddr)
-                                       size = end_paddr - start_paddr;
+                               if (size > end_paddr - physbase)
+                                       size = end_paddr - physbase;
 
                                dbg("reserve_bootmem %lx %lx\n", physbase,
                                    size);
index f26a22c..c0c416c 100644 (file)
@@ -41,7 +41,7 @@ static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
 static struct sysrq_key_op sysrq_xmon_op = 
 {
        .handler =      sysrq_handle_xmon,
-       .help_msg =     "xmon",
+       .help_msg =     "Xmon",
        .action_msg =   "Entering xmon\n",
 };
 
index 8576eaa..5761d7e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/kallsyms.h>
+#include <linux/cpumask.h>
 
 #include <asm/ptrace.h>
 #include <asm/string.h>
@@ -37,7 +38,7 @@
 #define skipbl xmon_skipbl
 
 #ifdef CONFIG_SMP
-volatile unsigned long cpus_in_xmon = 0;
+volatile cpumask_t cpus_in_xmon = CPU_MASK_NONE;
 static unsigned long got_xmon = 0;
 static volatile int take_xmon = -1;
 static volatile int leaving_xmon = 0;
@@ -288,17 +289,18 @@ xmon(struct pt_regs *excp)
        leaving_xmon = 0;
        /* possible race condition here if a CPU is held up and gets
         * here while we are exiting */
-       if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) {
+       if (cpu_test_and_set(smp_processor_id(), cpus_in_xmon)) {
                /* xmon probably caused an exception itself */
                printf("We are already in xmon\n");
                for (;;)
-                       ;
+                       cpu_relax();
        }
        while (test_and_set_bit(0, &got_xmon)) {
                if (take_xmon == smp_processor_id()) {
                        take_xmon = -1;
                        break;
                }
+               cpu_relax();
        }
        /*
         * XXX: breakpoints are removed while any cpu is in xmon
@@ -325,7 +327,7 @@ xmon(struct pt_regs *excp)
        leaving_xmon = 1;
        if (cmd != 's')
                clear_bit(0, &got_xmon);
-       clear_bit(smp_processor_id(), &cpus_in_xmon);
+       cpu_clear(smp_processor_id(), cpus_in_xmon);
 #endif /* CONFIG_SMP */
        set_msrd(msr);          /* restore interrupt enable */
 }
@@ -602,6 +604,7 @@ cmds(struct pt_regs *excp)
                        printf(" (type ? for help)\n");
                        break;
                }
+               cpu_relax();
        }
 }
 
@@ -638,7 +641,7 @@ static void cpu_cmd(void)
                /* print cpus waiting or in xmon */
                printf("cpus stopped:");
                for (cpu = 0; cpu < NR_CPUS; ++cpu) {
-                       if (test_bit(cpu, &cpus_in_xmon)) {
+                       if (cpu_isset(cpu, cpus_in_xmon)) {
                                printf(" %x", cpu);
                                if (cpu == smp_processor_id())
                                        printf("*", cpu);
@@ -664,6 +667,7 @@ static void cpu_cmd(void)
                        take_xmon = -1;
                        break;
                }
+               cpu_relax();
        }
 }
 #endif /* CONFIG_SMP */
index e3619bd..fcf149e 100644 (file)
@@ -12,7 +12,7 @@ obj-y    := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
            sys_sparc.o sunos_asm.o systbls.o \
            time.o windows.o cpu.o devices.o sclow.o \
            tadpole.o tick14.o ptrace.o sys_solaris.o \
-           unaligned.o muldiv.o semaphore.o sparc_ksyms.o
+           unaligned.o muldiv.o semaphore.o
 
 obj-$(CONFIG_PCI) += pcic.o
 obj-$(CONFIG_SUN4) += sun4setup.o
@@ -20,7 +20,7 @@ obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o
 obj-$(CONFIG_SUN_AUXIO) += auxio.o
 obj-$(CONFIG_PCI) += ebus.o
 obj-$(CONFIG_SUN_PM) += apc.o pmc.o
-obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o
 
 ifdef CONFIG_SUNOS_EMUL
 obj-y += sys_sunos.o sunos_ioctl.o
index 078c5db..c23185b 100644 (file)
@@ -85,22 +85,38 @@ extern int __divdi3(int, int);
 
 extern void dump_thread(struct pt_regs *, struct user *);
 
+/* Private functions with odd calling conventions. */
+extern void ___atomic_add(void);
+extern void ___atomic_sub(void);
+extern void ___set_bit(void);
+extern void ___clear_bit(void);
+extern void ___change_bit(void);
+
 /* One thing to note is that the way the symbols of the mul/div
  * support routines are named is a mess, they all start with
  * a '.' which makes it a bitch to export, here is the trick:
  */
 
-#define EXPORT_SYMBOL_DOT(sym)                                 \
-extern int __sparc_dot_ ## sym (int) __asm__("." #sym);                \
-const struct kernel_symbol __ksymtab___sparc_dot_##sym         \
-__attribute__((section("__ksymtab")))                          \
-= { (unsigned long)&__sparc_dot_##sym , "." #sym }
-
-#define EXPORT_SYMBOL_PRIVATE(sym)                             \
-extern int __sparc_priv_ ## sym (int) __asm__("__" #sym);      \
-const struct kernel_symbol __export_priv_##sym                 \
-__attribute__((section("__ksymtab"))) =                                \
-{ (unsigned long) &__sparc_priv_ ## sym, "__" #sym }
+/* If the interface of any of these special functions does ever
+ * change in an incompatible way, you must modify this.
+ */
+#define DOT_PROTO(sym) extern int __dot_##sym(int, int)
+
+#ifdef __GENKSYMS__
+#define EXPORT_SYMBOL_DOT(sym)                                         \
+       DOT_PROTO(sym);                                                 \
+       EXPORT_SYMBOL(__dot_ ## sym)
+#else /* !__GENKSYMS__ */
+#define EXPORT_SYMBOL_DOT(sym)                                         \
+       DOT_PROTO(sym) __asm__("." # sym);                              \
+       __CRC_SYMBOL(__dot_##sym, "")                                   \
+       static const char __kstrtab___dot_##sym[]                       \
+       __attribute__((section("__ksymtab_strings")))                   \
+       = "." #sym;                                                     \
+       static const struct kernel_symbol __ksymtab___dot_##sym         \
+       __attribute__((section("__ksymtab")))                           \
+       = { (unsigned long)&__dot_##sym, __kstrtab___dot_##sym }
+#endif
 
 /* used by various drivers */
 EXPORT_SYMBOL(sparc_cpu_model);
@@ -131,13 +147,13 @@ EXPORT_SYMBOL(sparc_valid_addr_bitmap);
 EXPORT_SYMBOL(phys_base);
 
 /* Atomic operations. */
-EXPORT_SYMBOL_PRIVATE(_atomic_add);
-EXPORT_SYMBOL_PRIVATE(_atomic_sub);
+EXPORT_SYMBOL(___atomic_add);
+EXPORT_SYMBOL(___atomic_sub);
 
 /* Bit operations. */
-EXPORT_SYMBOL_PRIVATE(_set_bit);
-EXPORT_SYMBOL_PRIVATE(_clear_bit);
-EXPORT_SYMBOL_PRIVATE(_change_bit);
+EXPORT_SYMBOL(___set_bit);
+EXPORT_SYMBOL(___clear_bit);
+EXPORT_SYMBOL(___change_bit);
 
 #ifdef CONFIG_SMP
 /* IRQ implementation. */
index 3099188..f19d4db 100644 (file)
@@ -242,7 +242,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_IDEDMA_ONLYDISK=y
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 CONFIG_BLK_DEV_ALI15X3=y
index 5430c71..c78cf75 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 
 #include <asm/errno.h>
 #include <asm/ptrace.h>
index 86be83f..960802a 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * arch/v850/kernel/setup.c -- Arch-dependent initialization functions
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * 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
@@ -13,6 +13,7 @@
 
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/swap.h>                /* we don't have swap, but for nr_free_pages */
 #include <linux/irq.h>
 #include <linux/reboot.h>
 #include <linux/personality.h>
index 6ab5cee..ea3e51c 100644 (file)
@@ -17,6 +17,7 @@
    implementation.  */
 
 #include <asm/entry.h>
+#include <asm/cacheflush.h>
 #include <asm/v850e_cache.h>
 
 #define WAIT_UNTIL_CLEAR(value) while (value) {}
index 2f59cc1..55e21c8 100644 (file)
@@ -191,7 +191,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_IDEDMA_PCI_WIP is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
index 33a40ed..d46c2d4 100644 (file)
@@ -51,8 +51,8 @@
 int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */
 int acpi_ht __initdata = 1;    /* enable HT */
 
-int acpi_lapic = 0;
-int acpi_ioapic = 0;
+int acpi_lapic;
+int acpi_ioapic;
 
 /* --------------------------------------------------------------------------
                               Boot-time Configuration
@@ -439,7 +439,7 @@ acpi_boot_init (void)
         * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
         */
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
                return result;
@@ -447,7 +447,8 @@ acpi_boot_init (void)
 
        mp_register_lapic_address(acpi_lapic_addr);
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
+                                      MAX_APICS);
        if (!result) { 
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -459,7 +460,7 @@ acpi_boot_init (void)
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -496,8 +497,8 @@ acpi_boot_init (void)
                return 1;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
-       if (!result) { 
+       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS);
+       if (!result) {
                printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
                return -ENODEV;
        }
@@ -509,14 +510,15 @@ acpi_boot_init (void)
        /* Build a default routing table for legacy (ISA) interrupts. */
        mp_config_acpi_legacy_irqs();
 
-       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
+       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
+                                      NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
index 8122872..e8adf15 100644 (file)
@@ -34,12 +34,12 @@ struct sha256_ctx {
 
 static inline u32 Ch(u32 x, u32 y, u32 z)
 {
-       return ((x & y) ^ (~x & z));
+       return z ^ (x & (y ^ z));
 }
 
 static inline u32 Maj(u32 x, u32 y, u32 z)
 {
-       return ((x & y) ^ (x & z) ^ (y & z));
+       return (x & y) | (z & (x | y));
 }
 
 static inline u32 RORu32(u32 x, u32 y)
index 3d528d8..5749e05 100644 (file)
@@ -34,12 +34,12 @@ struct sha512_ctx {
 
 static inline u64 Ch(u64 x, u64 y, u64 z)
 {
-        return ((x & y) ^ (~x & z));
+        return z ^ (x & (y ^ z));
 }
 
 static inline u64 Maj(u64 x, u64 y, u64 z)
 {
-        return ((x & y) ^ (x & z) ^ (y & z));
+        return (x & y) | (z & (x | y));
 }
 
 static inline u64 RORu64(u64 x, u64 y)
@@ -249,7 +249,7 @@ sha512_final(void *ctx, u8 *hash)
 {
         struct sha512_ctx *sctx = ctx;
        
-        const static u8 padding[128] = { 0x80, };
+        static u8 padding[128] = { 0x80, };
 
         u32 t;
        u64 t2;
index 349581f..0a7fba4 100644 (file)
@@ -2,7 +2,7 @@
  *  asus_acpi.c - Asus Laptop ACPI Extras
  *
  *
- *  Copyright (C) 2002, 2003 Julien Lerouge, Karol Kozimor
+ *  Copyright (C) 2002, 2003, 2004 Julien Lerouge, Karol Kozimor
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  http://sourceforge.net/projects/acpi4asus/
  *
  *  Credits:
+ *  Pontus Fuchs   - Helper functions, cleanup
  *  Johann Wiesner - Small compile fixes
  *  John Belmonte  - ACPI code for Toshiba laptop was a good starting point.
  *
  *  TODO:
  *  add Fn key status
  *  Add mode selection on module loading (parameter) -> still necessary?
- *  Complete display switching -- may require dirty hacks?
+ *  Complete display switching -- may require dirty hacks or calling _DOS?
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 
-#define ASUS_ACPI_VERSION "0.26"
+#define ASUS_ACPI_VERSION "0.27"
 
 #define PROC_ASUS       "asus" //the directory
 #define PROC_MLED       "mled"
 #define PROC_WLED       "wled"
-#define PROC_INFOS      "info"
+#define PROC_TLED       "tled"
+#define PROC_INFO       "info"
 #define PROC_LCD        "lcd"
 #define PROC_BRN        "brn"
 #define PROC_DISP       "disp"
@@ -67,6 +68,7 @@
  */
 #define MLED_ON     0x01       //is MLED ON ?
 #define WLED_ON     0x02
+#define TLED_ON     0x04
 
 MODULE_AUTHOR("Julien Lerouge, Karol Kozimor");
 MODULE_DESCRIPTION(ACPI_HOTK_NAME);
@@ -81,22 +83,25 @@ MODULE_PARM(asus_gid, "i");
 MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n");
 
 
-/* For each model, all features implemented */
+/* For each model, all features implemented, 
+ * those marked with R are relative to HOTK, A for absolute */
 struct model_data {
-       char *name;             //name of the laptop
-       char *mt_mled;          //method to handle mled
-       char *mled_status;      //node to handle mled reading
-       char *mt_wled;          //method to handle wled
-       char *wled_status;      //node to handle wled reading
-       char *mt_lcd_switch;    //method to turn LCD ON/OFF
-       char *lcd_status;       //node to read LCD panel state
-       char *brightness_up;    //method to set brightness up
-       char *brightness_down;  //guess what ?
-       char *brightness_set;   //method to set absolute brightness
-       char *brightness_get;   //method to get absolute brightness
-       char *brightness_status;//node to get brightness
-       char *display_set;      //method to set video output
-       char *display_get;      //method to get video output
+       char *name;              //name of the laptop________________A
+       char *mt_mled;           //method to handle mled_____________R
+       char *mled_status;       //node to handle mled reading_______A
+       char *mt_wled;           //method to handle wled_____________R
+       char *wled_status;       //node to handle wled reading_______A
+       char *mt_tled;           //method to handle tled_____________R
+       char *tled_status;       //node to handle tled reading_______A
+       char *mt_lcd_switch;     //method to turn LCD ON/OFF_________A
+       char *lcd_status;        //node to read LCD panel state______A
+       char *brightness_up;     //method to set brightness up_______A
+       char *brightness_down;   //guess what ?______________________A
+       char *brightness_set;    //method to set absolute brightness_R
+       char *brightness_get;    //method to get absolute brightness_R
+       char *brightness_status; //node to get brightness____________A
+       char *display_set;       //method to set video output________R
+       char *display_get;       //method to get video output________R
 };
 
 /*
@@ -104,91 +109,239 @@ struct model_data {
  * about the hotk device
  */
 struct asus_hotk {
-       struct acpi_device *device;     //the device we are in
-       acpi_handle handle;             //the handle of the hotk device
-       char status;                    //status of the hotk, for LEDs, ...
-       struct model_data *methods;     //methods available on the laptop
-       u8 brightness;                  //brighness level
+       struct acpi_device *device; //the device we are in
+       acpi_handle handle;         //the handle of the hotk device
+       char status;                //status of the hotk, for LEDs, ...
+       struct model_data *methods; //methods available on the laptop
+       u8 brightness;              //brightness level
        enum {
-               A1X=0,          //A1340D, A1300F
-               A2X,            //A2500H
-               D1X,            //D1
-               L1X,            //L1400B
-               L2X,            //L2000D -> TODO check Q11 (Fn+F8)
-                               //         Calling this method simply hangs the
-                               //         computer, ISMI method hangs the laptop.
-               L3D,            //L3400D
-               L3X,            //L3C
-               L5X,            //L5C TODO this model seems to have one more
-                               //         LED, add support
-               M2X,            //M2400E
-               M3N,            //M3700N, but also S1300N -> TODO WLED
-               S1X,            //S1300A -> TODO special keys do not work ?
-               S2X,            //S200 (J1 reported), Victor MP-XP7210
-                               //TODO  A1370D does not seem to have an ATK device 
-                               //      L8400 model doesn't have ATK
+               A1x = 0,  //A1340D, A1300F
+               A2x,      //A2500H
+               D1x,      //D1
+               L2D,      //L2000D
+               L3C,      //L3800C
+               L3D,      //L3400D
+               L3H,      //L3H, but also L2000E
+               L5x,      //L5800C 
+               L8L,      //L8400L
+               M1A,      //M1300A
+               M2E,      //M2400E
+               S1x,      //S1300A, but also L1400B and M2400A (L84F)
+               S2x,      //S200 (J1 reported), Victor MP-XP7210
+                         //TODO  A1370D does not seem to have an ATK device 
+                         // L8400 model doesn't have ATK
+               xxN,      //M2400N, M3700N, S1300N (Centrino)
                END_MODEL
-       } model;                //Models currently supported
-       u16 event_count[128];   //count for each event TODO make this better
+       } model;              //Models currently supported
+       u16 event_count[128]; //count for each event TODO make this better
 };
 
 /* Here we go */
-#define L3X_PREFIX "\\_SB.PCI0.PX40.ECD0."
-#define S1X_PREFIX "\\_SB.PCI0.PX40."
-#define L1X_PREFIX S1X_PREFIX
-#define A1X_PREFIX "\\_SB.PCI0.ISA.EC0."
-#define S2X_PREFIX A1X_PREFIX
-#define M3N_PREFIX "\\_SB.PCI0.SBRG.EC0."
+#define A1x_PREFIX "\\_SB.PCI0.ISA.EC0."
+#define L3C_PREFIX "\\_SB.PCI0.PX40.ECD0."
+#define M1A_PREFIX "\\_SB.PCI0.PX40.EC0."
+#define S1x_PREFIX "\\_SB.PCI0.PX40."
+#define S2x_PREFIX A1x_PREFIX
+#define xxN_PREFIX "\\_SB.PCI0.SBRG.EC0."
 
 static struct model_data model_conf[END_MODEL] = {
         /*
-        * name|  mled |mled read|  wled |wled read| lcd sw |lcd read | 
-        * br up|br down | br set | br read | br status|set disp | get disp
-        *
-        * br set and read shall be in hotk device !
-        * same for set disp
+        * Those pathnames are relative to the HOTK / ATKD device :
+        *       - mt_mled
+        *       - mt_wled
+        *       - brightness_set
+        *       - brightness_get
+        *       - display_set
+        *       - display_get
         *
         * TODO I have seen a SWBX and AIBX method on some models, like L1400B,
         * it seems to be a kind of switch, but what for ?
         *
         */
-       {"A1X", "MLED", "\\MAIL", NULL, NULL, A1X_PREFIX "_Q10", "\\BKLI",
-        A1X_PREFIX "_Q0E", A1X_PREFIX "_Q0F", NULL, NULL, NULL, NULL, NULL},
-
-       {"A2X", "MLED", NULL, "WLED", "\\SG66", "\\Q10", "\\BAOF",
-        "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\CMOD", "SDSP", "\\INFB"},
-
-       {"D1X", "MLED", NULL, NULL, NULL, "\\Q0D", "\\GP11", 
-        "\\Q0C", "\\Q0B", NULL, NULL, "\\BLVL", "SDSP","\\INFB"},
-
-       {"L1X", "MLED", NULL, "WLED", NULL, L1X_PREFIX "Q10", "\\PNOF", 
-        L1X_PREFIX "Q0F", L1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL},
-        
-       {"L2X", "MLED", "\\SGP6", "WLED", "\\RCP3", "\\Q10", "\\SGP0", 
-        "\\Q0E", "\\Q0F", NULL, NULL, NULL, "SDSP", "\\INFB"},
-
-       {"L3D", "MLED", "\\MALD", "WLED", NULL, "\\Q10", "\\BKLG",
-        "\\Q0E", "\\Q0F", "SPLV", "GPLV", "\\BLVL", "SDSP", "\\INFB"},
 
-       {"L3X", "MLED", NULL, "WLED", NULL, L3X_PREFIX "_Q10", "\\GL32", 
-        L3X_PREFIX "_Q0F", L3X_PREFIX "_Q0E", "SPLV", "GPLV", "\\BLVL", "SDSP", 
-        "\\_SB.PCI0.PCI1.VGAC.NMAP"},
-
-       {"L5X", "MLED", NULL, "WLED", "WRED", "\\Q0D", "\\BAOF", 
-        "\\Q0C","\\Q0B", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"},
-        
-       {"M2X", "MLED", NULL, "WLED", NULL, "\\Q10", "\\GP06", 
-        "\\Q0E","\\Q0F", "SPLV", "GPLV", NULL, "SDSP", "\\INFB"},
-
-       {"M3N", "MLED", NULL, "WLED", "\\PO33", M3N_PREFIX "_Q10", "\\BKLT", 
-        M3N_PREFIX "_Q0F", M3N_PREFIX "_Q0E", "SPLV", "GPLV", "\\LBTN", "SDSP", 
-        "\\ADVG"},
-       
-       {"S1X", "MLED", "\\EMLE", "WLED", NULL, S1X_PREFIX "Q10", "\\PNOF", 
-        S1X_PREFIX "Q0F", S1X_PREFIX "Q0E", "SPLV", "GPLV", "\\BRIT", NULL, NULL},
-       
-       {"S2X", "MLED", "\\MAIL", NULL, NULL, S2X_PREFIX "_Q10", "\\BKLI",
-        S2X_PREFIX "_Q0B", S2X_PREFIX "_Q0A", NULL, NULL, NULL, NULL, NULL}
+       {
+               .name              = "A1x",
+               .mt_mled           = "MLED",
+               .mled_status       = "\\MAIL",
+               .mt_lcd_switch     = A1x_PREFIX "_Q10",
+               .lcd_status        = "\\BKLI",
+               .brightness_up     = A1x_PREFIX "_Q0E",
+               .brightness_down   = A1x_PREFIX "_Q0F",
+       },
+
+       {
+               .name              = "A2x",
+               .mt_mled           = "MLED",
+               .mt_wled           = "WLED",
+               .wled_status       = "\\SG66",
+               .mt_lcd_switch     = "\\Q10",
+               .lcd_status        = "\\BAOF",
+               .brightness_up     = "\\Q0E",
+               .brightness_down   = "\\Q0F",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .brightness_status = "\\CMOD",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "D1x",
+               .mt_mled           = "MLED",
+               .mt_lcd_switch     = "\\Q0D",
+               .lcd_status        = "\\GP11",
+               .brightness_up     = "\\Q0C",
+               .brightness_down   = "\\Q0B",
+               .brightness_status = "\\BLVL",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "L2D",
+               .mt_mled           = "MLED",
+               .mled_status       = "\\SGP6",
+               .mt_wled           = "WLED",
+               .wled_status       = "\\RCP3",
+               .mt_lcd_switch     = "\\Q10",
+               .lcd_status        = "\\SGP0",
+               .brightness_up     = "\\Q0E",
+               .brightness_down   = "\\Q0F",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "L3C",
+               .mt_mled           = "MLED",
+               .mt_wled           = "WLED",
+               .mt_lcd_switch     = L3C_PREFIX "_Q10",
+               .lcd_status        = "\\GL32",
+               .brightness_up     = L3C_PREFIX "_Q0F",
+               .brightness_down   = L3C_PREFIX "_Q0E",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .brightness_status = "\\BLVL",
+               .display_set       = "SDSP",
+               .display_get       = "\\_SB.PCI0.PCI1.VGAC.NMAP"
+       },
+
+       {
+               .name              = "L3D",
+               .mt_mled           = "MLED",
+               .mled_status       = "\\MALD",
+               .mt_wled           = "WLED",
+               .mt_lcd_switch     = "\\Q10",
+               .lcd_status        = "\\BKLG",
+               .brightness_up     = "\\Q0E",
+               .brightness_down   = "\\Q0F",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .brightness_status = "\\BLVL",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "L3H",
+               .mt_mled           = "MLED",
+               .mt_wled           = "WLED",
+               .mt_lcd_switch     = "EHK",
+               .lcd_status        = "\\_SB.PCI0.PM.PBC",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "L5x",
+               .mt_mled           = "MLED",
+//             .mt_wled           = "WLED",
+//             .wled_status       = "\\WRED",
+/* Present, but not controlled by ACPI */
+               .mt_tled           = "TLED",
+               .mt_lcd_switch     = "\\Q0D",
+               .lcd_status        = "\\BAOF",
+               .brightness_up     = "\\Q0C",
+               .brightness_down   = "\\Q0B",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "L8L"
+/* No features, but at least support the hotkeys */
+       },
+
+       {
+               .name              = "M1A",
+               .mt_mled           = "MLED",
+               .mt_lcd_switch     = M1A_PREFIX "Q10",
+               .lcd_status        = "\\PNOF",
+               .brightness_up     = M1A_PREFIX "Q0E",
+               .brightness_down   = M1A_PREFIX "Q0F",
+               .brightness_status = "\\BRIT",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "M2E",
+               .mt_mled           = "MLED",
+               .mt_wled           = "WLED",
+               .mt_lcd_switch     = "\\Q10",
+               .lcd_status        = "\\GP06",
+               .brightness_up     = "\\Q0E",
+               .brightness_down   = "\\Q0F",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .display_set       = "SDSP",
+               .display_get       = "\\INFB"
+       },
+
+       {
+               .name              = "S1x",
+               .mt_mled           = "MLED",
+               .mled_status       = "\\EMLE",
+               .mt_wled           = "WLED",
+               .mt_lcd_switch     = S1x_PREFIX "Q10" ,
+               .lcd_status        = "\\PNOF",
+               .brightness_up     = S1x_PREFIX "Q0F",
+               .brightness_down   = S1x_PREFIX "Q0E",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .brightness_status = "\\BRIT",
+       },
+
+       {
+               .name              = "S2x",
+               .mt_mled           = "MLED",
+               .mled_status       = "\\MAIL",
+               .mt_lcd_switch     = S2x_PREFIX "_Q10",
+               .lcd_status        = "\\BKLI",
+               .brightness_up     = S2x_PREFIX "_Q0B",
+               .brightness_down   = S2x_PREFIX "_Q0A",
+       },
+
+       {
+               .name              = "xxN",
+               .mt_mled           = "MLED",
+//             .mt_wled           = "WLED",
+//             .wled_status       = "\\PO33",
+/* Present, but not controlled by ACPI */
+               .mt_lcd_switch     = xxN_PREFIX "_Q10",
+               .lcd_status        = "\\BKLT",
+               .brightness_up     = xxN_PREFIX "_Q0F",
+               .brightness_down   = xxN_PREFIX "_Q0E",
+               .brightness_set    = "SPLV",
+               .brightness_get    = "GPLV",
+               .brightness_status = "\\LBTN",
+               .display_set       = "SDSP",
+               .display_get       = "\\ADVG"
+       }
 };
 
 /* procdir we use */
@@ -264,7 +417,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
                void *data)
 {
        int len = 0;
-       int sfun;
+       int temp;
        struct asus_hotk *hotk = (struct asus_hotk *) data;
        char buf[16];           //enough for all info
        /*
@@ -275,8 +428,23 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
        len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
        len += sprintf(page + len, "Model reference    : %s\n", 
                       hotk->methods->name);
-       if(read_acpi_int(hotk->handle, "SFUN", &sfun))
-               len += sprintf(page + len, "SFUN value         : 0x%04x\n", sfun);
+       /* 
+        * The SFUN method probably allows the original driver to get the list 
+        * of features supported by a given model. For now, 0x0100 or 0x0800 
+        * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
+        * The significance of others is yet to be found.
+        */
+       if (read_acpi_int(hotk->handle, "SFUN", &temp))
+               len += sprintf(page + len, "SFUN value         : 0x%04x\n", temp);
+       /*
+        * Another value for userspace: the ASYM method returns 0x02 for
+        * battery low and 0x04 for battery critical, it's readings tend to be
+        * more accurate than those provided by _BST. 
+        * Note: since not all the laptops provide this method, errors are
+        * silently ignored.
+        */
+       if (read_acpi_int(hotk->handle, "ASYM", &temp))
+               len += sprintf(page + len, "ASYM value         : 0x%04x\n", temp);
        if (asus_info) {
                snprintf(buf, 16, "%d", asus_info->length);
                len += sprintf(page + len, "DSDT length        : %s\n", buf);
@@ -300,128 +468,179 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
 }
 
 
-/* 
- * proc file handlers
+/*
+ * /proc handlers
+ * We write our info in page, we begin at offset off and cannot write more
+ * than count bytes. We set eof to 1 if we handle those 2 values. We return the
+ * number of bytes written in page
  */
+
+/* Generic LED functions */
 static int
-proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
-              void *data)
+read_led(struct asus_hotk *hotk, const char *ledname, int ledmask)
 {
-       int len = 0;
-       struct asus_hotk *hotk = (struct asus_hotk *) data;
-       int led_status = 0;
-       /*
-        * We use the easy way, we don't care of off and count, so we don't set eof
-        * to 1
-        */
-       if (hotk->methods->mled_status) {
-               if (read_acpi_int(NULL, hotk->methods->mled_status, 
-                                 &led_status))
-                       len =  sprintf(page, "%d\n", led_status);
+       if (ledname) {
+               int led_status;
+
+               if (read_acpi_int(NULL, ledname, &led_status))
+                       return led_status;
                else
-                       printk(KERN_WARNING "Asus ACPI: Error reading MLED "
+                       printk(KERN_WARNING "Asus ACPI: Error reading LED "
                               "status\n");
-       } else {
-               len = sprintf(page, "%d\n", (hotk->status & MLED_ON) ? 1 : 0);
        }
-
-       return len;
+       return (hotk->status & ledmask) ? 1 : 0;
 }
 
 
+/* FIXME: kill extraneous args so it can be called independently */
 static int
-proc_write_mled(struct file *file, const char *buffer,
-               unsigned long count, void *data)
+write_led(const char *buffer, unsigned long count, struct asus_hotk *hotk, 
+          char *ledname, int ledmask, int invert)
 {
        int value;
        int led_out = 0;
-       struct asus_hotk *hotk = (struct asus_hotk *) data;
 
-
-
-       /* scan expression.  Multiple expressions may be delimited with ; */
        if (sscanf(buffer, "%i", &value) == 1)
-               led_out = ~value & 1;
+               led_out = value ? 1 : 0;
 
        hotk->status =
-           (value) ? (hotk->status | MLED_ON) : (hotk->status & ~MLED_ON);
-
-       /* We don't have to check mt_mled exists if we are here :) */
-       if (!write_acpi_int(hotk->handle, hotk->methods->mt_mled, led_out,
-                           NULL))
-               printk(KERN_WARNING "Asus ACPI: MLED write failed\n");
+           (led_out) ? (hotk->status | ledmask) : (hotk->status & ~ledmask);
 
+       if (invert) /* invert target value */
+               led_out = !led_out & 0x1;
 
+       if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
+               printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", ledname);
 
        return count;
 }
 
+
 /*
- * We write our info in page, we begin at offset off and cannot write more
- * than count bytes. We set eof to 1 if we handle those 2 values. We return the
- * number of bytes written in page
+ * Proc handlers for MLED
  */
 static int
-proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
+proc_read_mled(char *page, char **start, off_t off, int count, int *eof,
               void *data)
 {
-       int len = 0;
        struct asus_hotk *hotk = (struct asus_hotk *) data;
-       int led_status;
+       return sprintf(page, "%d\n", read_led(hotk, hotk->methods->mled_status, MLED_ON));
+}
 
-       if (hotk->methods->wled_status) {
-               if (read_acpi_int(NULL, hotk->methods->wled_status, 
-                                 &led_status))
-                       len = sprintf(page, "%d\n", led_status);
-               else
-                       printk(KERN_WARNING "Asus ACPI: Error reading WLED "
-                              "status\n");
-       } else {
-               len = sprintf(page, "%d\n", (hotk->status & WLED_ON) ? 1 : 0);
-       }
 
-       return len;
+static int
+proc_write_mled(struct file *file, const char *buffer,
+               unsigned long count, void *data)
+{
+       struct asus_hotk *hotk = (struct asus_hotk *) data;
+       return write_led(buffer, count, hotk, hotk->methods->mt_mled, MLED_ON, 1);
+}
+
+/*
+ * Proc handlers for WLED
+ */
+static int
+proc_read_wled(char *page, char **start, off_t off, int count, int *eof,
+              void *data)
+{
+       struct asus_hotk *hotk = (struct asus_hotk *) data;
+       return sprintf(page, "%d\n", read_led(hotk, hotk->methods->wled_status, WLED_ON));
 }
 
 static int
 proc_write_wled(struct file *file, const char *buffer,
                unsigned long count, void *data)
 {
-       int value;
-       int led_out = 0;
        struct asus_hotk *hotk = (struct asus_hotk *) data;
+       return write_led(buffer, count, hotk, hotk->methods->mt_wled, WLED_ON, 0);
+}
 
-       /* scan expression.  Multiple expressions may be delimited with ; */
-       if (sscanf(buffer, "%i", &value) == 1)
-               led_out = value & 1;
-
-       hotk->status =
-           (value) ? (hotk->status | WLED_ON) : (hotk->status & ~WLED_ON);
-
-       /* We don't have to check if mt_wled exists if we are here :) */
-       if (!write_acpi_int(hotk->handle, hotk->methods->mt_wled, led_out,
-                           NULL))
-               printk(KERN_WARNING "Asus ACPI: WLED write failed\n");
-
+/*
+ * Proc handlers for TLED
+ */
+static int
+proc_read_tled(char *page, char **start, off_t off, int count, int *eof,
+              void *data)
+{
+       struct asus_hotk *hotk = (struct asus_hotk *) data;
+       return sprintf(page, "%d\n", read_led(hotk, hotk->methods->tled_status, TLED_ON));
+}
 
-       return count;
+static int
+proc_write_tled(struct file *file, const char *buffer,
+               unsigned long count, void *data)
+{
+       struct asus_hotk *hotk = (struct asus_hotk *) data;
+       return write_led(buffer, count, hotk, hotk->methods->mt_tled, TLED_ON, 0);
 }
 
 
+
 static int get_lcd_state(struct asus_hotk *hotk)
 {
        int lcd = 0;
 
-       /* We don't have to check anything, if we are here */
-       if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
-               printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n");
+       if (hotk->model != L3H) {
+       /* We don't have to check anything if we are here */
+               if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
+                       printk(KERN_WARNING "Asus ACPI: Error reading LCD status\n");
        
-       if (hotk->model == L2X)
-               lcd = ~lcd;
+               if (hotk->model == L2D)
+                       lcd = ~lcd;
+       } else { /* L3H and the like have to be handled differently */
+               acpi_status status = 0;
+               struct acpi_object_list input;
+               union acpi_object mt_params[2];
+               struct acpi_buffer output;
+               union acpi_object out_obj;
+               
+               input.count = 2;
+               input.pointer = mt_params;
+               /* Note: the following values are partly guessed up, but 
+                  otherwise they seem to work */
+               mt_params[0].type = ACPI_TYPE_INTEGER;
+               mt_params[0].integer.value = 0x02;
+               mt_params[1].type = ACPI_TYPE_INTEGER;
+               mt_params[1].integer.value = 0x02;
+
+               output.length = sizeof(out_obj);
+               output.pointer = &out_obj;
+               
+               status = acpi_evaluate_object(NULL, hotk->methods->lcd_status, &input, &output);
+               if (status != AE_OK)
+                       return -1;
+               if (out_obj.type == ACPI_TYPE_INTEGER)
+                       /* That's what the AML code does */
+                       lcd = out_obj.integer.value >> 8;
+       }
        
        return (lcd & 1);
 }
 
+static int set_lcd_state(struct asus_hotk *hotk, int value)
+{
+       int lcd = 0;
+       acpi_status status = 0;
+
+       lcd = value ? 1 : 0;
+       if (lcd != get_lcd_state(hotk)) {
+               /* switch */
+               if (hotk->model != L3H) {
+                       status =
+                           acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch,
+                                                NULL, NULL);
+               } else { /* L3H and the like have to be handled differently */
+                       if (!write_acpi_int(hotk->handle, hotk->methods->mt_lcd_switch, 0x07, NULL))
+                               status = AE_ERROR;
+                       /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, 
+                          the exact behaviour is simulated here */
+               }
+               if (ACPI_FAILURE(status))
+                       printk(KERN_WARNING "Asus ACPI: Error switching LCD\n");
+       }
+       return 0;
+
+}
 
 static int
 proc_read_lcd(char *page, char **start, off_t off, int count, int *eof,
@@ -436,26 +655,10 @@ proc_write_lcd(struct file *file, const char *buffer,
               unsigned long count, void *data)
 {
        int value;
-       int lcd = 0;
-       acpi_status status = 0;
-       int lcd_status = 0;
        struct asus_hotk *hotk = (struct asus_hotk *) data;
-
-       /* scan expression.  Multiple expressions may be delimited with ; */
+       
        if (sscanf(buffer, "%i", &value) == 1)
-               lcd = value & 1;
-
-       lcd_status = get_lcd_state(hotk);
-
-       if (lcd_status != lcd) {
-               /* switch */
-               status =
-                   acpi_evaluate_object(NULL, hotk->methods->mt_lcd_switch,
-                                        NULL, NULL);
-               if (ACPI_FAILURE(status))
-                       printk(KERN_WARNING "Asus ACPI: Error switching LCD\n");
-       }
-
+               set_lcd_state(hotk, value);
        return count;
 }
 
@@ -521,7 +724,6 @@ proc_write_brn(struct file *file, const char *buffer,
        int value;
        struct asus_hotk *hotk = (struct asus_hotk *) data;
 
-       /* scan expression.  Multiple expressions may be delimited with ; */
        if (sscanf(buffer, "%d", &value) == 1) {
                value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
                        /* 0 <= value <= 15 */
@@ -546,7 +748,6 @@ static void set_display(int value, struct asus_hotk *hotk)
  * Now, *this* one could be more user-friendly, but so far, no-one has 
  * complained. The significance of bits is the same as in proc_write_disp()
  */
-
 static int
 proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
              void *data)
@@ -560,12 +761,11 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
 }
 
 /*
- * Experimental support for display switching. As of now: 0x01 should activate 
- * the LCD output, 0x02 should do for CRT, and 0x04 for TV-Out. Any combination 
+ * Experimental support for display switching. As of now: 1 should activate 
+ * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination 
  * (bitwise) of these will suffice. I never actually tested 3 displays hooked up 
- * simultaneously, so be warned.
+ * simultaneously, so be warned. See the acpi4asus README for more info.
  */
-
 static int
 proc_write_disp(struct file *file, const char *buffer,
               unsigned long count, void *data)
@@ -573,7 +773,6 @@ proc_write_disp(struct file *file, const char *buffer,
        int value;
        struct asus_hotk *hotk = (struct asus_hotk *) data;
 
-       /* scan expression.  Multiple expressions may be delimited with ; */
        if (sscanf(buffer, "%d", &value) == 1)
                set_display(value, hotk);
        else {
@@ -583,6 +782,31 @@ proc_write_disp(struct file *file, const char *buffer,
        return count;
 }
 
+
+typedef int (proc_readfunc)(char *page, char **start, off_t off, int count,
+                            int *eof, void *data);
+typedef int (proc_writefunc)(struct file *file, const char *buffer,
+                             unsigned long count, void *data);
+
+static int
+__init asus_proc_add(char *name, proc_writefunc *writefunc,
+                    proc_readfunc *readfunc, mode_t mode,
+                    struct acpi_device *device)
+{
+       struct proc_dir_entry *proc = create_proc_entry(name, mode, acpi_device_dir(device));
+       if(!proc) {
+               printk(KERN_WARNING "  Unable to create %s fs entry\n", name);
+               return -1;
+       }
+       proc->write_proc = writefunc;
+       proc->read_proc = readfunc;
+       proc->data = acpi_driver_data(device);
+       proc->owner = THIS_MODULE;
+       proc->uid = asus_uid;
+       proc->gid = asus_gid;
+       return 0;
+}
+
 static int __init asus_hotk_add_fs(struct acpi_device *device)
 {
        struct proc_dir_entry *proc;
@@ -605,46 +829,28 @@ static int __init asus_hotk_add_fs(struct acpi_device *device)
        if (!acpi_device_dir(device))
                return(-ENODEV);
 
-       proc = create_proc_entry(PROC_INFOS, mode, acpi_device_dir(device));
+       proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device));
        if (proc) {
                proc->read_proc = proc_read_info;
                proc->data = acpi_driver_data(device);
                proc->owner = THIS_MODULE;
                proc->uid = asus_uid;
-               proc->gid = asus_gid;;
+               proc->gid = asus_gid;
        } else {
-               printk(KERN_WARNING "  Unable to create " PROC_INFOS
+               printk(KERN_WARNING "  Unable to create " PROC_INFO
                       " fs entry\n");
        }
 
        if (hotk->methods->mt_wled) {
-               proc = create_proc_entry(PROC_WLED, mode, acpi_device_dir(device));
-               if (proc) {
-                       proc->write_proc = proc_write_wled;
-                       proc->read_proc = proc_read_wled;
-                       proc->data = acpi_driver_data(device);
-                       proc->owner = THIS_MODULE;
-                       proc->uid = asus_uid;
-                       proc->gid = asus_gid;;
-               } else {
-                       printk(KERN_WARNING "  Unable to create " PROC_WLED
-                              " fs entry\n");
-               }
+               asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled, mode, device);
        }
 
        if (hotk->methods->mt_mled) {
-               proc = create_proc_entry(PROC_MLED, mode, acpi_device_dir(device));
-               if (proc) {
-                       proc->write_proc = proc_write_mled;
-                       proc->read_proc = proc_read_mled;
-                       proc->data = acpi_driver_data(device);
-                       proc->owner = THIS_MODULE;
-                       proc->uid = asus_uid;
-                       proc->gid = asus_gid;;
-               } else {
-                       printk(KERN_WARNING "  Unable to create " PROC_MLED
-                              " fs entry\n");
-               }
+               asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, mode, device);
+       }
+
+       if (hotk->methods->mt_tled) {
+               asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled, mode, device);
        }
 
        /* 
@@ -652,49 +858,17 @@ static int __init asus_hotk_add_fs(struct acpi_device *device)
         * from keyboard 
         */
        if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
-               proc = create_proc_entry(PROC_LCD, mode, acpi_device_dir(device));
-               if (proc) {
-                       proc->write_proc = proc_write_lcd;
-                       proc->read_proc = proc_read_lcd;
-                       proc->data = acpi_driver_data(device);
-                       proc->owner = THIS_MODULE;
-                       proc->uid = asus_uid;
-                       proc->gid = asus_gid;;
-               } else {
-                       printk(KERN_WARNING "  Unable to create " PROC_LCD
-                              " fs entry\n");
-               }
+               asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, device);
        }
        
        if ((hotk->methods->brightness_up && hotk->methods->brightness_down) ||
            (hotk->methods->brightness_get && hotk->methods->brightness_get)) {
-               proc = create_proc_entry(PROC_BRN, mode, acpi_device_dir(device));
-               if (proc) {
-                       proc->write_proc = proc_write_brn;
-                       proc->read_proc = proc_read_brn;
-                       proc->data = acpi_driver_data(device);
-                       proc->owner = THIS_MODULE;
-                       proc->uid = asus_uid;
-                       proc->gid = asus_gid;;
-               } else {
-                       printk(KERN_WARNING "  Unable to create " PROC_BRN
-                              " fs entry\n");
-               }
+               asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, device);
        }
 
        if (hotk->methods->display_set) {
-               proc = create_proc_entry(PROC_DISP, mode, acpi_device_dir(device));
-               if (proc) {
-                       proc->write_proc = proc_write_disp;
-                       proc->read_proc = proc_read_disp;
-                       proc->data = acpi_driver_data(device);
-                       proc->owner = THIS_MODULE;
-                       proc->uid = asus_uid;
-                       proc->gid = asus_gid;;
-               } else {
-                       printk(KERN_WARNING "  Unable to create " PROC_DISP
-                              " fs entry\n");
-               }
+               asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, mode, device);
+
        }
 
        return 0;
@@ -761,11 +935,6 @@ static int __init asus_hotk_get_info(struct asus_hotk *hotk)
        else if (bsts_result)
                printk(KERN_NOTICE "  BSTS called, 0x%02x returned\n", bsts_result);
 
-       /*
-        * Here, we also use asus_info to make decision. For example, on INIT
-        * method, S1X and L1X models both reports to be L84F, but they don't
-        * have the same methods (L1X has WLED, S1X don't)
-        */
        model = (union acpi_object *) buffer.pointer;
        if (model->type == ACPI_TYPE_STRING) {
                printk(KERN_NOTICE "  %s model detected, ", model->string.pointer);
@@ -774,52 +943,63 @@ static int __init asus_hotk_get_info(struct asus_hotk *hotk)
        hotk->model = END_MODEL;
        if (strncmp(model->string.pointer, "L3D", 3) == 0)
                hotk->model = L3D;
-               /*
-                * L2B has same settings that L3X, except for GL32, but as
-                * there is no node to get the LCD status, and as GL32 is never
-                * used anywhere else, I assume it's safe, even if lcd get is
-                * broken for this model (TODO fix it ?)
-                */
+       else if (strncmp(model->string.pointer, "L3H", 3) == 0 ||
+                strncmp(model->string.pointer, "L2E", 3) == 0)
+               hotk->model = L3H;
        else if (strncmp(model->string.pointer, "L3", 2) == 0 ||
                 strncmp(model->string.pointer, "L2B", 3) == 0)
-               hotk->model = L3X;
+               hotk->model = L3C;
+       else if (strncmp(model->string.pointer, "L8L", 3) == 0)
+               hotk->model = L8L;
+       else if (strncmp(model->string.pointer, "M2N", 3) == 0 ||
+                strncmp(model->string.pointer, "M3N", 3) == 0 ||
+                strncmp(model->string.pointer, "S1N", 3) == 0 ||
+                strncmp(model->string.pointer, "S5N", 3) == 0)
+               hotk->model = xxN;
+       else if (strncmp(model->string.pointer, "M1", 2) == 0)
+               hotk->model = M1A;
        else if (strncmp(model->string.pointer, "M2", 2) == 0)
-               hotk->model = M2X;
-       else if (strncmp(model->string.pointer, "M3N", 3) == 0 ||
-                strncmp(model->string.pointer, "S1N", 3) == 0)
-               hotk->model = M3N; /* S1300N is similar enough */
+               hotk->model = M2E;
        else if (strncmp(model->string.pointer, "L2", 2) == 0)
-               hotk->model = L2X;
-       else if (strncmp(model->string.pointer, "L8", 2) == 0) {
-               /* S1300A reports L84F, but L1400B too */
-               if (asus_info) {
-                       if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
-                               hotk->model = L1X;
-               } else
-                       hotk->model = S1X;
-       }
+               hotk->model = L2D;
+       else if (strncmp(model->string.pointer, "L8", 2) == 0)
+               hotk->model = S1x;
        else if (strncmp(model->string.pointer, "D1", 2) == 0)
-               hotk->model = D1X;
+               hotk->model = D1x;
        else if (strncmp(model->string.pointer, "A1", 2) == 0)
-               hotk->model = A1X;
+               hotk->model = A1x;
        else if (strncmp(model->string.pointer, "A2", 2) == 0)
-               hotk->model = A2X;
+               hotk->model = A2x;
        else if (strncmp(model->string.pointer, "J1", 2) == 0)
-               hotk->model = S2X;
+               hotk->model = S2x;
        else if (strncmp(model->string.pointer, "L5", 2) == 0)
-               hotk->model = L5X;
+               hotk->model = L5x;
 
        if (hotk->model == END_MODEL) {
                /* By default use the same values, as I don't know others */
                printk("unsupported, trying default values, supply the "
                       "developers with your DSDT\n");
-               hotk->model = L2X;
+               hotk->model = M2E;
        } else {
                printk("supported\n");
        }
 
        hotk->methods = &model_conf[hotk->model];
 
+       /* Sort of per-model blacklist */
+       if (strncmp(model->string.pointer, "L2B", 3) == 0)
+               hotk->methods->lcd_status = NULL; 
+       /* L2B is similar enough to L3C to use its settings, with this only 
+          exception */
+       else if (strncmp(model->string.pointer, "S5N", 3) == 0)
+               hotk->methods->mt_mled = NULL; 
+       /* S5N has no MLED */
+       else if (asus_info) {
+               if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
+                       hotk->methods->mled_status = NULL;
+       /* S1300A reports L84F, but L1400B too, account for that */
+       }
+
        acpi_os_free(model);
 
        return AE_OK;
@@ -917,8 +1097,6 @@ static int __init asus_hotk_add(struct acpi_device *device)
 }
 
 
-
-
 static int asus_hotk_remove(struct acpi_device *device, int type)
 {
        acpi_status status = 0;
@@ -940,15 +1118,13 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
 }
 
 
-
-
 static int __init asus_acpi_init(void)
 {
        int result;
 
        asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
        if (!asus_proc_dir) {
-               printk(KERN_ERR "Asus ACPI: Unable to create /proc entry");
+               printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
                return(-ENODEV);
        }
        asus_proc_dir->owner = THIS_MODULE;
@@ -963,7 +1139,6 @@ static int __init asus_acpi_init(void)
 }
 
 
-
 static void __exit asus_acpi_exit(void)
 {
        acpi_bus_unregister_driver(&asus_hotk_driver);
index 62a484e..15494a4 100644 (file)
@@ -30,8 +30,9 @@
 #include <linux/errno.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
+#include <acpi/acmacros.h>
 
-extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler);
+extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries);
 
 void __init
 acpi_table_print_srat_entry (
@@ -46,9 +47,9 @@ acpi_table_print_srat_entry (
        {
                struct acpi_table_processor_affinity *p =
                        (struct acpi_table_processor_affinity*) header;
-               printk(KERN_INFO PREFIX "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
                       p->apic_id, p->lsapic_eid, p->proximity_domain,
-                      p->flags.enabled?"enabled":"disabled");
+                      p->flags.enabled?"enabled":"disabled"));
        }
                break;
 
@@ -56,11 +57,11 @@ acpi_table_print_srat_entry (
        {
                struct acpi_table_memory_affinity *p =
                        (struct acpi_table_memory_affinity*) header;
-               printk(KERN_INFO PREFIX "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
                       p->base_addr_hi, p->base_addr_lo, p->length_hi, p->length_lo,
                       p->memory_type, p->proximity_domain,
                       p->flags.enabled ? "enabled" : "disabled",
-                      p->flags.hot_pluggable ? " hot-pluggable" : "");
+                      p->flags.hot_pluggable ? " hot-pluggable" : ""));
        }
                break;
 
@@ -97,7 +98,7 @@ acpi_parse_slit (unsigned long phys_addr, unsigned long size)
 static int __init
 acpi_parse_processor_affinity (acpi_table_entry_header *header)
 {
-       struct acpi_table_processor_affinity *processor_affinity = NULL;
+       struct acpi_table_processor_affinity *processor_affinity;
 
        processor_affinity = (struct acpi_table_processor_affinity*) header;
        if (!processor_affinity)
@@ -115,7 +116,7 @@ acpi_parse_processor_affinity (acpi_table_entry_header *header)
 static int __init
 acpi_parse_memory_affinity (acpi_table_entry_header *header)
 {
-       struct acpi_table_memory_affinity *memory_affinity = NULL;
+       struct acpi_table_memory_affinity *memory_affinity;
 
        memory_affinity = (struct acpi_table_memory_affinity*) header;
        if (!memory_affinity)
@@ -133,7 +134,7 @@ acpi_parse_memory_affinity (acpi_table_entry_header *header)
 static int __init
 acpi_parse_srat (unsigned long phys_addr, unsigned long size)
 {
-       struct acpi_table_srat  *srat = NULL;
+       struct acpi_table_srat  *srat;
 
        if (!phys_addr || !size)
                return -EINVAL;
@@ -149,10 +150,11 @@ acpi_parse_srat (unsigned long phys_addr, unsigned long size)
 int __init
 acpi_table_parse_srat (
        enum acpi_srat_entry_id id,
-       acpi_madt_entry_handler handler)
+       acpi_madt_entry_handler handler,
+       unsigned int max_entries)
 {
        return acpi_table_parse_madt_family(ACPI_SRAT, sizeof(struct acpi_table_srat),
-                                           id, handler);
+                                           id, handler, max_entries);
 }
 
 
@@ -166,9 +168,11 @@ acpi_numa_init()
 
        if (result > 0) {
                result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY,
-                                              acpi_parse_processor_affinity);
+                                              acpi_parse_processor_affinity,
+                                              NR_CPUS);
                result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY,
-                                              acpi_parse_memory_affinity);
+                                              acpi_parse_memory_affinity,
+                                              NR_NODE_MEMBLKS);
        } else {
                /* FIXME */
                printk("Warning: acpi_table_parse(ACPI_SRAT) returned %d!\n",result);
index 28ffe37..9dbc354 100644 (file)
@@ -315,7 +315,6 @@ acpi_pci_irq_enable (
 {
        int                     irq = 0;
        u8                      pin = 0;
-       static u16              irq_mask = 0;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
 
@@ -372,10 +371,13 @@ acpi_pci_irq_enable (
         * Make sure all (legacy) PCI IRQs are set as level-triggered.
         */
 #ifdef CONFIG_X86
-       if ((dev->irq < 16) &&  !((1 << dev->irq) & irq_mask)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq));
-               irq_mask |= (1 << dev->irq);
-               eisa_set_level_irq(dev->irq);
+       {
+               static u16 irq_mask;
+               if ((dev->irq < 16) &&  !((1 << dev->irq) & irq_mask)) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq));
+                       irq_mask |= (1 << dev->irq);
+                       eisa_set_level_irq(dev->irq);
+               }
        }
 #endif
 #ifdef CONFIG_IOSAPIC
index 1b85aff..8bf340c 100644 (file)
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -22,7 +23,7 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *  TBD:
- *     1. Make # power/performance states dynamic.
+ *     1. Make # power states dynamic.
  *     2. Support duty_cycle values that span bit 4.
  *     3. Optimize by having scheduler determine business instead of
  *        having us try to calculate it here.
@@ -55,9 +56,9 @@
 #define ACPI_PROCESSOR_DEVICE_NAME     "Processor"
 #define ACPI_PROCESSOR_FILE_INFO       "info"
 #define ACPI_PROCESSOR_FILE_POWER      "power"
-#define ACPI_PROCESSOR_FILE_PERFORMANCE        "performance"
 #define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
 #define ACPI_PROCESSOR_FILE_LIMIT      "limit"
+#define ACPI_PROCESSOR_FILE_PERFORMANCE        "performance"
 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
 #define ACPI_PROCESSOR_NOTIFY_POWER    0x81
 
@@ -746,7 +747,62 @@ acpi_processor_get_power_info (
 /* --------------------------------------------------------------------------
                               Performance Management
    -------------------------------------------------------------------------- */
-int 
+#ifdef CONFIG_CPU_FREQ
+
+static DECLARE_MUTEX(performance_sem);
+
+/*
+ * _PPC support is implemented as a CPUfreq policy notifier: 
+ * This means each time a CPUfreq driver registered also with
+ * the ACPI core is asked to change the speed policy, the maximum
+ * value is adjusted so that it is within the platform limit.
+ * 
+ * Also, when a new platform limit value is detected, the CPUfreq
+ * policy is adjusted accordingly.
+ */
+
+static int acpi_processor_ppc_is_init = 0;
+
+static int acpi_processor_ppc_notifier(struct notifier_block *nb, 
+       unsigned long event,
+       void *data)
+{
+       struct cpufreq_policy *policy = data;
+       struct acpi_processor *pr;
+       unsigned int ppc = 0;
+
+       down(&performance_sem);
+
+       if (event != CPUFREQ_INCOMPATIBLE)
+               goto out;
+
+       pr = processors[policy->cpu];
+       if (!pr || !pr->performance)
+               goto out;
+
+       ppc = (unsigned int) pr->performance_platform_limit;
+       if (!ppc)
+               goto out;
+
+       if (ppc > pr->performance->state_count)
+               goto out;
+
+       cpufreq_verify_within_limits(policy, 0, 
+               pr->performance->states[ppc].core_frequency * 1000);
+
+ out:
+       up(&performance_sem);
+
+       return 0;
+}
+
+
+static struct notifier_block acpi_ppc_notifier_block = {
+       .notifier_call = acpi_processor_ppc_notifier,
+};
+
+
+static int
 acpi_processor_get_platform_limit (
        struct acpi_processor*  pr)
 {
@@ -770,35 +826,491 @@ acpi_processor_get_platform_limit (
 
        pr->performance_platform_limit = (int) ppc;
        
-       acpi_processor_get_limit_info(pr);
+       return_VALUE(0);
+}
+
+
+static int acpi_processor_ppc_has_changed(
+       struct acpi_processor *pr)
+{
+       int ret = acpi_processor_get_platform_limit(pr);
+       if (ret < 0)
+               return (ret);
+       else
+               return cpufreq_update_policy(pr->id);
+}
+
+
+static void acpi_processor_ppc_init(void) {
+       if (!cpufreq_register_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
+               acpi_processor_ppc_is_init = 1;
+       else
+               printk(KERN_DEBUG "Warning: Processor Platform Limit not supported.\n");
+}
+
+
+static void acpi_processor_ppc_exit(void) {
+       if (acpi_processor_ppc_is_init)
+               cpufreq_unregister_notifier(&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
+       acpi_processor_ppc_is_init = 0;
+}
+
+/*
+ * when registering a cpufreq driver with this ACPI processor driver, the
+ * _PCT and _PSS structures are read out and written into struct
+ * acpi_processor_performance.
+ */
+
+static int acpi_processor_set_pdc (struct acpi_processor *pr)
+{
+       acpi_status             status = AE_OK;
+       u32                     arg0_buf[3];
+       union acpi_object       arg0 = {ACPI_TYPE_BUFFER};
+       struct acpi_object_list no_object = {1, &arg0};
+       struct acpi_object_list *pdc;
+
+       ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
        
+       arg0.buffer.length = 12;
+       arg0.buffer.pointer = (u8 *) arg0_buf;
+       arg0_buf[0] = ACPI_PDC_REVISION_ID;
+       arg0_buf[1] = 0;
+       arg0_buf[2] = 0;
+
+       pdc = (pr->performance->pdc) ? pr->performance->pdc : &no_object;
+
+       status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
+
+       if ((ACPI_FAILURE(status)) && (pr->performance->pdc))
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Error evaluating _PDC, using legacy perf. control...\n"));
+
+       return_VALUE(status);
+}
+
+
+static int 
+acpi_processor_get_performance_control (
+       struct acpi_processor *pr)
+{
+       int                     result = 0;
+       acpi_status             status = 0;
+       struct acpi_buffer      buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object       *pct = NULL;
+       union acpi_object       obj = {0};
+
+       ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
+
+       status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
+       if(ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
+               return_VALUE(-ENODEV);
+       }
+
+       pct = (union acpi_object *) buffer.pointer;
+       if (!pct || (pct->type != ACPI_TYPE_PACKAGE) 
+               || (pct->package.count != 2)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+       /*
+        * control_register
+        */
+
+       obj = pct->package.elements[0];
+
+       if ((obj.type != ACPI_TYPE_BUFFER) 
+               || (obj.buffer.length < sizeof(struct acpi_pct_register)) 
+               || (obj.buffer.pointer == NULL)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+                       "Invalid _PCT data (control_register)\n"));
+               result = -EFAULT;
+               goto end;
+       }
+       memcpy(&pr->performance->control_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
+
+
+       /*
+        * status_register
+        */
+
+       obj = pct->package.elements[1];
+
+       if ((obj.type != ACPI_TYPE_BUFFER) 
+               || (obj.buffer.length < sizeof(struct acpi_pct_register)) 
+               || (obj.buffer.pointer == NULL)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+                       "Invalid _PCT data (status_register)\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+       memcpy(&pr->performance->status_register, obj.buffer.pointer, sizeof(struct acpi_pct_register));
+
+end:
+       acpi_os_free(buffer.pointer);
+
+       return_VALUE(result);
+}
+
+
+static int 
+acpi_processor_get_performance_states (
+       struct acpi_processor   *pr)
+{
+       int                     result = 0;
+       acpi_status             status = AE_OK;
+       struct acpi_buffer      buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       struct acpi_buffer      format = {sizeof("NNNNNN"), "NNNNNN"};
+       struct acpi_buffer      state = {0, NULL};
+       union acpi_object       *pss = NULL;
+       int                     i = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
+
+       status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
+       if(ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
+               return_VALUE(-ENODEV);
+       }
+
+       pss = (union acpi_object *) buffer.pointer;
+       if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", 
+               pss->package.count));
+
+       pr->performance->state_count = pss->package.count;
+       pr->performance->states = kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, GFP_KERNEL);
+       if (!pr->performance->states) {
+               result = -ENOMEM;
+               goto end;
+       }
+
+       for (i = 0; i < pr->performance->state_count; i++) {
+
+               struct acpi_processor_px *px = &(pr->performance->states[i]);
+
+               state.length = sizeof(struct acpi_processor_px);
+               state.pointer = px;
+
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
+
+               status = acpi_extract_package(&(pss->package.elements[i]), 
+                       &format, &state);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+                       result = -EFAULT;
+                       kfree(pr->performance->states);
+                       goto end;
+               }
+
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+                       "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
+                       i, 
+                       (u32) px->core_frequency, 
+                       (u32) px->power, 
+                       (u32) px->transition_latency, 
+                       (u32) px->bus_master_latency,
+                       (u32) px->control, 
+                       (u32) px->status));
+
+               if (!px->core_frequency) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "core_frequency is 0\n"));
+                       result = -EFAULT;
+                       kfree(pr->performance->states);
+                       goto end;
+               }
+       }
+
+end:
+       acpi_os_free(buffer.pointer);
+
+       return_VALUE(result);
+}
+
+
+static int
+acpi_processor_get_performance_info (
+       struct acpi_processor   *pr)
+{
+       int                     result = 0;
+       acpi_status             status = AE_OK;
+       acpi_handle             handle = NULL;
+
+       ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
+
+       if (!pr || !pr->performance || !pr->handle)
+               return_VALUE(-EINVAL);
+
+       status = acpi_get_handle(pr->handle, "_PCT", &handle);
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+                       "ACPI-based processor performance control unavailable\n"));
+               return_VALUE(-ENODEV);
+       }
+
+       acpi_processor_set_pdc(pr);
+
+       result = acpi_processor_get_performance_control(pr);
+       if (result)
+               return_VALUE(result);
+
+       result = acpi_processor_get_performance_states(pr);
+       if (result)
+               return_VALUE(result);
+
+       result = acpi_processor_get_platform_limit(pr);
+       if (result)
+               return_VALUE(result);
+
        return_VALUE(0);
 }
-EXPORT_SYMBOL(acpi_processor_get_platform_limit);
+
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
+/* /proc/acpi/processor/../performance interface (DEPRECATED) */
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_processor_perf_fops = {
+       .open           = acpi_processor_perf_open_fs,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
+{
+       struct acpi_processor   *pr = (struct acpi_processor *)seq->private;
+       int                     i = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
+
+       if (!pr)
+               goto end;
+
+       if (!pr->performance) {
+               seq_puts(seq, "<not supported>\n");
+               goto end;
+       }
+
+       seq_printf(seq, "state count:             %d\n"
+                       "active state:            P%d\n",
+                       pr->performance->state_count,
+                       pr->performance->state);
+
+       seq_puts(seq, "states:\n");
+       for (i = 0; i < pr->performance->state_count; i++)
+               seq_printf(seq, "   %cP%d:                  %d MHz, %d mW, %d uS\n",
+                       (i == pr->performance->state?'*':' '), i,
+                       (u32) pr->performance->states[i].core_frequency,
+                       (u32) pr->performance->states[i].power,
+                       (u32) pr->performance->states[i].transition_latency);
+
+end:
+       return 0;
+}
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
+{
+       return single_open(file, acpi_processor_perf_seq_show,
+                                               PDE(inode)->data);
+}
+
+static int
+acpi_processor_write_performance (
+        struct file            *file,
+        const char             __user *buffer,
+        size_t                 count,
+        loff_t                 *data)
+{
+       int                     result = 0;
+       struct seq_file         *m = (struct seq_file *) file->private_data;
+       struct acpi_processor   *pr = (struct acpi_processor *) m->private;
+       struct acpi_processor_performance *perf;
+       char                    state_string[12] = {'\0'};
+       unsigned int            new_state = 0;
+       struct cpufreq_policy   policy;
+
+       ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
+
+       if (!pr || (count > sizeof(state_string) - 1))
+               return_VALUE(-EINVAL);
+
+       perf = pr->performance;
+       if (!perf)
+               return_VALUE(-EINVAL);
+       
+       if (copy_from_user(state_string, buffer, count))
+               return_VALUE(-EFAULT);
+       
+       state_string[count] = '\0';
+       new_state = simple_strtoul(state_string, NULL, 0);
+
+       if (new_state >= perf->state_count)
+               return_VALUE(-EINVAL);
+
+       cpufreq_get_policy(&policy, pr->id);
+
+       policy.cpu = pr->id;
+       policy.min = perf->states[new_state].core_frequency * 1000;
+       policy.max = perf->states[new_state].core_frequency * 1000;
+
+       result = cpufreq_set_policy(&policy);
+       if (result)
+               return_VALUE(result);
+
+       return_VALUE(count);
+}
+
+static void
+acpi_cpufreq_add_file (
+       struct acpi_processor *pr)
+{
+       struct proc_dir_entry   *entry = NULL;
+       struct acpi_device      *device = NULL;
+
+       ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+       if (acpi_bus_get_device(pr->handle, &device))
+               return_VOID;
+
+       /* add file 'performance' [R/W] */
+       entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+                 S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+       if (!entry)
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                       "Unable to create '%s' fs entry\n",
+                       ACPI_PROCESSOR_FILE_PERFORMANCE));
+       else {
+               entry->proc_fops = &acpi_processor_perf_fops;
+               entry->proc_fops->write = acpi_processor_write_performance;
+               entry->data = acpi_driver_data(device);
+       }
+       return_VOID;
+}
+
+static void
+acpi_cpufreq_remove_file (
+       struct acpi_processor *pr)
+{
+       struct acpi_device      *device = NULL;
+
+       ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+       if (acpi_bus_get_device(pr->handle, &device))
+               return_VOID;
+
+       /* remove file 'performance' */
+       remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+                 acpi_device_dir(device));
+
+       return_VOID;
+}
+
+#else
+static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
+static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
+#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
+
 
 int 
 acpi_processor_register_performance (
        struct acpi_processor_performance * performance,
-       struct acpi_processor ** pr,
        unsigned int cpu)
 {
+       struct acpi_processor *pr;
+
        ACPI_FUNCTION_TRACE("acpi_processor_register_performance");
 
-       *pr = processors[cpu];
-       if (!*pr)
+       if (!acpi_processor_ppc_is_init)
+               return_VALUE(-EINVAL);
+
+       down(&performance_sem);
+
+       pr = processors[cpu];
+       if (!pr) {
+               up(&performance_sem);
                return_VALUE(-ENODEV);
+       }
 
-       if ((*pr)->performance)
+       if (pr->performance) {
+               up(&performance_sem);
                return_VALUE(-EBUSY);
+       }
 
-       (*pr)->performance = performance;
-       performance->pr = *pr;
-       return 0;
+       pr->performance = performance;
+
+       if (acpi_processor_get_performance_info(pr)) {
+               pr->performance = NULL;
+               up(&performance_sem);
+               return_VALUE(-EIO);
+       }
+
+       acpi_cpufreq_add_file(pr);
+
+       up(&performance_sem);
+       return_VALUE(0);
 }
 EXPORT_SYMBOL(acpi_processor_register_performance);
 
-/* for the rest of it, check cpufreq/acpi.c */
 
+void 
+acpi_processor_unregister_performance (
+       struct acpi_processor_performance * performance,
+       unsigned int cpu)
+{
+       struct acpi_processor *pr;
+
+       ACPI_FUNCTION_TRACE("acpi_processor_unregister_performance");
+
+       if (!acpi_processor_ppc_is_init)
+               return_VOID;
+
+       down(&performance_sem);
+
+       pr = processors[cpu];
+       if (!pr) {
+               up(&performance_sem);
+               return_VOID;
+       }
+
+       kfree(pr->performance->states);
+       pr->performance = NULL;
+
+       acpi_cpufreq_remove_file(pr);
+
+       up(&performance_sem);
+
+       return_VOID;
+}
+EXPORT_SYMBOL(acpi_processor_unregister_performance);
+
+
+/* for the rest of it, check arch/i386/kernel/cpu/cpufreq/acpi.c */
+
+#else  /* !CONFIG_CPU_FREQ */
+
+static void acpi_processor_ppc_init(void) { return; }
+static void acpi_processor_ppc_exit(void) { return; }
+
+static int acpi_processor_ppc_has_changed(struct acpi_processor *pr) {
+       static unsigned int printout = 1;
+       if (printout) {
+               printk(KERN_WARNING "Warning: Processor Platform Limit event detected, but not handled.\n");
+               printk(KERN_WARNING "Consider compiling CPUfreq support into your kernel.\n");
+               printout = 0;
+       }
+       return 0;
+}
+
+#endif /* CONFIG_CPU_FREQ */
 
 /* --------------------------------------------------------------------------
                               Throttling Control
@@ -1043,27 +1555,6 @@ acpi_processor_apply_limit (
        if (!pr->flags.limit)
                return_VALUE(-ENODEV);
 
-#ifdef CONFIG_CPU_FREQ
-       if (pr->flags.performance) {
-               px = pr->performance_platform_limit;
-               if (pr->limit.user.px > px)
-                       px = pr->limit.user.px;
-               if (pr->limit.thermal.px > px)
-                       px = pr->limit.thermal.px;
-               {
-                       struct cpufreq_policy policy;
-                       policy.cpu = pr->id;
-                       cpufreq_get_policy(&policy, pr->id);
-                       policy.max = pr->performance->states[px].core_frequency * 1000; /* racy */
-                       result = cpufreq_set_policy(&policy);
-               }
-               if (result)
-                       goto end;
-       } else if (pr->performance_platform_limit) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Platform limit event detected. Consider using ACPI P-States CPUfreq driver\n"));
-       }
-#endif
-
        if (pr->flags.throttling) {
                if (pr->limit.user.tx > tx)
                        tx = pr->limit.user.tx;
@@ -1091,6 +1582,113 @@ end:
 }
 
 
+#ifdef CONFIG_CPU_FREQ
+
+/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
+ * offers (in most cases) voltage scaling in addition to frequency scaling, and
+ * thus a cubic (instead of linear) reduction of energy. Also, we allow for
+ * _any_ cpufreq driver and not only the acpi-cpufreq driver.
+ */
+
+static unsigned int cpufreq_thermal_reduction_pctg[NR_CPUS];
+static unsigned int acpi_thermal_cpufreq_is_init = 0;
+
+
+static int cpu_has_cpufreq(unsigned int cpu)
+{
+       struct cpufreq_policy policy;
+       if (!acpi_thermal_cpufreq_is_init)
+               return -ENODEV;
+       if (!cpufreq_get_policy(&policy, cpu))
+               return -ENODEV;
+       return 0;
+}
+
+
+static int acpi_thermal_cpufreq_increase(unsigned int cpu)
+{
+       if (!cpu_has_cpufreq)
+               return -ENODEV;
+
+       if (cpufreq_thermal_reduction_pctg[cpu] < 60) {
+               cpufreq_thermal_reduction_pctg[cpu] += 20;
+               cpufreq_update_policy(cpu);
+               return 0;
+       }
+
+       return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
+{
+       if (!cpu_has_cpufreq)
+               return -ENODEV;
+
+       if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
+               cpufreq_thermal_reduction_pctg[cpu] -= 20;
+               cpufreq_update_policy(cpu);
+               return 0;
+       }
+
+       return -ERANGE;
+}
+
+
+static int acpi_thermal_cpufreq_notifier(
+       struct notifier_block *nb,
+       unsigned long event,
+       void *data)
+{
+       struct cpufreq_policy *policy = data;
+       unsigned long max_freq = 0;
+
+       if (event != CPUFREQ_ADJUST)
+               goto out;
+
+       max_freq = (policy->cpuinfo.max_freq * (100 - cpufreq_thermal_reduction_pctg[policy->cpu])) / 100;
+
+       cpufreq_verify_within_limits(policy, 0, max_freq);
+
+ out:
+       return 0;
+}
+
+
+static struct notifier_block acpi_thermal_cpufreq_notifier_block = {
+       .notifier_call = acpi_thermal_cpufreq_notifier,
+};
+
+
+static void acpi_thermal_cpufreq_init(void) {
+       int i;
+
+       for (i=0; i<NR_CPUS; i++)
+               cpufreq_thermal_reduction_pctg[i] = 0;
+
+       i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+       if (!i)
+               acpi_thermal_cpufreq_is_init = 1;
+}
+
+static void acpi_thermal_cpufreq_exit(void) {
+       if (acpi_thermal_cpufreq_is_init)
+               cpufreq_unregister_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
+       acpi_thermal_cpufreq_is_init = 0;
+}
+
+#else /* ! CONFIG_CPU_FREQ */
+
+static void acpi_thermal_cpufreq_init(void) { return; }
+static void acpi_thermal_cpufreq_exit(void) { return; }
+static int acpi_thermal_cpufreq_increase(unsigned int cpu) { return -ENODEV; }
+static int acpi_thermal_cpufreq_decrease(unsigned int cpu) { return -ENODEV; }
+
+
+#endif
+
+
 int
 acpi_processor_set_thermal_limit (
        acpi_handle             handle,
@@ -1099,7 +1697,6 @@ acpi_processor_set_thermal_limit (
        int                     result = 0;
        struct acpi_processor   *pr = NULL;
        struct acpi_device      *device = NULL;
-       int                     px = 0;
        int                     tx = 0;
 
        ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
@@ -1116,12 +1713,7 @@ acpi_processor_set_thermal_limit (
        if (!pr)
                return_VALUE(-ENODEV);
 
-       if (!pr->flags.limit)
-               return_VALUE(-ENODEV);
-
        /* Thermal limits are always relative to the current Px/Tx state. */
-       if (pr->flags.performance)
-               pr->limit.thermal.px = pr->performance->state;
        if (pr->flags.throttling)
                pr->limit.thermal.tx = pr->throttling.state;
 
@@ -1130,26 +1722,27 @@ acpi_processor_set_thermal_limit (
         * performance state.
         */
 
-       px = pr->limit.thermal.px;
        tx = pr->limit.thermal.tx;
 
        switch (type) {
 
        case ACPI_PROCESSOR_LIMIT_NONE:
-               px = 0;
+               do {
+                       result = acpi_thermal_cpufreq_decrease(pr->id);
+               } while (!result);
                tx = 0;
                break;
 
        case ACPI_PROCESSOR_LIMIT_INCREMENT:
-               if (pr->flags.performance) {
-                       if (px == (pr->performance->state_count - 1))
-                               ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+               /* if going up: P-states first, T-states later */
+
+               result = acpi_thermal_cpufreq_increase(pr->id);
+               if (!result)
+                       goto end;
+               else if (result == -ERANGE)
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
                                        "At maximum performance state\n"));
-                       else {
-                               px++;
-                               goto end;
-                       }
-               }
+
                if (pr->flags.throttling) {
                        if (tx == (pr->throttling.state_count - 1))
                                ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
@@ -1160,37 +1753,41 @@ acpi_processor_set_thermal_limit (
                break;
 
        case ACPI_PROCESSOR_LIMIT_DECREMENT:
-               if (pr->flags.performance) {
-                       if (px == pr->performance_platform_limit)
-                               ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-                                       "At minimum performance state\n"));
-                       else  {
-                               px--;
-                               goto end;
-                       }
-               }
+               /* if going down: T-states first, P-states later */
+
                if (pr->flags.throttling) {
                        if (tx == 0)
                                ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
                                        "At minimum throttling state\n"));
-                       else
+                       else {
                                tx--;
+                               goto end;
+                       }
                }
+
+               result = acpi_thermal_cpufreq_decrease(pr->id);
+               if (result == -ERANGE)
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+                                       "At minimum performance state\n"));
+
                break;
        }
 
 end:
-       pr->limit.thermal.px = px;
-       pr->limit.thermal.tx = tx;
+       if (pr->flags.throttling) {
+               pr->limit.thermal.px = 0;
+               pr->limit.thermal.tx = tx;
 
-       result = acpi_processor_apply_limit(pr);
-       if (result)
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-                       "Unable to set thermal limit\n"));
+               result = acpi_processor_apply_limit(pr);
+               if (result)
+                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+                                         "Unable to set thermal limit\n"));
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
-               pr->limit.thermal.px,
-               pr->limit.thermal.tx));
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
+                                 pr->limit.thermal.px,
+                                 pr->limit.thermal.tx));
+       } else
+               result = 0;
 
        return_VALUE(result);
 }
@@ -1205,7 +1802,7 @@ acpi_processor_get_limit_info (
        if (!pr)
                return_VALUE(-EINVAL);
 
-       if (pr->flags.performance || pr->flags.throttling)
+       if (pr->flags.throttling)
                pr->flags.limit = 1;
 
        return_VALUE(0);
@@ -1232,14 +1829,12 @@ static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
                        "bus mastering control:   %s\n"
                        "power management:        %s\n"
                        "throttling control:      %s\n"
-                       "performance management:  %s\n"
                        "limit interface:         %s\n",
                        pr->id,
                        pr->acpi_id,
                        pr->flags.bm_control ? "yes" : "no",
                        pr->flags.power ? "yes" : "no",
                        pr->flags.throttling ? "yes" : "no",
-                       pr->flags.performance ? "yes" : "no",
                        pr->flags.limit ? "yes" : "no");
 
 end:
@@ -1396,11 +1991,9 @@ static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
        }
 
        seq_printf(seq, "active limit:            P%d:T%d\n"
-                       "platform limit:          P%d:T0\n"
                        "user limit:              P%d:T%d\n"
                        "thermal limit:           P%d:T%d\n",
                        pr->limit.state.px, pr->limit.state.tx,
-                       pr->flags.performance?pr->performance_platform_limit:0,
                        pr->limit.user.px, pr->limit.user.tx,
                        pr->limit.thermal.px, pr->limit.thermal.tx);
 
@@ -1447,15 +2040,6 @@ acpi_processor_write_limit (
                return_VALUE(-EINVAL);
        }
 
-       if (pr->flags.performance) {
-               if ((px < pr->performance_platform_limit) 
-                       || (px > (pr->performance->state_count - 1))) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid px\n"));
-                       return_VALUE(-EINVAL);
-               }
-               pr->limit.user.px = px;
-       }
-
        if (pr->flags.throttling) {
                if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) {
                        ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n"));
@@ -1635,9 +2219,9 @@ acpi_processor_get_info (
        }
 
        acpi_processor_get_power_info(pr);
-       pr->flags.performance = 0;
-       pr->performance_platform_limit = 0;
-       acpi_processor_get_platform_limit(pr);
+#ifdef CONFIG_CPU_FREQ
+       acpi_processor_ppc_has_changed(pr);
+#endif
        acpi_processor_get_throttling_info(pr);
        acpi_processor_get_limit_info(pr);
 
@@ -1651,7 +2235,6 @@ acpi_processor_notify (
        u32                     event,
        void                    *data)
 {
-       int                     result = 0;
        struct acpi_processor   *pr = (struct acpi_processor *) data;
        struct acpi_device      *device = NULL;
 
@@ -1665,9 +2248,7 @@ acpi_processor_notify (
 
        switch (event) {
        case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
-               result = acpi_processor_get_platform_limit(pr);
-               if (!result)
-                       acpi_processor_apply_limit(pr);
+               acpi_processor_ppc_has_changed(pr);
                acpi_bus_generate_event(device, event, 
                        pr->performance_platform_limit);
                break;
@@ -1813,6 +2394,10 @@ acpi_processor_init (void)
                return_VALUE(-ENODEV);
        }
 
+       acpi_thermal_cpufreq_init();
+
+       acpi_processor_ppc_init();
+
        return_VALUE(0);
 }
 
@@ -1822,6 +2407,10 @@ acpi_processor_exit (void)
 {
        ACPI_FUNCTION_TRACE("acpi_processor_exit");
 
+       acpi_processor_ppc_exit();
+
+       acpi_thermal_cpufreq_exit();
+
        acpi_bus_unregister_driver(&acpi_processor_driver);
 
        remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
index e997203..2583a0f 100644 (file)
@@ -302,13 +302,14 @@ acpi_table_parse_madt_family (
        enum acpi_table_id      id,
        unsigned long           madt_size,
        int                     entry_id,
-       acpi_madt_entry_handler handler)
+       acpi_madt_entry_handler handler,
+       unsigned int            max_entries)
 {
        void                    *madt = NULL;
-       acpi_table_entry_header *entry = NULL;
-       unsigned long           count = 0;
-       unsigned long           madt_end = 0;
-       unsigned int                    i = 0;
+       acpi_table_entry_header *entry;
+       unsigned int            count = 0;
+       unsigned long           madt_end;
+       unsigned int            i;
 
        if (!handler)
                return -EINVAL;
@@ -342,13 +343,18 @@ acpi_table_parse_madt_family (
                ((unsigned long) madt + madt_size);
 
        while (((unsigned long) entry) < madt_end) {
-               if (entry->type == entry_id) {
-                       count++;
+               if (entry->type == entry_id &&
+                   (!max_entries || count++ < max_entries))
                        handler(entry);
-               }
+
                entry = (acpi_table_entry_header *)
                        ((unsigned long) entry + entry->length);
        }
+       if (max_entries && count > max_entries) {
+               printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of "
+                      "%i found\n", acpi_table_signatures[id], entry_id,
+                      count - max_entries, count);
+       }
 
        return count;
 }
@@ -357,10 +363,11 @@ acpi_table_parse_madt_family (
 int __init
 acpi_table_parse_madt (
        enum acpi_madt_entry_id id,
-       acpi_madt_entry_handler handler)
+       acpi_madt_entry_handler handler,
+       unsigned int max_entries)
 {
        return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt),
-                                           id, handler);
+                                           id, handler, max_entries);
 }
 
 
@@ -585,4 +592,3 @@ acpi_table_init (void)
 
        return 0;
 }
-
index e7063cc..245685a 100644 (file)
@@ -55,8 +55,8 @@ MODULE_LICENSE("GPL");
 
 /* Toshiba ACPI method paths */
 #define METHOD_LCD_BRIGHTNESS  "\\_SB_.PCI0.VGA_.LCD_._BCM"
-#define METHOD_HCI_1          "\\_SB_.VALD.GHCI"
-#define METHOD_HCI_2          "\\_SB_.VALZ.GHCI"
+#define METHOD_HCI_1           "\\_SB_.VALD.GHCI"
+#define METHOD_HCI_2           "\\_SB_.VALZ.GHCI"
 #define METHOD_VIDEO_OUT       "\\_SB_.VALX.DSSX"
 
 /* Toshiba HCI interface definitions
@@ -170,7 +170,7 @@ read_acpi_int(const char* methodName, int* pVal)
 }
 #endif
 
-static const char*            method_hci /*= 0*/;
+static const char*             method_hci /*= 0*/;
 
 /* Perform a raw HCI call.  Here we don't care about input or output buffer
  * format.
@@ -233,7 +233,7 @@ hci_read1(u32 reg, u32* out1, u32* result)
        return status;
 }
 
-static struct proc_dir_entry* toshiba_proc_dir /*= 0*/;
+static struct proc_dir_entry*  toshiba_proc_dir /*= 0*/;
 static int                     force_fan;
 static int                     last_key_event;
 static int                     key_event_valid;
@@ -350,7 +350,7 @@ write_video(const char* buffer, unsigned long count)
         *  NOTE: to keep scanning simple, invalid fields are ignored
         */
        while (remain) {
-               if (snscanf(buffer, remain, " lcd_out : %i", &value) == 1)
+               if (snscanf(buffer, remain, " lcd_out : %i", &value) == 1)
                        lcd_out = value & 1;
                else if (snscanf(buffer, remain, " crt_out : %i", &value) == 1)
                        crt_out = value & 1;
index 9f93e1d..aa1cbe3 100644 (file)
@@ -255,7 +255,7 @@ static void atmtcp_c_close(struct atm_vcc *vcc)
        dev_data = PRIV(atmtcp_dev);
        dev_data->vcc = NULL;
        if (dev_data->persist) return;
-       PRIV(atmtcp_dev) = NULL;
+       atmtcp_dev->dev_data = NULL;
        kfree(dev_data);
        shutdown_atm_dev(atmtcp_dev);
        vcc->dev_data = NULL;
@@ -380,7 +380,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result)
        }
        dev->ci_range.vpi_bits = MAX_VPI_BITS;
        dev->ci_range.vci_bits = MAX_VCI_BITS;
-       PRIV(dev) = dev_data;
+       dev->dev_data = dev_data;
        PRIV(dev)->vcc = NULL;
        PRIV(dev)->persist = persist;
        if (result) *result = dev;
index a758c22..b51aa87 100644 (file)
@@ -664,8 +664,8 @@ alloc_scq(struct idt77252_dev *card, int class)
        skb_queue_head_init(&scq->transmit);
        skb_queue_head_init(&scq->pending);
 
-       TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08x\n",
-                scq->base, scq->next, scq->last, scq->paddr);
+       TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08llx\n",
+                scq->base, scq->next, scq->last, (unsigned long long)scq->paddr);
 
        return scq;
 }
index 4c7f389..28982a1 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 
-#define DEBUG
+#undef DEBUG
 
 #include <linux/device.h>
 #include <linux/module.h>
index d4f5086..74aa58b 100644 (file)
 #include <linux/completion.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "Compaq CISS Driver (v 2.5.0)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,5,0)
+#define DRIVER_NAME "Compaq CISS Driver (v 2.6.0)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,0)
 
 /* Embedded module documentation macros - see modules.h */
-MODULE_AUTHOR("Charles M. White III - Compaq Computer Corporation");
-MODULE_DESCRIPTION("Driver for Compaq Smart Array Controller 5xxx v. 2.5.0");
+MODULE_AUTHOR("Hewlett-Packard Company");
+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.0");
+MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
+                       " SA6i");
 MODULE_LICENSE("GPL");
 
 #include "cciss_cmd.h"
@@ -75,6 +77,8 @@ const struct pci_device_id cciss_pci_device_id[] = {
                0x0E11, 0x409C, 0, 0, 0},
        { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
                0x0E11, 0x409D, 0, 0, 0},
+       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+               0x0E11, 0x4091, 0, 0, 0},
        {0,}
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -94,6 +98,7 @@ static struct board_type products[] = {
        { 0x409B0E11, "Smart Array 642", &SA5_access},
        { 0x409C0E11, "Smart Array 6400", &SA5_access},
        { 0x409D0E11, "Smart Array 6400 EM", &SA5_access},
+       { 0x40910E11, "Smart Array 6i", &SA5_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
@@ -103,7 +108,7 @@ static struct board_type products[] = {
 /*define how many times we will try a command because of bus resets */
 #define MAX_CMD_RETRIES 3
 
-#define READ_AHEAD      128
+#define READ_AHEAD      256
 #define NR_CMDS                 384 /* #commands that can be outstanding */
 #define MAX_CTLR 8
 
@@ -151,6 +156,11 @@ static struct block_device_operations cciss_fops  = {
 /*
  * Report information about this controller.
  */
+#define ENG_GIG 1048576000
+#define ENG_GIG_FACTOR (ENG_GIG/512)
+#define RAID_UNKNOWN 6
+static const char *raid_label[] = {"0","4","1(0+1)","5","5+1","ADG",
+                                          "UNKNOWN"};
 #ifdef CONFIG_PROC_FS
 
 static struct proc_dir_entry *proc_cciss;
@@ -163,49 +173,80 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
         int size, i, ctlr;
         ctlr_info_t *h = (ctlr_info_t*)data;
         drive_info_struct *drv;
+       unsigned long flags;
+       unsigned int vol_sz, vol_sz_frac;
 
         ctlr = h->ctlr;
-        size = sprintf(buffer, "%s:  Compaq %s Controller\n"
-                "       Board ID: 0x%08lx\n"
-               "       Firmware Version: %c%c%c%c\n"
-                "       Memory Address: 0x%08lx\n"
-                "       IRQ: %d\n"
-                "       Logical drives: %d\n"
-               "       Highest Logical Volume ID: %d\n"
-                "       Current Q depth: %d\n"
-                "       Max Q depth since init: %d\n"
-               "       Max # commands on controller since init: %d\n"
-               "       Max SG entries since init: %d\n\n",
+
+       /* prevent displaying bogus info during configuration
+        * or deconfiguration of a logical volume
+        */
+       spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+       if (h->busy_configuring) {
+               spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+       return -EBUSY;
+       }
+       h->busy_configuring = 1;
+       spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+
+        size = sprintf(buffer, "%s: HP %s Controller\n"
+               "Board ID: 0x%08lx\n"
+               "Firmware Version: %c%c%c%c\n"
+               "IRQ: %d\n"
+               "Logical drives: %d\n"
+               "Current Q depth: %d\n"
+               "Current # commands on controller: %d\n"
+               "Max Q depth since init: %d\n"
+               "Max # commands on controller since init: %d\n"
+               "Max SG entries since init: %d\n\n",
                 h->devname,
                 h->product_name,
                 (unsigned long)h->board_id,
                h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3],
-                (unsigned long)h->vaddr,
                 (unsigned int)h->intr,
                 h->num_luns, 
-                h->highest_lun, 
-                h->Qdepth, h->maxQsinceinit, h->max_outstanding, h->maxSG);
+               h->Qdepth, h->commands_outstanding,
+               h->maxQsinceinit, h->max_outstanding, h->maxSG);
 
         pos += size; len += size;
        cciss_proc_tape_report(ctlr, buffer, &pos, &len);
        for(i=0; i<h->highest_lun; i++) {
+               sector_t tmp;
+
                 drv = &h->drv[i];
                if (drv->block_size == 0)
                        continue;
-                size = sprintf(buffer+len, "cciss/c%dd%d: blksz=%d nr_blocks=%llu\n",
-                                ctlr, i, drv->block_size, (unsigned long long)drv->nr_blocks);
+               vol_sz = drv->nr_blocks;
+               sector_div(vol_sz, ENG_GIG_FACTOR);
+
+               /*
+                * Awkwardly do this:
+                * vol_sz_frac =
+                *     (drv->nr_blocks%ENG_GIG_FACTOR)*100/ENG_GIG_FACTOR;
+                */
+               tmp = drv->nr_blocks;
+               vol_sz_frac = sector_div(tmp, ENG_GIG_FACTOR);
+
+               /* Now, vol_sz_frac = (drv->nr_blocks%ENG_GIG_FACTOR) */
+
+               vol_sz_frac *= 100;
+               sector_div(vol_sz_frac, ENG_GIG_FACTOR);
+
+               if (drv->raid_level > 5)
+                       drv->raid_level = RAID_UNKNOWN;
+               size = sprintf(buffer+len, "cciss/c%dd%d:"
+                               "\t%4d.%02dGB\tRAID %s\n",
+                               ctlr, i, vol_sz,vol_sz_frac,
+                               raid_label[drv->raid_level]);
                 pos += size; len += size;
         }
 
-       size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n",
-                        h->nr_allocs, h->nr_frees);
-        pos += size; len += size;
-
         *eof = 1;
         *start = buffer+offset;
         len -= offset;
         if (len>length)
                 len = length;
+       h->busy_configuring = 0;
         return len;
 }
 
@@ -1304,7 +1345,7 @@ cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
                *total_size = 0;
                *block_size = BLOCK_SIZE;
        }
-       printk(KERN_INFO "      blocks= %d block_size= %d\n",
+       printk(KERN_INFO "      blocks= %u block_size= %d\n",
                *total_size, *block_size);
        return;
 }
@@ -1978,7 +2019,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
 
 
        /* Is this interrupt for us? */
-       if ( h->access.intr_pending(h) == 0)
+       if (( h->access.intr_pending(h) == 0) || (h->interrupts_enabled == 0))
                return IRQ_NONE;
 
        /*
@@ -2078,18 +2119,61 @@ static void release_io_mem(ctlr_info_t *c)
        c->io_mem_addr = 0;
        c->io_mem_length = 0;
 }
+
+static int find_PCI_BAR_index(struct pci_dev *pdev,
+                               unsigned long pci_bar_addr)
+{
+       int i, offset, mem_type, bar_type;
+       if (pci_bar_addr == PCI_BASE_ADDRESS_0) /* looking for BAR zero? */
+               return 0;
+       offset = 0;
+       for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
+               bar_type = pci_resource_flags(pdev, i) &
+                       PCI_BASE_ADDRESS_SPACE;
+               if (bar_type == PCI_BASE_ADDRESS_SPACE_IO)
+                       offset += 4;
+               else {
+                       mem_type = pci_resource_flags(pdev, i) &
+                               PCI_BASE_ADDRESS_MEM_TYPE_MASK;
+                       switch (mem_type) {
+                               case PCI_BASE_ADDRESS_MEM_TYPE_32:
+                               case PCI_BASE_ADDRESS_MEM_TYPE_1M:
+                                       offset += 4; /* 32 bit */
+                                       break;
+                               case PCI_BASE_ADDRESS_MEM_TYPE_64:
+                                       offset += 8;
+                                       break;
+                               default: /* reserved in PCI 2.2 */
+                                       printk(KERN_WARNING "Base address is invalid\n");
+                                       return -1;
+                               break;
+                       }
+               }
+               if (offset == pci_bar_addr - PCI_BASE_ADDRESS_0)
+                       return i+1;
+       }
+       return -1;
+}
+
 static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
-       ushort vendor_id, device_id, command;
-       unchar cache_line_size, latency_timer;
-       unchar irq, revision;
-       uint addr[6];
+       ushort subsystem_vendor_id, subsystem_device_id, command;
+       unchar irq = pdev->irq;
        __u32 board_id, scratchpad = 0;
-       int cfg_offset;
-       int cfg_base_addr;
-       int cfg_base_addr_index;
+       __u64 cfg_offset;
+       __u32 cfg_base_addr;
+       __u64 cfg_base_addr_index;
        int i;
 
+       /* check to see if controller has been disabled */
+       /* BEFORE trying to enable it */
+       (void) pci_read_config_word(pdev, PCI_COMMAND,&command);
+       if(!(command & 0x02))
+       {
+               printk(KERN_WARNING "cciss: controller appears to be disabled\n");
+               return(-1);
+       }
+
        if (pci_enable_device(pdev))
        {
                printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
@@ -2101,38 +2185,19 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
                return(-1);
        }
 
-       vendor_id = pdev->vendor;
-       device_id = pdev->device;
-       irq = pdev->irq;
-
-       for(i=0; i<6; i++)
-               addr[i] = pdev->resource[i].start;
-
-       (void) pci_read_config_word(pdev, PCI_COMMAND,&command);
-       (void) pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
-       (void) pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,
-                                               &cache_line_size);
-       (void) pci_read_config_byte(pdev, PCI_LATENCY_TIMER,
-                                               &latency_timer);
-       (void) pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID, 
-                                               &board_id);
-
-       /* check to see if controller has been disabled */
-       if(!(command & 0x02))
-       {
-               printk(KERN_WARNING "cciss: controller appears to be disabled\n");
-               return(-1);
-       }
+       subsystem_vendor_id = pdev->subsystem_vendor;
+       subsystem_device_id = pdev->subsystem_device;
+       board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
+                                       subsystem_vendor_id);
 
        /* search for our IO range so we can protect it */
-       for(i=0; i<6; i++)
+       for(i=0; i<DEVICE_COUNT_RESOURCE; i++)
        {
                /* is this an IO range */ 
-               if( pdev->resource[i].flags & 0x01 )
-               {
-                       c->io_mem_addr = pdev->resource[i].start;
-                       c->io_mem_length = pdev->resource[i].end -
-                               pdev->resource[i].start +1; 
+               if( pci_resource_flags(pdev, i) & 0x01 ) {
+                       c->io_mem_addr = pci_resource_start(pdev, i);
+                       c->io_mem_length = pci_resource_end(pdev, i) -
+                               pci_resource_start(pdev, i) +1;
 #ifdef CCISS_DEBUG
                        printk("IO value found base_addr[%d] %lx %lx\n", i,
                                c->io_mem_addr, c->io_mem_length);
@@ -2151,15 +2216,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        }
 
 #ifdef CCISS_DEBUG
-       printk("vendor_id = %x\n", vendor_id);
-       printk("device_id = %x\n", device_id);
        printk("command = %x\n", command);
-       for(i=0; i<6; i++)
-               printk("addr[%d] = %x\n", i, addr[i]);
-       printk("revision = %x\n", revision);
        printk("irq = %x\n", irq);
-       printk("cache_line_size = %x\n", cache_line_size);
-       printk("latency_timer = %x\n", latency_timer);
        printk("board_id = %x\n", board_id);
 #endif /* CCISS_DEBUG */ 
 
@@ -2170,7 +2228,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
          *   table
         */
 
-       c->paddr = addr[0] ; /* addressing mode bits already removed */
+       c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */
 #ifdef CCISS_DEBUG
        printk("address 0 = %x\n", c->paddr);
 #endif /* CCISS_DEBUG */ 
@@ -2192,22 +2250,27 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 
        /* get the address index number */
        cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET);
-       /* I am not prepared to deal with a 64 bit address value */
-       cfg_base_addr &= 0xffff;
+       cfg_base_addr &= (__u32) 0x0000ffff;
 #ifdef CCISS_DEBUG
        printk("cfg base address = %x\n", cfg_base_addr);
 #endif /* CCISS_DEBUG */
-       cfg_base_addr_index = (cfg_base_addr  - PCI_BASE_ADDRESS_0)/4;
+       cfg_base_addr_index =
+               find_PCI_BAR_index(pdev, cfg_base_addr);
 #ifdef CCISS_DEBUG
        printk("cfg base address index = %x\n", cfg_base_addr_index);
 #endif /* CCISS_DEBUG */
+       if (cfg_base_addr_index == -1) {
+               printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n");
+               release_io_mem(c);
+               return -1;
+       }
 
        cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET);
 #ifdef CCISS_DEBUG
        printk("cfg offset = %x\n", cfg_offset);
 #endif /* CCISS_DEBUG */
        c->cfgtable = (CfgTable_struct *) 
-               remap_pci_mem((addr[cfg_base_addr_index] & 0xfffffff0)
+               remap_pci_mem(pci_resource_start(pdev, cfg_base_addr_index)
                                + cfg_offset, sizeof(CfgTable_struct));
        c->board_id = board_id;
 
@@ -2236,6 +2299,17 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
                printk("Does not appear to be a valid CISS config table\n");
                return -1;
        }
+
+#ifdef CONFIG_X86
+{
+       /* Need to enable prefetch in the SCSI core for 6400 in x86 */
+       __u32 prefetch;
+       prefetch = readl(&(c->cfgtable->SCSI_Prefetch));
+       prefetch |= 0x100;
+       writel(prefetch, &(c->cfgtable->SCSI_Prefetch));
+}
+#endif
+
 #ifdef CCISS_DEBUG
        printk("Trying to put board into Simple mode\n");
 #endif /* CCISS_DEBUG */ 
@@ -2501,6 +2575,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        if (!q)
                goto clean4;
 
+       q->backing_dev_info.ra_pages = READ_AHEAD;
        hba[i]->queue = q;
        q->queuedata = hba[i];
 
@@ -2610,7 +2685,6 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
        pci_set_drvdata(pdev, NULL);
        iounmap((void*)hba[i]->vaddr);
        cciss_unregister_scsi(i);  /* unhook from SCSI subsystem */
-       blk_cleanup_queue(hba[i]->queue);
        unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
        remove_proc_entry(hba[i]->devname, proc_cciss); 
        
@@ -2621,6 +2695,7 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
                        del_gendisk(disk);
        }
 
+       blk_cleanup_queue(hba[i]->queue);
        pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
                            hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
        pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
@@ -2646,7 +2721,7 @@ int __init cciss_init(void)
        printk(KERN_INFO DRIVER_NAME "\n");
 
        /* Register for our PCI devices */
-       return pci_register_driver(&cciss_pci_driver);
+       return pci_module_init(&cciss_pci_driver);
 }
 
 static int __init init_cciss_module(void)
index f1bb1e9..825855c 100644 (file)
@@ -32,6 +32,7 @@ typedef struct _drive_info_struct
        int     heads;
        int     sectors;
        int     cylinders;
+       int     raid_level;
 } drive_info_struct;
 
 struct ctlr_info 
@@ -42,13 +43,13 @@ struct ctlr_info
        char    firm_ver[4]; // Firmware version 
        struct pci_dev *pdev;
        __u32   board_id;
-       ulong   vaddr;
-       __u32   paddr;  
+       unsigned long vaddr;
+       unsigned long paddr;
        unsigned long io_mem_addr;
        unsigned long io_mem_length;
        CfgTable_struct *cfgtable;
        int     intr;
-
+       int     interrupts_enabled;
        int     max_commands;
        int     commands_outstanding;
        int     max_outstanding; /* Debug */ 
@@ -78,6 +79,7 @@ struct ctlr_info
         unsigned long                  *cmd_pool_bits;
        int                     nr_allocs;
        int                     nr_frees; 
+       int                     busy_configuring;
 
        // Disk structures we need to pass back
        struct gendisk   *gendisk[NWD];
@@ -134,9 +136,11 @@ static void SA5_intr_mask(ctlr_info_t *h, unsigned long val)
 {
        if (val) 
        { /* Turn interrupts on */
+               h->interrupts_enabled = 1;
                writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
        } else /* Turn them off */
        {
+               h->interrupts_enabled = 0;
                writel( SA5_INTR_OFF, 
                        h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
        }
@@ -150,9 +154,11 @@ static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val)
 {
         if (val)
         { /* Turn interrupts on */
+               h->interrupts_enabled = 1;
                 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
         } else /* Turn them off */
         {
+               h->interrupts_enabled = 0;
                 writel( SA5B_INTR_OFF,
                         h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
         }
index 568c74e..a88a888 100644 (file)
@@ -265,6 +265,7 @@ typedef struct _CfgTable_struct {
   DWORD            Reserved; 
   BYTE             ServerName[16];
   DWORD            HeartBeat;
+  DWORD            SCSI_Prefetch;
 } CfgTable_struct;
 #pragma pack()  
 #endif // CCISS_CMD_H
index bd10b21..a6b4e85 100644 (file)
@@ -223,7 +223,6 @@ struct gendisk *get_gendisk(dev_t dev, int *part)
        struct kobject *kobj = kobj_lookup(bdev_map, dev, part);
        return  kobj ? to_disk(kobj) : NULL;
 }
-EXPORT_SYMBOL(get_gendisk);
 
 #ifdef CONFIG_PROC_FS
 /* iterator */
diff --git a/drivers/block/paride/Transition-notes b/drivers/block/paride/Transition-notes
new file mode 100644 (file)
index 0000000..7037490
--- /dev/null
@@ -0,0 +1,128 @@
+Lemma 1:
+       If ps_tq is scheduled, ps_tq_active is 1.  ps_tq_int() can be called
+       only when ps_tq_active is 1.
+Proof: All assignments to ps_tq_active and all scheduling of ps_tq happen
+       under ps_spinlock.  There are three places where that can happen:
+       one in ps_set_intr() (A) and two in ps_tq_int() (B and C).
+       Consider the sequnce of these events.  A can not be preceded by
+       anything except B, since it is under if (!ps_tq_active) under
+       ps_spinlock.  C is always preceded by B, since we can't reach it
+       other than through B and we don't drop ps_spinlock between them.
+       IOW, the sequence is A?(BA|BC|B)*.  OTOH, number of B can not exceed
+       the sum of numbers of A and C, since each call of ps_tq_int() is
+       the result of ps_tq execution.  Therefore, the sequence starts with
+       A and each B is preceded by either A or C.  Moments when we enter
+       ps_tq_int() are sandwiched between {A,C} and B in that sequence,
+       since at any time number of B can not exceed the number of these
+       moments which, in turn, can not exceed the number of A and C.
+       In other words, the sequence of events is (A or C set ps_tq_active to
+       1 and schedule ps_tq, ps_tq is executed, ps_tq_int() is entered,
+       B resets ps_tq_active)*.
+
+
+consider the following area:
+       * in do_pd_request1(): to calls of pi_do_claimed() and return in
+         case when pd_req is NULL.
+       * in next_request(): to call of do_pd_request1()
+       * in do_pd_read(): to call of ps_set_intr()
+       * in do_pd_read_start(): to calls of pi_do_claimed(), next_request()
+and ps_set_intr()
+       * in do_pd_read_drq(): to calls of pi_do_claimed() and next_request()
+       * in do_pd_write(): to call of ps_set_intr()
+       * in do_pd_write_start(): to calls of pi_do_claimed(), next_request()
+and ps_set_intr()
+       * in do_pd_write_done(): to calls of pi_do_claimed() and next_request()
+       * in ps_set_intr(): to check for ps_tq_active and to scheduling
+         ps_tq if ps_tq_active was 0.
+       * in ps_tq_int(): from the moment when we get ps_spinlock() to the
+         return, call of con() or scheduling ps_tq.
+       * in pi_schedule_claimed() when called from pi_do_claimed() called from
+         pd.c, everything until returning 1 or setting or setting ->claim_cont
+         on the path that returns 0
+       * in pi_do_claimed() when called from pd.c, everything until the call
+         of pi_do_claimed() plus the everything until the call of cont() if
+         pi_do_claimed() has returned 1.
+       * in pi_wake_up() called for PIA that belongs to pd.c, everything from
+         the moment when pi_spinlock has been acquired.
+
+Lemma 2:
+       1) at any time at most one thread of execution can be in that area or
+       be preempted there.
+       2) When there is such a thread, pd_busy is set or pd_lock is held by
+       that thread.
+       3) When there is such a thread, ps_tq_active is 0 or ps_spinlock is
+       held by that thread.
+       4) When there is such a thread, all PIA belonging to pd.c have NULL
+       ->claim_cont or pi_spinlock is held by thread in question.
+
+Proof: consider the first moment when the above is not true.
+
+(1) can become not true if some thread enters that area while another is there.
+       a) do_pd_request1() can be called from next_request() or do_pd_request()
+          In the first case the thread was already in the area.  In the second,
+          the thread was holding pd_lock and found pd_busy not set, which would
+          mean that (2) was already not true.
+       b) ps_set_intr() and pi_schedule_claimed() can be called only from the
+          area.
+       c) pi_do_claimed() is called by pd.c only from the area.
+       d) ps_tq_int() can enter the area only when the thread is holding
+          ps_spinlock and ps_tq_active is 1 (due to Lemma 1).  It means that
+          (3) was already not true.
+       e) do_pd_{read,write}* could be called only from the area.  The only
+          case that needs consideration is call from pi_wake_up() and there
+          we would have to be called for the PIA that got ->claimed_cont
+          from pd.c.  That could happen only if pi_do_claimed() had been
+          called from pd.c for that PIA, which happens only for PIA belonging
+          to pd.c.
+       f) pi_wake_up() can enter the area only when the thread is holding
+          pi_spinlock and ->claimed_cont is non-NULL for PIA belonging to
+          pd.c.  It means that (4) was already not true.
+
+(2) can become not true only when pd_lock is released by the thread in question.
+       Indeed, pd_busy is reset only in the area and thread that resets
+       it is holding pd_lock.  The only place within the area where we
+       release pd_lock is in pd_next_buf() (called from within the area).
+       But that code does not reset pd_busy, so pd_busy would have to be
+       0 when pd_next_buf() had acquired pd_lock.  If it become 0 while
+       we were acquiring the lock, (1) would be already false, since
+       the thread that had reset it would be in the area simulateously.
+       If it was 0 before we tried to acquire pd_lock, (2) would be
+       already false.
+
+For similar reasons, (3) can become not true only when ps_spinlock is released
+by the thread in question.  However, all such places within the area are right
+after resetting ps_tq_active to 0.
+
+(4) is done the same way - all places where we release pi_spinlock within
+the area are either after resetting ->claimed_cont to NULL while holding
+pi_spinlock, or after not tocuhing ->claimed_cont since acquiring pi_spinlock
+also in the area.  The only place where ->claimed_cont is made non-NULL is
+in the area, under pi_spinlock and we do not release it until after leaving
+the area.
+
+QED.
+
+
+Corollary 1: ps_tq_active can be killed.  Indeed, the only place where we
+check its value is in ps_set_intr() and if it had been non-zero at that
+point, we would have violated either (2.1) (if it was set while ps_set_intr()
+was acquiring ps_spinlock) or (2.3) (if it was set when we started to
+acquire ps_spinlock).
+
+Corollary 2: ps_spinlock can be killed.  Indeed, Lemma 1 and Lemma 2 show
+that the only possible contention is between scheduling ps_tq followed by
+immediate release of spinlock and beginning of execution of ps_tq on
+another CPU.
+
+Corollary 3: assignment to pd_busy in do_pd_read_start() and do_pd_write_start()
+can be killed.  Indeed, we are not holding pd_lock and thus pd_busy is already
+1 here.
+
+Corollary 4: in ps_tq_int() uses of con can be replaced with uses of
+ps_continuation, since the latter is changed only from the area.
+We don't need to reset it to NULL, since we are guaranteed that there
+will be a call of ps_set_intr() before we look at ps_continuation again.
+We can remove the check for ps_continuation being NULL for the same
+reason - the value is guaranteed to be set by the last ps_set_intr() and
+we never pass it NULL.  Assignements in the beginning of ps_set_intr()
+can be taken to callers as long as they remain within the area.
index ff1e744..71646db 100644 (file)
@@ -228,7 +228,7 @@ static int bpck6_init_proto(PIA *pi)
 
        if (p) {
                memset(p, 0, sizeof(PPC));
-               pi->private = (int)p;
+               pi->private = (unsigned long)p;
                return 0;
        }
 
index 313ec47..56b3824 100644 (file)
@@ -261,7 +261,7 @@ static int frpw_test_proto( PIA *pi, char * scratch, int verbose )
        frpw_disconnect(pi);
 
         if (verbose)  {
-            printk("%s: frpw: port 0x%x, chip %d, mode %d, test=(%d,%d,%d)\n",
+            printk("%s: frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n",
                    pi->device,pi->port,(pi->private%2),pi->mode,e[0],e[1],r);
         }
 
index 0852e72..d95e4f8 100644 (file)
@@ -102,7 +102,7 @@ static void pi_wake_up(void *p)
 
 #endif
 
-void pi_do_claimed(PIA * pi, void (*cont) (void))
+int pi_schedule_claimed(PIA * pi, void (*cont) (void))
 {
 #ifdef CONFIG_PARPORT
        unsigned long flags;
@@ -111,12 +111,19 @@ void pi_do_claimed(PIA * pi, void (*cont) (void))
        if (pi->pardev && parport_claim(pi->pardev)) {
                pi->claim_cont = cont;
                spin_unlock_irqrestore(&pi_spinlock, flags);
-               return;
+               return 0;
        }
        pi->claimed = 1;
        spin_unlock_irqrestore(&pi_spinlock, flags);
 #endif
-       cont();
+       return 1;
+}
+EXPORT_SYMBOL(pi_schedule_claimed);
+
+void pi_do_claimed(PIA * pi, void (*cont) (void))
+{
+       if (pi_schedule_claimed(pi, cont))
+               cont();
 }
 
 EXPORT_SYMBOL(pi_do_claimed);
@@ -133,7 +140,7 @@ static void pi_claim(PIA * pi)
 #endif
 }
 
-static void pi_unclaim(PIA * pi)
+void pi_unclaim(PIA * pi)
 {
        pi->claimed = 0;
 #ifdef CONFIG_PARPORT
@@ -142,6 +149,8 @@ static void pi_unclaim(PIA * pi)
 #endif
 }
 
+EXPORT_SYMBOL(pi_unclaim);
+
 void pi_connect(PIA * pi)
 {
        pi_claim(pi);
index b6f6d60..46bd0a4 100644 (file)
@@ -45,7 +45,7 @@ struct pi_adapter  {
        int     saved_r0;            /* saved port state */
        int     saved_r2;            /* saved port state */
        int     reserved;            /* number of ports reserved */
-       int     private;             /* for protocol module */
+       unsigned long   private;     /* for protocol module */
 
        wait_queue_head_t parq;     /* semaphore for parport sharing */
        void    *pardev;             /* pointer to pardevice */
@@ -88,11 +88,14 @@ extern void pi_write_block(PIA *pi, char * buf, int count);
 
 extern void pi_read_block(PIA *pi, char * buf, int count);
 
+extern void pi_unclaim(PIA *pi);
+
 extern void pi_connect(PIA *pi);
 
 extern void pi_disconnect(PIA *pi);
 
 extern void pi_do_claimed(PIA *pi, void (*cont)(void));
+extern int pi_schedule_claimed(PIA *pi, void (*cont)(void));
 
 /* macros and functions exported to the protocol modules */
 
index 52005b0..0d2c19d 100644 (file)
@@ -138,7 +138,6 @@ static int drive2[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
 static int drive3[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
 
 static int (*drives[4])[8] = {&drive0, &drive1, &drive2, &drive3};
-static int pd_drive_count;
 
 enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
 
@@ -153,6 +152,8 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <asm/uaccess.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
 
 static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED;
 
@@ -188,7 +189,6 @@ MODULE_PARM(drive2, "1-8i");
 MODULE_PARM(drive3, "1-8i");
 
 #include "paride.h"
-#include "pseudo.h"
 
 #define PD_BITS    4
 
@@ -235,21 +235,6 @@ MODULE_PARM(drive3, "1-8i");
 #define IDE_IDENTIFY           0xec
 #define IDE_EJECT              0xed
 
-void pd_setup(char *str, int *ints);
-static int pd_open(struct inode *inode, struct file *file);
-static void do_pd_request(request_queue_t * q);
-static int pd_ioctl(struct inode *inode, struct file *file,
-                   unsigned int cmd, unsigned long arg);
-static int pd_release(struct inode *inode, struct file *file);
-static int pd_revalidate(struct gendisk *p);
-static int pd_detect(void);
-static void do_pd_read(void);
-static void do_pd_read_start(void);
-static void do_pd_write(void);
-static void do_pd_write_start(void);
-static void do_pd_read_drq(void);
-static void do_pd_write_done(void);
-
 #define PD_NAMELEN     8
 
 struct pd_unit {
@@ -266,153 +251,19 @@ struct pd_unit {
        int removable;          /* removable media device  ?  */
        int standby;
        int alt_geom;
-       int present;
        char name[PD_NAMELEN];  /* pda, pdb, etc ... */
        struct gendisk *gd;
 };
 
 struct pd_unit pd[PD_UNITS];
 
-static int pd_identify(struct pd_unit *disk);
-static void pd_media_check(struct pd_unit *disk);
-static void pd_doorlock(struct pd_unit *disk, int func);
-static int pd_check_media(struct gendisk *p);
-static void pd_eject(struct pd_unit *disk);
-
 static char pd_scratch[512];   /* scratch block buffer */
 
-/* the variables below are used mainly in the I/O request engine, which
-   processes only one request at a time.
-*/
-
-static struct pd_unit *pd_current; /* current request's drive */
-static int pd_retries = 0;     /* i/o error retry count */
-static int pd_busy = 0;                /* request being processed ? */
-static struct request *pd_req; /* current request */
-static int pd_block;           /* address of next requested block */
-static int pd_count;           /* number of blocks still to do */
-static int pd_run;             /* sectors in current cluster */
-static int pd_cmd;             /* current command READ/WRITE */
-static char *pd_buf;           /* buffer for request in progress */
-
-static DECLARE_WAIT_QUEUE_HEAD(pd_wait_open);
-
 static char *pd_errs[17] = { "ERR", "INDEX", "ECC", "DRQ", "SEEK", "WRERR",
        "READY", "BUSY", "AMNF", "TK0NF", "ABRT", "MCR",
        "IDNF", "MC", "UNC", "???", "TMO"
 };
 
-/* kernel glue structures */
-
-extern struct block_device_operations pd_fops;
-
-static struct block_device_operations pd_fops = {
-       .owner          = THIS_MODULE,
-       .open           = pd_open,
-       .release        = pd_release,
-       .ioctl          = pd_ioctl,
-       .media_changed  = pd_check_media,
-       .revalidate_disk= pd_revalidate
-};
-
-static void pd_init_units(void)
-{
-       int unit;
-
-       pd_drive_count = 0;
-       for (unit = 0; unit < PD_UNITS; unit++) {
-               int *parm = *drives[unit];
-               struct pd_unit *disk = pd + unit;
-               disk->pi = &disk->pia;
-               disk->access = 0;
-               disk->changed = 1;
-               disk->capacity = 0;
-               disk->drive = parm[D_SLV];
-               disk->present = 0;
-               snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a'+unit);
-               disk->alt_geom = parm[D_GEO];
-               disk->standby = parm[D_SBY];
-               if (parm[D_PRT])
-                       pd_drive_count++;
-       }
-}
-
-static int pd_open(struct inode *inode, struct file *file)
-{
-       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
-
-       disk->access++;
-
-       if (disk->removable) {
-               pd_media_check(disk);
-               pd_doorlock(disk, IDE_DOORLOCK);
-       }
-       return 0;
-}
-
-static int pd_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
-       struct hd_geometry *geo = (struct hd_geometry *) arg;
-       struct hd_geometry g;
-
-       switch (cmd) {
-       case CDROMEJECT:
-               if (disk->access == 1)
-                       pd_eject(disk);
-               return 0;
-       case HDIO_GETGEO:
-               if (disk->alt_geom) {
-                       g.heads = PD_LOG_HEADS;
-                       g.sectors = PD_LOG_SECTS;
-                       g.cylinders = disk->capacity / (g.heads * g.sectors);
-               } else {
-                       g.heads = disk->heads;
-                       g.sectors = disk->sectors;
-                       g.cylinders = disk->cylinders;
-               }
-               g.start = get_start_sect(inode->i_bdev);
-               if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
-                       return -EFAULT;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int pd_release(struct inode *inode, struct file *file)
-{
-       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
-
-       if (!--disk->access && disk->removable)
-               pd_doorlock(disk, IDE_DOORUNLOCK);
-
-       return 0;
-}
-
-static int pd_check_media(struct gendisk *p)
-{
-       struct pd_unit *disk = p->private_data;
-       int r;
-       if (!disk->removable)
-               return 0;
-       pd_media_check(disk);
-       r = disk->changed;
-       disk->changed = 0;
-       return r;
-}
-
-static int pd_revalidate(struct gendisk *p)
-{
-       struct pd_unit *disk = p->private_data;
-       if (pd_identify(disk))
-               set_capacity(p, disk->capacity);
-       else
-               set_capacity(p, 0);
-       return 0;
-}
-
 static inline int status_reg(struct pd_unit *disk)
 {
        return pi_read_regr(disk->pi, 1, 6);
@@ -453,11 +304,9 @@ static void pd_print_error(struct pd_unit *disk, char *msg, int status)
 
 static void pd_reset(struct pd_unit *disk)
 {                              /* called only for MASTER drive */
-       pi_connect(disk->pi);
        write_status(disk, 4);
        udelay(50);
        write_status(disk, 0);
-       pi_disconnect(disk->pi);
        udelay(250);
 }
 
@@ -514,6 +363,236 @@ static void pd_ide_command(struct pd_unit *disk, int func, int block, int count)
        pd_send_command(disk, count, s, h, c0, c1, func);
 }
 
+/* The i/o request engine */
+
+enum action {Fail = 0, Ok = 1, Hold, Wait};
+
+static struct request *pd_req; /* current request */
+static enum action (*phase)(void);
+
+static void run_fsm(void);
+
+static void ps_tq_int( void *data);
+
+static DECLARE_WORK(fsm_tq, ps_tq_int, NULL);
+
+static void schedule_fsm(void)
+{
+       if (!nice)
+               schedule_work(&fsm_tq);
+       else
+               schedule_delayed_work(&fsm_tq, nice-1);
+}
+
+static void ps_tq_int(void *data)
+{
+       run_fsm();
+}
+
+static enum action do_pd_io_start(void);
+static enum action pd_special(void);
+static enum action do_pd_read_start(void);
+static enum action do_pd_write_start(void);
+static enum action do_pd_read_drq(void);
+static enum action do_pd_write_done(void);
+
+static struct request_queue *pd_queue;
+static int pd_claimed;
+
+static struct pd_unit *pd_current; /* current request's drive */
+static PIA *pi_current; /* current request's PIA */
+
+static void run_fsm(void)
+{
+       while (1) {
+               enum action res;
+               unsigned long saved_flags;
+               int stop = 0;
+
+               if (!phase) {
+                       pd_current = pd_req->rq_disk->private_data;
+                       pi_current = pd_current->pi;
+                       phase = do_pd_io_start;
+               }
+
+               switch (pd_claimed) {
+                       case 0:
+                               pd_claimed = 1;
+                               if (!pi_schedule_claimed(pi_current, run_fsm))
+                                       return;
+                       case 1:
+                               pd_claimed = 2;
+                               pi_current->proto->connect(pi_current);
+               }
+
+               switch(res = phase()) {
+                       case Ok: case Fail:
+                               pi_disconnect(pi_current);
+                               pd_claimed = 0;
+                               phase = NULL;
+                               spin_lock_irqsave(&pd_lock, saved_flags);
+                               end_request(pd_req, res);
+                               pd_req = elv_next_request(pd_queue);
+                               if (!pd_req)
+                                       stop = 1;
+                               spin_unlock_irqrestore(&pd_lock, saved_flags);
+                               if (stop)
+                                       return;
+                       case Hold:
+                               schedule_fsm();
+                               return;
+                       case Wait:
+                               pi_disconnect(pi_current);
+                               pd_claimed = 0;
+               }
+       }
+}
+
+static int pd_retries = 0;     /* i/o error retry count */
+static int pd_block;           /* address of next requested block */
+static int pd_count;           /* number of blocks still to do */
+static int pd_run;             /* sectors in current cluster */
+static int pd_cmd;             /* current command READ/WRITE */
+static char *pd_buf;           /* buffer for request in progress */
+
+static enum action do_pd_io_start(void)
+{
+       if (pd_req->flags & REQ_SPECIAL) {
+               phase = pd_special;
+               return pd_special();
+       }
+
+       pd_cmd = rq_data_dir(pd_req);
+       if (pd_cmd == READ || pd_cmd == WRITE) {
+               pd_block = pd_req->sector;
+               pd_count = pd_req->current_nr_sectors;
+               if (pd_block + pd_count > get_capacity(pd_req->rq_disk))
+                       return Fail;
+               pd_run = pd_req->nr_sectors;
+               pd_buf = pd_req->buffer;
+               pd_retries = 0;
+               if (pd_cmd == READ)
+                       return do_pd_read_start();
+               else
+                       return do_pd_write_start();
+       }
+       return Fail;
+}
+
+static enum action pd_special(void)
+{
+       enum action (*func)(struct pd_unit *) = pd_req->special;
+       return func(pd_current);
+}
+
+static int pd_next_buf(void)
+{
+       unsigned long saved_flags;
+
+       pd_count--;
+       pd_run--;
+       pd_buf += 512;
+       pd_block++;
+       if (!pd_run)
+               return 1;
+       if (pd_count)
+               return 0;
+       spin_lock_irqsave(&pd_lock, saved_flags);
+       end_request(pd_req, 1);
+       pd_count = pd_req->current_nr_sectors;
+       pd_buf = pd_req->buffer;
+       spin_unlock_irqrestore(&pd_lock, saved_flags);
+       return 0;
+}
+
+static unsigned long pd_timeout;
+
+static enum action do_pd_read_start(void)
+{
+       if (pd_wait_for(pd_current, STAT_READY, "do_pd_read") & STAT_ERR) {
+               if (pd_retries < PD_MAX_RETRIES) {
+                       pd_retries++;
+                       return Wait;
+               }
+               return Fail;
+       }
+       pd_ide_command(pd_current, IDE_READ, pd_block, pd_run);
+       phase = do_pd_read_drq;
+       pd_timeout = jiffies + PD_TMO;
+       return Hold;
+}
+
+static enum action do_pd_write_start(void)
+{
+       if (pd_wait_for(pd_current, STAT_READY, "do_pd_write") & STAT_ERR) {
+               if (pd_retries < PD_MAX_RETRIES) {
+                       pd_retries++;
+                       return Wait;
+               }
+               return Fail;
+       }
+       pd_ide_command(pd_current, IDE_WRITE, pd_block, pd_run);
+       while (1) {
+               if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_write_drq") & STAT_ERR) {
+                       if (pd_retries < PD_MAX_RETRIES) {
+                               pd_retries++;
+                               return Wait;
+                       }
+                       return Fail;
+               }
+               pi_write_block(pd_current->pi, pd_buf, 512);
+               if (pd_next_buf())
+                       break;
+       }
+       phase = do_pd_write_done;
+       pd_timeout = jiffies + PD_TMO;
+       return Hold;
+}
+
+static inline int pd_ready(void)
+{
+       return !(status_reg(pd_current) & STAT_BUSY);
+}
+
+static enum action do_pd_read_drq(void)
+{
+       if (!pd_ready() && !time_after_eq(jiffies, pd_timeout))
+               return Hold;
+
+       while (1) {
+               if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_read_drq") & STAT_ERR) {
+                       if (pd_retries < PD_MAX_RETRIES) {
+                               pd_retries++;
+                               phase = do_pd_read_start;
+                               return Wait;
+                       }
+                       return Fail;
+               }
+               pi_read_block(pd_current->pi, pd_buf, 512);
+               if (pd_next_buf())
+                       break;
+       }
+       return Ok;
+}
+
+static enum action do_pd_write_done(void)
+{
+       if (!pd_ready() && !time_after_eq(jiffies, pd_timeout))
+               return Hold;
+
+       if (pd_wait_for(pd_current, STAT_READY, "do_pd_write_done") & STAT_ERR) {
+               if (pd_retries < PD_MAX_RETRIES) {
+                       pd_retries++;
+                       phase = do_pd_write_start;
+                       return Wait;
+               }
+               return Fail;
+       }
+       return Ok;
+}
+
+/* special io requests */
+
 /* According to the ATA standard, the default CHS geometry should be
    available following a reset.  Some Western Digital drives come up
    in a mode where only LBA addresses are accepted until the device
@@ -522,43 +601,45 @@ static void pd_ide_command(struct pd_unit *disk, int func, int block, int count)
 
 static void pd_init_dev_parms(struct pd_unit *disk)
 {
-       pi_connect(disk->pi);
        pd_wait_for(disk, 0, DBMSG("before init_dev_parms"));
        pd_send_command(disk, disk->sectors, 0, disk->heads - 1, 0, 0,
                        IDE_INIT_DEV_PARMS);
        udelay(300);
        pd_wait_for(disk, 0, "Initialise device parameters");
-       pi_disconnect(disk->pi);
 }
 
-static void pd_doorlock(struct pd_unit *disk, int func)
+static enum action pd_door_lock(struct pd_unit *disk)
+{
+       if (!(pd_wait_for(disk, STAT_READY, "Lock") & STAT_ERR)) {
+               pd_send_command(disk, 1, 0, 0, 0, 0, IDE_DOORLOCK);
+               pd_wait_for(disk, STAT_READY, "Lock done");
+       }
+       return Ok;
+}
+
+static enum action pd_door_unlock(struct pd_unit *disk)
 {
-       pi_connect(disk->pi);
        if (!(pd_wait_for(disk, STAT_READY, "Lock") & STAT_ERR)) {
-               pd_send_command(disk, 1, 0, 0, 0, 0, func);
+               pd_send_command(disk, 1, 0, 0, 0, 0, IDE_DOORUNLOCK);
                pd_wait_for(disk, STAT_READY, "Lock done");
        }
-       pi_disconnect(disk->pi);
+       return Ok;
 }
 
-static void pd_eject(struct pd_unit *disk)
+static enum action pd_eject(struct pd_unit *disk)
 {
-       pi_connect(disk->pi);
        pd_wait_for(disk, 0, DBMSG("before unlock on eject"));
        pd_send_command(disk, 1, 0, 0, 0, 0, IDE_DOORUNLOCK);
        pd_wait_for(disk, 0, DBMSG("after unlock on eject"));
        pd_wait_for(disk, 0, DBMSG("before eject"));
        pd_send_command(disk, 0, 0, 0, 0, 0, IDE_EJECT);
        pd_wait_for(disk, 0, DBMSG("after eject"));
-       pi_disconnect(disk->pi);
+       return Ok;
 }
 
-static void pd_media_check(struct pd_unit *disk)
+static enum action pd_media_check(struct pd_unit *disk)
 {
-       int r;
-
-       pi_connect(disk->pi);
-       r = pd_wait_for(disk, STAT_READY, DBMSG("before media_check"));
+       int r = pd_wait_for(disk, STAT_READY, DBMSG("before media_check"));
        if (!(r & STAT_ERR)) {
                pd_send_command(disk, 1, 1, 0, 0, 0, IDE_READ_VRFY);
                r = pd_wait_for(disk, STAT_READY, DBMSG("RDY after READ_VRFY"));
@@ -571,20 +652,17 @@ static void pd_media_check(struct pd_unit *disk)
                pd_send_command(disk, 1, 1, 0, 0, 0, IDE_READ_VRFY);
                r = pd_wait_for(disk, STAT_READY, DBMSG("RDY after VRFY"));
        }
-       pi_disconnect(disk->pi);
-
+       return Ok;
 }
 
 static void pd_standby_off(struct pd_unit *disk)
 {
-       pi_connect(disk->pi);
        pd_wait_for(disk, 0, DBMSG("before STANDBY"));
        pd_send_command(disk, 0, 0, 0, 0, 0, IDE_STANDBY);
        pd_wait_for(disk, 0, DBMSG("after STANDBY"));
-       pi_disconnect(disk->pi);
 }
 
-static int pd_identify(struct pd_unit *disk)
+static enum action pd_identify(struct pd_unit *disk)
 {
        int j;
        char id[PD_ID_LEN + 1];
@@ -598,17 +676,13 @@ static int pd_identify(struct pd_unit *disk)
        if (disk->drive == 0)
                pd_reset(disk);
 
-       pi_connect(disk->pi);
        write_reg(disk, 6, DRIVE(disk));
        pd_wait_for(disk, 0, DBMSG("before IDENT"));
        pd_send_command(disk, 1, 0, 0, 0, 0, IDE_IDENTIFY);
 
-       if (pd_wait_for(disk, STAT_DRQ, DBMSG("IDENT DRQ")) & STAT_ERR) {
-               pi_disconnect(disk->pi);
-               return 0;
-       }
+       if (pd_wait_for(disk, STAT_DRQ, DBMSG("IDENT DRQ")) & STAT_ERR)
+               return Fail;
        pi_read_block(disk->pi, pd_scratch, 512);
-       pi_disconnect(disk->pi);
        disk->can_lba = pd_scratch[99] & 2;
        disk->sectors = le16_to_cpu(*(u16 *) (pd_scratch + 12));
        disk->heads = le16_to_cpu(*(u16 *) (pd_scratch + 6));
@@ -640,250 +714,209 @@ static int pd_identify(struct pd_unit *disk)
        if (!disk->standby)
                pd_standby_off(disk);
 
-       return 1;
-}
-
-static int pd_probe_drive(struct pd_unit *disk)
-{
-       if (disk->drive == -1) {
-               for (disk->drive = 0; disk->drive <= 1; disk->drive++)
-                       if (pd_identify(disk))
-                               return 1;
-               return 0;
-       }
-       return pd_identify(disk);
+       return Ok;
 }
 
-static struct request_queue *pd_queue;
+/* end of io request engine */
 
-static int pd_detect(void)
+static void do_pd_request(request_queue_t * q)
 {
-       int k, unit;
-       struct pd_unit *disk;
-
-       k = 0;
-       if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
-               disk = pd;
-               if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch,
-                           PI_PD, verbose, disk->name)) {
-                       if (pd_probe_drive(disk)) {
-                               disk->present = 1;
-                               k = 1;
-                       } else
-                               pi_release(disk->pi);
-               }
+       if (pd_req)
+               return;
+       pd_req = elv_next_request(q);
+       if (!pd_req)
+               return;
 
-       } else {
-               for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
-                       int *parm = *drives[unit];
-                       if (!parm[D_PRT])
-                               continue;
-                       if (pi_init(disk->pi, 0, parm[D_PRT], parm[D_MOD],
-                                    parm[D_UNI], parm[D_PRO], parm[D_DLY],
-                                    pd_scratch, PI_PD, verbose, disk->name)) {
-                               if (pd_probe_drive(disk)) {
-                                       disk->present = 1;
-                                       k = unit + 1;
-                               } else
-                                       pi_release(disk->pi);
-                       }
-               }
-       }
-       for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
-               if (disk->present) {
-                       struct gendisk *p = alloc_disk(1 << PD_BITS);
-                       if (!p) {
-                               disk->present = 0;
-                               k--;
-                               continue;
-                       }
-                       strcpy(p->disk_name, disk->name);
-                       p->fops = &pd_fops;
-                       p->major = major;
-                       p->first_minor = unit << PD_BITS;
-                       set_capacity(p, disk->capacity);
-                       disk->gd = p;
-                       p->private_data = disk;
-                       p->queue = pd_queue;
-                       add_disk(p);
-               }
-       }
-       if (k)
-               return 1;
-       printk("%s: no valid drive found\n", name);
-       return 0;
+       schedule_fsm();
 }
 
-/* The i/o request engine */
-
-static int pd_ready(void)
+static int pd_special_command(struct pd_unit *disk,
+                     enum action (*func)(struct pd_unit *disk))
 {
-       return !(status_reg(pd_current) & STAT_BUSY);
+       DECLARE_COMPLETION(wait);
+       struct request rq;
+       int err = 0;
+
+       memset(&rq, 0, sizeof(rq));
+       rq.errors = 0;
+       rq.rq_status = RQ_ACTIVE;
+       rq.rq_disk = disk->gd;
+       rq.ref_count = 1;
+       rq.waiting = &wait;
+       blk_insert_request(disk->gd->queue, &rq, 0, func, 0);
+       wait_for_completion(&wait);
+       rq.waiting = NULL;
+       if (rq.errors)
+               err = -EIO;
+       blk_put_request(&rq);
+       return err;
 }
 
-static void do_pd_request(request_queue_t * q)
+/* kernel glue structures */
+
+static int pd_open(struct inode *inode, struct file *file)
 {
-       if (pd_busy)
-               return;
-repeat:
-       pd_req = elv_next_request(q);
-       if (!pd_req)
-               return;
+       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
 
-       pd_block = pd_req->sector;
-       pd_run = pd_req->nr_sectors;
-       pd_count = pd_req->current_nr_sectors;
-       pd_current = pd_req->rq_disk->private_data;
-       if (pd_block + pd_count > get_capacity(pd_req->rq_disk)) {
-               end_request(pd_req, 0);
-               goto repeat;
-       }
+       disk->access++;
 
-       pd_cmd = rq_data_dir(pd_req);
-       pd_buf = pd_req->buffer;
-       pd_retries = 0;
-
-       pd_busy = 1;
-       if (pd_cmd == READ)
-               pi_do_claimed(pd_current->pi, do_pd_read);
-       else if (pd_cmd == WRITE)
-               pi_do_claimed(pd_current->pi, do_pd_write);
-       else {
-               pd_busy = 0;
-               end_request(pd_req, 0);
-               goto repeat;
+       if (disk->removable) {
+               pd_special_command(disk, pd_media_check);
+               pd_special_command(disk, pd_door_lock);
        }
+       return 0;
 }
 
-static int pd_next_buf(void)
+static int pd_ioctl(struct inode *inode, struct file *file,
+        unsigned int cmd, unsigned long arg)
 {
-       unsigned long saved_flags;
+       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
+       struct hd_geometry *geo = (struct hd_geometry *) arg;
+       struct hd_geometry g;
 
-       pd_count--;
-       pd_run--;
-       pd_buf += 512;
-       pd_block++;
-       if (!pd_run)
-               return 1;
-       if (pd_count)
+       switch (cmd) {
+       case CDROMEJECT:
+               if (disk->access == 1)
+                       pd_special_command(disk, pd_eject);
                return 0;
-       spin_lock_irqsave(&pd_lock, saved_flags);
-       end_request(pd_req, 1);
-       pd_count = pd_req->current_nr_sectors;
-       pd_buf = pd_req->buffer;
-       spin_unlock_irqrestore(&pd_lock, saved_flags);
-       return 0;
+       case HDIO_GETGEO:
+               if (disk->alt_geom) {
+                       g.heads = PD_LOG_HEADS;
+                       g.sectors = PD_LOG_SECTS;
+                       g.cylinders = disk->capacity / (g.heads * g.sectors);
+               } else {
+                       g.heads = disk->heads;
+                       g.sectors = disk->sectors;
+                       g.cylinders = disk->cylinders;
+               }
+               g.start = get_start_sect(inode->i_bdev);
+               if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
+                       return -EFAULT;
+               return 0;
+       default:
+               return -EINVAL;
+       }
 }
 
-static inline void next_request(int success)
+static int pd_release(struct inode *inode, struct file *file)
 {
-       unsigned long saved_flags;
+       struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
 
-       spin_lock_irqsave(&pd_lock, saved_flags);
-       end_request(pd_req, success);
-       pd_busy = 0;
-       do_pd_request(pd_queue);
-       spin_unlock_irqrestore(&pd_lock, saved_flags);
+       if (!--disk->access && disk->removable)
+               pd_special_command(disk, pd_door_unlock);
+
+       return 0;
 }
 
-static void do_pd_read(void)
+static int pd_check_media(struct gendisk *p)
 {
-       ps_set_intr(do_pd_read_start, 0, 0, nice);
+       struct pd_unit *disk = p->private_data;
+       int r;
+       if (!disk->removable)
+               return 0;
+       pd_special_command(disk, pd_media_check);
+       r = disk->changed;
+       disk->changed = 0;
+       return r;
 }
 
-static void do_pd_read_start(void)
+static int pd_revalidate(struct gendisk *p)
 {
-       pd_busy = 1;
-
-       pi_connect(pd_current->pi);
-       if (pd_wait_for(pd_current, STAT_READY, "do_pd_read") & STAT_ERR) {
-               pi_disconnect(pd_current->pi);
-               if (pd_retries < PD_MAX_RETRIES) {
-                       pd_retries++;
-                       pi_do_claimed(pd_current->pi, do_pd_read_start);
-                       return;
-               }
-               next_request(0);
-               return;
-       }
-       pd_ide_command(pd_current, IDE_READ, pd_block, pd_run);
-       ps_set_intr(do_pd_read_drq, pd_ready, PD_TMO, nice);
+       struct pd_unit *disk = p->private_data;
+       if (pd_special_command(disk, pd_identify) == 0)
+               set_capacity(p, disk->capacity);
+       else
+               set_capacity(p, 0);
+       return 0;
 }
 
-static void do_pd_read_drq(void)
+static struct block_device_operations pd_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pd_open,
+       .release        = pd_release,
+       .ioctl          = pd_ioctl,
+       .media_changed  = pd_check_media,
+       .revalidate_disk= pd_revalidate
+};
+
+/* probing */
+
+static void pd_probe_drive(struct pd_unit *disk)
 {
-       while (1) {
-               if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_read_drq") & STAT_ERR) {
-                       pi_disconnect(pd_current->pi);
-                       if (pd_retries < PD_MAX_RETRIES) {
-                               pd_retries++;
-                               pi_do_claimed(pd_current->pi, do_pd_read_start);
+       struct gendisk *p = alloc_disk(1 << PD_BITS);
+       if (!p)
+               return;
+       strcpy(p->disk_name, disk->name);
+       p->fops = &pd_fops;
+       p->major = major;
+       p->first_minor = (disk - pd) << PD_BITS;
+       disk->gd = p;
+       p->private_data = disk;
+       p->queue = pd_queue;
+
+       if (disk->drive == -1) {
+               for (disk->drive = 0; disk->drive <= 1; disk->drive++)
+                       if (pd_special_command(disk, pd_identify) == 0)
                                return;
-                       }
-                       next_request(0);
-                       return;
-               }
-               pi_read_block(pd_current->pi, pd_buf, 512);
-               if (pd_next_buf())
-                       break;
-       }
-       pi_disconnect(pd_current->pi);
-       next_request(1);
+       } else if (pd_special_command(disk, pd_identify) == 0)
+               return;
+       disk->gd = NULL;
+       put_disk(p);
 }
 
-static void do_pd_write(void)
+static int pd_detect(void)
 {
-       ps_set_intr(do_pd_write_start, 0, 0, nice);
-}
+       int found = 0, unit, pd_drive_count = 0;
+       struct pd_unit *disk;
 
-static void do_pd_write_start(void)
-{
-       pd_busy = 1;
+       for (unit = 0; unit < PD_UNITS; unit++) {
+               int *parm = *drives[unit];
+               struct pd_unit *disk = pd + unit;
+               disk->pi = &disk->pia;
+               disk->access = 0;
+               disk->changed = 1;
+               disk->capacity = 0;
+               disk->drive = parm[D_SLV];
+               snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a'+unit);
+               disk->alt_geom = parm[D_GEO];
+               disk->standby = parm[D_SBY];
+               if (parm[D_PRT])
+                       pd_drive_count++;
+       }
 
-       pi_connect(pd_current->pi);
-       if (pd_wait_for(pd_current, STAT_READY, "do_pd_write") & STAT_ERR) {
-               pi_disconnect(pd_current->pi);
-               if (pd_retries < PD_MAX_RETRIES) {
-                       pd_retries++;
-                       pi_do_claimed(pd_current->pi, do_pd_write_start);
-                       return;
+       if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
+               disk = pd;
+               if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch,
+                           PI_PD, verbose, disk->name)) {
+                       pd_probe_drive(disk);
+                       if (!disk->gd)
+                               pi_release(disk->pi);
                }
-               next_request(0);
-               return;
-       }
-       pd_ide_command(pd_current, IDE_WRITE, pd_block, pd_run);
-       while (1) {
-               if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_write_drq") & STAT_ERR) {
-                       pi_disconnect(pd_current->pi);
-                       if (pd_retries < PD_MAX_RETRIES) {
-                               pd_retries++;
-                               pi_do_claimed(pd_current->pi, do_pd_write_start);
-                               return;
+
+       } else {
+               for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
+                       int *parm = *drives[unit];
+                       if (!parm[D_PRT])
+                               continue;
+                       if (pi_init(disk->pi, 0, parm[D_PRT], parm[D_MOD],
+                                    parm[D_UNI], parm[D_PRO], parm[D_DLY],
+                                    pd_scratch, PI_PD, verbose, disk->name)) {
+                               pd_probe_drive(disk);
+                               if (!disk->gd)
+                                       pi_release(disk->pi);
                        }
-                       next_request(0);
-                       return;
                }
-               pi_write_block(pd_current->pi, pd_buf, 512);
-               if (pd_next_buf())
-                       break;
        }
-       ps_set_intr(do_pd_write_done, pd_ready, PD_TMO, nice);
-}
-
-static void do_pd_write_done(void)
-{
-       if (pd_wait_for(pd_current, STAT_READY, "do_pd_write_done") & STAT_ERR) {
-               pi_disconnect(pd_current->pi);
-               if (pd_retries < PD_MAX_RETRIES) {
-                       pd_retries++;
-                       pi_do_claimed(pd_current->pi, do_pd_write_start);
-                       return;
+       for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
+               if (disk->gd) {
+                       set_capacity(disk->gd, disk->capacity);
+                       add_disk(disk->gd);
+                       found = 1;
                }
-               next_request(0);
-               return;
        }
-       pi_disconnect(pd_current->pi);
-       next_request(1);
+       if (!found)
+               printk("%s: no valid drive found\n", name);
+       return found;
 }
 
 static int __init pd_init(void)
@@ -902,7 +935,6 @@ static int __init pd_init(void)
 
        printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
               name, name, PD_VERSION, major, cluster, nice);
-       pd_init_units();
        if (!pd_detect())
                goto out3;
 
@@ -922,8 +954,8 @@ static void __exit pd_exit(void)
        int unit;
        unregister_blkdev(major, name);
        for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
-               if (disk->present) {
-                       struct gendisk *p = disk->gd;
+               struct gendisk *p = disk->gd;
+               if (p) {
                        disk->gd = NULL;
                        del_gendisk(p);
                        put_disk(p);
index 7047756..63e30e0 100644 (file)
@@ -743,7 +743,7 @@ static void ps2esdi_geometry_int_handler(u_int int_ret_code)
        drive_num = int_ret_code >> 5;
        switch (int_ret_code & 0xf) {
        case INT_CMD_COMPLETE:
-               for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
+               for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
                if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
                        printk("%s: timeout reading status word\n", DEVICE_NAME);
                        outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
@@ -879,7 +879,7 @@ static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
                break;
 
        case INT_CMD_COMPLETE:
-               for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
+               for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
                if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
                        printk("%s: timeout reading status word\n", DEVICE_NAME);
                        outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
index 530d906..99d77ca 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kbd_kern.h>
 #include <asm/uaccess.h>
 #include <linux/spinlock.h>
+#include <linux/cpumask.h>
 
 extern int hvc_count(int *);
 extern int hvc_get_chars(int index, char *buf, int count);
@@ -223,10 +224,10 @@ static void hvc_poll(int index)
        spin_unlock_irqrestore(&hp->lock, flags);
 }
 
-#if defined (CONFIG_XMON)
-extern unsigned long cpus_in_xmon;
+#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
+extern cpumask_t cpus_in_xmon;
 #else
-unsigned long cpus_in_xmon=0;
+static const cpumask_t cpus_in_xmon = CPU_MASK_NONE;
 #endif
 
 
@@ -237,7 +238,7 @@ int khvcd(void *unused)
        daemonize("khvcd");
 
        for (;;) {
-               if (!cpus_in_xmon) {
+               if (cpus_empty(cpus_in_xmon)) {
                        for (i = 0; i < MAX_NR_HVC_CONSOLES; ++i)
                                hvc_poll(i);
                }
@@ -268,8 +269,9 @@ int __init hvc_init(void)
                return -ENOMEM;
 
        hvc_driver->owner = THIS_MODULE;
+       hvc_driver->devfs_name = "hvc/";
        hvc_driver->driver_name = "hvc";
-       hvc_driver->name = "hvc/";
+       hvc_driver->name = "hvc";
        hvc_driver->major = HVC_MAJOR;
        hvc_driver->minor_start = HVC_MINOR;
        hvc_driver->type = TTY_DRIVER_TYPE_SYSTEM;
index 2a08cf6..faa31cc 100644 (file)
@@ -201,8 +201,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
        if (scancode < 0 || scancode >= dev->keycodemax)
                return -EINVAL;
 
-       oldkey = INPUT_KEYCODE(dev, scancode);
-       SET_INPUT_KEYCODE(dev, scancode, oldkey);
+       oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
 
        clear_bit(oldkey, dev->keybit);
        set_bit(keycode, dev->keybit);
index 8fa6721..3f27b90 100644 (file)
@@ -509,6 +509,7 @@ static int __init mxser_module_init(void)
 
        mxvar_sdriver->owner = THIS_MODULE;
        mxvar_sdriver->name = "ttyM";
+       mxvar_sdriver->devfs_name = "tts/M";
        mxvar_sdriver->major = ttymajor;
        mxvar_sdriver->minor_start = 0;
        mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL;
index d62cc28..337a9f8 100644 (file)
@@ -244,7 +244,6 @@ typedef struct _mgslpc_info {
        char netname[10];
        struct net_device *netdev;
        struct net_device_stats netstats;
-       struct net_device netdevice;
 #endif
 } MGSLPC_INFO;
 
@@ -4206,35 +4205,46 @@ void tx_timeout(unsigned long context)
 #ifdef CONFIG_SYNCLINK_SYNCPPP
 /* syncppp net device routines
  */
+static void mgslpc_setup(struct net_device *dev)
+{
+       dev->open = mgslpc_sppp_open;
+       dev->stop = mgslpc_sppp_close;
+       dev->hard_start_xmit = mgslpc_sppp_tx;
+       dev->do_ioctl = mgslpc_sppp_ioctl;
+       dev->get_stats = mgslpc_net_stats;
+       dev->tx_timeout = mgslpc_sppp_tx_timeout;
+       dev->watchdog_timeo = 10*HZ;
+}
 
 void mgslpc_sppp_init(MGSLPC_INFO *info)
 {
        struct net_device *d;
 
        sprintf(info->netname,"mgslp%d",info->line);
+       d = alloc_netdev(0, info->netname, mgslpc_setup);
+       if (!d) {
+               printk(KERN_WARNING "%s: alloc_netdev failed.\n",
+                                               info->netname);
+               return;
+       }
 
        info->if_ptr = &info->pppdev;
-       info->netdev = info->pppdev.dev = &info->netdevice;
+       info->netdev = info->pppdev.dev = d;
 
        sppp_attach(&info->pppdev);
 
-       d = info->netdev;
-       strcpy(d->name,info->netname);
        d->base_addr = info->io_base;
        d->irq = info->irq_level;
        d->priv = info;
-       d->init = NULL;
-       d->open = mgslpc_sppp_open;
-       d->stop = mgslpc_sppp_close;
-       d->hard_start_xmit = mgslpc_sppp_tx;
-       d->do_ioctl = mgslpc_sppp_ioctl;
-       d->get_stats = mgslpc_net_stats;
-       d->tx_timeout = mgslpc_sppp_tx_timeout;
-       d->watchdog_timeo = 10*HZ;
 
        if (register_netdev(d)) {
                printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
                sppp_detach(info->netdev);
+               info->netdev = NULL;
+               info->pppdev.dev = NULL;
+               free_netdev(d);
                return;
        }
 
@@ -4246,8 +4256,11 @@ void mgslpc_sppp_delete(MGSLPC_INFO *info)
 {
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("mgslpc_sppp_delete(%s)\n",info->netname);       
-       sppp_detach(info->netdev);
        unregister_netdev(info->netdev);
+       sppp_detach(info->netdev);
+       free_netdev(info->netdev);
+       info->netdev = NULL;
+       info->pppdev.dev = NULL;
 }
 
 int mgslpc_sppp_open(struct net_device *d)
index a15a789..78b5612 100644 (file)
@@ -239,6 +239,7 @@ static struct sonypi_event sonypi_pkeyev[] = {
        { 0x01, SONYPI_EVENT_PKEY_P1 },
        { 0x02, SONYPI_EVENT_PKEY_P2 },
        { 0x04, SONYPI_EVENT_PKEY_P3 },
+       { 0x5c, SONYPI_EVENT_PKEY_P1 },
        { 0, 0 }
 };
 
@@ -333,6 +334,7 @@ struct sonypi_eventtypes {
        { SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
        { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
        { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
+       { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
 
        { 0, 0, 0, 0 }
 };
index 585196d..8e4f37e 100644 (file)
@@ -327,7 +327,6 @@ struct mgsl_struct {
        char netname[10];
        struct net_device *netdev;
        struct net_device_stats netstats;
-       struct net_device netdevice;
 #endif
 };
 
@@ -737,8 +736,8 @@ int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long
 
 #ifdef CONFIG_SYNCLINK_SYNCPPP
 /* SPPP/HDLC stuff */
-void mgsl_sppp_init(struct mgsl_struct *info);
-void mgsl_sppp_delete(struct mgsl_struct *info);
+static void mgsl_sppp_init(struct mgsl_struct *info);
+static void mgsl_sppp_delete(struct mgsl_struct *info);
 int mgsl_sppp_open(struct net_device *d);
 int mgsl_sppp_close(struct net_device *d);
 void mgsl_sppp_tx_timeout(struct net_device *d);
@@ -7820,36 +7819,45 @@ int usc_loopmode_send_active( struct mgsl_struct * info )
 #ifdef CONFIG_SYNCLINK_SYNCPPP
 /* syncppp net device routines
  */
+static void mgsl_setup(struct net_device *dev)
+{
+       dev->open = mgsl_sppp_open;
+       dev->stop = mgsl_sppp_close;
+       dev->hard_start_xmit = mgsl_sppp_tx;
+       dev->do_ioctl = mgsl_sppp_ioctl;
+       dev->get_stats = mgsl_net_stats;
+       dev->tx_timeout = mgsl_sppp_tx_timeout;
+       dev->watchdog_timeo = 10*HZ;
+}
 
-void mgsl_sppp_init(struct mgsl_struct *info)
+static void mgsl_sppp_init(struct mgsl_struct *info)
 {
        struct net_device *d;
 
        sprintf(info->netname,"mgsl%d",info->line);
 
+       d = alloc_netdev(0, info->netname, mgsl_setup);
+       if (!d) {
+               printk(KERN_WARNING "%s: alloc_netdev failed.\n",
+                                               info->netname);
+               return;
+       }
+
        info->if_ptr = &info->pppdev;
-       info->netdev = info->pppdev.dev = &info->netdevice;
+       info->netdev = info->pppdev.dev = d;
 
        sppp_attach(&info->pppdev);
 
-       d = info->netdev;
-       strcpy(d->name,info->netname);
        d->base_addr = info->io_base;
        d->irq = info->irq_level;
        d->dma = info->dma_level;
        d->priv = info;
-       d->init = NULL;
-       d->open = mgsl_sppp_open;
-       d->stop = mgsl_sppp_close;
-       d->hard_start_xmit = mgsl_sppp_tx;
-       d->do_ioctl = mgsl_sppp_ioctl;
-       d->get_stats = mgsl_net_stats;
-       d->tx_timeout = mgsl_sppp_tx_timeout;
-       d->watchdog_timeo = 10*HZ;
 
        if (register_netdev(d)) {
                printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
                sppp_detach(info->netdev);
+               info->netdev = NULL;
+               free_netdev(d);
                return;
        }
 
@@ -7861,8 +7869,11 @@ void mgsl_sppp_delete(struct mgsl_struct *info)
 {
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("mgsl_sppp_delete(%s)\n",info->netname); 
-       sppp_detach(info->netdev);
        unregister_netdev(info->netdev);
+       sppp_detach(info->netdev);
+       free_netdev(info->netdev);
+       info->netdev = NULL;
+       info->pppdev.dev = NULL;
 }
 
 int mgsl_sppp_open(struct net_device *d)
index 82c7afe..f602821 100644 (file)
@@ -289,7 +289,6 @@ typedef struct _synclinkmp_info {
        char netname[10];
        struct net_device *netdev;
        struct net_device_stats netstats;
-       struct net_device netdevice;
 #endif
 } SLMP_INFO;
 
@@ -1627,35 +1626,44 @@ static void set_break(struct tty_struct *tty, int break_state)
 
 /* syncppp support and callbacks */
 
+static void cb_setup(struct net_device *dev)
+{
+       dev->open = sppp_cb_open;
+       dev->stop = sppp_cb_close;
+       dev->hard_start_xmit = sppp_cb_tx;
+       dev->do_ioctl = sppp_cb_ioctl;
+       dev->get_stats = sppp_cb_net_stats;
+       dev->tx_timeout = sppp_cb_tx_timeout;
+       dev->watchdog_timeo = 10*HZ;
+}
+
 static void sppp_init(SLMP_INFO *info)
 {
        struct net_device *d;
 
        sprintf(info->netname,"mgslm%dp%d",info->adapter_num,info->port_num);
 
+       d = alloc_netdev(0, info->netname, cb_setup);
+       if (!d) {
+               printk(KERN_WARNING "%s: alloc_netdev failed.\n",
+                                               info->netname);
+               return;
+       }
+
        info->if_ptr = &info->pppdev;
-       info->netdev = info->pppdev.dev = &info->netdevice;
+       info->netdev = info->pppdev.dev = d;
 
        sppp_attach(&info->pppdev);
 
-       d = info->netdev;
-       strcpy(d->name,info->netname);
-       d->base_addr = 0;
        d->irq = info->irq_level;
-       d->dma = 0;
        d->priv = info;
-       d->init = NULL;
-       d->open = sppp_cb_open;
-       d->stop = sppp_cb_close;
-       d->hard_start_xmit = sppp_cb_tx;
-       d->do_ioctl = sppp_cb_ioctl;
-       d->get_stats = sppp_cb_net_stats;
-       d->tx_timeout = sppp_cb_tx_timeout;
-       d->watchdog_timeo = 10*HZ;
 
        if (register_netdev(d)) {
                printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
                sppp_detach(info->netdev);
+               info->netdev = NULL;
+               info->pppdev.dev = NULL;
+               free_netdev(d);
                return;
        }
 
@@ -1667,8 +1675,11 @@ static void sppp_delete(SLMP_INFO *info)
 {
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("sppp_delete(%s)\n",info->netname);
-       sppp_detach(info->netdev);
        unregister_netdev(info->netdev);
+       sppp_detach(info->netdev);
+       free_netdev(info->netdev);
+       info->netdev = NULL;
+       info->pppdev.dev = NULL;
 }
 
 static int sppp_cb_open(struct net_device *d)
index 4f456c1..9d9aa44 100644 (file)
@@ -28,6 +28,7 @@
                         transfers. Add i2c_xfer routine.
     2003/09/21 BenH    Rework state machine with Paulus help
     2004/01/21 BenH    Merge in Greg KH changes, polled mode is back
+    2004/02/05 BenH    Merge 64 bits fixes from the g5 ppc64 tree
 
     My understanding of the various modes supported by keywest are:
 
index de8a4b2..f0626dd 100644 (file)
@@ -511,27 +511,6 @@ config IDEDMA_ONLYDISK
 
          Generally say N here.
 
-config IDEDMA_PCI_WIP
-       bool "ATA Work(s) In Progress (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       help
-         If you enable this you will be able to use and test highly
-         developmental projects. If you say N, the configurator will
-         simply skip those options.
-
-         It is SAFEST to say N to this question.
-
-config IDEDMA_NEW_DRIVE_LISTINGS
-       bool "Good-Bad DMA Model-Firmware (WIP)"
-       depends on IDEDMA_PCI_WIP
-       help
-         If you say Y here, the model and firmware revision of your drive
-         will be compared against a blacklist of buggy drives that claim to
-         be (U)DMA capable but aren't. This is a blanket on/off test with no
-         speed limit options.
-
-         If in doubt, say N.
-
 config BLK_DEV_ADMA
        bool
        depends on PCI && BLK_DEV_IDEPCI
@@ -630,8 +609,8 @@ config BLK_DEV_HPT34X
          DVD II drives, by the manufacturer.
 
 config HPT34X_AUTODMA
-       bool "HPT34X AUTODMA support (WIP)"
-       depends on BLK_DEV_HPT34X && IDEDMA_PCI_WIP
+       bool "HPT34X AUTODMA support (EXPERIMENTAL)"
+       depends on BLK_DEV_HPT34X && EXPERIMENTAL
        help
          This is a dangerous thing to attempt currently! Please read the
          comments at the top of <file:drivers/ide/pci/hpt34x.c>.  If you say Y
index 488c784..7cc48f1 100644 (file)
@@ -20,7 +20,7 @@ ide-core-$(CONFIG_BLK_DEV_CMD640)     += pci/cmd640.o
 
 # Core IDE code - must come before legacy
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)      += setup-pci.o
-ide-core-$(CONFIG_BLK_DEV_IDEDMA_PCI)  += ide-dma.o
+ide-core-$(CONFIG_BLK_DEV_IDEDMA)      += ide-dma.o
 ide-core-$(CONFIG_BLK_DEV_IDE_TCQ)     += ide-tcq.o
 ide-core-$(CONFIG_PROC_FS)             += ide-proc.o
 ide-core-$(CONFIG_BLK_DEV_IDEPNP)      += ide-pnp.o
index 5bf7dc8..09d3f94 100644 (file)
@@ -330,72 +330,6 @@ static int icside_set_speed(ide_drive_t *drive, u8 xfer_mode)
        return on;
 }
 
-/*
- * The following is a sick duplication from ide-dma.c ;(
- *
- * This should be defined in one place only.
- */
-struct drive_list_entry {
-       const char * id_model;
-       const char * id_firmware;
-};
-
-static const struct drive_list_entry drive_whitelist [] = {
-       { "Micropolis 2112A",                   "ALL"           },
-       { "CONNER CTMA 4000",                   "ALL"           },
-       { "CONNER CTT8000-A",                   "ALL"           },
-       { "ST34342A",                           "ALL"           },
-       { NULL,                                 NULL            }
-};
-
-static struct drive_list_entry drive_blacklist [] = {
-       { "WDC AC11000H",                       "ALL"           },
-       { "WDC AC22100H",                       "ALL"           },
-       { "WDC AC32500H",                       "ALL"           },
-       { "WDC AC33100H",                       "ALL"           },
-       { "WDC AC31600H",                       "ALL"           },
-       { "WDC AC32100H",                       "24.09P07"      },
-       { "WDC AC23200L",                       "21.10N21"      },
-       { "Compaq CRD-8241B",                   "ALL"           },
-       { "CRD-8400B",                          "ALL"           },
-       { "CRD-8480B",                          "ALL"           },
-       { "CRD-8480C",                          "ALL"           },
-       { "CRD-8482B",                          "ALL"           },
-       { "CRD-84",                             "ALL"           },
-       { "SanDisk SDP3B",                      "ALL"           },
-       { "SanDisk SDP3B-64",                   "ALL"           },
-       { "SANYO CD-ROM CRD",                   "ALL"           },
-       { "HITACHI CDR-8",                      "ALL"           },
-       { "HITACHI CDR-8335",                   "ALL"           },
-       { "HITACHI CDR-8435",                   "ALL"           },
-       { "Toshiba CD-ROM XM-6202B",            "ALL"           },
-       { "CD-532E-A",                          "ALL"           },
-       { "E-IDE CD-ROM CR-840",                "ALL"           },
-       { "CD-ROM Drive/F5A",                   "ALL"           },
-       { "RICOH CD-R/RW MP7083A",              "ALL"           },
-       { "WPI CDD-820",                        "ALL"           },
-       { "SAMSUNG CD-ROM SC-148C",             "ALL"           },
-       { "SAMSUNG CD-ROM SC-148F",             "ALL"           },
-       { "SAMSUNG CD-ROM SC",                  "ALL"           },
-       { "SanDisk SDP3B-64",                   "ALL"           },
-       { "SAMSUNG CD-ROM SN-124",              "ALL"           },
-       { "PLEXTOR CD-R PX-W8432T",             "ALL"           },
-       { "ATAPI CD-ROM DRIVE 40X MAXIMUM",     "ALL"           },
-       { "_NEC DV5800A",                       "ALL"           },
-       { NULL,                                 NULL            }
-};
-
-static int
-in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
-{
-       for ( ; drive_table->id_model ; drive_table++)
-               if ((!strcmp(drive_table->id_model, id->model)) &&
-                   ((!strstr(drive_table->id_firmware, id->fw_rev)) ||
-                    (!strcmp(drive_table->id_firmware, "ALL"))))
-                       return 1;
-       return 0;
-}
-
 static int icside_dma_host_off(ide_drive_t *drive)
 {
        return 0;
@@ -437,11 +371,8 @@ static int icside_dma_check(ide_drive_t *drive)
        /*
         * Consult the list of known "bad" drives
         */
-       if (in_drive_list(id, drive_blacklist)) {
-               printk("%s: Disabling DMA for %s (blacklisted)\n",
-                       drive->name, id->model);
+       if (__ide_dma_bad_drive(drive))
                goto out;
-       }
 
        /*
         * Enable DMA on any drive that has multiword DMA
@@ -454,7 +385,7 @@ static int icside_dma_check(ide_drive_t *drive)
        /*
         * Consult the list of known "good" drives
         */
-       if (in_drive_list(id, drive_whitelist)) {
+       if (__ide_dma_good_drive(drive)) {
                if (id->eide_dma_time > 150)
                        goto out;
                xfer_mode = XFER_MW_DMA_1;
@@ -954,18 +885,10 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
                break;
        }
 
-       if (ret == 0) {
+       if (ret == 0)
                ecard_set_drvdata(ec, state);
-
-               /*
-                * this locks the driver in-core - remove this
-                * comment and the line below when we can
-                * safely remove interfaces.
-                */
-               MOD_INC_USE_COUNT;
-       } else {
+       else
                kfree(state);
-       }
  out:
        return ret;
 }
@@ -1048,14 +971,8 @@ static int __init icside_init(void)
        return ecard_register_driver(&icside_driver);
 }
 
-static void __exit icside_exit(void)
-{
-       ecard_remove_driver(&icside_driver);
-}
-
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("ICS IDE driver");
 
 module_init(icside_init);
-module_exit(icside_exit);
index f8af375..2269c28 100644 (file)
@@ -33,14 +33,6 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
 
        if (ret)
                ecard_release(ec);
-       /*
-        * this locks the driver in-core - remove this
-        * comment and the two lines below when we can
-        * safely remove interfaces.
-        */
-       else
-               MOD_INC_USE_COUNT;
-
        return ret;
 }
 
@@ -68,13 +60,7 @@ static int __init rapide_init(void)
        return ecard_register_driver(&rapide_driver);
 }
 
-static void __exit rapide_exit(void)
-{
-       ecard_remove_driver(&rapide_driver);
-}
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Yellowstone RAPIDE driver");
 
 module_init(rapide_init);
-module_exit(rapide_exit);
index 6aaf3bb..580da53 100644 (file)
@@ -2860,6 +2860,10 @@ int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose)
 static
 void ide_cdrom_release_real (struct cdrom_device_info *cdi)
 {
+       ide_drive_t *drive = cdi->handle;
+
+       if (!cdi->use_count)
+               CDROM_STATE_FLAGS(drive)->toc_valid = 0;
 }
 
 
index ac2a3ec..cc76767 100644 (file)
@@ -470,9 +470,10 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
        }
 
        if (rq_data_dir(rq) == READ) {
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
                if (blk_rq_tagged(rq))
-                       return hwif->ide_dma_queued_read(drive);
-
+                       return __ide_dma_queued_read(drive);
+#endif
                if (drive->using_dma && !hwif->ide_dma_read(drive))
                        return ide_started;
 
@@ -483,10 +484,10 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
                return ide_started;
        } else if (rq_data_dir(rq) == WRITE) {
                ide_startstop_t startstop;
-
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
                if (blk_rq_tagged(rq))
-                       return hwif->ide_dma_queued_write(drive);
-
+                       return __ide_dma_queued_write(drive);
+#endif
                if (drive->using_dma && !(HWIF(drive)->ide_dma_write(drive)))
                        return ide_started;
 
@@ -1400,13 +1401,10 @@ static int set_acoustic (ide_drive_t *drive, int arg)
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
 static int set_using_tcq(ide_drive_t *drive, int arg)
 {
-       ide_hwif_t *hwif = HWIF(drive);
        int ret;
 
        if (!drive->driver)
                return -EPERM;
-       if (!hwif->ide_dma_queued_on || !hwif->ide_dma_queued_off)
-               return -ENXIO;
        if (arg == drive->queue_depth && drive->using_tcq)
                return 0;
 
@@ -1420,9 +1418,9 @@ static int set_using_tcq(ide_drive_t *drive, int arg)
        }
 
        if (arg)
-               ret = HWIF(drive)->ide_dma_queued_on(drive);
+               ret = __ide_dma_queued_on(drive);
        else
-               ret = HWIF(drive)->ide_dma_queued_off(drive);
+               ret = __ide_dma_queued_off(drive);
 
        return ret ? -EIO : 0;
 }
@@ -1673,7 +1671,7 @@ static void idedisk_setup (ide_drive_t *drive)
 
 #ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
        if (drive->using_dma)
-               HWIF(drive)->ide_dma_queued_on(drive);
+               __ide_dma_queued_on(drive);
 #endif
 }
 
index 8864718..205c282 100644 (file)
 #include <asm/irq.h>
 
 struct drive_list_entry {
-       char * id_model;
-       char * id_firmware;
+       const char *id_model;
+       const char *id_firmware;
 };
 
-struct drive_list_entry drive_whitelist [] = {
+static const struct drive_list_entry drive_whitelist [] = {
 
        { "Micropolis 2112A"    ,       "ALL"           },
        { "CONNER CTMA 4000"    ,       "ALL"           },
@@ -103,7 +103,7 @@ struct drive_list_entry drive_whitelist [] = {
        { 0                     ,       0               }
 };
 
-struct drive_list_entry drive_blacklist [] = {
+static const struct drive_list_entry drive_blacklist [] = {
 
        { "WDC AC11000H"        ,       "ALL"           },
        { "WDC AC22100H"        ,       "ALL"           },
@@ -151,7 +151,7 @@ struct drive_list_entry drive_blacklist [] = {
  *     Returns 1 if the drive is found in the table.
  */
 
-static int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table)
+static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
 {
        for ( ; drive_table->id_model ; drive_table++)
                if ((!strcmp(drive_table->id_model, id->model)) &&
@@ -161,6 +161,7 @@ static int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_
        return 0;
 }
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *     ide_dma_intr    -       IDE DMA interrupt handler
  *     @drive: the drive the interrupt is for
@@ -512,9 +513,9 @@ int __ide_dma_off_quietly (ide_drive_t *drive)
 
        if (HWIF(drive)->ide_dma_host_off(drive))
                return 1;
-
-       HWIF(drive)->ide_dma_queued_off(drive);
-
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+       __ide_dma_queued_off(drive);
+#endif
        return 0;
 }
 
@@ -764,6 +765,7 @@ int __ide_dma_test_irq (ide_drive_t *drive)
 }
 
 EXPORT_SYMBOL(__ide_dma_test_irq);
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 int __ide_dma_bad_drive (ide_drive_t *drive)
 {
@@ -771,8 +773,9 @@ int __ide_dma_bad_drive (ide_drive_t *drive)
 
        int blacklist = in_drive_list(id, drive_blacklist);
        if (blacklist) {
-               printk(KERN_WARNING "%s: Disabling (U)DMA for %s\n", drive->name, id->model);
-               return(blacklist);
+               printk(KERN_WARNING "%s: Disabling (U)DMA for %s (blacklisted)\n",
+                                   drive->name, id->model);
+               return blacklist;
        }
        return 0;
 }
@@ -787,6 +790,7 @@ int __ide_dma_good_drive (ide_drive_t *drive)
 
 EXPORT_SYMBOL(__ide_dma_good_drive);
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /*
  * Used for HOST FIFO counters for VDMA
  * PIO over DMA, effective ATA-Bridge operator.
@@ -850,22 +854,6 @@ int __ide_dma_verbose (ide_drive_t *drive)
 
 EXPORT_SYMBOL(__ide_dma_verbose);
 
-/**
- *     __ide_dma_retune        -       default retune handler
- *     @drive: drive to retune
- *
- *     Default behaviour when we decide to return the IDE DMA setup.
- *     The default behaviour is "we don't"
- */
-int __ide_dma_retune (ide_drive_t *drive)
-{
-       printk(KERN_WARNING "%s: chipset supported call only\n", __FUNCTION__);
-       return 1;
-}
-
-EXPORT_SYMBOL(__ide_dma_retune);
-
 int __ide_dma_lostirq (ide_drive_t *drive)
 {
        printk("%s: DMA interrupt recovery\n", drive->name);
@@ -1104,28 +1092,9 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
                hwif->ide_dma_verbose = &__ide_dma_verbose;
        if (!hwif->ide_dma_timeout)
                hwif->ide_dma_timeout = &__ide_dma_timeout;
-       if (!hwif->ide_dma_retune)
-               hwif->ide_dma_retune = &__ide_dma_retune;
        if (!hwif->ide_dma_lostirq)
                hwif->ide_dma_lostirq = &__ide_dma_lostirq;
 
-       /*
-        * dma queued ops. if tcq isn't set, queued on and off are just
-        * dummy functions. cuts down on ifdef hell
-        */
-       if (!hwif->ide_dma_queued_on)
-               hwif->ide_dma_queued_on = __ide_dma_queued_on;
-       if (!hwif->ide_dma_queued_off)
-               hwif->ide_dma_queued_off = __ide_dma_queued_off;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-       if (!hwif->ide_dma_queued_read)
-               hwif->ide_dma_queued_read = __ide_dma_queued_read;
-       if (!hwif->ide_dma_queued_write)
-               hwif->ide_dma_queued_write = __ide_dma_queued_write;
-       if (!hwif->ide_dma_queued_start)
-               hwif->ide_dma_queued_start = __ide_dma_queued_start;
-#endif
-
        if (hwif->chipset != ide_trm290) {
                u8 dma_stat = hwif->INB(hwif->dma_status);
                printk(", BIOS settings: %s:%s, %s:%s",
@@ -1139,3 +1108,4 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_dma);
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
index ee27933..23bb5eb 100644 (file)
@@ -14,7 +14,6 @@
 
 static int __init ide_generic_init(void)
 {
-       MOD_INC_USE_COUNT;
        if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
                ide_get_lock(NULL, NULL); /* for atari only */
 
index a239bba..262dd19 100644 (file)
 #include <asm/bitops.h>
 
 /*
- *     IDE operator we assign to an unplugged device so that
- *     we don't trash new hardware assigned the same resources
- */
-static u8 ide_unplugged_inb (unsigned long port)
-{
-       return 0xFF;
-}
-
-static u16 ide_unplugged_inw (unsigned long port)
-{
-       return 0xFFFF;
-}
-
-static void ide_unplugged_insw (unsigned long port, void *addr, u32 count)
-{
-}
-
-static u32 ide_unplugged_inl (unsigned long port)
-{
-       return 0xFFFFFFFF;
-}
-
-static void ide_unplugged_insl (unsigned long port, void *addr, u32 count)
-{
-}
-
-static void ide_unplugged_outb (u8 val, unsigned long port)
-{
-}
-
-static void ide_unplugged_outbsync (ide_drive_t *drive, u8 addr, unsigned long port)
-{
-}
-
-static void ide_unplugged_outw (u16 val, unsigned long port)
-{
-}
-
-static void ide_unplugged_outsw (unsigned long port, void *addr, u32 count)
-{
-}
-
-static void ide_unplugged_outl (u32 val, unsigned long port)
-{
-}
-
-static void ide_unplugged_outsl (unsigned long port, void *addr, u32 count)
-{
-}
-
-void unplugged_hwif_iops (ide_hwif_t *hwif)
-{
-       hwif->OUTB      = ide_unplugged_outb;
-       hwif->OUTBSYNC  = ide_unplugged_outbsync;
-       hwif->OUTW      = ide_unplugged_outw;
-       hwif->OUTL      = ide_unplugged_outl;
-       hwif->OUTSW     = ide_unplugged_outsw;
-       hwif->OUTSL     = ide_unplugged_outsl;
-       hwif->INB       = ide_unplugged_inb;
-       hwif->INW       = ide_unplugged_inw;
-       hwif->INL       = ide_unplugged_inl;
-       hwif->INSW      = ide_unplugged_insw;
-       hwif->INSL      = ide_unplugged_insl;
-}
-
-EXPORT_SYMBOL(unplugged_hwif_iops);
-
-/*
  *     Conventional PIO operations for ATA devices
  */
 
index 72ef85b..eb16f6e 100644 (file)
@@ -200,12 +200,14 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
                        if (!hwif->ide_dma_read(drive))
                                return ide_started;
                        break;
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
                case WIN_READDMA_QUEUED:
                case WIN_READDMA_QUEUED_EXT:
-                       return hwif->ide_dma_queued_read(drive);
+                       return __ide_dma_queued_read(drive);
                case WIN_WRITEDMA_QUEUED:
                case WIN_WRITEDMA_QUEUED_EXT:
-                       return hwif->ide_dma_queued_write(drive);
+                       return __ide_dma_queued_write(drive);
+#endif
                default:
                        if (task->handler == NULL)
                                return ide_stopped;
@@ -772,14 +774,20 @@ EXPORT_SYMBOL(task_mulout_intr);
 static u8 wait_drive_not_busy(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
-       int retries = 5;
+       int retries = 100;
        u8 stat;
+
        /*
-        * (ks) Last sector was transfered, wait until drive is ready.
-        * This can take up to 10 usec. We willl wait max 50 us.
+        * Last sector was transfered, wait until drive is ready.
+        * This can take up to 10 usec, but we will wait max 1 ms
+        * (drive_cmd_intr() waits that long).
         */
        while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
                udelay(10);
+
+       if (!retries)
+               printk(KERN_ERR "%s: drive still BUSY!\n", drive->name);
+
        return stat;
 }
 
index ecf528a..6a432b5 100644 (file)
@@ -353,7 +353,7 @@ ide_startstop_t ide_service(ide_drive_t *drive)
                 */
                TCQ_PRINTK("ide_service: starting command, stat=%x\n", stat);
                spin_unlock_irqrestore(&ide_lock, flags);
-               return HWIF(drive)->ide_dma_queued_start(drive);
+               return __ide_dma_queued_start(drive);
        }
 
        printk(KERN_ERR "ide_service: missing request for tag %d\n", tag);
@@ -729,7 +729,7 @@ static ide_startstop_t ide_dma_queued_rw(ide_drive_t *drive, u8 command)
        feat = hwif->INB(IDE_NSECTOR_REG);
        if (!(feat & REL)) {
                TCQ_PRINTK("IMMED in queued_start, feat=%x\n", feat);
-               return hwif->ide_dma_queued_start(drive);
+               return __ide_dma_queued_start(drive);
        }
 
        /*
index c22cb0d..fd11055 100644 (file)
@@ -197,18 +197,6 @@ ide_hwif_t ide_hwifs[MAX_HWIFS];   /* master data repository */
 
 EXPORT_SYMBOL(ide_hwifs);
 
-ide_devices_t *idedisk;
-ide_devices_t *idecd;
-ide_devices_t *idefloppy;
-ide_devices_t *idetape;
-ide_devices_t *idescsi;
-
-EXPORT_SYMBOL(idedisk);
-EXPORT_SYMBOL(idecd);
-EXPORT_SYMBOL(idefloppy);
-EXPORT_SYMBOL(idetape);
-EXPORT_SYMBOL(idescsi);
-
 extern ide_driver_t idedefault_driver;
 static void setup_driver_defaults(ide_driver_t *driver);
 
@@ -311,7 +299,9 @@ static void __init init_ide_data (void)
                init_hwif_data(index);
 
        /* Add default hw interfaces */
+       initializing = 1;
        ide_init_default_hwifs();
+       initializing = 0;
 
        idebus_parameter = 0;
        system_bus_speed = 0;
@@ -858,16 +848,8 @@ void ide_unregister (unsigned int index)
        hwif->ide_dma_good_drive        = old_hwif.ide_dma_good_drive;
        hwif->ide_dma_count             = old_hwif.ide_dma_count;
        hwif->ide_dma_verbose           = old_hwif.ide_dma_verbose;
-       hwif->ide_dma_retune            = old_hwif.ide_dma_retune;
        hwif->ide_dma_lostirq           = old_hwif.ide_dma_lostirq;
        hwif->ide_dma_timeout           = old_hwif.ide_dma_timeout;
-       hwif->ide_dma_queued_on         = old_hwif.ide_dma_queued_on;
-       hwif->ide_dma_queued_off        = old_hwif.ide_dma_queued_off;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-       hwif->ide_dma_queued_read       = old_hwif.ide_dma_queued_read;
-       hwif->ide_dma_queued_write      = old_hwif.ide_dma_queued_write;
-       hwif->ide_dma_queued_start      = old_hwif.ide_dma_queued_start;
-#endif
 #endif
 
 #if 0
index 2b8fe04..8e45b97 100644 (file)
@@ -530,7 +530,6 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi
        if (dev->device != d->device)
                BUG();
        d->init_setup(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -554,13 +553,7 @@ static int aec62xx_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void aec62xx_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(aec62xx_ide_init);
-module_exit(aec62xx_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for ARTOP AEC62xx IDE");
index 7420214..73398a1 100644 (file)
@@ -868,7 +868,6 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
        d->init_hwif = init_hwif_common_ali15x3;
 #endif /* CONFIG_SPARC64 */
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -889,13 +888,7 @@ static int ali15x3_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void ali15x3_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(ali15x3_ide_init);
-module_exit(ali15x3_ide_exit);
 
 MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox");
 MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");
index c45c0ea..7f86e50 100644 (file)
@@ -448,7 +448,6 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_
        if (dev->device != amd_chipset->device) BUG();
        if (dev->device != amd_config->id) BUG();
        ide_setup_pci_device(dev, amd_chipset);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -480,13 +479,7 @@ static int amd74xx_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void amd74xx_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(amd74xx_ide_init);
-module_exit(amd74xx_ide_exit);
 
 MODULE_AUTHOR("Vojtech Pavlik");
 MODULE_DESCRIPTION("AMD PCI IDE driver");
index 99a8080..f342a28 100644 (file)
@@ -752,7 +752,6 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -775,13 +774,7 @@ static int cmd64x_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void cmd64x_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(cmd64x_ide_init);
-module_exit(cmd64x_ide_exit);
 
 MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for CMD64x IDE");
index 6d6313e..00ef1ef 100644 (file)
@@ -291,7 +291,6 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
                probe_hwif_init(&ide_hwifs[index.b.low]);
        if((index.b.high & 0xf0) != 0xf0)
                probe_hwif_init(&ide_hwifs[index.b.high]);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -312,13 +311,7 @@ static int cs5520_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void cs5520_ide_exit(void)
-{
-       return ide_pci_unregister_driver(&driver);
-}
-
 module_init(cs5520_ide_init);
-module_exit(cs5520_ide_exit);
 
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("PCI driver module for Cyrix 5510/5520 IDE");
index 29a8102..bf0e614 100644 (file)
@@ -413,7 +413,6 @@ static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_devic
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -433,13 +432,7 @@ static int cs5530_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void cs5530_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(cs5530_ide_init);
-module_exit(cs5530_ide_exit);
 
 MODULE_AUTHOR("Mark Lord");
 MODULE_DESCRIPTION("PCI driver module for Cyrix/NS 5530 IDE");
index eeb125a..26c0ef0 100644 (file)
@@ -434,7 +434,6 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
                dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
                ide_setup_pci_devices(dev, dev2, d);
        }
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -454,13 +453,7 @@ static int cy82c693_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void cy82c693_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(cy82c693_ide_init);
-module_exit(cy82c693_ide_exit);
 
 MODULE_AUTHOR("Andreas Krebs, Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for the Cypress CY82C693 IDE");
index 491255e..d0a840d 100644 (file)
@@ -121,7 +121,6 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi
                return 1; 
        }
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -150,13 +149,7 @@ static int generic_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void generic_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(generic_ide_init);
-module_exit(generic_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for generic PCI IDE");
index f4da1f9..8ce180b 100644 (file)
@@ -331,7 +331,6 @@ static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_devic
        d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
 
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -351,13 +350,7 @@ static int hpt34x_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void hpt34x_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(hpt34x_ide_init);
-module_exit(hpt34x_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for Highpoint 34x IDE");
index 4924eeb..6cbc113 100644 (file)
@@ -1220,7 +1220,6 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
        if (dev->device != d->device)
                BUG();
        d->init_setup(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -1244,13 +1243,7 @@ static int hpt366_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void hpt366_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(hpt366_ide_init);
-module_exit(hpt366_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for Highpoint HPT366 IDE");
index 525abe5..91d511b 100644 (file)
@@ -295,7 +295,6 @@ static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_devic
             (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))))
                 return 1; /* IT8172 is more than only a IDE controller */
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -315,13 +314,7 @@ static int it8172_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void it8172_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(it8172_ide_init);
-module_exit(it8172_ide_exit);
 
 MODULE_AUTHOR("SteveL@mvista.com");
 MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE");
index 72b9c9a..4dd37cd 100644 (file)
@@ -198,7 +198,7 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
        }
 
        if (!using_inta)
-               hwif->irq = hwif->channel ? 15 : 14;    /* legacy mode */
+               hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
        else if (!hwif->irq && hwif->mate && hwif->mate->irq)
                hwif->irq = hwif->mate->irq;    /* share IRQ with mate */
 
@@ -225,7 +225,6 @@ static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_devi
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -245,13 +244,7 @@ static int ns87415_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void ns87415_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(ns87415_ide_init);
-module_exit(ns87415_ide_exit);
 
 MODULE_AUTHOR("Mark Lord, Eddie Dost, Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for NS87415 IDE");
index 4e88634..ca8ec44 100644 (file)
@@ -361,7 +361,6 @@ static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_devi
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -382,13 +381,7 @@ static int opti621_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void opti621_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(opti621_ide_init);
-module_exit(opti621_ide_exit);
 
 MODULE_AUTHOR("Jaromir Koutek, Jan Harkes, Mark Lord");
 MODULE_DESCRIPTION("PCI driver module for Opti621 IDE");
index aa3a6b5..3f1535d 100644 (file)
@@ -675,7 +675,6 @@ static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_de
        if (dev->device != d->device)
                BUG();
        d->init_setup(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -701,13 +700,7 @@ static int pdc202new_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void pdc202new_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(pdc202new_ide_init);
-module_exit(pdc202new_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
 MODULE_DESCRIPTION("PCI driver module for Promise PDC20268 and higher");
index 6f4a7e2..b468806 100644 (file)
@@ -913,7 +913,6 @@ static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_dev
        if (dev->device != d->device)
                BUG();
        d->init_setup(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -937,13 +936,7 @@ static int pdc202xx_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void pdc202xx_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(pdc202xx_ide_init);
-module_exit(pdc202xx_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
 MODULE_DESCRIPTION("PCI driver module for older Promise IDE");
index 4d9ebf7..7c57816 100644 (file)
@@ -743,7 +743,6 @@ static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_
        if (dev->device != d->device)
                BUG();
        d->init_setup(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -815,13 +814,7 @@ static int piix_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void piix_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(piix_ide_init);
-module_exit(piix_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick, Andrzej Krzysztofowicz");
 MODULE_DESCRIPTION("PCI driver module for Intel PIIX IDE");
index e280c31..c306b4f 100644 (file)
@@ -62,7 +62,6 @@ static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_devic
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -83,13 +82,7 @@ static int rz1000_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void rz1000_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(rz1000_ide_init);
-module_exit(rz1000_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for RZ1000 IDE");
index 5a35bdc..4c22187 100644 (file)
@@ -554,7 +554,6 @@ static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_devic
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -576,13 +575,7 @@ static int sc1200_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void sc1200_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(sc1200_ide_init);
-module_exit(sc1200_ide_exit);
 
 MODULE_AUTHOR("Mark Lord");
 MODULE_DESCRIPTION("PCI driver module for NS SC1200 IDE");
index b5afd8c..fa9fe55 100644 (file)
@@ -801,7 +801,6 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
        if (dev->device != d->device)
                BUG();
        d->init_setup(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -828,13 +827,7 @@ static int svwks_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void svwks_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(svwks_ide_init);
-module_exit(svwks_ide_exit);
 
 MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for Serverworks OSB4/CSB5/CSB6 IDE");
index 4d8332a..550e505 100644 (file)
@@ -653,7 +653,6 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        hwif->ide_dma_good_drive = &__ide_dma_good_drive;
        hwif->ide_dma_count = &__ide_dma_count;
        hwif->ide_dma_verbose = &sgiioc4_ide_dma_verbose;
-       hwif->ide_dma_retune = &__ide_dma_retune;
        hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
        hwif->ide_dma_timeout = &__ide_dma_timeout;
        hwif->INB = &sgiioc4_INB;
@@ -795,8 +794,6 @@ sgiioc4_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        if (pci_init_sgiioc4(dev, d))
                return 0;
 
-       MOD_INC_USE_COUNT;
-
        return 0;
 }
 
@@ -818,14 +815,7 @@ sgiioc4_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void
-sgiioc4_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(sgiioc4_ide_init);
-module_exit(sgiioc4_ide_exit);
 
 MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)");
 MODULE_DESCRIPTION("PCI driver module for SGI IOC4 Base-IO Card");
index 9128ad4..0202611 100644 (file)
@@ -1168,7 +1168,6 @@ static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_devi
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -1190,13 +1189,7 @@ static int siimage_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void siimage_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(siimage_ide_init);
-module_exit(siimage_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick, Alan Cox");
 MODULE_DESCRIPTION("PCI driver module for SiI IDE");
index 3068287..d8a8108 100644 (file)
@@ -953,7 +953,6 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -973,13 +972,7 @@ static int sis5513_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void sis5513_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(sis5513_ide_init);
-module_exit(sis5513_ide_exit);
 
 MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik");
 MODULE_DESCRIPTION("PCI driver module for SIS IDE");
index 4c060b9..1c721c5 100644 (file)
@@ -506,7 +506,6 @@ static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_dev
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -526,13 +525,7 @@ static int sl82c105_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void sl82c105_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(sl82c105_ide_init);
-module_exit(sl82c105_ide_exit);
 
 MODULE_DESCRIPTION("PCI driver module for W82C105 IDE");
 MODULE_LICENSE("GPL");
index 1f01228..11d07ea 100644 (file)
@@ -373,7 +373,6 @@ static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_dev
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -393,13 +392,7 @@ static int slc90e66_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void slc90e66_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(slc90e66_ide_init);
-module_exit(slc90e66_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for SLC90E66 IDE");
index cbb1b6a..471ed5e 100644 (file)
@@ -45,6 +45,7 @@
 
 static struct pci_dev *triflex_dev;
 
+#ifdef CONFIG_PROC_FS
 static int triflex_get_info(char *buf, char **addr, off_t offset, int count)
 {
        char *p = buf;
@@ -91,6 +92,7 @@ static int triflex_get_info(char *buf, char **addr, off_t offset, int count)
        
        return len > count ? count : len;
 }
+#endif
 
 static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed)
 {
@@ -224,7 +226,6 @@ static int __devinit triflex_init_one(struct pci_dev *dev,
        
        ide_setup_pci_device(dev, d);
        triflex_dev = dev;
-       MOD_INC_USE_COUNT;
        
        return 0;
 }
@@ -240,13 +241,7 @@ static int triflex_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void triflex_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(triflex_ide_init);
-module_exit(triflex_ide_exit);
 
 MODULE_AUTHOR("Torben Mathiasen");
 MODULE_DESCRIPTION("PCI driver module for Compaq Triflex IDE");
index 08ac52d..b208926 100644 (file)
 
 static unsigned int __devinit init_chipset_triflex(struct pci_dev *, const char *);
 static void init_hwif_triflex(ide_hwif_t *);
+#ifdef CONFIG_PROC_FS
 static int triflex_get_info(char *, char **, off_t, int);
 
+static ide_pci_host_proc_t triflex_proc __initdata = {
+       .name           = "triflex",
+       .set            = 1,
+       .get_info       = triflex_get_info,
+};
+#endif
+
 static ide_pci_device_t triflex_devices[] __devinitdata = {
        {
                .vendor         = PCI_VENDOR_ID_COMPAQ,
@@ -33,14 +41,6 @@ static ide_pci_device_t triflex_devices[] __devinitdata = {
        }
 };
 
-#ifdef CONFIG_PROC_FS
-static ide_pci_host_proc_t triflex_proc __initdata = {
-       .name           = "triflex",
-       .set            = 1,
-       .get_info       = triflex_get_info,
-};
-#endif
-
 static struct pci_device_id triflex_pci_tbl[] = {
        { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, PCI_ANY_ID, 
                PCI_ANY_ID, 0, 0, 0 },
index dfc7190..b1ed360 100644 (file)
@@ -403,7 +403,6 @@ static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_devic
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -423,13 +422,7 @@ static int trm290_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void trm290_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(trm290_ide_init);
-module_exit(trm290_ide_exit);
 
 MODULE_AUTHOR("Mark Lord");
 MODULE_DESCRIPTION("PCI driver module for Tekram TRM290 IDE");
index ee2628f..7a1ce9f 100644 (file)
@@ -615,7 +615,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
        if (dev->device != d->device)
                BUG();
        ide_setup_pci_device(dev, d);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -636,13 +635,7 @@ static int via_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
-static void via_ide_exit(void)
-{
-       ide_pci_unregister_driver(&driver);
-}
-
 module_init(via_ide_init);
-module_exit(via_ide_exit);
 
 MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick");
 MODULE_DESCRIPTION("PCI driver module for VIA IDE");
index c03ed38..a97f5a1 100644 (file)
@@ -2164,15 +2164,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        hwif->ide_dma_bad_drive = &__ide_dma_bad_drive;
        hwif->ide_dma_verbose = &__ide_dma_verbose;
        hwif->ide_dma_timeout = &__ide_dma_timeout;
-       hwif->ide_dma_retune = &__ide_dma_retune;
        hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
-       hwif->ide_dma_queued_on = &__ide_dma_queued_on;
-       hwif->ide_dma_queued_off = &__ide_dma_queued_off;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-       hwif->ide_dma_queued_read = __ide_dma_queued_read;
-       hwif->ide_dma_queued_write = __ide_dma_queued_write;
-       hwif->ide_dma_queued_start = __ide_dma_queued_start;
-#endif
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO
        if (!noautodma)
index a4143ad..230ac0b 100644 (file)
@@ -395,8 +395,8 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
        }
 }
 
-/* This function is called by register_netdev */
-static int ether1394_init_dev (struct net_device *dev)
+/* This function is called right before register_netdev */
+static void ether1394_init_dev (struct net_device *dev)
 {
        /* Our functions */
        dev->open               = ether1394_open;
@@ -423,8 +423,6 @@ static int ether1394_init_dev (struct net_device *dev)
        dev->type               = ARPHRD_IEEE1394;
 
        ether1394_reset_priv (dev, 1);
-
-       return 0;
 }
 
 /*
@@ -461,8 +459,6 @@ static void ether1394_add_host (struct hpsb_host *host)
 
        SET_MODULE_OWNER(dev);
 
-       dev->init = ether1394_init_dev;
-
        priv = (struct eth1394_priv *)dev->priv;
 
        spin_lock_init(&priv->lock);
@@ -483,6 +479,8 @@ static void ether1394_add_host (struct hpsb_host *host)
                goto out;
         }
 
+       ether1394_init_dev(dev);
+
        if (register_netdev (dev)) {
                ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n");
                goto out;
@@ -507,7 +505,7 @@ static void ether1394_add_host (struct hpsb_host *host)
 
 out:
        if (dev != NULL)
-               kfree(dev);
+               free_netdev(dev);
        if (hi)
                hpsb_destroy_hostinfo(&eth1394_highlevel, host);
 
index 91fdd5c..350b32a 100644 (file)
@@ -209,7 +209,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        struct evdev *evdev = list->evdev;
        struct input_dev *dev = evdev->handle.dev;
        struct input_absinfo abs;
-       int i, t, u, v;
+       int t, u, v;
 
        if (!evdev->exist) return -ENODEV;
 
@@ -231,10 +231,8 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                        if (get_user(t, ((int *) arg) + 0)) return -EFAULT;
                        if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
                        if (get_user(v, ((int *) arg) + 1)) return -EFAULT;
-                       u = INPUT_KEYCODE(dev, t);
-                       SET_INPUT_KEYCODE(dev, t, v);
-                       for (i = 0; i < dev->keycodemax; i++) if (v == u) break;
-                       if (i == dev->keycodemax) clear_bit(u, dev->keybit);
+                       u = SET_INPUT_KEYCODE(dev, t, v);
+                       clear_bit(u, dev->keybit);
                        set_bit(v, dev->keybit);
                        return 0;
 
index 9d757ce..0ee467e 100644 (file)
@@ -531,9 +531,7 @@ static struct db9 __init *db9_probe(int *config)
                return NULL;
        }
 
-       for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next)
-               config[0]--;
-
+       pp = parport_find_number(config[0]);
        if (!pp) {
                printk(KERN_ERR "db9.c: no such parport\n");
                return NULL;
@@ -542,12 +540,15 @@ static struct db9 __init *db9_probe(int *config)
        if (db9_bidirectional[config[1]]) {
                if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
                        printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
+                       parport_put_port(pp);
                        return NULL;
                }
        }
 
-       if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL)))
+       if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL))) {
+               parport_put_port(pp);
                return NULL;
+       }
        memset(db9, 0, sizeof(struct db9));
 
        db9->mode = config[1];
@@ -556,6 +557,7 @@ static struct db9 __init *db9_probe(int *config)
        db9->timer.function = db9_timer;
 
        db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+       parport_put_port(pp);
 
        if (!db9->pd) {
                printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
index ec5ece7..ae94ab8 100644 (file)
@@ -478,20 +478,23 @@ static struct gc __init *gc_probe(int *config)
        if (config[0] < 0)
                return NULL;
 
-       for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next)
-               config[0]--;
+       pp = parport_find_number(config[0]);
 
        if (!pp) {
                printk(KERN_ERR "gamecon.c: no such parport\n");
                return NULL;
        }
 
-       if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL)))
+       if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL))) {
+               parport_put_port(pp);
                return NULL;
+       }
        memset(gc, 0, sizeof(struct gc));
 
        gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
 
+       parport_put_port(pp);
+
        if (!gc->pd) {
                printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
                kfree(gc);
index 5ad4f8e..718e8f7 100644 (file)
@@ -142,19 +142,22 @@ static struct tgfx __init *tgfx_probe(int *config)
        if (config[0] < 0)
                return NULL;
 
-       for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next)
-               config[0]--;
+       pp = parport_find_number(config[0]);
 
        if (!pp) {
                printk(KERN_ERR "turbografx.c: no such parport\n");
                return NULL;
        }
 
-       if (!(tgfx = kmalloc(sizeof(struct tgfx), GFP_KERNEL)))
+       if (!(tgfx = kmalloc(sizeof(struct tgfx), GFP_KERNEL))) {
+               parport_put_port(pp);
                return NULL;
+       }
        memset(tgfx, 0, sizeof(struct tgfx));
 
        tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+               
+       parport_put_port(pp);
 
        if (!tgfx->pd) {
                printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
index 1fb1789..144bb86 100644 (file)
@@ -375,13 +375,14 @@ static char i8042_mux_phys[4][32];
 static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        unsigned long flags;
-       unsigned char str, data;
+       unsigned char str, data = 0;
        unsigned int dfl;
        int ret;
 
        spin_lock_irqsave(&i8042_lock, flags);
        str = i8042_read_status();
-       data = i8042_read_data();
+       if (str & I8042_STR_OBF)
+               data = i8042_read_data();
        spin_unlock_irqrestore(&i8042_lock, flags);
 
        if (~str & I8042_STR_OBF) {
index 1ee9e62..1df2dd1 100644 (file)
@@ -151,7 +151,7 @@ static int parkbd_getport(void)
                return -ENODEV;
        }
 
-       for (pp = parport_enumerate(); pp != NULL && (parkbd > 0); pp = pp->next) parkbd--;
+       pp = parport_find_number(parkbd);
 
        if (pp == NULL) {
                printk(KERN_ERR "parkbd: no such parport\n");
@@ -159,6 +159,7 @@ static int parkbd_getport(void)
        }
 
        parkbd_dev = parport_register_device(pp, "parkbd", NULL, NULL, parkbd_interrupt, PARPORT_DEV_EXCL, NULL);
+       parport_put_port(pp);
 
        if (!parkbd_dev)
                return -ENODEV;
index f5026cd..7cecab0 100644 (file)
@@ -4,7 +4,6 @@
 
 # Each configuration option enables a list of files.
 
-# Turn that into a separate config option
 obj-$(CONFIG_PPC_PMAC)         += macio_asic.o
 
 obj-$(CONFIG_PMAC_PBOOK)       += mediabay.o
@@ -26,4 +25,4 @@ obj-$(CONFIG_ADB_MACIO)               += macio-adb.o
 
 obj-$(CONFIG_THERM_PM72)       += therm_pm72.o
 obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o
-obj-$(CONFIG_THERM_IBOOKG4)    += therm_adt7467.o
+obj-$(CONFIG_THERM_ADT7467)    += therm_adt7467.o
index a519c4c..f0100c0 100644 (file)
@@ -2551,7 +2551,6 @@ powerbook_sleep_grackle(void)
        return 0;
 }
 
-
 static int __pmac
 powerbook_sleep_Core99(void)
 {
index 013bdf8..40efcf8 100644 (file)
@@ -205,7 +205,7 @@ config VIDEO_ZR36120
 
 config VIDEO_MEYE
        tristate "Sony Vaio Picturebook Motion Eye Video For Linux (EXPERIMENTAL)"
-       depends on VIDEO_DEV && SONYPI
+       depends on VIDEO_DEV && SONYPI && !HIGHMEM64G
        ---help---
          This is the video4linux driver for the Motion Eye camera found
          in the Vaio Picturebook laptops. Please read the material in
index c30faa3..c90ec3b 100644 (file)
@@ -958,45 +958,64 @@ static char *parport[MAX_CAMS] = { NULL, };
 MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "s");
 #endif
 
-static void __exit exit_bw_qcams(void)
+static int accept_bwqcam(struct parport *port)
 {
-       unsigned int i;
-
-       for (i = 0; i < num_cams; i++)
-               close_bwqcam(qcams[i]);
-}
-
-static int __init init_bw_qcams(void)
-{
-       struct parport *port;
 #ifdef MODULE
        int n;
-       
-       if(parport[0] && strncmp(parport[0], "auto", 4)){
+
+       if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
                /* user gave parport parameters */
                for(n=0; parport[n] && n<MAX_CAMS; n++){
                        char *ep;
                        unsigned long r;
                        r = simple_strtoul(parport[n], &ep, 0);
-                       if(ep == parport[n]){
+                       if (ep == parport[n]) {
                                printk(KERN_ERR
                                        "bw-qcam: bad port specifier \"%s\"\n",
                                        parport[n]);
                                continue;
                        }
-                       for (port=parport_enumerate(); port; port=port->next){
-                               if(r!=port->number)
-                                       continue;
-                               init_bwqcam(port);
-                               break;
-                       }
+                       if (r == port->number)
+                               return 1;
                }
-               return (num_cams)?0:-ENODEV;
-       } 
-       /* no parameter or "auto" */
-       for (port = parport_enumerate(); port; port=port->next)
+               return 0;
+       }
+#endif
+       return 1;
+}
+
+static void bwqcam_attach(struct parport *port)
+{
+       if (accept_bwqcam(port))
                init_bwqcam(port);
+}
 
+static void bwqcam_detach(struct parport *port)
+{
+       int i;
+       for (i = 0; i < num_cams; i++) {
+               struct qcam_device *qcam = qcams[i];
+               if (qcam && qcam->pdev->port == port) {
+                       qcams[i] = NULL;
+                       close_bwqcam(qcam);
+               }
+       }
+}
+
+static struct parport_driver bwqcam_driver = {
+       .name   = "bw-qcam",
+       .attach = bwqcam_attach,
+       .detach = bwqcam_detach,
+};
+
+static void __exit exit_bw_qcams(void)
+{
+       parport_unregister_driver(&bwqcam_driver);
+}
+
+static int __init init_bw_qcams(void)
+{
+#ifdef MODULE
        /* Do some sanity checks on the module parameters. */
        if (maxpoll > 5000) {
                printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
@@ -1007,13 +1026,8 @@ static int __init init_bw_qcams(void)
                printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
                yieldlines = 1;
        }
-
-       return (num_cams)?0:-ENODEV;
-#else
-       for (port = parport_enumerate(); port; port=port->next)
-               init_bwqcam(port);
-       return 0;
 #endif
+       return parport_register_driver(&bwqcam_driver);
 }
 
 module_init(init_bw_qcams);
index a8f6239..53d5722 100644 (file)
@@ -160,23 +160,29 @@ static void rvfree(void * mem, unsigned long size) {
        }
 }
 
-/* return a page table pointing to N pages of locked memory */
+/* return a page table pointing to N pages of locked memory
+ *
+ * NOTE: The meye device expects dma_addr_t size to be 32 bits
+ * (the toc must be exactly 1024 entries each of them being 4 bytes
+ * in size, the whole result being 4096 bytes). We're using here
+ * dma_addr_t for corectness but the compilation of this driver is
+ * disabled for HIGHMEM64G=y, where sizeof(dma_addr_t) != 4 */
 static int ptable_alloc(void) {
-       u32 *pt;
+       dma_addr_t *pt;
        int i;
 
        memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
 
-       meye.mchip_ptable[MCHIP_NB_PAGES] = dma_alloc_coherent(&meye.mchip_dev->dev, 
-                                                              PAGE_SIZE, 
-                                                              &meye.mchip_dmahandle,
-                                                              GFP_KERNEL);
-       if (!meye.mchip_ptable[MCHIP_NB_PAGES]) {
+       meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
+                                                  PAGE_SIZE,
+                                                  &meye.mchip_dmahandle,
+                                                  GFP_KERNEL);
+       if (!meye.mchip_ptable_toc) {
                meye.mchip_dmahandle = 0;
                return -1;
        }
 
-       pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
+       pt = meye.mchip_ptable_toc;
        for (i = 0; i < MCHIP_NB_PAGES; i++) {
                meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev, 
                                                          PAGE_SIZE,
@@ -184,13 +190,18 @@ static int ptable_alloc(void) {
                                                          GFP_KERNEL);
                if (!meye.mchip_ptable[i]) {
                        int j;
-                       pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
+                       pt = meye.mchip_ptable_toc;
                        for (j = 0; j < i; ++j) {
                                dma_free_coherent(&meye.mchip_dev->dev,
                                                  PAGE_SIZE,
                                                  meye.mchip_ptable[j], *pt);
                                pt++;
                        }
+                       dma_free_coherent(&meye.mchip_dev->dev,
+                                         PAGE_SIZE,
+                                         meye.mchip_ptable_toc,
+                                         meye.mchip_dmahandle);
+                       meye.mchip_ptable_toc = 0;
                        meye.mchip_dmahandle = 0;
                        return -1;
                }
@@ -200,10 +211,10 @@ static int ptable_alloc(void) {
 }
 
 static void ptable_free(void) {
-       u32 *pt;
+       dma_addr_t *pt;
        int i;
 
-       pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
+       pt = meye.mchip_ptable_toc;
        for (i = 0; i < MCHIP_NB_PAGES; i++) {
                if (meye.mchip_ptable[i])
                        dma_free_coherent(&meye.mchip_dev->dev, 
@@ -212,13 +223,14 @@ static void ptable_free(void) {
                pt++;
        }
 
-       if (meye.mchip_ptable[MCHIP_NB_PAGES])
+       if (meye.mchip_ptable_toc)
                dma_free_coherent(&meye.mchip_dev->dev, 
                                  PAGE_SIZE, 
-                                 meye.mchip_ptable[MCHIP_NB_PAGES],
+                                 meye.mchip_ptable_toc,
                                  meye.mchip_dmahandle);
 
        memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
+       meye.mchip_ptable_toc = 0;
        meye.mchip_dmahandle = 0;
 }
 
index 5e1f658..9ac3919 100644 (file)
@@ -298,7 +298,8 @@ struct meye {
        u8 mchip_fnum;                  /* current mchip frame number */
 
        unsigned char *mchip_mmregs;    /* mchip: memory mapped registers */
-       u8 *mchip_ptable[MCHIP_NB_PAGES+1];/* mchip: ptable + ptable toc */
+       u8 *mchip_ptable[MCHIP_NB_PAGES];/* mchip: ptable */
+       dma_addr_t *mchip_ptable_toc;   /* mchip: ptable toc */
        dma_addr_t mchip_dmahandle;     /* mchip: dma handle to ptable toc */
 
        unsigned char *grab_fbuffer;    /* capture framebuffer */
index bbb97e3..75d77dd 100644 (file)
@@ -87,11 +87,13 @@ struct msp3400c {
        int dfp_regs[DFP_COUNT];
 
        /* thread */
-       struct task_struct  *thread;
+       pid_t                tpid;
+       struct completion    texit;
        wait_queue_head_t    wq;
 
-       struct semaphore    *notify;
-       int                  active,restart,rmmod;
+       int                  active:1;
+       int                  restart:1;
+       int                  rmmod:1;
 
        int                  watch_stereo;
        struct timer_list    wake_stereo;
@@ -101,14 +103,12 @@ struct msp3400c {
 #define HAVE_SIMPLE(msp)  ((msp->rev1      & 0xff) >= 'D'-'@')
 #define HAVE_RADIO(msp)   ((msp->rev1      & 0xff) >= 'G'-'@')
 
-#define MSP3400_MAX 4
-static struct i2c_client *msps[MSP3400_MAX];
-
 #define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */
 
 /* ---------------------------------------------------------------------- */
 
-#define dprintk     if (debug) printk
+#define dprintk      if (debug >= 1) printk
+#define d2printk     if (debug >= 2) printk
 
 MODULE_PARM(once,"i");
 MODULE_PARM(debug,"i");
@@ -735,6 +735,22 @@ autodetect_stereo(struct i2c_client *client)
  * in the ioctl while doing the sound carrier & stereo detect
  */
 
+static int msp34xx_sleep(struct msp3400c *msp, int timeout)
+{
+       DECLARE_WAITQUEUE(wait, current);
+
+       add_wait_queue(&msp->wq, &wait);
+       if (!msp->rmmod) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (timeout < 0)
+                       schedule();
+               else
+                       schedule_timeout(timeout);
+       }
+       remove_wait_queue(&msp->wq, &wait);
+       return msp->rmmod || signal_pending(current);
+}
+
 static void msp3400c_stereo_wake(unsigned long data)
 {
        struct msp3400c *msp = (struct msp3400c*)data;   /* XXX alpha ??? */
@@ -771,26 +787,16 @@ static int msp3400c_thread(void *data)
        struct CARRIER_DETECT *cd;
        int count, max1,max2,val1,val2, val,this;
        
-       lock_kernel();
        daemonize("msp3400");
-       msp->thread = current;
-       unlock_kernel();
-
+       allow_signal(SIGTERM);
        printk("msp3400: daemon started\n");
-       if(msp->notify != NULL)
-               up(msp->notify);
 
        for (;;) {
-               if (msp->rmmod)
-                       goto done;
-               if (debug > 1)
-                       printk("msp3400: thread: sleep\n");
-               interruptible_sleep_on(&msp->wq);
-               if (debug > 1)
-                       printk("msp3400: thread: wakeup\n");
-               if (msp->rmmod || signal_pending(current))
+               d2printk("msp3400: thread: sleep\n");
+               if (msp34xx_sleep(msp,-1))
                        goto done;
 
+               d2printk("msp3400: thread: wakeup\n");
                msp->active = 1;
 
                if (msp->watch_stereo) {
@@ -800,9 +806,7 @@ static int msp3400c_thread(void *data)
                }
 
                /* some time for the tuner to sync */
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ/5);
-               if (signal_pending(current))
+               if (msp34xx_sleep(msp,HZ/5))
                        goto done;
                
        restart:
@@ -835,9 +839,7 @@ static int msp3400c_thread(void *data)
                for (this = 0; this < count; this++) {
                        msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
 
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(HZ/10);
-                       if (signal_pending(current))
+                       if (msp34xx_sleep(msp,HZ/10))
                                goto done;
                        if (msp->restart)
                                msp->restart = 0;
@@ -872,9 +874,7 @@ static int msp3400c_thread(void *data)
                for (this = 0; this < count; this++) {
                        msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
 
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(HZ/10);
-                       if (signal_pending(current))
+                       if (msp34xx_sleep(msp,HZ/10))
                                goto done;
                        if (msp->restart)
                                goto restart;
@@ -973,13 +973,9 @@ static int msp3400c_thread(void *data)
        }
 
 done:
-       dprintk(KERN_DEBUG "msp3400: thread: exit\n");
        msp->active = 0;
-       msp->thread = NULL;
-
-       if(msp->notify != NULL)
-               up(msp->notify);
-       return 0;
+       dprintk(KERN_DEBUG "msp3400: thread: exit\n");
+        complete_and_exit(&msp->texit, 0);
 }
 
 /* ----------------------------------------------------------------------- */
@@ -1019,26 +1015,16 @@ static int msp3410d_thread(void *data)
        struct msp3400c *msp = i2c_get_clientdata(client);
        int mode,val,i,std;
     
-       lock_kernel();
        daemonize("msp3410 [auto]");
-       msp->thread = current;
-       unlock_kernel();
-
+       allow_signal(SIGTERM);
        printk("msp3410: daemon started\n");
-       if(msp->notify != NULL)
-               up(msp->notify);
-               
+
        for (;;) {
-               if (msp->rmmod)
-                       goto done;
-               if (debug > 1)
-                       printk(KERN_DEBUG "msp3410: thread: sleep\n");
-               interruptible_sleep_on(&msp->wq);
-               if (debug > 1)
-                       printk(KERN_DEBUG "msp3410: thread: wakeup\n");
-               if (msp->rmmod || signal_pending(current))
+               d2printk(KERN_DEBUG "msp3410: thread: sleep\n");
+               if (msp34xx_sleep(msp,-1))
                        goto done;
 
+               d2printk(KERN_DEBUG "msp3410: thread: wakeup\n");
                msp->active = 1;
 
                if (msp->watch_stereo) {
@@ -1048,9 +1034,7 @@ static int msp3410d_thread(void *data)
                }
        
                /* some time for the tuner to sync */
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ/5);
-               if (signal_pending(current))
+               if (msp34xx_sleep(msp,HZ/5))
                        goto done;
 
        restart:
@@ -1109,9 +1093,7 @@ static int msp3410d_thread(void *data)
                } else {
                        /* triggered autodetect */
                        for (;;) {
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule_timeout(HZ/10);
-                               if (signal_pending(current))
+                               if (msp34xx_sleep(msp,HZ/10))
                                        goto done;
                                if (msp->restart)
                                        goto restart;
@@ -1222,12 +1204,9 @@ static int msp3410d_thread(void *data)
        }
 
 done:
-       dprintk(KERN_DEBUG "msp3410: thread: exit\n");
        msp->active = 0;
-       msp->thread = NULL;
-
-       if(msp->notify != NULL)
-               up(msp->notify);
+       dprintk(KERN_DEBUG "msp3410: thread: exit\n");
+        complete_and_exit(&msp->texit, 0);
        return 0;
 }
 
@@ -1257,10 +1236,9 @@ static struct i2c_client client_template =
 
 static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
 {
-       DECLARE_MUTEX_LOCKED(sem);
        struct msp3400c *msp;
         struct i2c_client *c;
-       int i, rc;
+       int i;
 
         client_template.adapter = adap;
         client_template.addr = addr;
@@ -1342,24 +1320,13 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
        printk("\n");
 
        /* startup control thread */
-       msp->notify = &sem;
-       rc = kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread,
-                          (void *)c, 0);
-       if (rc < 0)
+       init_completion(&msp->texit);
+       msp->tpid = kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread,
+                                 (void *)c, 0);
+       if (msp->tpid < 0)
                printk(KERN_WARNING "msp34xx: kernel_thread() failed\n");
-       else
-               down(&sem);
-       msp->notify = NULL;
        wake_up_interruptible(&msp->wq);
 
-       /* update our own array */
-       for (i = 0; i < MSP3400_MAX; i++) {
-               if (NULL == msps[i]) {
-                       msps[i] = c;
-                       break;
-               }
-       }
-       
        /* done */
         i2c_attach_client(c);
        return 0;
@@ -1367,30 +1334,17 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
 
 static int msp_detach(struct i2c_client *client)
 {
-       DECLARE_MUTEX_LOCKED(sem);
        struct msp3400c *msp  = i2c_get_clientdata(client);
-       int i;
        
        /* shutdown control thread */
-       del_timer(&msp->wake_stereo);
-       if (msp->thread) 
-       {
-               msp->notify = &sem;
+       del_timer_sync(&msp->wake_stereo);
+       if (msp->tpid >= 0) {
                msp->rmmod = 1;
                wake_up_interruptible(&msp->wq);
-               down(&sem);
-               msp->notify = NULL;
+               wait_for_completion(&msp->texit);
        }
        msp3400c_reset(client);
 
-        /* update our own array */
-       for (i = 0; i < MSP3400_MAX; i++) {
-               if (client == msps[i]) {
-                       msps[i] = NULL;
-                       break;
-               }
-       }
-
        i2c_detach_client(client);
        kfree(msp);
        kfree(client);
@@ -1403,8 +1357,13 @@ static int msp_probe(struct i2c_adapter *adap)
        if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
                return i2c_probe(adap, &addr_data, msp_attach);
 #else
-       if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
+       switch (adap->id) {
+       case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
+       case I2C_ALGO_BIT | I2C_HW_B_BT848:
+       //case I2C_ALGO_SAA7134:
                return i2c_probe(adap, &addr_data, msp_attach);
+               break;
+       }
 #endif
        return 0;
 }
index 7bb3565..f60777a 100644 (file)
@@ -834,7 +834,7 @@ struct saa7134_board saa7134_boards[] = {
                }},
        },
         [SAA7134_BOARD_ECS_TVP3XP] = {
-                .name           = "Elitegroup ECS TVP3XP FM1216 Tuner Card",
+                .name           = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
                 .audio_clock    = 0x187de7,  // xtal 32.1 MHz
                 .tuner_type     = TUNER_PHILIPS_PAL,
                 .inputs         = {{
@@ -865,6 +865,82 @@ struct saa7134_board saa7134_boards[] = {
                         .amux   = LINE2,
                 },
         },
+        [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
+                .name           = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
+                .audio_clock    = 0x187de7,
+                .tuner_type     = TUNER_PHILIPS_NTSC,
+                .inputs         = {{
+                        .name   = name_tv,
+                        .vmux   = 1,
+                        .amux   = TV,
+                        .tv     = 1,
+                },{
+                        .name   = name_tv_mono,
+                        .vmux   = 1,
+                        .amux   = LINE2,
+                        .tv     = 1,
+                },{
+                        .name   = name_comp1,
+                        .vmux   = 3,
+                        .amux   = LINE1,
+                },{
+                        .name   = name_svideo,
+                        .vmux   = 8,
+                        .amux   = LINE1,
+                },{
+                        .name   = "CVid over SVid",
+                        .vmux   = 0,
+                        .amux   = LINE1,
+                }},
+                .radio = {
+                        .name   = name_radio,
+                        .amux   = LINE2,
+                },
+        },
+       [SAA7134_BOARD_AVACSSMARTTV] = {
+               /* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
+               .name           = "AVACS SmartTV",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_PAL,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 1,
+                       .amux = TV,
+                       .tv   = 1,
+                },{
+                       .name = name_tv_mono,
+                       .vmux = 1,
+                       .amux = LINE2,
+                       .tv   = 1,
+               },{
+                       .name = name_comp1,
+                       .vmux = 0,
+                       .amux = LINE2,
+               },{
+                       .name = name_comp2,
+                       .vmux = 3,
+                       .amux = LINE2,
+               },{
+                       .name = name_svideo,
+                       .vmux = 8,
+                       .amux = LINE2,
+               }},
+               .radio = {
+                       .name = name_radio,
+                       .amux = LINE2,
+                       .gpio = 0x200000,
+               },
+       },
+       [SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER] = {
+               /* Michael Smith <msmith@cbnco.com> */
+               .name           = "AVerMedia DVD EZMaker",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_ABSENT,
+               .inputs         = {{
+                       .name = name_comp1,
+                       .vmux = 3,
+               }},
+       },
 };
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
 
@@ -1023,6 +1099,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                 .subvendor    = 0x1461, /* Avermedia Technologies Inc */
                 .subdevice    = 0x2115,
                .driver_data  = SAA7134_BOARD_MD2819,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+                .subvendor    = 0x1461, /* Avermedia Technologies Inc */
+                .subdevice    = 0x10ff,
+               .driver_data  = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
         },{
                /* TransGear 3000TV */
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -1043,6 +1125,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                 .subdevice    = 0x4cb4,
                 .driver_data  = SAA7134_BOARD_ECS_TVP3XP,
         },{
+                .vendor       = PCI_VENDOR_ID_PHILIPS,
+                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+                .subvendor    = 0x1019,
+                .subdevice    = 0x4cb5,
+                .driver_data  = SAA7134_BOARD_ECS_TVP3XP_4CB5,
+        },{
                
                /* --- boards without eeprom + subsystem ID --- */
                 .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -1149,6 +1237,8 @@ int saa7134_board_init(struct saa7134_dev *dev)
                break;
        case SAA7134_BOARD_CINERGY400:
        case SAA7134_BOARD_CINERGY600:
+       case SAA7134_BOARD_ECS_TVP3XP:
+       case SAA7134_BOARD_ECS_TVP3XP_4CB5:
                dev->has_remote = 1;
                break;
        }
index 9a39e8c..9dfb484 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * handle saa7134 IR remotes via linux kernel input layer.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -13,9 +15,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
 #include <linux/module.h>
@@ -101,6 +100,63 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
        [ 0x23 ] = KEY_STOP,
 };
 
+/* Alfons Geser <a.geser@cox.net> */
+static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
+        [ 18 ] = KEY_POWER,
+        [  1 ] = KEY_TV,             // DVR
+        [ 21 ] = KEY_VIDEO,          // DVD
+        [ 23 ] = KEY_AUDIO,          // music
+
+                                     // DVR mode / DVD mode / music mode
+
+        [ 27 ] = KEY_MUTE,           // mute
+        [  2 ] = KEY_RESERVED,       // MTS/SAP / audio /autoseek
+        [ 30 ] = KEY_RESERVED,       // closed captioning / subtitle / seek
+        [ 22 ] = KEY_ZOOM,           // full screen
+        [ 28 ] = KEY_RESERVED,       // video source / eject /delall
+        [ 29 ] = KEY_RESERVED,       // playback / angle /del
+        [ 47 ] = KEY_SEARCH,         // scan / menu / playlist
+        [ 48 ] = KEY_RESERVED,       // CH surfing / bookmark / memo
+
+        [ 49 ] = KEY_HELP,           // help
+        [ 50 ] = KEY_RESERVED,       // num/memo
+        [ 51 ] = KEY_ESC,            // cancel
+
+       [ 12 ] = KEY_UP,             // up
+       [ 16 ] = KEY_DOWN,           // down
+       [  8 ] = KEY_LEFT,           // left
+       [  4 ] = KEY_RIGHT,          // right
+       [  3 ] = KEY_ENTER,          // select
+
+       [ 31 ] = KEY_REWIND,         // rewind
+       [ 32 ] = KEY_PLAYPAUSE,      // play/pause
+       [ 41 ] = KEY_FORWARD,        // forward
+       [ 20 ] = KEY_RESERVED,       // repeat
+       [ 43 ] = KEY_RECORD,         // recording
+       [ 44 ] = KEY_STOP,           // stop
+       [ 45 ] = KEY_PLAY,           // play
+       [ 46 ] = KEY_RESERVED,       // snapshot
+
+        [  0 ] = KEY_KP0,
+        [  5 ] = KEY_KP1,
+        [  6 ] = KEY_KP2,
+        [  7 ] = KEY_KP3,
+        [  9 ] = KEY_KP4,
+        [ 10 ] = KEY_KP5,
+        [ 11 ] = KEY_KP6,
+        [ 13 ] = KEY_KP7,
+        [ 14 ] = KEY_KP8,
+        [ 15 ] = KEY_KP9,
+
+        [ 42 ] = KEY_VOLUMEUP,
+        [ 17 ] = KEY_VOLUMEDOWN,
+        [ 24 ] = KEY_CHANNELUP,      // CH.tracking up
+        [ 25 ] = KEY_CHANNELDOWN,    // CH.tracking down
+
+        [ 19 ] = KEY_KPENTER,        // enter
+        [ 33 ] = KEY_KPDOT,          // . (decimal dot)
+};
+
 /* ---------------------------------------------------------------------- */
 
 static int build_key(struct saa7134_dev *dev)
@@ -111,9 +167,15 @@ static int build_key(struct saa7134_dev *dev)
        /* rising SAA7134_GPIO_GPRESCAN reads the status */
        saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
        saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
+
        gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
-       data = ir_extract_bits(gpio, ir->mask_keycode);
+        if (ir->polling) {
+                if (ir->last_gpio == gpio)
+                        return 0;
+                ir->last_gpio = gpio;
+        }
 
+       data = ir_extract_bits(gpio, ir->mask_keycode);
        printk("%s: build_key gpio=0x%x mask=0x%x data=%d\n",
               dev->name, gpio, ir->mask_keycode, data);
 
@@ -130,7 +192,21 @@ static int build_key(struct saa7134_dev *dev)
 
 void saa7134_input_irq(struct saa7134_dev *dev)
 {
+        struct saa7134_ir *ir = dev->remote;
+
+        if (!ir->polling)
+               build_key(dev);
+}
+
+static void saa7134_input_timer(unsigned long data)
+{
+       struct saa7134_dev *dev = (struct saa7134_dev*)data;
+       struct saa7134_ir *ir = dev->remote;
+       unsigned long timeout;
+
        build_key(dev);
+       timeout = jiffies + (ir->polling * HZ / 1000);
+       mod_timer(&ir->timer, timeout);
 }
 
 int saa7134_input_init1(struct saa7134_dev *dev)
@@ -140,6 +216,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        u32 mask_keycode = 0;
        u32 mask_keydown = 0;
        u32 mask_keyup   = 0;
+       int polling      = 0;
        int ir_type      = IR_TYPE_OTHER;
 
        /* detect & configure */
@@ -158,6 +235,13 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                mask_keycode = 0x00003f;
                mask_keyup   = 0x040000;
                break;
+       case SAA7134_BOARD_ECS_TVP3XP:
+       case SAA7134_BOARD_ECS_TVP3XP_4CB5:
+                ir_codes     = eztv_codes;
+                mask_keycode = 0x00017c;
+                mask_keyup   = 0x000002;
+               polling      = 50; // ms
+                break;
        }
        if (NULL == ir_codes) {
                printk("%s: Oops: IR config error [card=%d]\n",
@@ -174,6 +258,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        ir->mask_keycode = mask_keycode;
        ir->mask_keydown = mask_keydown;
        ir->mask_keyup   = mask_keyup;
+        ir->polling      = polling;
        
        /* init input device */
        snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -196,6 +281,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 
        /* all done */
        dev->remote = ir;
+       if (ir->polling) {
+               init_timer(&ir->timer);
+               ir->timer.function = saa7134_input_timer;
+               ir->timer.data     = (unsigned long)dev;
+               ir->timer.expires  = jiffies + HZ;
+               add_timer(&ir->timer);
+       }
+
        input_register_device(&dev->remote->dev);
        printk("%s: registered input device for IR\n",dev->name);
        return 0;
@@ -207,6 +300,8 @@ void saa7134_input_fini(struct saa7134_dev *dev)
                return;
        
        input_unregister_device(&dev->remote->dev);
+       if (dev->remote->polling)
+               del_timer_sync(&dev->remote->timer);
        kfree(dev->remote);
        dev->remote = NULL;
 }
index 983497a..907b865 100644 (file)
@@ -45,6 +45,9 @@ static unsigned int audio_ddep = 0;
 MODULE_PARM(audio_ddep,"i");
 MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite");
 
+static int audio_clock_override = UNSET;
+MODULE_PARM(audio_clock_override, "i");
+
 static int audio_clock_tweak = 0;
 MODULE_PARM(audio_clock_tweak, "i");
 MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
@@ -140,6 +143,9 @@ static void tvaudio_init(struct saa7134_dev *dev)
 {
        int clock = saa7134_boards[dev->board].audio_clock;
 
+       if (UNSET != audio_clock_override)
+               clock = audio_clock_override;
+
        /* init all audio registers */
        saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x00);
        if (need_resched())
@@ -296,8 +302,13 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
        DECLARE_WAITQUEUE(wait, current);
        
        add_wait_queue(&dev->thread.wq, &wait);
-       set_current_state(TASK_INTERRUPTIBLE);
-       schedule_timeout(timeout);
+       if (dev->thread.scan1 == dev->thread.scan2 && !dev->thread.shutdown) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (timeout < 0)
+                       schedule();
+               else
+                       schedule_timeout(timeout);
+       }
        remove_wait_queue(&dev->thread.wq, &wait);
        return dev->thread.scan1 != dev->thread.scan2;
 }
@@ -457,18 +468,11 @@ static int tvaudio_thread(void *data)
        unsigned int i, audio;
        int max1,max2,carrier,rx,mode,lastmode;
 
-       lock_kernel();
        daemonize("%s", dev->name);
-       dev->thread.task = current;
-       unlock_kernel();
-       if (dev->thread.notify != NULL)
-               up(dev->thread.notify);
-
+       allow_signal(SIGTERM);
        for (;;) {
-               if (dev->thread.exit || signal_pending(current))
-                       goto done;
-               interruptible_sleep_on(&dev->thread.wq);
-               if (dev->thread.exit || signal_pending(current))
+               tvaudio_sleep(dev,-1);
+               if (dev->thread.shutdown || signal_pending(current))
                        goto done;
 
        restart:
@@ -571,7 +575,7 @@ static int tvaudio_thread(void *data)
                for (;;) {
                        if (tvaudio_sleep(dev,5*HZ))
                                goto restart;
-                       if (dev->thread.exit || signal_pending(current))
+                       if (dev->thread.shutdown || signal_pending(current))
                                break;
                        if (UNSET == dev->thread.mode) {
                                rx = tvaudio_getstereo(dev,&tvaudio[i]);
@@ -587,9 +591,7 @@ static int tvaudio_thread(void *data)
        }
 
  done:
-       dev->thread.task = NULL;
-       if(dev->thread.notify != NULL)
-               up(dev->thread.notify);
+       complete_and_exit(&dev->thread.exit, 0);
        return 0;
 }
 
@@ -721,22 +723,16 @@ static int tvaudio_thread_ddep(void *data)
        struct saa7134_dev *dev = data;
        u32 value, norms;
 
-       lock_kernel();
        daemonize("%s", dev->name);
-       dev->thread.task = current;
-       unlock_kernel();
-       if (dev->thread.notify != NULL)
-               up(dev->thread.notify);
+       allow_signal(SIGTERM);
 
        /* unmute */
        saa_dsp_writel(dev, 0x474 >> 2, 0x00);
        saa_dsp_writel(dev, 0x450 >> 2, 0x00);
 
        for (;;) {
-               if (dev->thread.exit || signal_pending(current))
-                       goto done;
-               interruptible_sleep_on(&dev->thread.wq);
-               if (dev->thread.exit || signal_pending(current))
+               tvaudio_sleep(dev,-1);
+               if (dev->thread.shutdown || signal_pending(current))
                        goto done;
 
        restart:
@@ -808,9 +804,7 @@ static int tvaudio_thread_ddep(void *data)
        }
 
  done:
-       dev->thread.task = NULL;
-       if(dev->thread.notify != NULL)
-               up(dev->thread.notify);
+       complete_and_exit(&dev->thread.exit, 0);
        return 0;
 }
 
@@ -893,7 +887,6 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
 {
        DECLARE_MUTEX_LOCKED(sem);
        int (*my_thread)(void *data) = NULL;
-       int rc;
 
        /* enable I2S audio output */
        if (saa7134_boards[dev->board].i2s_rate) {
@@ -915,17 +908,16 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
                my_thread = tvaudio_thread_ddep;
                break;
        }
+
+       dev->thread.pid = -1;
        if (my_thread) {
                /* start tvaudio thread */
                init_waitqueue_head(&dev->thread.wq);
-               dev->thread.notify = &sem;
-               rc = kernel_thread(my_thread,dev,0);
-               if (rc < 0)
+               init_completion(&dev->thread.exit);
+               dev->thread.pid = kernel_thread(my_thread,dev,0);
+               if (dev->thread.pid < 0)
                        printk(KERN_WARNING "%s: kernel_thread() failed\n",
                               dev->name);
-               else
-                       down(&sem);
-               dev->thread.notify = NULL;
                wake_up_interruptible(&dev->thread.wq);
        }
 
@@ -934,15 +926,11 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
 
 int saa7134_tvaudio_fini(struct saa7134_dev *dev)
 {
-       DECLARE_MUTEX_LOCKED(sem);
-
        /* shutdown tvaudio thread */
-       if (dev->thread.task) {
-               dev->thread.notify = &sem;
-               dev->thread.exit = 1;
+       if (dev->thread.pid >= 0) {
+               dev->thread.shutdown = 1;
                wake_up_interruptible(&dev->thread.wq);
-               down(&sem);
-               dev->thread.notify = NULL;
+               wait_for_completion(&dev->thread.exit);
        }
        saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
        return 0;
@@ -950,7 +938,7 @@ int saa7134_tvaudio_fini(struct saa7134_dev *dev)
 
 int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
 {
-       if (dev->thread.task) {
+       if (dev->thread.pid >= 0) {
                dev->thread.mode = UNSET;
                dev->thread.scan2++;
                wake_up_interruptible(&dev->thread.wq);
index 9ba0cf9..9c14b7e 100644 (file)
@@ -151,6 +151,9 @@ struct saa7134_format {
 #define SAA7134_BOARD_MANLI_MTV001     28
 #define SAA7134_BOARD_TG3000TV         29
 #define SAA7134_BOARD_ECS_TVP3XP       30
+#define SAA7134_BOARD_ECS_TVP3XP_4CB5  31
+#define SAA7134_BOARD_AVACSSMARTTV     32
+#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
 
 #define SAA7134_INPUT_MAX 8
 
@@ -212,10 +215,10 @@ struct saa7134_pgtable {
 
 /* tvaudio thread status */
 struct saa7134_thread {
-       struct task_struct         *task;
+       pid_t                      pid;
+       struct completion          exit;
        wait_queue_head_t          wq;
-       struct semaphore           *notify;
-       unsigned int               exit;
+       unsigned int               shutdown;
        unsigned int               scan1;
        unsigned int               scan2;
        unsigned int               mode;
@@ -319,6 +322,9 @@ struct saa7134_ir {
        u32                        mask_keycode;
        u32                        mask_keydown;
        u32                        mask_keyup;
+        int                        polling;
+        u32                        last_gpio;
+        struct timer_list          timer;
 };
 
 /* global device status */
index 5b1ceb9..aef7016 100644 (file)
     
 
 /* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {0x86>>1,0x86>>1,I2C_CLIENT_END};
+static unsigned short normal_i2c[] = {
+       0x86 >>1,
+       0x96 >>1,
+       I2C_CLIENT_END,
+};
+static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
 /* insmod options */
index ab46bb9..7f90530 100644 (file)
@@ -746,6 +746,7 @@ static int microtune_init(struct i2c_client *c)
         printk("tuner: microtune: companycode=%04x part=%02x rev=%02x\n",
               company_code,buf[0x13],buf[0x14]);
        switch (company_code) {
+       case 0x30bf:
        case 0x3cbf:
        case 0x3dbf:
        case 0x4d54:
@@ -1060,6 +1061,7 @@ static int tuner_probe(struct i2c_adapter *adap)
                return i2c_probe(adap, &addr_data, tuner_attach);
 #else
        switch (adap->id) {
+       case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
        case I2C_ALGO_BIT | I2C_HW_B_BT848:
        case I2C_ALGO_BIT | I2C_HW_B_RIVA:
        case I2C_ALGO_SAA7134:
index 81f0244..ce2588a 100644 (file)
@@ -122,9 +122,10 @@ struct CHIPSTATE {
        __u16 left,right,treble,bass,mode;
        int prevmode;
        int norm;
+
        /* thread */
-       struct task_struct  *thread;
-       struct semaphore    *notify;
+       pid_t                tpid;
+       struct completion    texit;
        wait_queue_head_t    wq;
        struct timer_list    wt;
        int                  done;
@@ -269,23 +270,24 @@ static void chip_thread_wake(unsigned long data)
 
 static int chip_thread(void *data)
 {
+       DECLARE_WAITQUEUE(wait, current);
         struct CHIPSTATE *chip = data;
        struct CHIPDESC  *desc = chiplist + chip->type;
        
-       lock_kernel();
        daemonize("%s",i2c_clientname(&chip->c));
-       chip->thread = current;
-       unlock_kernel();
-
+       allow_signal(SIGTERM);
        dprintk("%s: thread started\n", i2c_clientname(&chip->c));
-       if(chip->notify != NULL)
-               up(chip->notify);
 
        for (;;) {
-               interruptible_sleep_on(&chip->wq);
-               dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
+               add_wait_queue(&chip->wq, &wait);
+               if (!chip->done) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule();
+               }
+               remove_wait_queue(&chip->wq, &wait);
                if (chip->done || signal_pending(current))
                        break;
+               dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
 
                /* don't do anything for radio or if mode != auto */
                if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0)
@@ -298,11 +300,8 @@ static int chip_thread(void *data)
                mod_timer(&chip->wt, jiffies+2*HZ);
        }
 
-       chip->thread = NULL;
        dprintk("%s: thread exiting\n", i2c_clientname(&chip->c));
-       if(chip->notify != NULL)
-               up(chip->notify);
-
+        complete_and_exit(&chip->texit, 0);
        return 0;
 }
 
@@ -1420,7 +1419,6 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
 {
        struct CHIPSTATE *chip;
        struct CHIPDESC  *desc;
-       int rc;
 
        chip = kmalloc(sizeof(*chip),GFP_KERNEL);
        if (!chip)
@@ -1480,21 +1478,18 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
                chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
        }
 
+       chip->tpid = -1;
        if (desc->checkmode) {
                /* start async thread */
-               DECLARE_MUTEX_LOCKED(sem);
-               chip->notify = &sem;
                init_timer(&chip->wt);
                chip->wt.function = chip_thread_wake;
                chip->wt.data     = (unsigned long)chip;
                init_waitqueue_head(&chip->wq);
-               rc = kernel_thread(chip_thread,(void *)chip,0);
-               if (rc < 0)
+               init_completion(&chip->texit);
+               chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
+               if (chip->tpid < 0)
                        printk(KERN_WARNING "%s: kernel_thread() failed\n",
                               i2c_clientname(&chip->c));
-               else
-                       down(&sem);
-               chip->notify = NULL;
                wake_up_interruptible(&chip->wq);
        }
        return 0;
@@ -1520,15 +1515,12 @@ static int chip_detach(struct i2c_client *client)
 {
        struct CHIPSTATE *chip = i2c_get_clientdata(client);
 
-       del_timer(&chip->wt);
-       if (NULL != chip->thread) {
+       del_timer_sync(&chip->wt);
+       if (chip->tpid >= 0) {
                /* shutdown async thread */
-               DECLARE_MUTEX_LOCKED(sem);
-               chip->notify = &sem;
                chip->done = 1;
                wake_up_interruptible(&chip->wq);
-               down(&sem);
-               chip->notify = NULL;
+               wait_for_completion(&chip->texit);
        }
        
        i2c_detach_client(&chip->c);
index 9547482..677eb16 100644 (file)
@@ -134,6 +134,8 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
                va.volume  = max(left,right);
                va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
                va.balance = (left<right) ? (65535-va.balance) : va.balance;
+               if (va.volume)
+                       va.flags &= ~VIDEO_AUDIO_MUTE;
                client->driver->command(client,VIDIOCSAUDIO,&va);
                client->driver->command(client,VIDIOCGAUDIO,&va);
                /* fall throuth */
@@ -267,6 +269,7 @@ static int tvmixer_clients(struct i2c_client *client)
 #else
        /* TV card ??? */
        switch (client->adapter->id) {
+       case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
        case I2C_ALGO_BIT | I2C_HW_B_BT848:
        case I2C_ALGO_BIT | I2C_HW_B_RIVA:
                /* ok, have a look ... */
index 585fc68..0359bae 100644 (file)
@@ -198,7 +198,7 @@ static int  mptscsih_setup(char *str);
 
 /* module entry point */
 static int  __init    mptscsih_init  (void);
-static void __exit    mptscsih_exit  (void);
+static void    mptscsih_exit  (void);
 
 static int  __devinit mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
 static void __devexit mptscsih_remove(struct pci_dev *);
@@ -1985,7 +1985,7 @@ __init mptscsih_init(void)
  *
  */
 static void
-__exit mptscsih_exit(void)
+mptscsih_exit(void)
 {
        MPT_ADAPTER     *ioc;
 
index b5b199e..599591c 100644 (file)
@@ -136,17 +136,14 @@ static const char version[] =
 
 #include "3c501.h"
 
-/* A zero-terminated list of I/O addresses to be probed.
-   The 3c501 can be at many locations, but here are the popular ones. */
-static unsigned int netcard_portlist[] __initdata = { 
-       0x280, 0x300, 0
-};
-
-
 /*
  *     The boilerplate probe code.
  */
 
+static int io=0x280;
+static int irq=5;
+static int mem_start;
+
 /**
  * el1_probe:          -       probe for a 3c501
  * @dev: The device structure passed in to probe. 
@@ -160,23 +157,47 @@ static unsigned int netcard_portlist[] __initdata = {
  * probe and failing to find anything.
  */
  
-int __init el1_probe(struct net_device *dev)
+struct net_device * __init el1_probe(int unit)
 {
-       int i;
-       int base_addr = dev->base_addr;
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       static unsigned ports[] = { 0x280, 0x300, 0};
+       unsigned *port;
+       int err = 0;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+               mem_start = dev->mem_start & 7;
+       }
 
        SET_MODULE_OWNER(dev);
 
-       if (base_addr > 0x1ff)  /* Check a single specified location. */
-               return el1_probe1(dev, base_addr);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
-
-       for (i = 0; netcard_portlist[i]; i++)
-               if (el1_probe1(dev, netcard_portlist[i]) == 0)
-                       return 0;
-
-       return -ENODEV;
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = el1_probe1(dev, io);
+       } else if (io != 0) {
+               err = -ENXIO;           /* Don't probe at all. */
+       } else {
+               for (port = ports; *port && el1_probe1(dev, *port); port++)
+                       ;
+               if (!*port)
+                       err = -ENODEV;
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, EL1_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /**
@@ -240,6 +261,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
         *      high.
         */
 
+       dev->irq = irq;
+
        if (dev->irq < 2)
        {
                unsigned long irq_mask;
@@ -267,8 +290,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
        dev->base_addr = ioaddr;
        memcpy(dev->dev_addr, station_addr, ETH_ALEN);
 
-       if (dev->mem_start & 0xf)
-               el_debug = dev->mem_start & 0x7;
+       if (mem_start & 0xf)
+               el_debug = mem_start & 0x7;
        if (autoirq)
                dev->irq = autoirq;
 
@@ -282,17 +305,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
        if (el_debug)
                printk(KERN_DEBUG "%s", version);
 
-       /*
-        *      Initialize the device structure.
-        */
-
-       dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev->priv == NULL) {
-               release_region(ioaddr, EL1_IO_EXTENT);
-               return -ENOMEM;
-       }
        memset(dev->priv, 0, sizeof(struct net_local));
-
        lp=dev->priv;
        spin_lock_init(&lp->lock);
        
@@ -308,13 +321,6 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
        dev->get_stats = &el1_get_stats;
        dev->set_multicast_list = &set_multicast_list;
        dev->ethtool_ops = &netdev_ethtool_ops;
-
-       /*
-        *      Setup the generic properties
-        */
-
-       ether_setup(dev);
-
        return 0;
 }
 
@@ -884,14 +890,8 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 #ifdef MODULE
 
-static struct net_device dev_3c501 = {
-       .init           = el1_probe,
-       .base_addr      = 0x280,
-       .irq            = 5,
-};
+static struct net_device *dev_3c501;
 
-static int io=0x280;
-static int irq=5;
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(io, "EtherLink I/O base address");
@@ -911,10 +911,9 @@ MODULE_PARM_DESC(irq, "EtherLink IRQ number");
  
 int init_module(void)
 {
-       dev_3c501.irq=irq;
-       dev_3c501.base_addr=io;
-       if (register_netdev(&dev_3c501) != 0)
-               return -EIO;
+       dev_3c501 = el1_probe(-1);
+       if (IS_ERR(dev_3c501))
+               return PTR_ERR(dev_3c501);
        return 0;
 }
 
@@ -927,19 +926,10 @@ int init_module(void)
  
 void cleanup_module(void)
 {
-       unregister_netdev(&dev_3c501);
-
-       /*
-        *      Free up the private structure, or leak memory :-)
-        */
-
-       kfree(dev_3c501.priv);
-       dev_3c501.priv = NULL;  /* gets re-allocated by el1_probe1 */
-
-       /*
-        *      If we don't do this, we can't re-insmod it later.
-        */
-       release_region(dev_3c501.base_addr, EL1_IO_EXTENT);
+       struct net_device *dev = dev_3c501;
+       unregister_netdev(dev);
+       release_region(dev->base_addr, EL1_IO_EXTENT);
+       free_netdev(dev);
 }
 
 #endif /* MODULE */
index de1dd2f..adb0588 100644 (file)
@@ -3,7 +3,6 @@
  *     Index to functions.
  */
 
-int el1_probe(struct net_device *dev);
 static int  el1_probe1(struct net_device *dev, int ioaddr);
 static int  el_open(struct net_device *dev);
 static void el_timeout(struct net_device *dev);
index 230153f..1a0ca52 100644 (file)
@@ -60,7 +60,6 @@ static const char version[] =
 #include "3c503.h"
 #define WRD_COUNT 4
 
-int el2_probe(struct net_device *dev);
 static int el2_pio_probe(struct net_device *dev);
 static int el2_probe1(struct net_device *dev, int ioaddr);
 
@@ -90,11 +89,11 @@ static struct ethtool_ops netdev_ethtool_ops;
    If the ethercard isn't found there is an optional probe for
    ethercard jumpered to programmed-I/O mode.
    */
-int __init 
-el2_probe(struct net_device *dev)
+static int __init do_el2_probe(struct net_device *dev)
 {
     int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
     int base_addr = dev->base_addr;
+    int irq = dev->irq;
 
     SET_MODULE_OWNER(dev);
     
@@ -104,16 +103,13 @@ el2_probe(struct net_device *dev)
        return -ENXIO;
 
     for (addr = addrs; *addr; addr++) {
-       int i;
-       unsigned int base_bits = isa_readb(*addr);
-       /* Find first set bit. */
-       for(i = 7; i >= 0; i--, base_bits >>= 1)
-           if (base_bits & 0x1)
-               break;
-       if (base_bits != 1)
+       unsigned base_bits = isa_readb(*addr);
+       int i = ffs(base_bits) - 1;
+       if (i == -1 || base_bits != (1 << i))
            continue;
        if (el2_probe1(dev, netcard_portlist[i]) == 0)
            return 0;
+       dev->irq = irq;
     }
 #if ! defined(no_probe_nonshared_memory)
     return el2_pio_probe(dev);
@@ -128,20 +124,54 @@ static int __init
 el2_pio_probe(struct net_device *dev)
 {
     int i;
-    int base_addr = dev ? dev->base_addr : 0;
+    int base_addr = dev->base_addr;
+    int irq = dev->irq;
 
     if (base_addr > 0x1ff)     /* Check a single specified location. */
        return el2_probe1(dev, base_addr);
     else if (base_addr != 0)   /* Don't probe at all. */
        return -ENXIO;
 
-    for (i = 0; netcard_portlist[i]; i++)
+    for (i = 0; netcard_portlist[i]; i++) {
        if (el2_probe1(dev, netcard_portlist[i]) == 0)
            return 0;
+       dev->irq = irq;
+    }
 
     return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       /* NB: el2_close() handles free_irq */
+       release_region(dev->base_addr, EL2_IO_EXTENT);
+}
+
+struct net_device * __init el2_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_el2_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 /* Probe for the Etherlink II card at I/O port base IOADDR,
    returning non-zero on success.  If found, set the station
    address and memory parameters in DEVICE. */
@@ -152,15 +182,19 @@ el2_probe1(struct net_device *dev, int ioaddr)
     static unsigned version_printed;
     unsigned long vendor_id;
 
-    /* FIXME: code reads ioaddr + 0x400, we request ioaddr + 16 */
     if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name))
        return -EBUSY;
 
+    if (!request_region(ioaddr + 0x400, 8, dev->name)) {
+       retval = -EBUSY;
+       goto out;
+    }
+
     /* Reset and/or avoid any lurking NE2000 */
     if (inb(ioaddr + 0x408) == 0xff) {
        mdelay(1);
        retval = -ENODEV;
-       goto out;
+       goto out1;
     }
 
     /* We verify that it's a 3C503 board by checking the first three octets
@@ -171,7 +205,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
     if (   (iobase_reg  & (iobase_reg - 1))
        || (membase_reg & (membase_reg - 1))) {
        retval = -ENODEV;
-       goto out;
+       goto out1;
     }
     saved_406 = inb_p(ioaddr + 0x406);
     outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
@@ -184,19 +218,13 @@ el2_probe1(struct net_device *dev, int ioaddr)
        /* Restore the register we frobbed. */
        outb(saved_406, ioaddr + 0x406);
        retval = -ENODEV;
-       goto out;
+       goto out1;
     }
 
     if (ei_debug  &&  version_printed++ == 0)
        printk(version);
 
     dev->base_addr = ioaddr;
-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
-    if (ethdev_init(dev)) {
-       printk ("3c503: unable to allocate memory for dev->priv.\n");
-       retval = -ENOMEM;
-       goto out;
-    }
 
     printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
 
@@ -322,7 +350,10 @@ el2_probe1(struct net_device *dev, int ioaddr)
        printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
               dev->name, ei_status.name, (wordlength+1)<<3);
     }
+    release_region(ioaddr + 0x400, 8);
     return 0;
+out1:
+    release_region(ioaddr + 0x400, 8);
 out:
     release_region(ioaddr, EL2_IO_EXTENT);
     return retval;
@@ -633,7 +664,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 #ifdef MODULE
 #define MAX_EL2_CARDS  4       /* Max number of EL2 cards per module */
 
-static struct net_device dev_el2[MAX_EL2_CARDS];
+static struct net_device *dev_el2[MAX_EL2_CARDS];
 static int io[MAX_EL2_CARDS];
 static int irq[MAX_EL2_CARDS];
 static int xcvr[MAX_EL2_CARDS];        /* choose int. or ext. xcvr */
@@ -651,28 +682,34 @@ ISA device autoprobes on a running machine are not recommended. */
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
-               struct net_device *dev = &dev_el2[this_dev];
-               dev->irq = irq[this_dev];
-               dev->base_addr = io[this_dev];
-               dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
-               dev->init = el2_probe;
                if (io[this_dev] == 0)  {
                        if (this_dev != 0) break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
+               if (do_el2_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_el2[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -681,13 +718,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
-               struct net_device *dev = &dev_el2[this_dev];
-               if (dev->priv != NULL) {
-                       void *priv = dev->priv;
-                       /* NB: el2_close() handles free_irq */
-                       release_region(dev->base_addr, EL2_IO_EXTENT);
+               struct net_device *dev = dev_el2[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index d1607ca..5ecdf5a 100644 (file)
@@ -1293,42 +1293,6 @@ static void elp_set_mc_list(struct net_device *dev)
        }
 }
 
-/******************************************************
- *
- * initialise Etherlink Plus board
- *
- ******************************************************/
-
-static inline void elp_init(struct net_device *dev)
-{
-       elp_device *adapter = dev->priv;
-
-       /*
-        * set ptrs to various functions
-        */
-       dev->open = elp_open;                           /* local */
-       dev->stop = elp_close;                          /* local */
-       dev->get_stats = elp_get_stats;                 /* local */
-       dev->hard_start_xmit = elp_start_xmit;          /* local */
-       dev->tx_timeout = elp_timeout;                  /* local */
-       dev->watchdog_timeo = 10*HZ;
-       dev->set_multicast_list = elp_set_mc_list;      /* local */
-       dev->ethtool_ops = &netdev_ethtool_ops;         /* local */
-
-       /* Setup the generic properties */
-       ether_setup(dev);
-
-       /*
-        * setup ptr to adapter specific information
-        */
-       memset(&(adapter->stats), 0, sizeof(struct net_device_stats));
-
-       /*
-        * memory information
-        */
-       dev->mem_start = dev->mem_end = 0;
-}
-
 /************************************************************
  *
  * A couple of tests to see if there's 3C505 or not
@@ -1442,12 +1406,13 @@ static int __init elp_autodetect(struct net_device *dev)
  * work at all if it was in a weird state).
  */
 
-int __init elplus_probe(struct net_device *dev)
+static int __init elplus_setup(struct net_device *dev)
 {
-       elp_device *adapter;
+       elp_device *adapter = dev->priv;
        int i, tries, tries1, okay;
        unsigned long timeout;
        unsigned long cookie = 0;
+       int err = -ENODEV;
 
        SET_MODULE_OWNER(dev);
 
@@ -1456,17 +1421,8 @@ int __init elplus_probe(struct net_device *dev)
         */
 
        dev->base_addr = elp_autodetect(dev);
-       if (!(dev->base_addr))
-               return -ENODEV;
-
-       /*
-        * setup ptr to adapter specific information
-        */
-       adapter = (elp_device *) (dev->priv = kmalloc(sizeof(elp_device), GFP_KERNEL));
-       if (adapter == NULL) {
-               printk(KERN_ERR "%s: out of memory\n", dev->name);
+       if (!dev->base_addr)
                return -ENODEV;
-       }
 
        adapter->send_pcb_semaphore = 0;
 
@@ -1544,8 +1500,7 @@ int __init elplus_probe(struct net_device *dev)
                outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
        }
        printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name);
-       release_region(dev->base_addr, ELP_IO_EXTENT);
-       return -ENODEV;
+       goto out;
 
       okay:
        if (dev->irq) {         /* Is there a preset IRQ? */
@@ -1560,14 +1515,14 @@ int __init elplus_probe(struct net_device *dev)
        case 0:
                printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n",
                       dev->name);
-               return -ENODEV;
+               goto out;
        case 1:
        case 6:
        case 8:
        case 13:
                printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n",
                       dev->name, dev->irq);
-               return -ENODEV;
+                      goto out;
        }
        /*
         *  Now we have the IRQ number so we can disable the interrupts from
@@ -1636,16 +1591,48 @@ int __init elplus_probe(struct net_device *dev)
                printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
        }
 
-       /*
-        * initialise the device
-        */
-       elp_init(dev);
+       dev->open = elp_open;                           /* local */
+       dev->stop = elp_close;                          /* local */
+       dev->get_stats = elp_get_stats;                 /* local */
+       dev->hard_start_xmit = elp_start_xmit;          /* local */
+       dev->tx_timeout = elp_timeout;                  /* local */
+       dev->watchdog_timeo = 10*HZ;
+       dev->set_multicast_list = elp_set_mc_list;      /* local */
+       dev->ethtool_ops = &netdev_ethtool_ops;         /* local */
+
+       memset(&(adapter->stats), 0, sizeof(struct net_device_stats));
+       dev->mem_start = dev->mem_end = 0;
+
+       err = register_netdev(dev);
+       if (err)
+               goto out;
 
        return 0;
+out:
+       release_region(dev->base_addr, ELP_IO_EXTENT);
+       return err;
+}
+
+struct net_device * __init elplus_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(elp_device));
+       int err;
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = elplus_setup(dev);
+       if (err) {
+               free_netdev(dev);
+               return ERR_PTR(err);
+       }
+       return dev;
 }
 
 #ifdef MODULE
-static struct net_device dev_3c505[ELP_MAX_CARDS];
+static struct net_device *dev_3c505[ELP_MAX_CARDS];
 static int io[ELP_MAX_CARDS];
 static int irq[ELP_MAX_CARDS];
 static int dma[ELP_MAX_CARDS];
@@ -1661,10 +1648,12 @@ int init_module(void)
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
-               struct net_device *dev = &dev_3c505[this_dev];
+               struct net_device *dev = alloc_etherdev(sizeof(elp_device));
+               if (!dev)
+                       break;
+
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
-               dev->init = elplus_probe;
                if (dma[this_dev]) {
                        dev->dma = dma[this_dev];
                } else {
@@ -1672,16 +1661,22 @@ int init_module(void)
                        printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n");
                }
                if (io[this_dev] == 0) {
-                       if (this_dev) break;
+                       if (this_dev) {
+                               free_netdev(dev);
+                               break;
+                       }
                        printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n");
                }
-               if (register_netdev(dev) != 0) {
+               if (elplus_setup(dev) != 0) {
                        printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
-                       if (found != 0) return 0;
-                       return -ENXIO;
+                       free_netdev(dev);
+                       break;
                }
+               dev_3c505[this_dev] = dev;
                found++;
        }
+       if (!found)
+               return -ENODEV;
        return 0;
 }
 
@@ -1690,12 +1685,11 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
-               struct net_device *dev = &dev_3c505[this_dev];
-               if (dev->priv != NULL) {
+               struct net_device *dev = dev_3c505[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
                        release_region(dev->base_addr, ELP_IO_EXTENT);
+                       free_netdev(dev);
                }
        }
 }
index f37d295..fda5670 100644 (file)
@@ -74,10 +74,6 @@ static unsigned int net_debug = NET_DEBUG;
 #define debug net_debug
 
 
-/* A zero-terminated list of common I/O addresses to be probed. */
-static unsigned int netcard_portlist[] __initdata =
-       { 0x300, 0x320, 0x340, 0x280, 0};
-
 /*
                        Details of the i82586.
 
@@ -286,8 +282,6 @@ static unsigned short init_words[] = {
 
 /* Index to functions, as function prototypes. */
 
-extern int el16_probe(struct net_device *dev); /* Called from Space.c */
-
 static int     el16_probe1(struct net_device *dev, int ioaddr);
 static int     el16_open(struct net_device *dev);
 static int     el16_send_packet(struct sk_buff *skb, struct net_device *dev);
@@ -301,6 +295,10 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
 static void init_82586_mem(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
+static int io = 0x300;
+static int irq;
+static int mem_start;
+
 \f
 /* Check for a network adaptor of this type, and return '0' iff one exists.
        If dev->base_addr == 0, probe all likely locations.
@@ -309,23 +307,50 @@ static struct ethtool_ops netdev_ethtool_ops;
        device and return success.
        */
 
-int __init el16_probe(struct net_device *dev)
+struct net_device * __init el16_probe(int unit)
 {
-       int base_addr = dev->base_addr;
-       int i;
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
+       unsigned *port;
+       int err = -ENODEV;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+               mem_start = dev->mem_start & 15;
+       }
 
        SET_MODULE_OWNER(dev);
 
-       if (base_addr > 0x1ff)  /* Check a single specified location. */
-               return el16_probe1(dev, base_addr);
-       else if (base_addr != 0)
-               return -ENXIO;          /* Don't probe at all. */
-
-       for (i = 0; netcard_portlist[i]; i++)
-               if (el16_probe1(dev, netcard_portlist[i]) == 0)
-                       return 0;
+       if (io > 0x1ff)         /* Check a single specified location. */
+               err = el16_probe1(dev, io);
+       else if (io != 0)
+               err = -ENXIO;           /* Don't probe at all. */
+       else {
+               for (port = ports; *port; port++) {
+                       err = el16_probe1(dev, *port);
+                       if (!err)
+                               break;
+               }
+       }
 
-       return -ENODEV;
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, EL16_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init el16_probe1(struct net_device *dev, int ioaddr)
@@ -383,8 +408,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
                printk(" %02x", dev->dev_addr[i]);
        }
 
-       if ((dev->mem_start & 0xf) > 0)
-               net_debug = dev->mem_start & 7;
+       if (mem_start)
+               net_debug = mem_start & 7;
 
 #ifdef MEM_BASE
        dev->mem_start = MEM_BASE;
@@ -416,27 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
        if (net_debug)
                printk(version);
 
-       /* Initialize the device structure. */
-       lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev->priv == NULL) {
-               retval = -ENOMEM;
-               goto out;
-       }
-       memset(dev->priv, 0, sizeof(struct net_local));
+       lp = dev->priv;
+       memset(lp, 0, sizeof(*lp));
        spin_lock_init(&lp->lock);
 
-       dev->open               = el16_open;
-       dev->stop               = el16_close;
+       dev->open = el16_open;
+       dev->stop = el16_close;
        dev->hard_start_xmit = el16_send_packet;
        dev->get_stats  = el16_get_stats;
        dev->tx_timeout = el16_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
        dev->ethtool_ops = &netdev_ethtool_ops;
-
-       ether_setup(dev);       /* Generic ethernet behaviour */
-
-       dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
-
+       dev->flags &= ~IFF_MULTICAST;   /* Multicast doesn't work */
        return 0;
 out:
        release_region(ioaddr, EL16_IO_EXTENT);
@@ -899,9 +915,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 };
 
 #ifdef MODULE
-static struct net_device dev_3c507;
-static int io = 0x300;
-static int irq;
+static struct net_device *dev_3c507;
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
@@ -911,26 +925,18 @@ int init_module(void)
 {
        if (io == 0)
                printk("3c507: You should not use auto-probing with insmod!\n");
-       dev_3c507.base_addr = io;
-       dev_3c507.irq       = irq;
-       dev_3c507.init      = el16_probe;
-       if (register_netdev(&dev_3c507) != 0) {
-               printk("3c507: register_netdev() returned non-zero.\n");
-               return -EIO;
-       }
-       return 0;
+       dev_3c507 = el16_probe(-1);
+       return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
 }
 
 void
 cleanup_module(void)
 {
-       unregister_netdev(&dev_3c507);
-       kfree(dev_3c507.priv);
-       dev_3c507.priv = NULL;
-
-       /* If we don't do this, we can't re-insmod it later. */
-       free_irq(dev_3c507.irq, &dev_3c507);
-       release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
+       struct net_device *dev = dev_3c507;
+       unregister_netdev(dev);
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, EL16_IO_EXTENT);
+       free_netdev(dev);
 }
 #endif /* MODULE */
 MODULE_LICENSE("GPL");
index d3e3d81..c125ab3 100644 (file)
@@ -307,7 +307,8 @@ struct boom_tx_desc {
 
 struct corkscrew_private {
        const char *product_name;
-       struct net_device *next_module;
+       struct list_head list;
+       struct net_device *our_dev;
        /* The Rx and Tx rings are here to keep them quad-word-aligned. */
        struct boom_rx_desc rx_ring[RX_RING_SIZE];
        struct boom_tx_desc tx_ring[TX_RING_SIZE];
@@ -329,6 +330,7 @@ struct corkscrew_private {
                full_bus_master_tx:1, full_bus_master_rx:1,     /* Boomerang  */
                tx_full:1;
        spinlock_t lock;
+       struct device *dev;
 };
 
 /* The action to take with a media selection timer tick.
@@ -367,17 +369,12 @@ static struct isapnp_device_id corkscrew_isapnp_adapters[] = {
 
 MODULE_DEVICE_TABLE(isapnp, corkscrew_isapnp_adapters);
 
-static int corkscrew_isapnp_phys_addr[3];
-
 static int nopnp;
 #endif /* __ISAPNP__ */
 
-static int corkscrew_scan(struct net_device *dev);
-static struct net_device *corkscrew_found_device(struct net_device *dev,
-                                                int ioaddr, int irq,
-                                                int product_index,
-                                                int options);
-static int corkscrew_probe1(struct net_device *dev);
+static struct net_device *corkscrew_scan(int unit);
+static void corkscrew_setup(struct net_device *dev, int ioaddr,
+                           struct pnp_dev *idev, int card_number);
 static int corkscrew_open(struct net_device *dev);
 static void corkscrew_timer(unsigned long arg);
 static int corkscrew_start_xmit(struct sk_buff *skb,
@@ -413,47 +410,99 @@ static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1, };
 #ifdef MODULE
 static int debug = -1;
 /* A list of all installed Vortex devices, for removing the driver module. */
-static struct net_device *root_corkscrew_dev;
+/* we will need locking (and refcounting) if we ever use it for more */
+static LIST_HEAD(root_corkscrew_dev);
 
 int init_module(void)
 {
-       int cards_found;
-
+       int found = 0;
        if (debug >= 0)
                corkscrew_debug = debug;
        if (corkscrew_debug)
                printk(version);
-
-       root_corkscrew_dev = NULL;
-       cards_found = corkscrew_scan(NULL);
-       return cards_found ? 0 : -ENODEV;
+       while (corkscrew_scan(-1))
+               found++;
+       return found ? 0 : -ENODEV;
 }
 
 #else
-int tc515_probe(struct net_device *dev)
+struct net_device *tc515_probe(int unit)
 {
-       int cards_found = 0;
+       struct net_device *dev = corkscrew_scan(unit);
+       static int printed;
 
-       SET_MODULE_OWNER(dev);
-
-       cards_found = corkscrew_scan(dev);
+       if (!dev)
+               return ERR_PTR(-ENODEV);
 
-       if (corkscrew_debug > 0 && cards_found)
+       if (corkscrew_debug > 0 && !printed) {
+               printed = 1;
                printk(version);
+       }
 
-       return cards_found ? 0 : -ENODEV;
+       return dev;
 }
 #endif                         /* not MODULE */
 
-static int corkscrew_scan(struct net_device *dev)
+static int check_device(unsigned ioaddr)
+{
+       int timer;
+
+       if (!request_region(ioaddr, CORKSCREW_TOTAL_SIZE, "3c515"))
+               return 0;
+       /* Check the resource configuration for a matching ioaddr. */
+       if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
+               release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
+               return 0;
+       }
+       /* Verify by reading the device ID from the EEPROM. */
+       outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
+       /* Pause for at least 162 us. for the read to take place. */
+       for (timer = 4; timer >= 0; timer--) {
+               udelay(162);
+               if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
+                       break;
+       }
+       if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
+               release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
+               return 0;
+       }
+       return 1;
+}
+
+static void cleanup_card(struct net_device *dev)
 {
-       int cards_found = 0;
+       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+       list_del_init(&vp->list);
+       if (dev->dma)
+               free_dma(dev->dma);
+       outw(TotalReset, dev->base_addr + EL3_CMD);
+       release_region(dev->base_addr, CORKSCREW_TOTAL_SIZE);
+       if (vp->dev)
+               pnp_device_detach(to_pnp_dev(vp->dev));
+}
+
+static struct net_device *corkscrew_scan(int unit)
+{
+       struct net_device *dev;
+       static int cards_found = 0;
        static int ioaddr;
+       int err;
 #ifdef __ISAPNP__
        short i;
        static int pnp_cards;
 #endif
 
+       dev = alloc_etherdev(sizeof(struct corkscrew_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
+
+       SET_MODULE_OWNER(dev);
+
 #ifdef __ISAPNP__
        if(nopnp == 1)
                goto no_pnp;
@@ -470,7 +519,7 @@ static int corkscrew_scan(struct net_device *dev)
                        if (pnp_activate_dev(idev) < 0) {
                                printk("pnp activate failed (out of resources?)\n");
                                pnp_device_detach(idev);
-                               return -ENOMEM;
+                               continue;
                        }
                        if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
                                pnp_device_detach(idev);
@@ -478,40 +527,22 @@ static int corkscrew_scan(struct net_device *dev)
                        }
                        ioaddr = pnp_port_start(idev, 0);
                        irq = pnp_irq(idev, 0);
-                       if(corkscrew_debug)
-                               printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
-                                       (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
-                                       
-                       if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
+                       if (!check_device(ioaddr)) {
                                pnp_device_detach(idev);
                                continue;
                        }
-                       /* Verify by reading the device ID from the EEPROM. */
-                       {
-                               int timer;
-                               outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
-                               /* Pause for at least 162 us. for the read to take place. */
-                               for (timer = 4; timer >= 0; timer--) {
-                                       udelay(162);
-                                       if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
-                                               == 0)
-                                                       break;
-                               }
-                               if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
-                                       pnp_device_detach(idev);
-                                       continue;
-                               }
-                       }
+                       if(corkscrew_debug)
+                               printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
+                                       (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
                        printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
                                inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
                        /* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
-                       corkscrew_isapnp_phys_addr[pnp_cards] = ioaddr;
-                       corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev
-                                       && dev->mem_start ? dev->
-                                       mem_start : options[cards_found]);
-                       dev = 0;
+                       corkscrew_setup(dev, ioaddr, idev, cards_found++);
                        pnp_cards++;
-                       cards_found++;
+                       err = register_netdev(dev);
+                       if (!err)
+                               return dev;
+                       cleanup_card(dev);
                }
        }
 no_pnp:
@@ -519,122 +550,64 @@ no_pnp:
 
        /* Check all locations on the ISA bus -- evil! */
        for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
-               int irq;
-#ifdef __ISAPNP__
-               /* Make sure this was not already picked up by isapnp */
-               if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue;
-               if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue;
-               if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue;
-#endif /* __ISAPNP__ */
-               if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE))
+               if (!check_device(ioaddr))
                        continue;
-               /* Check the resource configuration for a matching ioaddr. */
-               if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0))
-                       continue;
-               /* Verify by reading the device ID from the EEPROM. */
-               {
-                       int timer;
-                       outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
-                       /* Pause for at least 162 us. for the read to take place. */
-                       for (timer = 4; timer >= 0; timer--) {
-                               udelay(162);
-                               if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
-                                   == 0)
-                                       break;
-                       }
-                       if (inw(ioaddr + Wn0EepromData) != 0x6d50)
-                               continue;
-               }
+
                printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
                     inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
-               irq = inw(ioaddr + 0x2002) & 15;
-               corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID,
-                                      dev && dev->mem_start ?  dev->mem_start :
-                                        (cards_found >= MAX_UNITS ? -1 :
-                                               options[cards_found]));
-               dev = 0;
-               cards_found++;
+               corkscrew_setup(dev, ioaddr, NULL, cards_found++);
+               err = register_netdev(dev);
+               if (!err)
+                       return dev;
+               cleanup_card(dev);
        }
-       if (corkscrew_debug)
-               printk(KERN_INFO "%d 3c515 cards found.\n", cards_found);
-       return cards_found;
+       free_netdev(dev);
+       return NULL;
 }
 
-static struct net_device *corkscrew_found_device(struct net_device *dev,
-                                                int ioaddr, int irq,
-                                                int product_index,
-                                                int options)
+static void corkscrew_setup(struct net_device *dev, int ioaddr,
+                           struct pnp_dev *idev, int card_number)
 {
-       struct corkscrew_private *vp;
-
-#ifdef MODULE
-       /* Allocate and fill new device structure. */
-       int dev_size = sizeof(struct net_device) + sizeof(struct corkscrew_private) + 15;       /* Pad for alignment */
+       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+       unsigned int eeprom[0x40], checksum = 0;        /* EEPROM contents */
+       int i;
+       int irq;
 
-       dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
-       if (!dev)
-               return NULL;
-       memset(dev, 0, dev_size);
-       /* Align the Rx and Tx ring entries.  */
-       dev->priv = (void *) (((long) dev + sizeof(struct net_device) + 15) & ~15);
-       vp = (struct corkscrew_private *) dev->priv;
-       dev->base_addr = ioaddr;
-       dev->irq = irq;
-       dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
-       dev->init = corkscrew_probe1;
-       vp->product_name = "3c515";
-       vp->options = options;
-       if (options >= 0) {
-               vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
-               vp->full_duplex = (options & 8) ? 1 : 0;
-               vp->bus_master = (options & 16) ? 1 : 0;
+       if (idev) {
+               irq = pnp_irq(idev, 0);
+               vp->dev = &idev->dev;
        } else {
-               vp->media_override = 7;
-               vp->full_duplex = 0;
-               vp->bus_master = 0;
-       }
-       ether_setup(dev);
-       vp->next_module = root_corkscrew_dev;
-       root_corkscrew_dev = dev;
-       SET_MODULE_OWNER(dev);
-       if (register_netdev(dev) != 0) {
-               kfree(dev);
-               return NULL;
+               irq = inw(ioaddr + 0x2002) & 15;
        }
-#else                          /* not a MODULE */
-       /* Caution: quad-word alignment required for rings! */
-       dev->priv = kmalloc(sizeof(struct corkscrew_private), GFP_KERNEL);
-       if (!dev->priv)
-               return NULL;
-       memset(dev->priv, 0, sizeof(struct corkscrew_private));
-       dev = init_etherdev(dev, sizeof(struct corkscrew_private));
+
        dev->base_addr = ioaddr;
        dev->irq = irq;
-       dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
-       vp = (struct corkscrew_private *) dev->priv;
+       dev->dma = inw(ioaddr + 0x2000) & 7;
        vp->product_name = "3c515";
-       vp->options = options;
-       if (options >= 0) {
-               vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
-               vp->full_duplex = (options & 8) ? 1 : 0;
-               vp->bus_master = (options & 16) ? 1 : 0;
+       vp->options = dev->mem_start;
+       vp->our_dev = dev;
+
+       if (!vp->options) {
+                if (card_number >= MAX_UNITS)
+                       vp->options = -1;
+               else
+                       vp->options = options[card_number];
+       }
+
+       if (vp->options >= 0) {
+               vp->media_override = vp->options & 7;
+               if (vp->media_override == 2)
+                       vp->media_override = 0;
+               vp->full_duplex = (vp->options & 8) ? 1 : 0;
+               vp->bus_master = (vp->options & 16) ? 1 : 0;
        } else {
                vp->media_override = 7;
                vp->full_duplex = 0;
                vp->bus_master = 0;
        }
-
-       corkscrew_probe1(dev);
-#endif                         /* MODULE */
-       return dev;
-}
-
-static int corkscrew_probe1(struct net_device *dev)
-{
-       int ioaddr = dev->base_addr;
-       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
-       unsigned int eeprom[0x40], checksum = 0;        /* EEPROM contents */
-       int i;
+#ifdef MODULE
+       list_add(&vp->list, &root_corkscrew_dev);
+#endif
 
        printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
 
@@ -706,9 +679,6 @@ static int corkscrew_probe1(struct net_device *dev)
        /* vp->full_bus_master_rx = 0; */
        vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
 
-       /* We do a request_region() to register /proc/ioports info. */
-       request_region(ioaddr, CORKSCREW_TOTAL_SIZE, vp->product_name);
-
        /* The 3c51x-specific entries in the device structure. */
        dev->open = &corkscrew_open;
        dev->hard_start_xmit = &corkscrew_start_xmit;
@@ -718,8 +688,6 @@ static int corkscrew_probe1(struct net_device *dev)
        dev->get_stats = &corkscrew_get_stats;
        dev->set_multicast_list = &set_rx_mode;
        dev->ethtool_ops = &netdev_ethtool_ops;
-
-       return 0;
 }
 \f
 
@@ -1607,20 +1575,16 @@ static struct ethtool_ops netdev_ethtool_ops = {
 #ifdef MODULE
 void cleanup_module(void)
 {
-       struct net_device *next_dev;
-
-       while (root_corkscrew_dev) {
-               next_dev =
-                   ((struct corkscrew_private *) root_corkscrew_dev->
-                    priv)->next_module;
-               if (root_corkscrew_dev->dma)
-                       free_dma(root_corkscrew_dev->dma);
-               unregister_netdev(root_corkscrew_dev);
-               outw(TotalReset, root_corkscrew_dev->base_addr + EL3_CMD);
-               release_region(root_corkscrew_dev->base_addr,
-                              CORKSCREW_TOTAL_SIZE);
-               free_netdev(root_corkscrew_dev);
-               root_corkscrew_dev = next_dev;
+       while (!list_empty(&root_corkscrew_dev)) {
+               struct net_device *dev;
+               struct corkscrew_private *vp;
+
+               vp = list_entry(root_corkscrew_dev.next,
+                               struct corkscrew_private, list);
+               dev = vp->our_dev;
+               unregister_netdev(dev);
+               cleanup_card(dev);
+               free_netdev(dev);
        }
 }
 #endif                         /* MODULE */
index dcaf90e..d479223 100644 (file)
@@ -410,7 +410,7 @@ static int elmc_getinfo(char *buf, int slot, void *d)
 
 /*****************************************************************/
 
-int __init elmc_probe(struct net_device *dev)
+static int __init do_elmc_probe(struct net_device *dev)
 {
        static int slot;
        int base_addr = dev->base_addr;
@@ -420,7 +420,7 @@ int __init elmc_probe(struct net_device *dev)
        int i = 0;
        unsigned int size = 0;
        int retval;
-       struct priv *pr;
+       struct priv *pr = dev->priv;
 
        SET_MODULE_OWNER(dev);
        if (MCA_bus == 0) {
@@ -455,10 +455,9 @@ int __init elmc_probe(struct net_device *dev)
        }
 
        /* we didn't find any 3c523 in the slots we checked for */
-       if (slot == MCA_NOTFOUND) {
-               retval = ((base_addr || irq) ? -ENXIO : -ENODEV);
-               goto err_out;
-       }
+       if (slot == MCA_NOTFOUND)
+               return ((base_addr || irq) ? -ENXIO : -ENODEV);
+
        mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
        mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
 
@@ -497,13 +496,7 @@ int __init elmc_probe(struct net_device *dev)
                break;
        }
 
-       pr = dev->priv = kmalloc(sizeof(struct priv), GFP_KERNEL);
-       if (dev->priv == NULL) {
-               retval = -ENOMEM;
-               goto err_out;
-       }
        memset(pr, 0, sizeof(struct priv));
-
        pr->slot = slot;
 
        printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
@@ -530,8 +523,6 @@ int __init elmc_probe(struct net_device *dev)
        if (!check586(dev, dev->mem_start, size)) {
                printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
                       dev->mem_start);
-               kfree(dev->priv);
-               dev->priv = NULL;
                retval = -ENODEV;
                goto err_out;
        }
@@ -573,8 +564,6 @@ int __init elmc_probe(struct net_device *dev)
 #endif
        dev->ethtool_ops = &netdev_ethtool_ops;
        
-       ether_setup(dev);
-
        /* note that we haven't actually requested the IRQ from the kernel.
           That gets done in elmc_open().  I'm not sure that's such a good idea,
           but it works, so I'll go with it. */
@@ -585,9 +574,41 @@ int __init elmc_probe(struct net_device *dev)
 
        return 0;
 err_out:
+       mca_set_adapter_procfn(slot, NULL, NULL);
        release_region(dev->base_addr, ELMC_IO_EXTENT);
        return retval;
 }
+static void cleanup_card(struct net_device *dev)
+{
+       mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot, NULL, NULL);
+       release_region(dev->base_addr, ELMC_IO_EXTENT);
+}
+
+struct net_device * __init elmc_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct priv));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_elmc_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
 
 /**********************************************
  * init the chip (elmc-interrupt should be disabled?!)
@@ -1245,7 +1266,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 /* Increase if needed ;) */
 #define MAX_3C523_CARDS 4
 
-static struct net_device dev_elmc[MAX_3C523_CARDS];
+static struct net_device *dev_elmc[MAX_3C523_CARDS];
 static int irq[MAX_3C523_CARDS];
 static int io[MAX_3C523_CARDS];
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
@@ -1258,16 +1279,24 @@ int init_module(void)
        int this_dev,found = 0;
 
        /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */        
-       for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) 
-               {
-               struct net_device *dev = &dev_elmc[this_dev];
+       for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
+               struct net_device *dev = alloc_etherdev(sizeof(struct priv));
+               if (!dev)
+                       break;
                dev->irq=irq[this_dev];
                dev->base_addr=io[this_dev];
-               dev->init=elmc_probe;
-               if(register_netdev(dev)!=0) {
-                       if(io[this_dev]==0) break;
-                       printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
-               } else found++;
+               if (do_elmc_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_elmc[this_dev] = dev;
+                               found++;
+                               continue;
+                       }
+                       cleanup_card(dev);
+               }
+               free_netdev(dev);
+               if (io[this_dev]==0)
+                       break;
+               printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
        }
 
        if(found==0) {
@@ -1279,31 +1308,12 @@ int init_module(void)
 void cleanup_module(void)
 {
        int this_dev;
-       for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
-
-               struct net_device *dev = &dev_elmc[this_dev];
-               if(dev->priv) {
-                       /* shutdown interrupts on the card */
-                       elmc_id_reset586();
-                       if (dev->irq != 0) {
-                               /* this should be done by close, but if we failed to
-                                  initialize properly something may have gotten hosed. */
-                               free_irq(dev->irq, dev);
-                               dev->irq = 0;
-                       }
-                       if (dev->base_addr != 0) {
-                               release_region(dev->base_addr, ELMC_IO_EXTENT);
-                               dev->base_addr = 0;
-                       }
-                       irq[this_dev] = 0;
-                       io[this_dev] = 0;
+       for (this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
+               struct net_device *dev = dev_elmc[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-
-                       mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
-                              NULL, NULL);
-
-                       kfree(dev->priv);
-                       dev->priv = NULL;
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index ca9fcce..43745e0 100644 (file)
@@ -212,8 +212,6 @@ static inline u16 next_tx(u16 tx) { return (tx+1)&(TX_RING_LEN-1); };
 
 
 /* Index to functions, as function prototypes. */
-extern int mc32_probe(struct net_device *dev);
-
 static int     mc32_probe1(struct net_device *dev, int ioaddr);
 static int      mc32_command(struct net_device *dev, u16 cmd, void *data, int len);
 static int     mc32_open(struct net_device *dev);
@@ -226,9 +224,19 @@ static void        mc32_set_multicast_list(struct net_device *dev);
 static void    mc32_reset_multicast_list(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
+static void cleanup_card(struct net_device *dev)
+{
+       struct mc32_local *lp=dev->priv;
+       unsigned slot = lp->slot;
+       mca_mark_as_unused(slot);
+       mca_set_adapter_name(slot, NULL);
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, MC32_IO_EXTENT);
+}
+
 /**
  * mc32_probe  -       Search for supported boards
- * @dev: device to probe
+ * @unit: interface number to use
  *
  * Because MCA bus is a real bus and we can scan for cards we could do a
  * single scan for all boards here. Right now we use the passed in device
@@ -236,10 +244,18 @@ static struct ethtool_ops netdev_ethtool_ops;
  * in particular.
  */
 
-int __init mc32_probe(struct net_device *dev)
+struct net_device *__init mc32_probe(int unit)
 {
+       struct net_device *dev = alloc_etherdev(sizeof(struct mc32_local));
        static int current_mca_slot = -1;
        int i;
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0)
+               sprintf(dev->name, "eth%d", unit);
 
        SET_MODULE_OWNER(dev);
 
@@ -260,12 +276,18 @@ int __init mc32_probe(struct net_device *dev)
                                mca_set_adapter_name(current_mca_slot, 
                                                mc32_adapters[i].name);
                                mca_mark_as_used(current_mca_slot);
-                               return 0;
+                               err = register_netdev(dev);
+                               if (err) {
+                                       cleanup_card(dev);
+                                       free_netdev(dev);
+                                       dev = ERR_PTR(err);
+                               }
+                               return dev;
                        }
                        
                }
        }
-       return -ENODEV;
+       return ERR_PTR(-ENODEV);
 }
 
 /**
@@ -285,7 +307,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        int i, err;
        u8 POS;
        u32 base;
-       struct mc32_local *lp;
+       struct mc32_local *lp = dev->priv;
        static u16 mca_io_bases[]={
                0x7280,0x7290,
                0x7680,0x7690,
@@ -412,24 +434,14 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
         *      Grab the IRQ
         */
 
-       i = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
-       if (i) {
+       err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+       if (err) {
                release_region(dev->base_addr, MC32_IO_EXTENT);
                printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
-               return i;
+               goto err_exit_ports;
        }
 
-
-       /* Initialize the device structure. */
-       dev->priv = kmalloc(sizeof(struct mc32_local), GFP_KERNEL);
-       if (dev->priv == NULL)
-       {
-               err = -ENOMEM;
-               goto err_exit_irq; 
-       }
-
-       memset(dev->priv, 0, sizeof(struct mc32_local));
-       lp = dev->priv;
+       memset(lp, 0, sizeof(struct mc32_local));
        lp->slot = slot;
 
        i=0;
@@ -443,7 +455,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                {
                        printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
                        err = -ENODEV; 
-                       goto err_exit_free;
+                       goto err_exit_irq;
                }
                udelay(1000);
                if(inb(dev->base_addr+2)&(1<<5))
@@ -458,7 +470,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                else
                        printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
                err = -ENODEV; 
-               goto err_exit_free;
+               goto err_exit_irq;
        }
        
        base=0;
@@ -474,7 +486,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                        {
                                printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
                                err = -ENODEV;
-                               goto err_exit_free;
+                               goto err_exit_irq;
                        }
                }
 
@@ -517,15 +529,11 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        dev->watchdog_timeo     = HZ*5; /* Board does all the work */
        dev->ethtool_ops        = &netdev_ethtool_ops;
 
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-       
        return 0;
 
-err_exit_free:
-       kfree(dev->priv);
 err_exit_irq:
        free_irq(dev->irq, dev);
+err_exit_ports:
        release_region(dev->base_addr, MC32_IO_EXTENT);
        return err;
 }
@@ -1630,7 +1638,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 #ifdef MODULE
 
-static struct net_device this_device;
+static struct net_device *this_device;
 
 /**
  *     init_module             -       entry point
@@ -1642,12 +1650,9 @@ static struct net_device this_device;
 
 int init_module(void)
 {
-       int result;
-       
-       this_device.init = mc32_probe;
-       if ((result = register_netdev(&this_device)) != 0)
-               return result;
-
+       this_device = mc32_probe(-1);
+       if (IS_ERR(this_device))
+               return PTR_ERR(this_device);
        return 0;
 }
 
@@ -1664,24 +1669,9 @@ int init_module(void)
 
 void cleanup_module(void)
 {
-       int slot;
-       
-       unregister_netdev(&this_device);
-
-       /*
-        * If we don't do this, we can't re-insmod it later.
-        */
-        
-       if (this_device.priv)
-       {
-               struct mc32_local *lp=this_device.priv;
-               slot = lp->slot;
-               mca_mark_as_unused(slot);
-               mca_set_adapter_name(slot, NULL);
-               kfree(this_device.priv);
-       }
-       free_irq(this_device.irq, &this_device);
-       release_region(this_device.base_addr, MC32_IO_EXTENT);
+       unregister_netdev(this_device);
+       cleanup_card(this_device);
+       free_netdev(this_device);
 }
 
 #endif /* MODULE */
index 9fd9376..1d90e88 100644 (file)
@@ -92,7 +92,7 @@
 */
 
 #define DRV_NAME       "8139too"
-#define DRV_VERSION    "0.9.26"
+#define DRV_VERSION    "0.9.27"
 
 
 #include <linux/config.h>
 #define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
 #define PFX DRV_NAME ": "
 
+/* Default Message level */
+#define RTL8139_DEF_MSG_ENABLE   (NETIF_MSG_DRV   | \
+                                 NETIF_MSG_PROBE  | \
+                                 NETIF_MSG_LINK)
+
 
 /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
 #ifdef CONFIG_8139TOO_PIO
 #define USE_IO_OPS 1
 #endif
 
-/* use a 16K rx ring buffer instead of the default 32K */
-#ifdef CONFIG_SH_DREAMCAST
-#define USE_BUF16K 1
-#endif
-
 /* define to 1 to enable copious debugging info */
 #undef RTL8139_DEBUG
 
 #  define assert(expr) do {} while (0)
 #else
 #  define assert(expr) \
-        if(!(expr)) {                                  \
-        printk( "Assertion failed! %s,%s,%s,line=%d\n",        \
-        #expr,__FILE__,__FUNCTION__,__LINE__);         \
+        if(unlikely(!(expr))) {                                        \
+        printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n",        \
+        #expr,__FILE__,__FUNCTION__,__LINE__);                 \
         }
 #endif
 
 static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
-
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
    The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
 static int multicast_filter_limit = 32;
@@ -169,16 +166,16 @@ static int multicast_filter_limit = 32;
 /* bitmapped message enable number */
 static int debug = -1;
 
-/* Size of the in-memory receive ring. */
-#ifdef USE_BUF16K
-#define RX_BUF_LEN_IDX 1       /* 0==8K, 1==16K, 2==32K, 3==64K */
-#else
-#define RX_BUF_LEN_IDX 2       /* 0==8K, 1==16K, 2==32K, 3==64K */
-#endif
-#define RX_BUF_LEN     (8192 << RX_BUF_LEN_IDX)
+/* Ring size is now a config option */
+#define RX_BUF_LEN     (8192 << CONFIG_8139_RXBUF_IDX)
 #define RX_BUF_PAD     16
 #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
+
+#if RX_BUF_LEN == 65536
+#define RX_BUF_TOT_LEN RX_BUF_LEN
+#else
 #define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
+#endif
 
 /* Number of Tx descriptor registers. */
 #define NUM_TX_DESC    4
@@ -251,6 +248,10 @@ static struct pci_device_id rtl8139_pci_tbl[] = {
        {0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
        {0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
        {0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+       {0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+       {0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+       {0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+       {0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, 
 
 #ifdef CONFIG_SH_SECUREEDGE5410
        /* Bogus 8139 silicon reports 8129 without external PROM :-( */
@@ -450,7 +451,7 @@ enum RxConfigBits {
        RxCfgRcv32K = (1 << 12),
        RxCfgRcv64K = (1 << 11) | (1 << 12),
 
-       /* Disable packet wrap at end of Rx buffer */
+       /* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
        RxNoWrap = (1 << 7),
 };
 
@@ -560,6 +561,7 @@ struct rtl8139_private {
        int drv_flags;
        struct pci_dev *pci_dev;
        u32 pci_state[16];
+       u32 msg_enable;
        struct net_device_stats stats;
        unsigned char *rx_ring;
        unsigned int cur_rx;    /* Index into the Rx buffer of next Rx pkt. */
@@ -574,6 +576,7 @@ struct rtl8139_private {
        char twistie, twist_row, twist_col;     /* Twister tune state. */
        unsigned int default_port:4;    /* Last dev->if_port value. */
        spinlock_t lock;
+       spinlock_t rx_lock;
        chip_t chipset;
        pid_t thr_pid;
        wait_queue_head_t thr_wait;
@@ -590,13 +593,11 @@ MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 
 MODULE_PARM (multicast_filter_limit, "i");
-MODULE_PARM (max_interrupt_work, "i");
 MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM (full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM (debug, "i");
 MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
 MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
-MODULE_PARM_DESC (max_interrupt_work, "8139too maximum events handled per interrupt");
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
@@ -610,6 +611,10 @@ static void rtl8139_tx_timeout (struct net_device *dev);
 static void rtl8139_init_ring (struct net_device *dev);
 static int rtl8139_start_xmit (struct sk_buff *skb,
                               struct net_device *dev);
+static int rtl8139_poll(struct net_device *dev, int *budget);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void rtl8139_poll_controller(struct net_device *dev);
+#endif
 static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
                               struct pt_regs *regs);
 static int rtl8139_close (struct net_device *dev);
@@ -682,16 +687,32 @@ static const u16 rtl8139_intr_mask =
        PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
        TxErr | TxOK | RxErr | RxOK;
 
-#ifdef USE_BUF16K 
+static const u16 rtl8139_norx_intr_mask =
+       PCIErr | PCSTimeout | RxUnderrun |
+       TxErr | TxOK | RxErr ;
+
+#if CONFIG_8139_RXBUF_IDX == 0
+static const unsigned int rtl8139_rx_config =
+       RxCfgRcv8K | RxNoWrap |
+       (RX_FIFO_THRESH << RxCfgFIFOShift) |
+       (RX_DMA_BURST << RxCfgDMAShift);
+#elif CONFIG_8139_RXBUF_IDX == 1
 static const unsigned int rtl8139_rx_config =
        RxCfgRcv16K | RxNoWrap |
        (RX_FIFO_THRESH << RxCfgFIFOShift) |
        (RX_DMA_BURST << RxCfgDMAShift);
-#else
+#elif CONFIG_8139_RXBUF_IDX == 2
 static const unsigned int rtl8139_rx_config =
        RxCfgRcv32K | RxNoWrap |
        (RX_FIFO_THRESH << RxCfgFIFOShift) |
        (RX_DMA_BURST << RxCfgDMAShift);
+#elif CONFIG_8139_RXBUF_IDX == 3
+static const unsigned int rtl8139_rx_config =
+       RxCfgRcv64K |
+       (RX_FIFO_THRESH << RxCfgFIFOShift) |
+       (RX_DMA_BURST << RxCfgDMAShift);
+#else
+#error "Invalid configuration for 8139_RXBUF_IDX"
 #endif
 
 static const unsigned int rtl8139_tx_config =
@@ -868,9 +889,7 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
 
 match:
        DPRINTK ("chipset id (%d) == index %d, '%s'\n",
-               tmp,
-               tp->chipset,
-               rtl_chip_info[tp->chipset].name);
+                version, i, rtl_chip_info[i].name);
 
        if (tp->chipset >= CH_8139B) {
                u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
@@ -964,6 +983,8 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        /* The Rtl8139-specific entries in the device structure. */
        dev->open = rtl8139_open;
        dev->hard_start_xmit = rtl8139_start_xmit;
+       dev->poll = rtl8139_poll;
+       dev->weight = 64;
        dev->stop = rtl8139_close;
        dev->get_stats = rtl8139_get_stats;
        dev->set_multicast_list = rtl8139_set_rx_mode;
@@ -971,6 +992,9 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        dev->ethtool_ops = &rtl8139_ethtool_ops;
        dev->tx_timeout = rtl8139_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = rtl8139_poll_controller;
+#endif
 
        /* note: the hardware is not capable of sg/csum/highdma, however
         * through the use of skb_copy_and_csum_dev we enable these
@@ -986,7 +1010,10 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        /* note: tp->chipset set in rtl8139_init_board */
        tp->drv_flags = board_info[ent->driver_data].hw_flags;
        tp->mmio_addr = ioaddr;
+       tp->msg_enable =
+               (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
        spin_lock_init (&tp->lock);
+       spin_lock_init (&tp->rx_lock);
        init_waitqueue_head (&tp->thr_wait);
        init_completion (&tp->thr_exited);
        tp->mii.dev = dev;
@@ -1288,9 +1315,7 @@ static int rtl8139_open (struct net_device *dev)
 {
        struct rtl8139_private *tp = dev->priv;
        int retval;
-#ifdef RTL8139_DEBUG
        void *ioaddr = tp->mmio_addr;
-#endif
 
        retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
        if (retval)
@@ -1319,8 +1344,10 @@ static int rtl8139_open (struct net_device *dev)
 
        rtl8139_init_ring (dev);
        rtl8139_hw_start (dev);
+       netif_start_queue (dev);
 
-       DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d"
+       if (netif_msg_ifup(tp))
+               printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d"
                        " GP Pins %2.2x %s-duplex.\n",
                        dev->name, pci_resource_start (tp->pci_dev, 1),
                        dev->irq, RTL_R8 (MediaStatus),
@@ -1337,7 +1364,7 @@ static void rtl_check_media (struct net_device *dev, unsigned int init_media)
        struct rtl8139_private *tp = dev->priv;
 
        if (tp->phys[0] >= 0) {
-               mii_check_media(&tp->mii, 1, init_media);
+               mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
        }
 }
 
@@ -1407,8 +1434,6 @@ static void rtl8139_hw_start (struct net_device *dev)
 
        /* Enable all known interrupts by setting the interrupt mask. */
        RTL_W16 (IntrMask, rtl8139_intr_mask);
-
-       netif_start_queue (dev);
 }
 
 
@@ -1631,7 +1656,7 @@ static inline void rtl8139_start_thread(struct net_device *dev)
        }
 }
 
-static void rtl8139_tx_clear (struct rtl8139_private *tp)
+static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
 {
        tp->cur_tx = 0;
        tp->dirty_tx = 0;
@@ -1661,6 +1686,7 @@ static void rtl8139_tx_timeout (struct net_device *dev)
        if (tmp8 & CmdTxEnb)
                RTL_W8 (ChipCmd, CmdRxEnb);
 
+       spin_lock(&tp->rx_lock);
        /* Disable interrupts by clearing the interrupt mask. */
        RTL_W16 (IntrMask, 0x0000);
 
@@ -1679,9 +1705,12 @@ static void rtl8139_tx_timeout (struct net_device *dev)
        spin_unlock_irqrestore (&tp->lock, flags);
 
        /* ...and finally, reset everything */
-       rtl8139_hw_start (dev);
-
-       netif_wake_queue (dev);
+       if (netif_running(dev)) {
+               rtl8139_hw_start (dev);
+               netif_wake_queue (dev);
+       }
+       spin_unlock(&tp->rx_lock);
+       
 }
 
 
@@ -1695,6 +1724,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
        /* Calculate the next Tx descriptor entry. */
        entry = tp->cur_tx % NUM_TX_DESC;
 
+       /* Note: the chip doesn't have auto-pad! */
        if (likely(len < TX_BUF_SIZE)) {
                if (len < ETH_ZLEN)
                        memset(tp->tx_buf[entry], 0, ETH_ZLEN);
@@ -1706,7 +1736,6 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
                return 0;
        }
 
-       /* Note: the chip doesn't have auto-pad! */
        spin_lock_irq(&tp->lock);
        RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
                   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
@@ -1720,8 +1749,9 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue (dev);
        spin_unlock_irq(&tp->lock);
 
-       DPRINTK ("%s: Queued Tx packet size %u to slot %d.\n",
-                dev->name, len, entry);
+       if (netif_msg_tx_queued(tp))
+               printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
+                       dev->name, len, entry);
 
        return 0;
 }
@@ -1751,8 +1781,9 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
                /* Note: TxCarrierLost is always asserted at 100mbps. */
                if (txstatus & (TxOutOfWindow | TxAborted)) {
                        /* There was an major error, log it. */
-                       DPRINTK ("%s: Transmit error, Tx status %8.8x.\n",
-                                dev->name, txstatus);
+                       if (netif_msg_tx_err(tp))
+                               printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
+                                       dev->name, txstatus);
                        tp->stats.tx_errors++;
                        if (txstatus & TxAborted) {
                                tp->stats.tx_aborted_errors++;
@@ -1792,8 +1823,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
        if (tp->dirty_tx != dirty_tx) {
                tp->dirty_tx = dirty_tx;
                mb();
-               if (netif_queue_stopped (dev))
-                       netif_wake_queue (dev);
+               netif_wake_queue (dev);
        }
 }
 
@@ -1807,8 +1837,9 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
        int tmp_work;
 #endif
 
-       DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
-                dev->name, rx_status);
+       if (netif_msg_rx_err (tp)) 
+               printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
+                       dev->name, rx_status);
        tp->stats.rx_errors++;
        if (!(rx_status & RxStatusOK)) {
                if (rx_status & RxTooLong) {
@@ -1880,30 +1911,41 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
 #endif
 }
 
-static void rtl8139_rx_interrupt (struct net_device *dev,
-                                 struct rtl8139_private *tp, void *ioaddr)
+#if CONFIG_8139_RXBUF_IDX == 3
+static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
+                                u32 offset, unsigned int size)
 {
-       unsigned char *rx_ring;
-       u16 cur_rx;
+       u32 left = RX_BUF_LEN - offset;
 
-       assert (dev != NULL);
-       assert (tp != NULL);
-       assert (ioaddr != NULL);
+       if (size > left) {
+               memcpy(skb->data, ring + offset, left);
+               memcpy(skb->data+left, ring, size - left);
+       } else
+               memcpy(skb->data, ring + offset, size);
+}
+#endif
 
-       rx_ring = tp->rx_ring;
-       cur_rx = tp->cur_rx;
+static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
+                     int budget)
+{
+       void *ioaddr = tp->mmio_addr;
+       int received = 0;
+       unsigned char *rx_ring = tp->rx_ring;
+       unsigned int cur_rx = tp->cur_rx;
 
        DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
                 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
                 RTL_R16 (RxBufAddr),
                 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-       while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-               int ring_offset = cur_rx % RX_BUF_LEN;
+       while (netif_running(dev) && received < budget 
+              && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
+               u32 ring_offset = cur_rx % RX_BUF_LEN;
                u32 rx_status;
                unsigned int rx_size;
                unsigned int pkt_size;
                struct sk_buff *skb;
+               u16 status;
 
                rmb();
 
@@ -1912,8 +1954,9 @@ static void rtl8139_rx_interrupt (struct net_device *dev,
                rx_size = rx_status >> 16;
                pkt_size = rx_size - 4;
 
-               DPRINTK ("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
-                        " cur %4.4x.\n", dev->name, rx_status,
+               if (netif_msg_rx_status(tp))
+                       printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
+                               " cur %4.4x.\n", dev->name, rx_status,
                         rx_size, cur_rx);
 #if RTL8139_DEBUG > 2
                {
@@ -1930,9 +1973,9 @@ static void rtl8139_rx_interrupt (struct net_device *dev,
                 * Theoretically, this should never happen
                 * since EarlyRx is disabled.
                 */
-               if (rx_size == 0xfff0) {
+               if (unlikely(rx_size == 0xfff0)) {
                        tp->xstats.early_rx++;
-                       break;
+                       goto done;
                }
 
                /* If Rx err or invalid rx_size/rx_status received
@@ -1940,55 +1983,69 @@ static void rtl8139_rx_interrupt (struct net_device *dev,
                 * Rx process gets reset, so we abort any further
                 * Rx processing.
                 */
-               if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
-                   (rx_size < 8) ||
-                   (!(rx_status & RxStatusOK))) {
+               if (unlikely((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+                            (rx_size < 8) ||
+                            (!(rx_status & RxStatusOK)))) {
                        rtl8139_rx_err (rx_status, dev, tp, ioaddr);
-                       return;
+                       return -1;
                }
 
                /* Malloc up new buffer, compatible with net-2e. */
                /* Omit the four octet CRC from the length. */
 
-               /* TODO: consider allocating skb's outside of
-                * interrupt context, both to speed interrupt processing,
-                * and also to reduce the chances of having to
-                * drop packets here under memory pressure.
-                */
-
                skb = dev_alloc_skb (pkt_size + 2);
-               if (skb) {
+               if (likely(skb)) {
                        skb->dev = dev;
                        skb_reserve (skb, 2);   /* 16 byte align the IP fields. */
-
+#if CONFIG_8139_RXBUF_IDX == 3
+                       wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
+#else
                        eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+#endif
                        skb_put (skb, pkt_size);
 
                        skb->protocol = eth_type_trans (skb, dev);
-                       netif_rx (skb);
+
                        dev->last_rx = jiffies;
                        tp->stats.rx_bytes += pkt_size;
                        tp->stats.rx_packets++;
+
+                       netif_receive_skb (skb);
                } else {
-                       printk (KERN_WARNING
-                               "%s: Memory squeeze, dropping packet.\n",
-                               dev->name);
+                       if (net_ratelimit()) 
+                               printk (KERN_WARNING
+                                       "%s: Memory squeeze, dropping packet.\n",
+                                       dev->name);
                        tp->stats.rx_dropped++;
                }
+               received++;
 
                cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
-               RTL_W16 (RxBufPtr, cur_rx - 16);
-
-               if (RTL_R16 (IntrStatus) & RxAckBits)
+               RTL_W16 (RxBufPtr, (u16) (cur_rx - 16));
+
+               /* Clear out errors and receive interrupts */
+               status = RTL_R16 (IntrStatus) & RxAckBits;
+               if (likely(status != 0)) {
+                       if (unlikely(status & (RxFIFOOver | RxOverflow))) {
+                               tp->stats.rx_errors++;
+                               if (status & RxFIFOOver)
+                                       tp->stats.rx_fifo_errors++;
+                       }
                        RTL_W16_F (IntrStatus, RxAckBits);
+               }
        }
 
+ done:
+
+#if RTL8139_DEBUG > 1
        DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
                 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
                 RTL_R16 (RxBufAddr),
                 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
+#endif
 
        tp->cur_rx = cur_rx;
+       return received;
 }
 
 
@@ -2014,14 +2071,12 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
                status &= ~RxUnderrun;
        }
 
-       /* XXX along with rtl8139_rx_err, are we double-counting errors? */
-       if (status &
-           (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
+       if (status & (RxUnderrun | RxErr))
                tp->stats.rx_errors++;
 
        if (status & PCSTimeout)
                tp->stats.rx_length_errors++;
-       if (status & (RxUnderrun | RxFIFOOver))
+       if (status & RxUnderrun)
                tp->stats.rx_fifo_errors++;
        if (status & PCIErr) {
                u16 pci_cmd_status;
@@ -2033,6 +2088,39 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
        }
 }
 
+static int rtl8139_poll(struct net_device *dev, int *budget)
+{
+       struct rtl8139_private *tp = dev->priv;
+       void *ioaddr = tp->mmio_addr;
+       int orig_budget = min(*budget, dev->quota);
+       int done = 1;
+
+       spin_lock(&tp->rx_lock);
+       if (likely(RTL_R16(IntrStatus) & RxAckBits)) {
+               int work_done;
+
+               work_done = rtl8139_rx(dev, tp, orig_budget);
+               if (likely(work_done > 0)) {
+                       *budget -= work_done;
+                       dev->quota -= work_done;
+                       done = (work_done < orig_budget);
+               }
+       }
+
+       if (done) {
+               /*
+                * Order is important since data can get interrupted
+                * again when we think we are done.
+                */
+               local_irq_disable();
+               RTL_W16_F(IntrMask, rtl8139_intr_mask);
+               __netif_rx_complete(dev);
+               local_irq_enable();
+       }
+       spin_unlock(&tp->rx_lock);
+
+       return !done;
+}
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
@@ -2041,68 +2129,59 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct rtl8139_private *tp = dev->priv;
-       int boguscnt = max_interrupt_work;
        void *ioaddr = tp->mmio_addr;
-       int ackstat, status;
+       u16 status, ackstat;
        int link_changed = 0; /* avoid bogus "uninit" warning */
        int handled = 0;
 
        spin_lock (&tp->lock);
+       status = RTL_R16 (IntrStatus);
 
-       do {
-               status = RTL_R16 (IntrStatus);
+       /* shared irq? */
+       if (unlikely((status & rtl8139_intr_mask) == 0)) 
+               goto out;
 
-               /* h/w no longer present (hotplug?) or major error, bail */
-               if (status == 0xFFFF)
-                       break;
+       handled = 1;
 
-               if ((status &
-                    (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
-                     RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
-                       break;
+       /* h/w no longer present (hotplug?) or major error, bail */
+       if (unlikely(status == 0xFFFF)) 
+               goto out;
 
-               handled = 1;
+       /* close possible race's with dev_close */
+       if (unlikely(!netif_running(dev))) {
+               RTL_W16 (IntrMask, 0);
+               goto out;
+       }
 
-               /* Acknowledge all of the current interrupt sources ASAP, but
-                  an first get an additional status bit from CSCR. */
-               if (status & RxUnderrun)
-                       link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
+       /* Acknowledge all of the current interrupt sources ASAP, but
+          an first get an additional status bit from CSCR. */
+       if (unlikely(status & RxUnderrun))
+               link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
 
-               /* The chip takes special action when we clear RxAckBits,
-                * so we clear them later in rtl8139_rx_interrupt
-                */
-               ackstat = status & ~(RxAckBits | TxErr);
+       ackstat = status & ~(RxAckBits | TxErr);
+       if (ackstat)
                RTL_W16 (IntrStatus, ackstat);
 
-               DPRINTK ("%s: interrupt  status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n",
-                        dev->name, status, ackstat, RTL_R16 (IntrStatus));
-
-               if (netif_running (dev) && (status & RxAckBits))
-                       rtl8139_rx_interrupt (dev, tp, ioaddr);
-
-               /* Check uncommon events with one test. */
-               if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
-                             RxFIFOOver | RxErr))
-                       rtl8139_weird_interrupt (dev, tp, ioaddr,
-                                                status, link_changed);
-
-               if (netif_running (dev) && (status & (TxOK | TxErr))) {
-                       rtl8139_tx_interrupt (dev, tp, ioaddr);
-                       if (status & TxErr)
-                               RTL_W16 (IntrStatus, TxErr);
+       /* Receive packets are processed by poll routine.
+          If not running start it now. */
+       if (status & RxAckBits){
+               if (netif_rx_schedule_prep(dev)) {
+                       RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
+                       __netif_rx_schedule (dev);
                }
+       }
 
-               boguscnt--;
-       } while (boguscnt > 0);
-
-       if (boguscnt <= 0) {
-               printk (KERN_WARNING "%s: Too much work at interrupt, "
-                       "IntrStatus=0x%4.4x.\n", dev->name, status);
+       /* Check uncommon events with one test. */
+       if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
+               rtl8139_weird_interrupt (dev, tp, ioaddr,
+                                        status, link_changed);
 
-               /* Clear all interrupt sources. */
-               RTL_W16 (IntrStatus, 0xffff);
+       if (status & (TxOK | TxErr)) {
+               rtl8139_tx_interrupt (dev, tp, ioaddr);
+               if (status & TxErr)
+                       RTL_W16 (IntrStatus, TxErr);
        }
-
+ out:
        spin_unlock (&tp->lock);
 
        DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
@@ -2110,6 +2189,18 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
        return IRQ_RETVAL(handled);
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void rtl8139_poll_controller(struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       rtl8139_interrupt(dev->irq, dev, NULL);
+       enable_irq(dev->irq);
+}
+#endif
 
 static int rtl8139_close (struct net_device *dev)
 {
@@ -2130,8 +2221,9 @@ static int rtl8139_close (struct net_device *dev)
                }
                wait_for_completion (&tp->thr_exited);
        }
-
-       DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n",
+       
+       if (netif_msg_ifdown(tp))
+               printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
                        dev->name, RTL_R16 (IntrStatus));
 
        spin_lock_irqsave (&tp->lock, flags);
@@ -2289,12 +2381,14 @@ static u32 rtl8139_get_link(struct net_device *dev)
 
 static u32 rtl8139_get_msglevel(struct net_device *dev)
 {
-       return debug;
+       struct rtl8139_private *np = dev->priv;
+       return np->msg_enable;
 }
 
 static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
 {
-       debug = datum;
+       struct rtl8139_private *np = dev->priv;
+       np->msg_enable = datum;
 }
 
 /* TODO: we are too slack to do reg dumping for pio, for now */
index 1c60287..a9a23aa 100644 (file)
@@ -1129,21 +1129,40 @@ static void print_eth(unsigned char *add, char *str)
        printk(" %02X%02X, %s\n", add[12], add[13], str);
 }
 
-int __init i82596_probe(struct net_device *dev)
+static int io = 0x300;
+static int irq = 10;
+
+struct net_device * __init i82596_probe(int unit)
 {
+       struct net_device *dev;
        int i;
        struct i596_private *lp;
        char eth_addr[8];
        static int probed;
+       int err;
 
        if (probed)
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
        probed++;
+
+       dev = alloc_etherdev(0);
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       } else {
+               dev->base_addr = io;
+               dev->irq = irq;
+       }
+
 #ifdef ENABLE_MVME16x_NET
        if (MACH_IS_MVME16x) {
                if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
                        printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
-                       return -ENODEV;
+                       err = -ENODEV;
+                       goto out;
                }
                memcpy(eth_addr, (void *) 0xfffc1f2c, 6);       /* YUCK! Get addr from NOVRAM */
                dev->base_addr = MVME_I596_BASE;
@@ -1174,7 +1193,8 @@ int __init i82596_probe(struct net_device *dev)
 
                if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
                        printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
-                       return -EBUSY;
+                       err = -EBUSY;
+                       goto out;
                }
 
                for (i = 0; i < 8; i++) {
@@ -1190,8 +1210,8 @@ int __init i82596_probe(struct net_device *dev)
 
                if ((checksum % 0x100) || 
                    (memcmp(eth_addr, "\x00\x00\x49", 3) != 0)) {
-                       release_region(ioaddr, I596_TOTAL_SIZE);
-                       return -ENODEV;
+                       err = -ENODEV;
+                       goto out1;
                }
 
                dev->base_addr = ioaddr;
@@ -1200,13 +1220,10 @@ int __init i82596_probe(struct net_device *dev)
 #endif
        dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0);
        if (!dev->mem_start) {
-#ifdef ENABLE_APRICOT
-               release_region(dev->base_addr, I596_TOTAL_SIZE);
-#endif
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto out1;
        }
 
-       ether_setup(dev);
        DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
 
        for (i = 0; i < 6; i++)
@@ -1244,7 +1261,26 @@ int __init i82596_probe(struct net_device *dev)
        lp->scb.rfd = I596_NULL;
        lp->lock = SPIN_LOCK_UNLOCKED;
 
-       return 0;
+       err = register_netdev(dev);
+       if (err)
+               goto out2;
+       return dev;
+out2:
+#ifdef __mc68000__
+       /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
+        * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
+        */
+       kernel_set_cachemode((void *)(dev->mem_start), 4096,
+                       IOMAP_FULL_CACHING);
+#endif
+       free_page ((u32)(dev->mem_start));
+out1:
+#ifdef ENABLE_APRICOT
+       release_region(dev->base_addr, I596_TOTAL_SIZE);
+#endif
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -1532,11 +1568,9 @@ static void set_multicast_list(struct net_device *dev)
 }
 
 #ifdef MODULE
-static struct net_device dev_82596 = { .init = i82596_probe };
+static struct net_device *dev_82596;
 
 #ifdef ENABLE_APRICOT
-static int io = 0x300;
-static int irq = 10;
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(irq, "Apricot IRQ number");
 #endif
@@ -1547,34 +1581,31 @@ static int debug = -1;
 
 int init_module(void)
 {
-#ifdef ENABLE_APRICOT
-       dev_82596.base_addr = io;
-       dev_82596.irq = irq;
-#endif
        if (debug >= 0)
                i596_debug = debug;
-       if (register_netdev(&dev_82596) != 0)
-               return -EIO;
+       dev_82596 = i82596_probe(-1);
+       if (IS_ERR(dev_82596))
+               return PTR_ERR(dev_82596);
        return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev(&dev_82596);
+       unregister_netdev(dev_82596);
 #ifdef __mc68000__
        /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
         * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
         */
 
-       kernel_set_cachemode((void *)(dev_82596.mem_start), 4096,
+       kernel_set_cachemode((void *)(dev_82596->mem_start), 4096,
                        IOMAP_FULL_CACHING);
 #endif
-       free_page ((u32)(dev_82596.mem_start));
-       dev_82596.priv = NULL;
+       free_page ((u32)(dev_82596->mem_start));
 #ifdef ENABLE_APRICOT
        /* If we don't do this, we can't re-insmod it later. */
-       release_region(dev_82596.base_addr, I596_TOTAL_SIZE);
+       release_region(dev_82596->base_addr, I596_TOTAL_SIZE);
 #endif
+       free_netdev(dev_82596);
 }
 
 #endif                         /* MODULE */
index 7e5e811..eb33f04 100644 (file)
@@ -157,15 +157,8 @@ static void do_set_multicast_list(struct net_device *dev);
 int ei_open(struct net_device *dev)
 {
        unsigned long flags;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 
-       /* This can't happen unless somebody forgot to call ethdev_init(). */
-       if (ei_local == NULL) 
-       {
-               printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name);
-               return -ENXIO;
-       }
-       
        /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
            wrapper that does e.g. media check & then calls ei_tx_timeout. */
        if (dev->tx_timeout == NULL)
@@ -196,7 +189,7 @@ int ei_open(struct net_device *dev)
  */
 int ei_close(struct net_device *dev)
 {
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned long flags;
 
        /*
@@ -221,7 +214,7 @@ int ei_close(struct net_device *dev)
 void ei_tx_timeout(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int txsr, isr, tickssofar = jiffies - dev->trans_start;
        unsigned long flags;
 
@@ -267,7 +260,7 @@ void ei_tx_timeout(struct net_device *dev)
 static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int length, send_length, output_page;
        unsigned long flags;
        char scratch[ETH_ZLEN];
@@ -435,7 +428,7 @@ irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        }
     
        e8390_base = dev->base_addr;
-       ei_local = (struct ei_device *) dev->priv;
+       ei_local = (struct ei_device *) netdev_priv(dev);
 
        /*
         *      Protect the irq test too.
@@ -540,7 +533,7 @@ irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 static void ei_tx_err(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned char txsr = inb_p(e8390_base+EN0_TSR);
        unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
 
@@ -583,7 +576,7 @@ static void ei_tx_err(struct net_device *dev)
 static void ei_tx_intr(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int status = inb(e8390_base + EN0_TSR);
     
        outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */
@@ -675,7 +668,7 @@ static void ei_tx_intr(struct net_device *dev)
 static void ei_receive(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned char rxing_page, this_frame, next_frame;
        unsigned short current_offset;
        int rx_pkt_count = 0;
@@ -813,7 +806,7 @@ static void ei_rx_overrun(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
        unsigned char was_txing, must_resend = 0;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
     
        /*
         * Record whether a Tx was in progress and then issue the
@@ -881,7 +874,7 @@ static void ei_rx_overrun(struct net_device *dev)
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned long flags;
     
        /* If the card is stopped, just return the present stats. */
@@ -936,7 +929,7 @@ static void do_set_multicast_list(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
        int i;
-       struct ei_device *ei_local = (struct ei_device*)dev->priv;
+       struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
 
        if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) 
        {
@@ -990,53 +983,34 @@ static void do_set_multicast_list(struct net_device *dev)
 static void set_multicast_list(struct net_device *dev)
 {
        unsigned long flags;
-       struct ei_device *ei_local = (struct ei_device*)dev->priv;
+       struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
        
        spin_lock_irqsave(&ei_local->page_lock, flags);
        do_set_multicast_list(dev);
        spin_unlock_irqrestore(&ei_local->page_lock, flags);
 }      
 
-static inline void ei_device_init(struct ei_device *ei_local)
-{
-       spin_lock_init(&ei_local->page_lock);
-}
-
 /**
- * ethdev_init - init rest of 8390 device struct
+ * ethdev_setup - init rest of 8390 device struct
  * @dev: network device structure to init
  *
  * Initialize the rest of the 8390 device structure.  Do NOT __init
  * this, as it is used by 8390 based modular drivers too.
  */
 
-int ethdev_init(struct net_device *dev)
+static void ethdev_setup(struct net_device *dev)
 {
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        if (ei_debug > 1)
                printk(version);
     
-       if (dev->priv == NULL) 
-       {
-               dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
-               if (dev->priv == NULL)
-                       return -ENOMEM;
-               memset(dev->priv, 0, sizeof(struct ei_device));
-               ei_device_init(dev->priv);
-       }
-    
        dev->hard_start_xmit = &ei_start_xmit;
        dev->get_stats  = get_stats;
        dev->set_multicast_list = &set_multicast_list;
 
        ether_setup(dev);
-        
-       return 0;
-}
 
-/* wrapper to make alloc_netdev happy; probably should just cast... */
-static void __ethdev_init(struct net_device *dev)
-{
-       ethdev_init(dev);
+       spin_lock_init(&ei_local->page_lock);
 }
 
 /**
@@ -1044,15 +1018,10 @@ static void __ethdev_init(struct net_device *dev)
  *
  * Allocate 8390-specific net_device.
  */
-struct net_device *alloc_ei_netdev(void)
+struct net_device *__alloc_ei_netdev(int size)
 {
-       struct net_device *dev;
-       
-       dev = alloc_netdev(sizeof(struct ei_device), "eth%d", __ethdev_init);
-       if (dev)
-               ei_device_init(dev->priv);
-
-       return dev;
+       return alloc_netdev(sizeof(struct ei_device) + size, "eth%d",
+                               ethdev_setup);
 }
 
 \f
@@ -1072,7 +1041,7 @@ struct net_device *alloc_ei_netdev(void)
 void NS8390_init(struct net_device *dev, int startp)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int i;
        int endcfg = ei_local->word16
            ? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0))
@@ -1136,7 +1105,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
                                                                int start_page)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
    
        outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);
     
@@ -1156,9 +1125,8 @@ EXPORT_SYMBOL(ei_open);
 EXPORT_SYMBOL(ei_close);
 EXPORT_SYMBOL(ei_interrupt);
 EXPORT_SYMBOL(ei_tx_timeout);
-EXPORT_SYMBOL(ethdev_init);
 EXPORT_SYMBOL(NS8390_init);
-EXPORT_SYMBOL(alloc_ei_netdev);
+EXPORT_SYMBOL(__alloc_ei_netdev);
 
 #if defined(MODULE)
 
index f3415b7..1587a22 100644 (file)
@@ -39,12 +39,15 @@ extern int ei_debug;
 #define ei_debug 1
 #endif
 
-extern int ethdev_init(struct net_device *dev);
 extern void NS8390_init(struct net_device *dev, int startp);
 extern int ei_open(struct net_device *dev);
 extern int ei_close(struct net_device *dev);
 extern irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-extern struct net_device *alloc_ei_netdev(void);
+extern struct net_device *__alloc_ei_netdev(int size);
+static inline struct net_device *alloc_ei_netdev(void)
+{
+       return __alloc_ei_netdev(0);
+}
 
 /* You have one of these per-board */
 struct ei_device {
@@ -84,7 +87,7 @@ struct ei_device {
 /* The maximum time waited (in jiffies) before assuming a Tx failed. (20ms) */
 #define TX_TIMEOUT (20*HZ/100)
 
-#define ei_status (*(struct ei_device *)(dev->priv))
+#define ei_status (*(struct ei_device *)netdev_priv(dev))
 
 /* Some generic ethernet register configurations. */
 #define E8390_TX_IRQ_MASK      0xa     /* For register EN0_ISR */
index e4f9ede..78e8d5c 100644 (file)
@@ -1590,6 +1590,24 @@ config 8139_OLD_RX_RESET
          experience problems, you can enable this option to restore the
          old RX-reset behavior.  If unsure, say N.
 
+config 8139_RXBUF_IDX
+       int "Receive ring size (0 => 8K, 1 => 16K, 2 => 32K, 3 => 64K)"
+       depends on 8139TOO
+       range 0 3
+       default 1 if EMBEDDED || SH_DREAMCAST
+       default 2
+       help
+          The 8139too driver has a fixed area of memory for receiving data.
+          The default value is adequate for most systems. The 64KB 
+          ring size has hardware issues that may cause problems.
+          Values:
+               0  => 8 KB 
+               1  => 16 KB embedded systems
+               2  => 32 KB default for most systems
+               3  => 64 KB 
+          If unsure, use the default 2.
+
+
 config SIS900
        tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
        depends on NET_PCI && PCI
index a83aa51..d4c8308 100644 (file)
@@ -113,7 +113,6 @@ endif
 obj-$(CONFIG_DUMMY) += dummy.o
 obj-$(CONFIG_DE600) += de600.o
 obj-$(CONFIG_DE620) += de620.o
-obj-$(CONFIG_AT1500) += lance.o
 obj-$(CONFIG_LANCE) += lance.o
 obj-$(CONFIG_SUN3_82586) += sun3_82586.o
 obj-$(CONFIG_SUN3LANCE) += sun3lance.o
index 8d2489f..820e5af 100644 (file)
    ethernet adaptor have the name "eth[0123...]".
    */
 
-extern int ne2_probe(struct net_device *dev);
-extern int hp100_probe(struct net_device *dev);
-extern int ultra_probe(struct net_device *dev);
-extern int ultra32_probe(struct net_device *dev);
-extern int wd_probe(struct net_device *dev);
-extern int el2_probe(struct net_device *dev);
-extern int ne_probe(struct net_device *dev);
-extern int hp_probe(struct net_device *dev);
-extern int hp_plus_probe(struct net_device *dev);
-extern int express_probe(struct net_device *);
-extern int eepro_probe(struct net_device *);
-extern int at1500_probe(struct net_device *);
-extern int at1700_probe(struct net_device *);
-extern int fmv18x_probe(struct net_device *);
-extern int eth16i_probe(struct net_device *);
-extern int i82596_probe(struct net_device *);
-extern int ewrk3_probe(struct net_device *);
-extern int el1_probe(struct net_device *);
-extern int wavelan_probe(struct net_device *);
-extern int arlan_probe(struct net_device *);
-extern int el16_probe(struct net_device *);
-extern int elmc_probe(struct net_device *);
-extern int skmca_probe(struct net_device *);
-extern int elplus_probe(struct net_device *);
-extern int ac3200_probe(struct net_device *);
-extern int es_probe(struct net_device *);
-extern int lne390_probe(struct net_device *);
-extern int e2100_probe(struct net_device *);
-extern int ni5010_probe(struct net_device *);
-extern int ni52_probe(struct net_device *);
-extern int ni65_probe(struct net_device *);
-extern int sonic_probe(struct net_device *);
-extern int SK_init(struct net_device *);
-extern int seeq8005_probe(struct net_device *);
-extern int smc_init( struct net_device * );
-extern int atarilance_probe(struct net_device *);
-extern int sun3lance_probe(struct net_device *);
-extern int sun3_82586_probe(struct net_device *);
-extern int apne_probe(struct net_device *);
-extern int bionet_probe(struct net_device *);
-extern int pamsnet_probe(struct net_device *);
-extern int cs89x0_probe(struct net_device *dev);
-extern int hplance_probe(struct net_device *dev);
-extern int bagetlance_probe(struct net_device *);
-extern int mvme147lance_probe(struct net_device *dev);
-extern int tc515_probe(struct net_device *dev);
-extern int lance_probe(struct net_device *dev);
-extern int mace_probe(struct net_device *dev);
-extern int macsonic_probe(struct net_device *dev);
-extern int mac8390_probe(struct net_device *dev);
-extern int mac89x0_probe(struct net_device *dev);
-extern int mc32_probe(struct net_device *dev);
+extern struct net_device *ne2_probe(int unit);
+extern struct net_device *hp100_probe(int unit);
+extern struct net_device *ultra_probe(int unit);
+extern struct net_device *ultra32_probe(int unit);
+extern struct net_device *wd_probe(int unit);
+extern struct net_device *el2_probe(int unit);
+extern struct net_device *ne_probe(int unit);
+extern struct net_device *hp_probe(int unit);
+extern struct net_device *hp_plus_probe(int unit);
+extern struct net_device *express_probe(int unit);
+extern struct net_device *eepro_probe(int unit);
+extern struct net_device *at1700_probe(int unit);
+extern struct net_device *fmv18x_probe(int unit);
+extern struct net_device *eth16i_probe(int unit);
+extern struct net_device *i82596_probe(int unit);
+extern struct net_device *ewrk3_probe(int unit);
+extern struct net_device *el1_probe(int unit);
+extern struct net_device *wavelan_probe(int unit);
+extern struct net_device *arlan_probe(int unit);
+extern struct net_device *el16_probe(int unit);
+extern struct net_device *elmc_probe(int unit);
+extern struct net_device *skmca_probe(int unit);
+extern struct net_device *elplus_probe(int unit);
+extern struct net_device *ac3200_probe(int unit);
+extern struct net_device *es_probe(int unit);
+extern struct net_device *lne390_probe(int unit);
+extern struct net_device *e2100_probe(int unit);
+extern struct net_device *ni5010_probe(int unit);
+extern struct net_device *ni52_probe(int unit);
+extern struct net_device *ni65_probe(int unit);
+extern struct net_device *sonic_probe(int unit);
+extern struct net_device *SK_init(int unit);
+extern struct net_device *seeq8005_probe(int unit);
+extern struct net_device *smc_init(int unit);
+extern struct net_device *atarilance_probe(int unit);
+extern struct net_device *sun3lance_probe(int unit);
+extern struct net_device *sun3_82586_probe(int unit);
+extern struct net_device *apne_probe(int unit);
+extern struct net_device *bionet_probe(int unit);
+extern struct net_device *pamsnet_probe(int unit);
+extern struct net_device *cs89x0_probe(int unit);
+extern struct net_device *hplance_probe(int unit);
+extern struct net_device *bagetlance_probe(int unit);
+extern struct net_device *mvme147lance_probe(int unit);
+extern struct net_device *tc515_probe(int unit);
+extern struct net_device *lance_probe(int unit);
+extern struct net_device *mace_probe(int unit);
+extern struct net_device *macsonic_probe(int unit);
+extern struct net_device *mac8390_probe(int unit);
+extern struct net_device *mac89x0_probe(int unit);
+extern struct net_device *mc32_probe(int unit);
 extern struct net_device *cops_probe(int unit);
 extern struct net_device *ltpc_probe(void);
   
 /* Detachable devices ("pocket adaptors") */
-extern int de620_probe(struct net_device *);
+extern struct net_device *de620_probe(int unit);
 
 /* Fibre Channel adapters */
 extern int iph5526_probe(struct net_device *dev);
@@ -104,33 +103,22 @@ extern int iph5526_probe(struct net_device *dev);
 /* SBNI adapters */
 extern int sbni_probe(int unit);
 
-struct devprobe
-{
-       int (*probe)(struct net_device *dev);
+struct devprobe2 {
+       struct net_device *(*probe)(int unit);
        int status;     /* non-zero if autoprobe has failed */
 };
 
-/*
- * probe_list walks a list of probe functions and calls each so long
- * as a non-zero ioaddr is given, or as long as it hasn't already failed 
- * to find a card in the past (as recorded by "status") when asked to
- * autoprobe (i.e. a probe that fails to find a card when autoprobing
- * will not be asked to autoprobe again).  It exits when a card is found.
- */
-static int __init probe_list(struct net_device *dev, struct devprobe *plist)
+static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
 {
-       struct devprobe *p = plist;
-       unsigned long base_addr = dev->base_addr;
-
-       while (p->probe != NULL) {
-               if (base_addr && p->probe(dev) == 0)    /* probe given addr */
+       struct net_device *dev;
+       for (; p->probe; p++) {
+               if (autoprobe && p->status)
+                       continue;
+               dev = p->probe(unit);
+               if (!IS_ERR(dev))
                        return 0;
-               else if (p->status == 0) {              /* has autoprobe failed yet? */
-                       p->status = p->probe(dev);      /* no, try autoprobe */
-                       if (p->status == 0)
-                               return 0;
-               }
-               p++;
+               if (autoprobe)
+                       p->status = PTR_ERR(dev);
        }
        return -ENODEV;
 }
@@ -141,7 +129,8 @@ static int __init probe_list(struct net_device *dev, struct devprobe *plist)
  * drivers that probe for EISA cards (in the ISA group).  These are the
  * legacy EISA only driver probes, and also the legacy PCI probes
  */
-static struct devprobe eisa_probes[] __initdata = {
+
+static struct devprobe2 eisa_probes[] __initdata = {
 #ifdef CONFIG_ULTRA32 
        {ultra32_probe, 0},     
 #endif
@@ -157,8 +146,7 @@ static struct devprobe eisa_probes[] __initdata = {
        {NULL, 0},
 };
 
-
-static struct devprobe mca_probes[] __initdata = {
+static struct devprobe2 mca_probes[] __initdata = {
 #ifdef CONFIG_NE2_MCA
        {ne2_probe, 0},
 #endif
@@ -178,7 +166,7 @@ static struct devprobe mca_probes[] __initdata = {
  * ISA probes that touch addresses < 0x400 (including those that also
  * look for EISA/PCI/MCA cards in addition to ISA cards).
  */
-static struct devprobe isa_probes[] __initdata = {
+static struct devprobe2 isa_probes[] __initdata = {
 #ifdef CONFIG_HP100            /* ISA, EISA & PCI */
        {hp100_probe, 0},
 #endif 
@@ -215,9 +203,6 @@ static struct devprobe isa_probes[] __initdata = {
 #ifdef CONFIG_SEEQ8005 
        {seeq8005_probe, 0},
 #endif
-#ifdef CONFIG_AT1500
-       {at1500_probe, 0},
-#endif
 #ifdef CONFIG_CS89x0
        {cs89x0_probe, 0},
 #endif
@@ -272,14 +257,14 @@ static struct devprobe isa_probes[] __initdata = {
        {NULL, 0},
 };
 
-static struct devprobe parport_probes[] __initdata = {
+static struct devprobe2 parport_probes[] __initdata = {
 #ifdef CONFIG_DE620            /* D-Link DE-620 adapter */
        {de620_probe, 0},
 #endif
        {NULL, 0},
 };
 
-static struct devprobe m68k_probes[] __initdata = {
+static struct devprobe2 m68k_probes[] __initdata = {
 #ifdef CONFIG_ATARILANCE       /* Lance-based Atari ethernet boards */
        {atarilance_probe, 0},
 #endif
@@ -319,7 +304,7 @@ static struct devprobe m68k_probes[] __initdata = {
        {NULL, 0},
 };
 
-static struct devprobe mips_probes[] __initdata = {
+static struct devprobe2 mips_probes[] __initdata = {
 #ifdef CONFIG_MIPS_JAZZ_SONIC
        {sonic_probe, 0},
 #endif
@@ -334,83 +319,65 @@ static struct devprobe mips_probes[] __initdata = {
  * per bus interface. This drives the legacy devices only for now.
  */
  
-static int __init ethif_probe(int unit)
+static void __init ethif_probe2(int unit)
 {
-       struct net_device *dev;
-       int err = -ENODEV;
+       unsigned long base_addr = netdev_boot_base("eth", unit);
 
-       dev = alloc_etherdev(0);
-       if (!dev)
-               return -ENOMEM;
-
-       sprintf(dev->name, "eth%d", unit);
-       netdev_boot_setup_check(dev);
-
-       /* 
-        * Backwards compatibility - historically an I/O base of 1 was 
-        * used to indicate not to probe for this ethN interface 
-        */
-       if (__dev_get_by_name(dev->name) || dev->base_addr == 1) {
-               free_netdev(dev);
-               return -ENXIO;
-       }
-
-       /* 
-        * The arch specific probes are 1st so that any on-board ethernet
-        * will be probed before other ISA/EISA/MCA/PCI bus cards.
-        */
-       if (probe_list(dev, m68k_probes) == 0 ||
-           probe_list(dev, mips_probes) == 0 ||
-           probe_list(dev, eisa_probes) == 0 ||
-           probe_list(dev, mca_probes) == 0 ||
-           probe_list(dev, isa_probes) == 0 ||
-           probe_list(dev, parport_probes) == 0) 
-               err = register_netdev(dev);
-
-       if (err)
-               free_netdev(dev);
-       return err;
+       if (base_addr == 1)
+               return;
 
+       (void)( probe_list2(unit, m68k_probes, base_addr == 0) &&
+               probe_list2(unit, mips_probes, base_addr == 0) &&
+               probe_list2(unit, eisa_probes, base_addr == 0) &&
+               probe_list2(unit, mca_probes, base_addr == 0) &&
+               probe_list2(unit, isa_probes, base_addr == 0) &&
+               probe_list2(unit, parport_probes, base_addr == 0));
 }
 
 #ifdef CONFIG_TR
 /* Token-ring device probe */
-extern int ibmtr_probe(struct net_device *);
-extern int sk_isa_probe(struct net_device *);
-extern int proteon_probe(struct net_device *);
-extern int smctr_probe(struct net_device *);
+extern int ibmtr_probe_card(struct net_device *);
+extern struct net_device *sk_isa_probe(int unit);
+extern struct net_device *proteon_probe(int unit);
+extern struct net_device *smctr_probe(int unit);
+
+static struct devprobe2 tr_probes2[] __initdata = {
+#ifdef CONFIG_SKISA
+       {sk_isa_probe, 0},
+#endif
+#ifdef CONFIG_PROTEON
+       {proteon_probe, 0},
+#endif
+#ifdef CONFIG_SMCTR
+       {smctr_probe, 0},
+#endif
+       {NULL, 0},
+};
 
 static __init int trif_probe(int unit)
 {
-       struct net_device *dev;
        int err = -ENODEV;
-       
-       dev = alloc_trdev(0);
+#ifdef CONFIG_IBMTR
+       struct net_device *dev = alloc_trdev(0);
        if (!dev)
                return -ENOMEM;
 
        sprintf(dev->name, "tr%d", unit);
        netdev_boot_setup_check(dev);
-       if (
-#ifdef CONFIG_IBMTR
-           ibmtr_probe(dev) == 0  ||
-#endif
-#ifdef CONFIG_SKISA
-           sk_isa_probe(dev) == 0 || 
-#endif
-#ifdef CONFIG_PROTEON
-           proteon_probe(dev) == 0 ||
-#endif
-#ifdef CONFIG_SMCTR
-           smctr_probe(dev) == 0 ||
-#endif
-           0 ) 
-               err = register_netdev(dev);
-               
+       err = ibmtr_probe_card(dev);
        if (err)
                free_netdev(dev);
+#endif
        return err;
+}
 
+static void __init trif_probe2(int unit)
+{
+       unsigned long base_addr = netdev_boot_base("tr", unit);
+
+       if (base_addr == 1)
+               return;
+       probe_list2(unit, tr_probes2, base_addr == 0);
 }
 #endif
 
@@ -437,10 +404,11 @@ static int __init net_olddevs_init(void)
 #endif
 #ifdef CONFIG_TR
        for (num = 0; num < 8; ++num)
-               trif_probe(num);
+               if (!trif_probe(num))
+                       trif_probe2(num);
 #endif
        for (num = 0; num < 8; ++num)
-               ethif_probe(num);
+               ethif_probe2(num);
 
 #ifdef CONFIG_COPS
        cops_probe(0);
@@ -455,28 +423,3 @@ static int __init net_olddevs_init(void)
 }
 
 device_initcall(net_olddevs_init);
-
-/*
- * The @dev_base list is protected by @dev_base_lock and the rtln
- * semaphore.
- *
- * Pure readers hold dev_base_lock for reading.
- *
- * Writers must hold the rtnl semaphore while they loop through the
- * dev_base list, and hold dev_base_lock for writing when they do the
- * actual updates.  This allows pure readers to access the list even
- * while a writer is preparing to update it.
- *
- * To put it another way, dev_base_lock is held for writing only to
- * protect against pure readers; the rtnl semaphore provides the
- * protection against other writers.
- *
- * See, for example usages, register_netdevice() and
- * unregister_netdevice(), which must be called with the rtnl
- * semaphore held.
- */
-struct net_device *dev_base;
-rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
-
-EXPORT_SYMBOL(dev_base);
-EXPORT_SYMBOL(dev_base_lock);
index 2bfc203..05aa7d5 100644 (file)
@@ -737,7 +737,7 @@ static int __init a2065_probe(void)
                        continue;
                }
 
-               dev = init_etherdev(NULL, sizeof(struct lance_private));
+               dev = alloc_etherdev(sizeof(struct lance_private));
 
                if (dev == NULL) {
                        release_resource(r1);
@@ -791,17 +791,22 @@ static int __init a2065_probe(void)
                dev->set_multicast_list = &lance_set_multicast;
                dev->dma = 0;
 
-#ifdef MODULE
-               priv->next_module = root_a2065_dev;
-               root_a2065_dev = priv;
-#endif
-               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;
 
-               res = 0;
+               res = register_netdev(dev);
+               if (res) {
+                       release_resource(r1);
+                       release_resource(r2);
+                       free_netdev(dev);
+                       break;
+               }
+#ifdef MODULE
+               priv->next_module = root_a2065_dev;
+               root_a2065_dev = priv;
+#endif
        }
        return res;
 }
index 41391c0..cb25422 100644 (file)
@@ -75,7 +75,6 @@ static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
 #define AC_START_PG            0x00    /* First page of 8390 TX buffer */
 #define AC_STOP_PG             0x80    /* Last page +1 of the 8390 RX ring */
 
-int ac3200_probe(struct net_device *dev);
 static int ac_probe1(int ioaddr, struct net_device *dev);
 
 static int ac_open(struct net_device *dev);
@@ -96,9 +95,11 @@ static int ac_close_card(struct net_device *dev);
        or the unique value in the station address PROM.
        */
 
-int __init ac3200_probe(struct net_device *dev)
+static int __init do_ac3200_probe(struct net_device *dev)
 {
        unsigned short ioaddr = dev->base_addr;
+       int irq = dev->irq;
+       int mem_start = dev->mem_start;
 
        SET_MODULE_OWNER(dev);
 
@@ -110,13 +111,50 @@ int __init ac3200_probe(struct net_device *dev)
        if ( ! EISA_bus)
                return -ENXIO;
 
-       for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
+       for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
                if (ac_probe1(ioaddr, dev) == 0)
                        return 0;
+               dev->irq = irq;
+               dev->mem_start = mem_start;
+       }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       /* Someday free_irq may be in ac_close_card() */
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, AC_IO_EXTENT);
+       if (ei_status.reg0)
+               iounmap((void *)dev->mem_start);
+}
+
+struct net_device * __init ac3200_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_ac3200_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init ac_probe1(int ioaddr, struct net_device *dev)
 {
        int i, retval;
@@ -156,13 +194,6 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
        }
 #endif
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (", unable to allocate memory for dev->priv.\n");
-               retval = -ENOMEM;
-               goto out;
-       }
-
        /* Assign and allocate the interrupt now. */
        if (dev->irq == 0) {
                dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
@@ -210,7 +241,7 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
                        printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
                        printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
                        retval = -EINVAL;
-                       goto out2;
+                       goto out1;
                }
                dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100);
                if (dev->mem_start == 0) {
@@ -218,7 +249,7 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
                        printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
                        printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
                        retval = -EINVAL;
-                       goto out2;
+                       goto out1;
                }
                ei_status.reg0 = 1;     /* Use as remap flag */
                printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
@@ -247,11 +278,8 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
        dev->stop = &ac_close_card;
        NS8390_init(dev, 0);
        return 0;
-out2:
-       free_irq(dev->irq, dev);
 out1:
-       kfree(dev->priv);
-       dev->priv = NULL;
+       free_irq(dev->irq, dev);
 out:
        release_region(ioaddr, AC_IO_EXTENT);
        return retval;
@@ -338,7 +366,7 @@ static int ac_close_card(struct net_device *dev)
 
 #ifdef MODULE
 #define MAX_AC32_CARDS 4       /* Max number of AC32 cards per module */
-static struct net_device dev_ac32[MAX_AC32_CARDS];
+static struct net_device *dev_ac32[MAX_AC32_CARDS];
 static int io[MAX_AC32_CARDS];
 static int irq[MAX_AC32_CARDS];
 static int mem[MAX_AC32_CARDS];
@@ -354,26 +382,32 @@ MODULE_LICENSE("GPL");
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ac32[this_dev];
+               if (io[this_dev] == 0 && this_dev != 0)
+                       break;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
-               dev->init = ac3200_probe;
-               /* Default is to only install one card. */
-               if (io[this_dev] == 0 && this_dev != 0) break;
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               if (do_ac3200_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_ac32[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -382,16 +416,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ac32[this_dev];
-               if (dev->priv != NULL) {
-                       /* Someday free_irq may be in ac_close_card() */
-                       free_irq(dev->irq, dev);
-                       release_region(dev->base_addr, AC_IO_EXTENT);
-                       if (ei_status.reg0)
-                               iounmap((void *)dev->mem_start);
+               struct net_device *dev = dev_ac32[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index eaa214a..f8ad5f4 100644 (file)
@@ -1209,8 +1209,9 @@ static int __init ace_init(struct net_device *dev)
        switch(tig_ver){
 #ifndef CONFIG_ACENIC_OMIT_TIGON_I
        case 4:
-               printk(KERN_INFO "  Tigon I  (Rev. 4), Firmware: %i.%i.%i, ",
-                      tigonFwReleaseMajor, tigonFwReleaseMinor,
+       case 5:
+               printk(KERN_INFO "  Tigon I  (Rev. %i), Firmware: %i.%i.%i, ",
+                      tig_ver, tigonFwReleaseMajor, tigonFwReleaseMinor,
                       tigonFwReleaseFix);
                writel(0, &regs->LocalCtrl);
                ap->version = 1;
@@ -1235,7 +1236,7 @@ static int __init ace_init(struct net_device *dev)
                break;
        default:
                printk(KERN_WARNING "  Unsupported Tigon version detected "
-                      "(%i), ", tig_ver);
+                      "(%i)\n", tig_ver);
                ecode = -ENODEV;
                goto init_error;
        }
index d455b1e..9070b1d 100644 (file)
@@ -72,7 +72,7 @@
 #define NESM_STOP_PG   0x80    /* Last page +1 of RX ring */
 
 
-int apne_probe(struct net_device *dev);
+struct net_device * __init apne_probe(int unit);
 static int apne_probe1(struct net_device *dev, int ioaddr);
 
 static int apne_open(struct net_device *dev);
@@ -116,28 +116,37 @@ static const char version[] =
 
 static int apne_owned; /* signal if card already owned */
 
-int __init apne_probe(struct net_device *dev)
+struct net_device * __init apne_probe(int unit)
 {
+       struct net_device *dev;
 #ifndef MANUAL_CONFIG
        char tuple[8];
 #endif
+       int err;
 
        if (apne_owned)
-               return -ENODEV;
-
-       SET_MODULE_OWNER(dev);
+               return ERR_PTR(-ENODEV);
 
        if ( !(AMIGAHW_PRESENT(PCMCIA)) )
-               return (-ENODEV);
+               return ERR_PTR(-ENODEV);
                                 
        printk("Looking for PCMCIA ethernet card : ");
                                         
        /* check if a card is inserted */
        if (!(PCMCIA_INSERTED)) {
                printk("NO PCMCIA card inserted\n");
-               return (-ENODEV);
+               return ERR_PTR(-ENODEV);
        }
-                                                                                                
+
+       dev = alloc_ei_netdev();
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
+       SET_MODULE_OWNER(dev);
+
        /* disable pcmcia irq for readtuple */
        pcmcia_disable_irq();
 
@@ -145,17 +154,41 @@ int __init apne_probe(struct net_device *dev)
        if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) ||
                (tuple[2] != CISTPL_FUNCID_NETWORK)) {
                printk("not an ethernet card\n");
-               return (-ENODEV);
+               /* XXX: shouldn't we re-enable irq here? */
+               free_netdev(dev);
+               return ERR_PTR(-ENODEV);
        }
 #endif
 
        printk("ethernet PCMCIA card inserted\n");
 
-       if (init_pcmcia())
-               return apne_probe1(dev, IOBASE);
-       else
-               return (-ENODEV);
+       if (!init_pcmcia()) {
+               /* XXX: shouldn't we re-enable irq here? */
+               free_netdev(dev);
+               return ERR_PTR(-ENODEV);
+       }
 
+       if (!request_region(IOBASE, 0x20, dev->name)) {
+               free_netdev(dev);
+               return ERR_PTR(-EBUSY);
+       }
+
+       err = apne_probe1(dev, IOBASE);
+       if (err) {
+               release_region(IOBASE, 0x20);
+               free_netdev(dev);
+               return ERR_PTR(err);
+       }
+       err = register_netdev(dev);
+       if (!err)
+               return dev;
+
+       pcmcia_disable_irq();
+       free_irq(IRQ_AMIGA_PORTS, dev);
+       pcmcia_reset();
+       release_region(IOBASE, 0x20);
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init apne_probe1(struct net_device *dev, int ioaddr)
@@ -280,13 +313,6 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
     i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, dev->name, dev);
     if (i) return i;
 
-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
-    if (ethdev_init(dev)) {
-       printk (" unable to get memory for dev->priv.\n");
-       free_irq(IRQ_AMIGA_PORTS, dev);
-       return -ENOMEM;
-    }
-
     for(i = 0; i < ETHER_ADDR_LEN; i++) {
        printk(" %2.2x", SA_prom[i]);
        dev->dev_addr[i] = SA_prom[i];
@@ -534,32 +560,27 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 #ifdef MODULE
-static struct net_device apne_dev;
+static struct net_device *apne_dev;
 
 int init_module(void)
 {
-       int err;
-
-       apne_dev.init = apne_probe;
-       if ((err = register_netdev(&apne_dev))) {
-               if (err == -EIO)
-                       printk("No PCMCIA NEx000 ethernet card found.\n");
-               return (err);
-       }
-       return (0);
+       apne_dev = apne_probe(-1);
+       if (IS_ERR(apne_dev))
+               return PTR_ERR(apne_dev);
+       return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev(&apne_dev);
+       unregister_netdev(apne_dev);
 
        pcmcia_disable_irq();
 
-       free_irq(IRQ_AMIGA_PORTS, &apne_dev);
+       free_irq(IRQ_AMIGA_PORTS, apne_dev);
 
        pcmcia_reset();
 
-       apne_owned = 0;
+       free_netdev(apne_dev);
 }
 
 #endif
index ee8b64a..8c0a962 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/ip.h>
 #include <linux/atalk.h>
 #include <linux/if_arp.h>
@@ -55,34 +56,24 @@ static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt);
 static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 
 
-static int __init ipddp_init(struct net_device *dev)
+static struct net_device * __init ipddp_init(void)
 {
        static unsigned version_printed;
+       struct net_device *dev;
+       int err;
+
+       dev = alloc_etherdev(sizeof(struct net_device_stats));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
        SET_MODULE_OWNER(dev);
+       strcpy(dev->name, "ipddp%d");
 
        if (version_printed++ == 0)
                 printk(version);
 
-       /* Let the user now what mode we are in */
-       if(ipddp_mode == IPDDP_ENCAP)
-               printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n", 
-                       dev->name);
-       if(ipddp_mode == IPDDP_DECAP)
-               printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>\n", 
-                       dev->name);
-
-       /* Fill in the device structure with ethernet-generic values. */
-        ether_setup(dev);
-
        /* Initalize the device structure. */
         dev->hard_start_xmit = ipddp_xmit;
-
-        dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
-        if(!dev->priv)
-                return -ENOMEM;
-        memset(dev->priv,0,sizeof(struct net_device_stats));
-
         dev->get_stats      = ipddp_get_stats;
         dev->do_ioctl       = ipddp_ioctl;
 
@@ -97,7 +88,21 @@ static int __init ipddp_init(struct net_device *dev)
          */
         dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1;
 
-        return 0;
+       err = register_netdev(dev);
+       if (err) {
+               free_netdev(dev);
+               return ERR_PTR(err);
+       }
+
+       /* Let the user now what mode we are in */
+       if(ipddp_mode == IPDDP_ENCAP)
+               printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n", 
+                       dev->name);
+       if(ipddp_mode == IPDDP_DECAP)
+               printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>\n", 
+                       dev->name);
+
+        return dev;
 }
 
 /*
@@ -281,23 +286,16 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
         }
 }
 
-static struct net_device dev_ipddp;
+static struct net_device *dev_ipddp;
 
 MODULE_LICENSE("GPL");
 MODULE_PARM(ipddp_mode, "i");
 
 static int __init ipddp_init_module(void)
 {
-       int err;
-
-       dev_ipddp.init = ipddp_init;
-       err=dev_alloc_name(&dev_ipddp, "ipddp%d");
-        if(err < 0)
-                return err;
-
-       if(register_netdev(&dev_ipddp) != 0)
-                return -EIO;
-
+       dev_ipddp = ipddp_init();
+        if (IS_ERR(dev_ipddp))
+                return PTR_ERR(dev_ipddp);
        return 0;
 }
 
@@ -305,8 +303,8 @@ static void __exit ipddp_cleanup_module(void)
 {
         struct ipddp_route *p;
 
-       unregister_netdev(&dev_ipddp);
-        kfree(dev_ipddp.priv);
+       unregister_netdev(dev_ipddp);
+        free_netdev(dev_ipddp);
 
         while (ipddp_route_list) {
                 p = ipddp_route_list->next;
index 1b10bc1..cc7476f 100644 (file)
@@ -1213,7 +1213,7 @@ out3:
 out2:
        release_region(io, 8);
 out1:
-       kfree(dev);
+       free_netdev(dev);
 out:
        return ERR_PTR(err);
 }
index 9530fb4..77ff7df 100644 (file)
@@ -26,6 +26,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -85,8 +86,6 @@ static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offse
  */
 static int __init arcrimi_probe(struct net_device *dev)
 {
-       int retval;
-
        BUGLVL(D_NORMAL) printk(VERSION);
        BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
 
@@ -114,11 +113,7 @@ static int __init arcrimi_probe(struct net_device *dev)
                       "ID!\n");
                return -ENODEV;
        }
-       retval = arcrimi_found(dev);
-       if (retval < 0) {
-               release_mem_region(dev->mem_start, BUFFER_SIZE);
-       }
-       return retval;
+       return arcrimi_found(dev);
 }
 
 
@@ -129,11 +124,13 @@ static int __init arcrimi_probe(struct net_device *dev)
 static int __init arcrimi_found(struct net_device *dev)
 {
        struct arcnet_local *lp;
-       u_long first_mirror, last_mirror, shmem;
+       unsigned long first_mirror, last_mirror, shmem;
        int mirror_size;
+       int err;
 
        /* reserve the irq */
        if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
+               release_mem_region(dev->mem_start, BUFFER_SIZE);
                BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
                return -ENODEV;
        }
@@ -168,11 +165,7 @@ static int __init arcrimi_found(struct net_device *dev)
 
        /* initialize the rest of the device structure. */
 
-       lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
-       if (!lp) {
-               BUGMSG(D_NORMAL, "Can't allocate device data!\n");
-               goto err_free_irq;
-       }
+       lp = dev->priv;
        lp->card_name = "RIM I";
        lp->hw.command = arcrimi_command;
        lp->hw.status = arcrimi_status;
@@ -181,18 +174,6 @@ static int __init arcrimi_found(struct net_device *dev)
        lp->hw.owner = THIS_MODULE;
        lp->hw.copy_to_card = arcrimi_copy_to_card;
        lp->hw.copy_from_card = arcrimi_copy_from_card;
-       lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
-       if (!lp->mem_start) {
-               BUGMSG(D_NORMAL, "Can't remap device memory!\n");
-               goto err_free_dev_priv;
-       }
-       /* Fill in the fields of the device structure with generic
-        * values.
-        */
-       arcdev_setup(dev);
-
-       /* get and check the station ID from offset 1 in shmem */
-       dev->dev_addr[0] = readb(lp->mem_start + 1);
 
        /*
         * re-reserve the memory region - arcrimi_probe() alloced this reqion
@@ -200,25 +181,40 @@ static int __init arcrimi_found(struct net_device *dev)
         * with the correct size.  There is a VERY slim chance this could
         * fail.
         */
-       release_mem_region(dev->mem_start, BUFFER_SIZE);
+       release_mem_region(shmem, BUFFER_SIZE);
        if (!request_mem_region(dev->mem_start,
                                dev->mem_end - dev->mem_start + 1,
                                "arcnet (90xx)")) {
                BUGMSG(D_NORMAL, "Card memory already allocated\n");
-               goto err_free_dev_priv;
+               goto err_free_irq;
        }
 
+       lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+       if (!lp->mem_start) {
+               BUGMSG(D_NORMAL, "Can't remap device memory!\n");
+               goto err_release_mem;
+       }
+
+       /* get and check the station ID from offset 1 in shmem */
+       dev->dev_addr[0] = readb(lp->mem_start + 1);
+
        BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, "
               "ShMem %lXh (%ld*%d bytes).\n",
               dev->dev_addr[0],
               dev->irq, dev->mem_start,
         (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
 
+       err = register_netdev(dev);
+       if (err)
+               goto err_unmap;
+
        return 0;
 
-      err_free_dev_priv:
-       kfree(dev->priv);
-      err_free_irq:
+err_unmap:
+       iounmap(lp->mem_start);
+err_release_mem:
+       release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+err_free_irq:
        free_irq(dev->irq, dev);
        return -EIO;
 }
@@ -294,94 +290,79 @@ static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offse
        TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
 }
 
-#ifdef MODULE
-
-static struct net_device *my_dev;
+static int node;
+static int io;                 /* use the insmod io= irq= node= options */
+static int irq;
+static char device[9];         /* use eg. device=arc1 to change name */
 
-/* Module parameters */
-
-static int node = 0;
-static int io = 0x0;           /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
-static int irq = 0;            /* or use the insmod io= irq= shmem= options */
-static char *device;           /* use eg. device="arc1" to change name */
-
-MODULE_PARM(node, "i");
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(device, "s");
+module_param(node, int, 0);
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param_string(device, device, sizeof(device), 0);
 MODULE_LICENSE("GPL");
 
-int init_module(void)
+static struct net_device *my_dev;
+
+static int __init arc_rimi_init(void)
 {
        struct net_device *dev;
-       int err;
 
-       dev = dev_alloc(device ? : "arc%d", &err);
+       dev = alloc_arcdev(device);
        if (!dev)
-               return err;
+               return -ENOMEM;
 
        if (node && node != 0xff)
                dev->dev_addr[0] = node;
 
-       dev->base_addr = io;
+       dev->mem_start = io;
        dev->irq = irq;
        if (dev->irq == 2)
                dev->irq = 9;
 
-       if (arcrimi_probe(dev))
+       if (arcrimi_probe(dev)) {
+               free_netdev(dev);
                return -EIO;
+       }
 
        my_dev = dev;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit arc_rimi_exit(void)
 {
        struct net_device *dev = my_dev;
        struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
 
        unregister_netdev(dev);
-       free_irq(dev->irq, dev);
        iounmap(lp->mem_start);
        release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
-       kfree(dev->priv);
+       free_irq(dev->irq, dev);
        free_netdev(dev);
 }
 
-#else
-
+#ifndef MODULE
 static int __init arcrimi_setup(char *s)
 {
-       struct net_device *dev;
        int ints[8];
-
        s = get_options(s, 8, ints);
        if (!ints[0])
                return 1;
-       dev = alloc_bootmem(sizeof(struct net_device));
-       memset(dev, 0, sizeof(struct net_device));
-       dev->init = arcrimi_probe;
-
        switch (ints[0]) {
        default:                /* ERROR */
                printk("arcrimi: Too many arguments.\n");
        case 3:         /* Node ID */
-               dev->dev_addr[0] = ints[3];
+               node = ints[3];
        case 2:         /* IRQ */
-               dev->irq = ints[2];
+               irq = ints[2];
        case 1:         /* IO address */
-               dev->mem_start = ints[1];
+               io = ints[1];
        }
        if (*s)
-               strncpy(dev->name, s, 9);
-       else
-               strcpy(dev->name, "arc%d");
-       if (register_netdev(dev))
-               printk(KERN_ERR "arc-rimi: Cannot register arcnet device\n");
-
+               snprintf(device, sizeof(device), "%s", s);
        return 1;
 }
-
 __setup("arcrimi=", arcrimi_setup);
-
 #endif                         /* MODULE */
+
+module_init(arc_rimi_init)
+module_exit(arc_rimi_exit)
index 1de786c..57c1b7d 100644 (file)
@@ -92,6 +92,7 @@ EXPORT_SYMBOL(arc_proto_null);
 EXPORT_SYMBOL(arcnet_unregister_proto);
 EXPORT_SYMBOL(arcnet_debug);
 EXPORT_SYMBOL(arcdev_setup);
+EXPORT_SYMBOL(alloc_arcdev);
 EXPORT_SYMBOL(arcnet_interrupt);
 
 /* Internal function prototypes */
@@ -331,6 +332,11 @@ void arcdev_setup(struct net_device *dev)
        dev->rebuild_header = arcnet_rebuild_header;
 }
 
+struct net_device *alloc_arcdev(char *name)
+{
+       return alloc_netdev(sizeof(struct arcnet_local),
+                           name && *name ? name : "arc%d", arcdev_setup);
+}
 
 /*
  * Open/initialize the board.  This is called sometime after booting when
index 1d71009..d94940d 100644 (file)
@@ -26,6 +26,7 @@
  * **********************
  */
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
@@ -117,49 +118,41 @@ out:
        return err;
 }
 
-
-#ifdef MODULE
-
-static struct net_device *my_dev;
-
-/* Module parameters */
-
 static int node = 0;
 static int io = 0x0;           /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
 static int irq = 0;            /* or use the insmod io= irq= shmem= options */
-static char *device;           /* use eg. device="arc1" to change name */
+static char device[9];         /* use eg. device="arc1" to change name */
 static int timeout = 3;
 static int backplane = 0;
 static int clockp = 0;
 static int clockm = 0;
 
-MODULE_PARM(node, "i");
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(device, "s");
-MODULE_PARM(timeout, "i");
-MODULE_PARM(backplane, "i");
-MODULE_PARM(clockp, "i");
-MODULE_PARM(clockm, "i");
+module_param(node, int, 0);
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param_string(device, device, sizeof(device), 0);
+module_param(timeout, int, 0);
+module_param(backplane, int, 0);
+module_param(clockp, int, 0);
+module_param(clockm, int, 0);
+
 MODULE_LICENSE("GPL");
 
-int init_module(void)
+static struct net_device *my_dev;
+
+static int __init com20020_init(void)
 {
        struct net_device *dev;
        struct arcnet_local *lp;
-       int err;
 
-       dev = dev_alloc(device ? : "arc%d", &err);
+       dev = alloc_arcdev(device);
        if (!dev)
-               return err;
-       lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
-       if (!lp)
                return -ENOMEM;
-       memset(lp, 0, sizeof(struct arcnet_local));
 
        if (node && node != 0xff)
                dev->dev_addr[0] = node;
 
+       lp = dev->priv;
        lp->backplane = backplane;
        lp->clockp = clockp & 7;
        lp->clockm = clockm & 3;
@@ -172,21 +165,24 @@ int init_module(void)
        if (dev->irq == 2)
                dev->irq = 9;
 
-       if (com20020isa_probe(dev))
+       if (com20020isa_probe(dev)) {
+               free_netdev(dev);
                return -EIO;
+       }
 
        my_dev = dev;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit com20020_exit(void)
 {
-       com20020_remove(my_dev);
+       unregister_netdev(my_dev);
+       free_irq(my_dev->irq, my_dev);
        release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
+       free_netdev(my_dev);
 }
 
-#else
-
+#ifndef MODULE
 static int __init com20020isa_setup(char *s)
 {
        struct net_device *dev;
@@ -196,37 +192,31 @@ static int __init com20020isa_setup(char *s)
        s = get_options(s, 8, ints);
        if (!ints[0])
                return 1;
-       dev = alloc_bootmem(sizeof(struct net_device) + sizeof(struct arcnet_local));
-       memset(dev, 0, sizeof(struct net_device) + sizeof(struct arcnet_local));
-       lp = dev->priv = (struct arcnet_local *) (dev + 1);
-       dev->init = com20020isa_probe;
 
        switch (ints[0]) {
        default:                /* ERROR */
                printk("com90xx: Too many arguments.\n");
        case 6:         /* Timeout */
-               lp->timeout = ints[6];
+               timeout = ints[6];
        case 5:         /* CKP value */
-               lp->clockp = ints[5];
+               clockp = ints[5];
        case 4:         /* Backplane flag */
-               lp->backplane = ints[4];
+               backplane = ints[4];
        case 3:         /* Node ID */
-               dev->dev_addr[0] = ints[3];
+               node = ints[3];
        case 2:         /* IRQ */
-               dev->irq = ints[2];
+               irq = ints[2];
        case 1:         /* IO address */
-               dev->base_addr = ints[1];
+               io = ints[1];
        }
        if (*s)
-               strncpy(dev->name, s, 9);
-       else
-               strcpy(dev->name, "arc%d");
-       if (register_netdev(dev))
-               printk(KERN_ERR "com20020: Cannot register arcnet device\n");
-
+               snprintf(device, sizeof(device), "%s", s);
        return 1;
 }
 
 __setup("com20020=", com20020isa_setup);
 
 #endif                         /* MODULE */
+
+module_init(com20020_init)
+module_exit(com20020_exit)
index 6ae9f59..96636ca 100644 (file)
@@ -27,6 +27,7 @@
  * **********************
  */
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
 /* Module parameters */
 
 static int node;
-static char *device;           /* use eg. device="arc1" to change name */
+static char device[9];         /* use eg. device="arc1" to change name */
 static int timeout = 3;
 static int backplane;
 static int clockp;
 static int clockm;
 
-MODULE_PARM(node, "i");
-MODULE_PARM(device, "s");
-MODULE_PARM(timeout, "i");
-MODULE_PARM(backplane, "i");
-MODULE_PARM(clockp, "i");
-MODULE_PARM(clockm, "i");
+module_param(node, int, 0);
+module_param_string(device, device, sizeof(device), 0);
+module_param(timeout, int, 0);
+module_param(backplane, int, 0);
+module_param(clockp, int, 0);
+module_param(clockm, int, 0);
 MODULE_LICENSE("GPL");
 
 static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -68,15 +69,11 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
 
        if (pci_enable_device(pdev))
                return -EIO;
-       dev = dev_alloc(device ? : "arc%d", &err);
+       dev = alloc_arcdev(device);
        if (!dev)
-               return err;
-       lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
-       if (!lp) {
-               err = -ENOMEM;
-               goto out_dev;
-       }
-       memset(lp, 0, sizeof(struct arcnet_local));
+               return -ENOMEM;
+       lp = dev->priv;
+
        pci_set_drvdata(pdev, dev);
 
        // SOHARD needs PCI base addr 4
@@ -89,6 +86,13 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
                ioaddr = pci_resource_start(pdev, 2);
        }
 
+       if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
+               BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
+                      ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+               err = -EBUSY;
+               goto out_dev;
+       }
+
        // Dummy access after Reset
        // ARCNET controller needs this access to detect bustype
        outb(0x00,ioaddr+1);
@@ -105,12 +109,6 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
        lp->timeout = timeout;
        lp->hw.owner = THIS_MODULE;
 
-       if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
-               BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
-                      ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
-               err = -EBUSY;
-               goto out_priv;
-       }
        if (ASTATUS() == 0xFF) {
                BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
                       "but seems empty!\n", ioaddr);
@@ -129,18 +127,18 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
 
 out_port:
        release_region(ioaddr, ARCNET_TOTAL_SIZE);
-out_priv:
-       kfree(dev->priv);
 out_dev:
-       kfree(dev);
+       free_netdev(dev);
        return err;
 }
 
 static void __devexit com20020pci_remove(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       com20020_remove(dev);
+       unregister_netdev(dev);
+       free_irq(dev->irq, dev);
        release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+       free_netdev(dev);
 }
 
 static struct pci_device_id com20020pci_id_table[] = {
index 6b76a5f..7fa829e 100644 (file)
@@ -172,11 +172,6 @@ int com20020_found(struct net_device *dev, int shared)
 
        dev->set_multicast_list = com20020_set_mc_list;
 
-       /* Fill in the fields of the device structure with generic
-        * values.
-        */
-       arcdev_setup(dev);
-
        if (!dev->dev_addr[0])
                dev->dev_addr[0] = inb(ioaddr + 8);     /* FIXME: do this some other way! */
 
@@ -221,7 +216,7 @@ int com20020_found(struct net_device *dev, int shared)
               lp->setup >> 1, 
               clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
 
-       if (!dev->init && register_netdev(dev)) {
+       if (register_netdev(dev)) {
                free_irq(dev->irq, dev);
                return -EIO;
        }
@@ -332,19 +327,10 @@ static void com20020_set_mc_list(struct net_device *dev)
        }
 }
 
-void com20020_remove(struct net_device *dev)
-{
-       unregister_netdev(dev);
-       free_irq(dev->irq, dev);
-       kfree(dev->priv);
-       free_netdev(dev);
-}
-
 #ifdef MODULE
 
 EXPORT_SYMBOL(com20020_check);
 EXPORT_SYMBOL(com20020_found);
-EXPORT_SYMBOL(com20020_remove);
 
 MODULE_LICENSE("GPL");
 
index 563b76b..ac2e0ff 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -234,6 +235,7 @@ static int __init com90io_found(struct net_device *dev)
 {
        struct arcnet_local *lp;
        int ioaddr = dev->base_addr;
+       int err;
 
        /* Reserve the irq */
        if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
@@ -246,15 +248,6 @@ static int __init com90io_found(struct net_device *dev)
                return -EBUSY;
        }
 
-       /* Initialize the rest of the device structure. */
-       dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
-       if (!dev->priv) {
-               free_irq(dev->irq, dev);
-               release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
-               return -ENOMEM;
-       }
-       memset(dev->priv, 0, sizeof(struct arcnet_local));
-
        lp = (struct arcnet_local *) (dev->priv);
        lp->card_name = "COM90xx I/O";
        lp->hw.command = com90io_command;
@@ -265,12 +258,6 @@ static int __init com90io_found(struct net_device *dev)
        lp->hw.copy_to_card = com90io_copy_to_card;
        lp->hw.copy_from_card = com90io_copy_from_card;
 
-       /*
-        * Fill in the fields of the device structure with generic
-        * values.
-        */
-       arcdev_setup(dev);
-
        lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag;
        SETCONF();
 
@@ -278,6 +265,14 @@ static int __init com90io_found(struct net_device *dev)
 
        dev->dev_addr[0] = get_buffer_byte(dev, 1);
 
+       err = register_netdev(dev);
+       if (err) {
+               outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
+               free_irq(dev->irq, dev);
+               release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+               return err;
+       }
+
        BUGMSG(D_NORMAL, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n",
               dev->dev_addr[0], dev->base_addr, dev->irq);
 
@@ -361,44 +356,67 @@ static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offse
        TIME("get_whole_buffer", count, get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
 }
 
-
-#ifdef MODULE
-
-static struct net_device *my_dev;
-
-/* Module parameters */
-
 static int io;                 /* use the insmod io= irq= shmem= options */
 static int irq;
-static char *device;           /* use eg. device=arc1 to change name */
+static char device[9];         /* use eg. device=arc1 to change name */
 
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(device, "s");
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param_string(device, device, sizeof(device), 0);
 MODULE_LICENSE("GPL");
 
-int init_module(void)
+#ifndef MODULE
+static int __init com90io_setup(char *s)
+{
+       int ints[4];
+       s = get_options(s, 4, ints);
+       if (!ints[0])
+               return 0;
+       switch (ints[0]) {
+       default:                /* ERROR */
+               printk("com90io: Too many arguments.\n");
+       case 2:         /* IRQ */
+               irq = ints[2];
+       case 1:         /* IO address */
+               io = ints[1];
+       }
+       if (*s)
+               snprintf(device, sizeof(device), "%s", s);
+       return 1;
+}
+__setup("com90io=", com90io_setup);
+#endif
+
+static struct net_device *my_dev;
+
+static int __init com90io_init(void)
 {
        struct net_device *dev;
        int err;
 
-       dev = dev_alloc(device ? : "arc%d", &err);
+       dev = alloc_arcdev(device);
        if (!dev)
-               return err;
+               return -ENOMEM;
+
+       SET_MODULE_OWNER(dev);
 
        dev->base_addr = io;
        dev->irq = irq;
        if (dev->irq == 2)
                dev->irq = 9;
 
-       if (com90io_probe(dev))
-               return -EIO;
+       err = com90io_probe(dev);
+
+       if (err) {
+               free_netdev(dev);
+               return err;
+       }
 
        my_dev = dev;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit com90io_exit(void)
 {
        struct net_device *dev = my_dev;
        int ioaddr = dev->base_addr;
@@ -410,42 +428,8 @@ void cleanup_module(void)
 
        free_irq(dev->irq, dev);
        release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
-       kfree(dev->priv);
        free_netdev(dev);
 }
 
-#else
-
-static int __init com90io_setup(char *s)
-{
-       struct net_device *dev;
-       int ints[4];
-
-       s = get_options(s, 4, ints);
-       if (!ints[0])
-               return 0;
-       dev = alloc_bootmem(sizeof(struct net_device));
-       memset(dev, 0, sizeof(struct net_device));
-       dev->init = com90io_probe;
-
-       switch (ints[0]) {
-       default:                /* ERROR */
-               printk("com90io: Too many arguments.\n");
-       case 2:         /* IRQ */
-               dev->irq = ints[2];
-       case 1:         /* IO address */
-               dev->base_addr = ints[1];
-       }
-       if (*s)
-               strncpy(dev->name, s, 9);
-       else
-               strcpy(dev->name, "arc%d");
-       if (register_netdev(dev))
-               printk(KERN_ERR "com90io: Cannot register arcnet device\n");
-
-       return 1;
-}
-
-__setup("com90io=", com90io_setup);
-
-#endif                         /* MODULE */
+module_init(com90io_init)
+module_exit(com90io_exit)
index 50d959b..0f51997 100644 (file)
@@ -25,6 +25,7 @@
  * **********************
  */
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -52,8 +53,7 @@
 
 
 /* Internal function declarations */
-static int com90xx_found(struct net_device *dev, int ioaddr, int airq,
-                        u_long shmem);
+static int com90xx_found(int ioaddr, int airq, u_long shmem);
 static void com90xx_command(struct net_device *dev, int command);
 static int com90xx_status(struct net_device *dev);
 static void com90xx_setmask(struct net_device *dev, int mask);
@@ -98,32 +98,43 @@ static int numcards;
 
 static int com90xx_skip_probe __initdata = 0;
 
-static int __init com90xx_probe(struct net_device *dev)
+/* Module parameters */
+
+static int io;                 /* use the insmod io= irq= shmem= options */
+static int irq;
+static int shmem;
+static char device[9];         /* use eg. device=arc1 to change name */
+
+module_param(io, int, 0);
+module_param(irq, int, 0);
+module_param(shmem, int, 0);
+module_param_string(device, device, sizeof(device), 0);
+
+static void __init com90xx_probe(void)
 {
-       int count, status, ioaddr, numprint, airq, retval = -ENODEV,
-        openparen = 0;
+       int count, status, ioaddr, numprint, airq, openparen = 0;
        unsigned long airqmask;
        int ports[(0x3f0 - 0x200) / 16 + 1] =
        {0};
        u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
        {0};
        int numports, numshmems, *port;
-       u_long *shmem;
+       u_long *p;
 
-       if (!dev && com90xx_skip_probe)
-               return -ENODEV;
+       if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
+               return;
 
        BUGLVL(D_NORMAL) printk(VERSION);
 
        /* set up the arrays where we'll store the possible probe addresses */
        numports = numshmems = 0;
-       if (dev && dev->base_addr)
-               ports[numports++] = dev->base_addr;
+       if (io)
+               ports[numports++] = io;
        else
                for (count = 0x200; count <= 0x3f0; count += 16)
                        ports[numports++] = count;
-       if (dev && dev->mem_start)
-               shmems[numshmems++] = dev->mem_start;
+       if (shmem)
+               shmems[numshmems++] = shmem;
        else
                for (count = 0xA0000; count <= 0xFF800; count += 2048)
                        shmems[numshmems++] = count;
@@ -143,22 +154,19 @@ static int __init com90xx_probe(struct net_device *dev)
 
                ioaddr = *port;
 
-               if (check_region(*port, ARCNET_TOTAL_SIZE)) {
+               if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
                        BUGMSG2(D_INIT_REASONS, "(check_region)\n");
                        BUGMSG2(D_INIT_REASONS, "S1: ");
                        BUGLVL(D_INIT_REASONS) numprint = 0;
-                       *port = ports[numports - 1];
-                       numports--;
-                       port--;
+                       *port-- = ports[--numports];
                        continue;
                }
                if (ASTATUS() == 0xFF) {
                        BUGMSG2(D_INIT_REASONS, "(empty)\n");
                        BUGMSG2(D_INIT_REASONS, "S1: ");
                        BUGLVL(D_INIT_REASONS) numprint = 0;
-                       *port = ports[numports - 1];
-                       numports--;
-                       port--;
+                       release_region(*port, ARCNET_TOTAL_SIZE);
+                       *port-- = ports[--numports];
                        continue;
                }
                inb(_RESET);    /* begin resetting card */
@@ -171,14 +179,14 @@ static int __init com90xx_probe(struct net_device *dev)
 
        if (!numports) {
                BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
-               return -ENODEV;
+               return;
        }
        /* Stage 2: we have now reset any possible ARCnet cards, so we can't
         * do anything until they finish.  If D_INIT, print the list of
         * cards that are left.
         */
        numprint = -1;
-       for (port = &ports[0]; port - ports < numports; port++) {
+       for (port = &ports[0]; port < ports + numports; port++) {
                numprint++;
                numprint %= 8;
                if (!numprint) {
@@ -194,8 +202,8 @@ static int __init com90xx_probe(struct net_device *dev)
         * 0xD1 byte in the right place, or are read-only.
         */
        numprint = -1;
-       for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
-               u_long ptr = *shmem;
+       for (p = &shmems[0]; p < shmems + numshmems; p++) {
+               u_long ptr = *p;
 
                numprint++;
                numprint %= 8;
@@ -203,15 +211,13 @@ static int __init com90xx_probe(struct net_device *dev)
                        BUGMSG2(D_INIT, "\n");
                        BUGMSG2(D_INIT, "S3: ");
                }
-               BUGMSG2(D_INIT, "%lXh ", *shmem);
+               BUGMSG2(D_INIT, "%lXh ", *p);
 
-               if (check_mem_region(*shmem, BUFFER_SIZE)) {
+               if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) {
                        BUGMSG2(D_INIT_REASONS, "(check_mem_region)\n");
                        BUGMSG2(D_INIT_REASONS, "Stage 3: ");
                        BUGLVL(D_INIT_REASONS) numprint = 0;
-                       *shmem = shmems[numshmems - 1];
-                       numshmems--;
-                       shmem--;
+                       *p-- = shmems[--numshmems];
                        continue;
                }
                if (isa_readb(ptr) != TESTvalue) {
@@ -219,9 +225,8 @@ static int __init com90xx_probe(struct net_device *dev)
                                isa_readb(ptr), TESTvalue);
                        BUGMSG2(D_INIT_REASONS, "S3: ");
                        BUGLVL(D_INIT_REASONS) numprint = 0;
-                       *shmem = shmems[numshmems - 1];
-                       numshmems--;
-                       shmem--;
+                       release_mem_region(*p, BUFFER_SIZE);
+                       *p-- = shmems[--numshmems];
                        continue;
                }
                /* By writing 0x42 to the TESTvalue location, we also make
@@ -233,9 +238,8 @@ static int __init com90xx_probe(struct net_device *dev)
                if (isa_readb(ptr) != 0x42) {
                        BUGMSG2(D_INIT_REASONS, "(read only)\n");
                        BUGMSG2(D_INIT_REASONS, "S3: ");
-                       *shmem = shmems[numshmems - 1];
-                       numshmems--;
-                       shmem--;
+                       release_mem_region(*p, BUFFER_SIZE);
+                       *p-- = shmems[--numshmems];
                        continue;
                }
                BUGMSG2(D_INIT_REASONS, "\n");
@@ -246,20 +250,22 @@ static int __init com90xx_probe(struct net_device *dev)
 
        if (!numshmems) {
                BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
-               return -ENODEV;
+               for (port = &ports[0]; port < ports + numports; port++)
+                       release_region(*port, ARCNET_TOTAL_SIZE);
+               return;
        }
        /* Stage 4: something of a dummy, to report the shmems that are
         * still possible after stage 3.
         */
        numprint = -1;
-       for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
+       for (p = &shmems[0]; p < shmems + numshmems; p++) {
                numprint++;
                numprint %= 8;
                if (!numprint) {
                        BUGMSG2(D_INIT, "\n");
                        BUGMSG2(D_INIT, "S4: ");
                }
-               BUGMSG2(D_INIT, "%lXh ", *shmem);
+               BUGMSG2(D_INIT, "%lXh ", *p);
        }
        BUGMSG2(D_INIT, "\n");
 
@@ -271,7 +277,8 @@ static int __init com90xx_probe(struct net_device *dev)
         * after the first one is found.
         */
        numprint = -1;
-       for (port = &ports[0]; port - ports < numports; port++) {
+       for (port = &ports[0]; port < ports + numports; port++) {
+               int found = 0;
                numprint++;
                numprint %= 8;
                if (!numprint) {
@@ -288,9 +295,8 @@ static int __init com90xx_probe(struct net_device *dev)
                        BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
                        BUGMSG2(D_INIT_REASONS, "S5: ");
                        BUGLVL(D_INIT_REASONS) numprint = 0;
-                       *port = ports[numports - 1];
-                       numports--;
-                       port--;
+                       release_region(*port, ARCNET_TOTAL_SIZE);
+                       *port-- = ports[--numports];
                        continue;
                }
                ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
@@ -300,15 +306,14 @@ static int __init com90xx_probe(struct net_device *dev)
                                status);
                        BUGMSG2(D_INIT_REASONS, "S5: ");
                        BUGLVL(D_INIT_REASONS) numprint = 0;
-                       *port = ports[numports - 1];
-                       numports--;
-                       port--;
+                       release_region(*port, ARCNET_TOTAL_SIZE);
+                       *port-- = ports[--numports];
                        continue;
                }
                /* skip this completely if an IRQ was given, because maybe
                 * we're on a machine that locks during autoirq!
                 */
-               if (!dev || !dev->irq) {
+               if (!irq) {
                        /* if we do this, we're sure to get an IRQ since the
                         * card has just reset and the NORXflag is on until
                         * we tell it to start receiving.
@@ -323,13 +328,12 @@ static int __init com90xx_probe(struct net_device *dev)
                                BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
                                BUGMSG2(D_INIT_REASONS, "S5: ");
                                BUGLVL(D_INIT_REASONS) numprint = 0;
-                               *port = ports[numports - 1];
-                               numports--;
-                               port--;
+                               release_region(*port, ARCNET_TOTAL_SIZE);
+                               *port-- = ports[--numports];
                                continue;
                        }
                } else {
-                       airq = dev->irq;
+                       airq = irq;
                }
 
                BUGMSG2(D_INIT, "(%d,", airq);
@@ -354,21 +358,20 @@ static int __init com90xx_probe(struct net_device *dev)
                mdelay(RESETtime);
 #endif
 
-               for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
-                       u_long ptr = *shmem;
+               for (p = &shmems[0]; p < shmems + numshmems; p++) {
+                       u_long ptr = *p;
 
                        if (isa_readb(ptr) == TESTvalue) {      /* found one */
-                               BUGMSG2(D_INIT, "%lXh)\n", *shmem);
+                               BUGMSG2(D_INIT, "%lXh)\n", *p);
                                openparen = 0;
 
                                /* register the card */
-                               retval = com90xx_found(dev, *port, airq, *shmem);
+                               if (com90xx_found(*port, airq, *p) == 0)
+                                       found = 1;
                                numprint = -1;
 
                                /* remove shmem from the list */
-                               *shmem = shmems[numshmems - 1];
-                               numshmems--;
-
+                               *p = shmems[--numshmems];
                                break;  /* go to the next I/O port */
                        } else {
                                BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
@@ -380,44 +383,39 @@ static int __init com90xx_probe(struct net_device *dev)
                        BUGLVL(D_INIT_REASONS) printk("S5: ");
                        BUGLVL(D_INIT_REASONS) numprint = 0;
                }
-               *port = ports[numports - 1];
-               numports--;
-               port--;
+               if (!found)
+                       release_region(*port, ARCNET_TOTAL_SIZE);
+               *port-- = ports[--numports];
        }
 
        BUGLVL(D_INIT_REASONS) printk("\n");
 
        /* Now put back TESTvalue on all leftover shmems. */
-       for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
-               isa_writeb(TESTvalue, *shmem);
-
-       if (retval && dev && !numcards)
-               BUGMSG2(D_NORMAL, "S5: No ARCnet cards found.\n");
-       return retval;
+       for (p = &shmems[0]; p < shmems + numshmems; p++) {
+               isa_writeb(TESTvalue, *p);
+               release_mem_region(*p, BUFFER_SIZE);
+       }
 }
 
 
 /* Set up the struct net_device associated with this card.  Called after
  * probing succeeds.
  */
-static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
-                               u_long shmem)
+static int __init com90xx_found(int ioaddr, int airq, u_long shmem)
 {
-       struct net_device *dev = dev0;
+       struct net_device *dev = NULL;
        struct arcnet_local *lp;
        u_long first_mirror, last_mirror;
-       int mirror_size, err;
+       int mirror_size;
 
-       /* allocate struct net_device if we don't have one yet */
-       if (!dev && !(dev = dev_alloc("arc%d", &err))) {
+       /* allocate struct net_device */
+       dev = alloc_arcdev(device);
+       if (!dev) {
                BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
-               return err;
-       }
-       lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
-       if (!lp) {
-               BUGMSG(D_NORMAL, "Can't allocate device data!\n");
-               goto err_free_dev;
+               release_mem_region(shmem, BUFFER_SIZE);
+               return -ENOMEM;
        }
+       lp = dev->priv;
        /* find the real shared memory start/end points, including mirrors */
 
        /* guess the actual size of one "memory mirror" - the number of
@@ -442,8 +440,18 @@ static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
        dev->mem_start = first_mirror;
        dev->mem_end = last_mirror + MIRROR_SIZE - 1;
 
+       release_mem_region(shmem, BUFFER_SIZE);
+       if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
+               goto err_free_dev;
+
+       /* reserve the irq */
+       if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
+               BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
+               goto err_release_mem;
+       }
+       dev->irq = airq;
+
        /* Initialize the rest of the device structure. */
-       memset(lp, 0, sizeof(struct arcnet_local));
        lp->card_name = "COM90xx";
        lp->hw.command = com90xx_command;
        lp->hw.status = com90xx_status;
@@ -455,24 +463,12 @@ static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
        lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
        if (!lp->mem_start) {
                BUGMSG(D_NORMAL, "Can't remap device memory!\n");
-               goto err_free_dev_priv;
+               goto err_free_irq;
        }
-       /* Fill in the fields of the device structure with generic values. */
-       arcdev_setup(dev);
 
        /* get and check the station ID from offset 1 in shmem */
        dev->dev_addr[0] = readb(lp->mem_start + 1);
 
-       /* reserve the irq */
-       if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
-               BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
-               goto err_unmap;
-       }
-       dev->irq = airq;
-
-       /* reserve the I/O and memory regions - guaranteed to work by check_region */
-       request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");
-       request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)");
        dev->base_addr = ioaddr;
 
        BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
@@ -481,23 +477,20 @@ static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
               dev->base_addr, dev->irq, dev->mem_start,
         (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
 
-       if (!dev0 && register_netdev(dev))
-               goto err_release;
+       if (register_netdev(dev))
+               goto err_unmap;
 
        cards[numcards++] = dev;
        return 0;
 
-      err_release:
+err_unmap:
+       iounmap(lp->mem_start);
+err_free_irq:
        free_irq(dev->irq, dev);
-       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+err_release_mem:
        release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
-      err_unmap:
-       iounmap(lp->mem_start);
-      err_free_dev_priv:
-       kfree(dev->priv);
-      err_free_dev:
-       if (!dev0)
-               kfree(dev);
+err_free_dev:
+       free_netdev(dev);
        return -EIO;
 }
 
@@ -587,37 +580,13 @@ static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offse
 }
 
 
-/* Module parameters */
-
-static int io;                 /* use the insmod io= irq= shmem= options */
-static int irq;
-static int shmem;
-static char *device;           /* use eg. device=arc1 to change name */
-
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(shmem, "i");
-MODULE_PARM(device, "s");
 MODULE_LICENSE("GPL");
 
 static int __init com90xx_init(void)
 {
-       struct net_device *dev;
-       int err;
-
-       if (io || irq || shmem || device) {
-               dev = dev_alloc(device ? : "arc%d", &err);
-               if (!dev)
-                       return err;
-               dev->base_addr = io;
-               dev->irq = irq;
-               if (dev->irq == 2)
-                       dev->irq = 9;
-               dev->mem_start = shmem;
-               com90xx_probe(dev);
-       } else
-               com90xx_probe(NULL);
-
+       if (irq == 2)
+               irq = 9;
+       com90xx_probe();
        if (!numcards)
                return -EIO;
        return 0;
@@ -638,7 +607,6 @@ static void __exit com90xx_exit(void)
                iounmap(lp->mem_start);
                release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
                release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
-               kfree(dev->priv);
                free_netdev(dev);
        }
 }
@@ -669,9 +637,7 @@ static int __init com90xx_setup(char *s)
        }
 
        if (*s)
-               strncpy(device, s, 9);
-       else
-               strcpy(device, "arc%d");
+               snprintf(device, sizeof(device), "%s", s);
 
        return 1;
 }
index 0babdc5..849c511 100644 (file)
@@ -168,7 +168,7 @@ static int __init ariadne_probe(void)
            continue;
        }
 
-       dev = init_etherdev(NULL, sizeof(struct ariadne_private));
+       dev = alloc_etherdev(sizeof(struct ariadne_private));
 
        if (dev == NULL) {
            release_resource(r1);
@@ -205,11 +205,17 @@ static int __init ariadne_probe(void)
        dev->get_stats = &ariadne_get_stats;
        dev->set_multicast_list = &set_multicast_list;
 
+       res = register_netdev(dev);
+       if (res) {
+           release_resource(r1);
+           release_resource(r2);
+           free_netdev(dev);
+           break;
+       }
 #ifdef MODULE
        priv->next_module = root_ariadne_dev;
        root_ariadne_dev = priv;
 #endif
-       res = 0;
     }
     return res;
 }
index 9362f39..8931196 100644 (file)
@@ -722,7 +722,7 @@ static int __init am79c961_init(void)
 release:
        release_region(dev->base_addr, 0x18);
 nodev:
-       kfree(dev);
+       free_netdev(dev);
 out:
        return ret;
 }
index 8824494..8791757 100644 (file)
@@ -923,8 +923,6 @@ static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
                result = -ENOMEM;
                goto out_release;
        }
-       memset(dev,0,sizeof(struct net_device));
-       memset(dev->priv, 0, sizeof(struct net_priv));
        priv = dev->priv;
 
        priv->tq_memupdate.routine=ether00_mem_update;
@@ -966,7 +964,7 @@ static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
  out_unmap:
        iounmap(map_addr);
  out_kfree:
-       kfree(dev);
+       free_netdev(dev);
  out_release:
        release_mem_region(dev_info->base_addr, MAC_REG_SIZE);
        return result;
index f24fdf4..42b5f69 100644 (file)
@@ -1068,7 +1068,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
 release:
        release_region(dev->base_addr, 16);
        release_region(dev->base_addr + 0x800, 4096);
-       kfree(dev);
+       free_netdev(dev);
 out:
        return ret;
 }
index 86c5d28..26d3d49 100644 (file)
@@ -908,7 +908,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
 failed:
        release_region(dev->base_addr, 128);
 free:
-       kfree(dev);
+       free_netdev(dev);
 out:
        return ret;
 }
index 7bf52ba..4d97337 100644 (file)
@@ -551,15 +551,12 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
 
        etherh_banner();
 
-       dev = alloc_etherdev(sizeof(struct etherh_priv));
+       dev = alloc_ei_netdev();
        if (!dev) {
                ret = -ENOMEM;
                goto out;
        }
 
-       /*
-        * alloc_etherdev allocs and zeros dev->priv
-        */
        eh = dev->priv;
 
        spin_lock_init(&eh->eidev.page_lock);
@@ -622,21 +619,12 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
                goto free;
        }
 
-       if (ethdev_init(dev)) {
-               ret = -ENODEV;
-               goto release;
-       }
-
        /*
         * If we're in the NIC slot, make sure the IRQ is enabled
         */
        if (dev->irq == 11)
                etherh_set_ctrl(eh, ETHERH_CP_IE);
 
-       /*
-        * Unfortunately, ethdev_init eventually calls
-        * ether_setup, which re-writes dev->flags.
-        */
        switch (ec->cid.product) {
        case PROD_ANT_ETHERM:
                dev_type = "ANT EtherM";
@@ -705,7 +693,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
  release:
        release_region(dev->base_addr, 16);
  free:
-       kfree(dev);
+       free_netdev(dev);
  out:
        return ret;
 }
index c015929..00dc529 100644 (file)
@@ -81,12 +81,12 @@ static int fmv18x_probe_list[] __initdata = {
  */
 
 #ifndef CONFIG_X86_PC9800
-static int at1700_probe_list[] __initdata = {
+static unsigned at1700_probe_list[] __initdata = {
        0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
 };
 
 #else /* CONFIG_X86_PC9800 */
-static int at1700_probe_list[] __initdata = {
+static unsigned at1700_probe_list[] __initdata = {
        0x1d6, 0x1d8, 0x1da, 0x1d4, 0xd4, 0xd2, 0xd8, 0xd0, 0
 };
 
@@ -196,8 +196,6 @@ struct net_local {
 
 /* Index to functions, as function prototypes. */
 
-extern int at1700_probe(struct net_device *dev);
-
 static int at1700_probe1(struct net_device *dev, int ioaddr);
 static int read_eeprom(long ioaddr, int location);
 static int net_open(struct net_device *dev);
@@ -232,24 +230,78 @@ static struct at1720_mca_adapters_struct at1720_mca_adapters[] __initdata = {
    (detachable devices only).
    */
 
-int __init at1700_probe(struct net_device *dev)
+#ifndef CONFIG_X86_PC9800
+static int io = 0x260;
+#else
+static int io = 0xd0;
+#endif
+
+static int irq;
+
+static void cleanup_card(struct net_device *dev)
 {
-       int i;
-       int base_addr = dev->base_addr;
+#ifdef CONFIG_MCA      
+       struct net_local *lp = dev->priv;
+       if (lp->mca_slot)
+               mca_mark_as_unused(lp->mca_slot);
+#endif 
+       free_irq(dev->irq, NULL);
+#ifndef CONFIG_X86_PC9800
+       release_region(dev->base_addr, AT1700_IO_EXTENT);
+#else
+       {
+               int i;
+               for (i = 0; i < 0x2000; i += 0x200)
+                       release_region(dev->base_addr + i, 2);
+       }
+#endif
+}
 
-       SET_MODULE_OWNER(dev);
+struct net_device * __init at1700_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       unsigned *port;
+       int err = 0;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+       } else {
+               dev->base_addr = io;
+               dev->irq = irq;
+       }
 
-       if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return at1700_probe1(dev, base_addr);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
+       SET_MODULE_OWNER(dev);
 
-       for (i = 0; at1700_probe_list[i]; i++) {
-               int ioaddr = at1700_probe_list[i];
-               if (at1700_probe1(dev, ioaddr) == 0)
-                       return 0;
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = at1700_probe1(dev, io);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = at1700_probe_list; *port; port++) {
+                       if (at1700_probe1(dev, *port) == 0)
+                               break;
+                       dev->irq = irq;
+               }
+               if (!*port)
+                       err = -ENODEV;
        }
-       return -ENODEV;
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /* The Fujitsu datasheet suggests that the NIC be probed for by checking its
@@ -267,7 +319,7 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
        char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
        unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
        int slot, ret = -ENODEV;
-       struct net_local *lp;
+       struct net_local *lp = dev->priv;
        
 #ifndef CONFIG_X86_PC9800
        if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name))
@@ -284,9 +336,10 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
        }
 #endif
 
-               /* Resetting the chip doesn't reset the ISA interface, so don't bother.
-          That means we have to be careful with the register values we probe for.
-          */
+       /* Resetting the chip doesn't reset the ISA interface, so don't bother.
+          That means we have to be careful with the register values we probe
+          for.
+        */
 #ifdef notdef
        printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
                   ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
@@ -331,15 +384,13 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
                                                break;
 
                                        /* probing for a card at a particular IO/IRQ */
-                               if (dev &&
-                                       ((dev->irq && dev->irq != irq) ||
-                                        (dev->base_addr && dev->base_addr != ioaddr))) {
+                               if ((dev->irq && dev->irq != irq) ||
+                                   (dev->base_addr && dev->base_addr != ioaddr)) {
                                        slot++;         /* probing next slot */
                                        continue;
                                }
 
-                               if (dev)
-                                       dev->irq = irq;
+                               dev->irq = irq;
                                
                                /* claim the slot */
                                mca_set_adapter_name( slot, at1720_mca_adapters[j].name );
@@ -476,13 +527,7 @@ found:
        if (net_debug)
                printk(version);
 
-       /* Initialize the device structure. */
-       dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev->priv == NULL) {
-               ret = -ENOMEM;
-               goto err_out;
-       }
-       memset(dev->priv, 0, sizeof(struct net_local));
+       memset(lp, 0, sizeof(struct net_local));
 
        dev->open               = net_open;
        dev->stop               = net_close;
@@ -492,11 +537,7 @@ found:
        dev->tx_timeout = net_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
 
-       lp = (struct net_local *)dev->priv;
-       lp->lock = SPIN_LOCK_UNLOCKED;
-
-       /* Fill in the fields of 'dev' with ethernet-generic values. */
-       ether_setup(dev);
+       spin_lock_init(&lp->lock);
 
        lp->jumpered = is_fmv18x;
        lp->mca_slot = slot;
@@ -505,14 +546,11 @@ found:
        if (ret) {
                printk ("  AT1700 at %#3x is unusable due to a conflict on"
                                "IRQ %d.\n", ioaddr, irq);
-               goto err_out_priv;
+               goto err_out;
        }
 
        return 0;
 
-err_out_priv:
-       kfree(dev->priv);
-       dev->priv = NULL;
 err_out:
 #ifndef CONFIG_X86_PC9800
        release_region(ioaddr, AT1700_IO_EXTENT);
@@ -940,14 +978,7 @@ set_rx_mode(struct net_device *dev)
 }
 
 #ifdef MODULE
-static struct net_device dev_at1700;
-#ifndef CONFIG_X86_PC9800
-static int io = 0x260;
-#else
-static int io = 0xd0;
-#endif
-
-static int irq;
+static struct net_device *dev_at1700;
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -960,41 +991,18 @@ int init_module(void)
 {
        if (io == 0)
                printk("at1700: You should not use auto-probing with insmod!\n");
-       dev_at1700.base_addr = io;
-       dev_at1700.irq       = irq;
-       dev_at1700.init      = at1700_probe;
-       if (register_netdev(&dev_at1700) != 0) {
-               printk("at1700: register_netdev() returned non-zero.\n");
-               return -EIO;
-       }
+       dev_at1700 = at1700_probe(-1);
+       if (IS_ERR(dev_at1700))
+               return PTR_ERR(dev_at1700);
        return 0;
 }
 
 void
 cleanup_module(void)
 {
-#ifdef CONFIG_MCA      
-       struct net_local *lp = dev_at1700.priv;
-       if(lp->mca_slot)
-       {
-               mca_mark_as_unused(lp->mca_slot);
-       }
-#endif 
-       unregister_netdev(&dev_at1700);
-       kfree(dev_at1700.priv);
-       dev_at1700.priv = NULL;
-
-       /* If we don't do this, we can't re-insmod it later. */
-       free_irq(dev_at1700.irq, NULL);
-#ifndef CONFIG_X86_PC9800
-       release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
-#else
-       {
-               int i;
-               for (i = 0; i < 0x2000; i += 0x200)
-                       release_region(dev_at1700.base_addr + i, 2);
-       }
-#endif
+       unregister_netdev(dev_at1700);
+       cleanup_card(dev_at1700);
+       free_netdev(dev_at1700);
 }
 #endif /* MODULE */
 MODULE_LICENSE("GPL");
index 36d5392..0aba8ca 100644 (file)
@@ -148,8 +148,6 @@ unsigned char *phys_nic_packet;
 
 /* Index to functions, as function prototypes.
  */
-extern int bionet_probe(struct net_device *dev);
-
 static int bionet_open(struct net_device *dev);
 static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev);
 static void bionet_poll_rx(struct net_device *);
@@ -321,15 +319,26 @@ end:
 
 /* Check for a network adaptor of this type, and return '0' if one exists.
  */
-int __init 
-bionet_probe(struct net_device *dev){
+struct net_device * __init bionet_probe(int unit)
+{
+       struct net_device *dev;
        unsigned char station_addr[6];
        static unsigned version_printed;
        static int no_more_found;       /* avoid "Probing for..." printed 4 times */
        int i;
+       int err;
 
        if (!MACH_IS_ATARI || no_more_found)
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
+
+       dev = alloc_etherdev(sizeof(struct net_local));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
+       SET_MODULE_OWNER(dev);
 
        printk("Probing for BioNet 100 Adapter...\n");
 
@@ -347,11 +356,10 @@ bionet_probe(struct net_device *dev){
        ||  station_addr[2] != 'O' ) {
                no_more_found = 1;
                printk( "No BioNet 100 found.\n" );
-               return -ENODEV;
+               free_netdev(dev);
+               return ERR_PTR(-ENODEV);
        }
 
-       SET_MODULE_OWNER(dev);
-
        if (bionet_debug > 0 && version_printed++ == 0)
                printk(version);
 
@@ -369,12 +377,6 @@ bionet_probe(struct net_device *dev){
                        nic_packet, phys_nic_packet );
        }
 
-       if (dev->priv == NULL)
-               dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (!dev->priv)
-               return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct net_local));
-
        dev->open               = bionet_open;
        dev->stop               = bionet_close;
        dev->hard_start_xmit    = bionet_send_packet;
@@ -390,8 +392,11 @@ bionet_probe(struct net_device *dev){
 #endif
                dev->dev_addr[i]  = station_addr[i];
        }
-       ether_setup(dev);
-       return 0;
+       err = register_netdev(dev);
+       if (!err)
+               return dev;
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /* Open/initialize the board.  This is called (in the current kernel)
@@ -640,25 +645,20 @@ static struct net_device_stats *net_get_stats(struct net_device *dev)
 
 #ifdef MODULE
 
-static struct net_device bio_dev;
-
-int
-init_module(void) {
-       int err;
+static struct net_device *bio_dev;
 
-       bio_dev.init = bionet_probe;
-       if ((err = register_netdev(&bio_dev))) {
-               if (err == -EEXIST)  {
-                       printk("BIONET: devices already present. Module not loaded.\n");
-               }
-               return err;
-       }
+int init_module(void)
+{
+       bio_dev = bionet_probe(-1);
+       if (IS_ERR(bio_dev))
+               return PTR_ERR(bio_dev);
        return 0;
 }
 
-void
-cleanup_module(void) {
-       unregister_netdev(&bio_dev);
+void cleanup_module(void)
+{
+       unregister_netdev(bio_dev);
+       free_netdev(bio_dev);
 }
 
 #endif /* MODULE */
index 27f6dcc..6bcb154 100644 (file)
@@ -110,8 +110,6 @@ static char *version =
 #undef READ
 #undef WRITE
 
-extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private);
-
 /* use 0 for production, 1 for verification, >2 for debug
  */
 #ifndef NET_DEBUG
@@ -158,8 +156,6 @@ static int  send_1_5 (int lun, unsigned char *command, int dma);
 static int     get_status (void);
 static int     calc_received (void *start_address);
 
-extern int pamsnet_probe(struct net_device *dev);
-
 static int pamsnet_open(struct net_device *dev);
 static int pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev);
 static void pamsnet_poll_rx(struct net_device *);
@@ -562,12 +558,12 @@ bad:
 /* Check for a network adaptor of this type, and return '0' if one exists.
  */
 
-int __init 
-pamsnet_probe (dev)
-       struct net_device *dev;
+struct net_device * __init pamsnet_probe (int unit)
 {
+       struct net_device *dev;
        int i;
        HADDR *hwaddr;
+       int err;
 
        unsigned char station_addr[6];
        static unsigned version_printed;
@@ -575,12 +571,18 @@ pamsnet_probe (dev)
        static int no_more_found;
 
        if (no_more_found)
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
+       no_more_found = 1;
 
+       dev = alloc_etherdev(sizeof(struct net_local));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
        SET_MODULE_OWNER(dev);
 
-       no_more_found = 1;
-
        printk("Probing for PAM's Net/GK Adapter...\n");
 
        /* Allocate the DMA buffer here since we need it for probing! */
@@ -618,11 +620,12 @@ pamsnet_probe (dev)
        ENABLE_IRQ();
        stdma_release();
 
-       if (lance_target < 0)
+       if (lance_target < 0) {
                printk("No PAM's Net/GK found.\n");
+               free_netdev(dev);
+               return ERR_PTR(-ENODEV);
+       }
 
-       if ((dev == NULL) || (lance_target < 0))
-               return -ENODEV;
        if (pamsnet_debug > 0 && version_printed++ == 0)
                printk(version);
 
@@ -632,12 +635,6 @@ pamsnet_probe (dev)
                station_addr[3], station_addr[4], station_addr[5]);
 
        /* Initialize the device structure. */
-       if (dev->priv == NULL)
-               dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (!dev->priv)
-               return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct net_local));
-
        dev->open               = pamsnet_open;
        dev->stop               = pamsnet_close;
        dev->hard_start_xmit    = pamsnet_send_packet;
@@ -653,9 +650,12 @@ pamsnet_probe (dev)
 #endif
                dev->dev_addr[i]  = station_addr[i];
        }
-       ether_setup(dev);
+       err = register_netdev(dev);
+       if (!err)
+               return dev;
 
-       return(0);
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /* Open/initialize the board.  This is called (in the current kernel)
@@ -866,25 +866,20 @@ static struct net_device_stats *net_get_stats(struct net_device *dev)
 
 #ifdef MODULE
 
-static struct net_device pam_dev;
-
-int
-init_module(void) {
-       int err;
+static struct net_device *pam_dev;
 
-       pam_dev.init = pamsnet_probe;
-       if ((err = register_netdev(&pam_dev))) {
-               if (err == -EEXIST)  {
-                       printk("PAM's Net/GK: devices already present. Module not loaded.\n");
-               }
-               return err;
-       }
+int init_module(void)
+{
+       pam_dev = pamsnet_probe(-1);
+       if (IS_ERR(pam_dev))
+               return PTR_ERR(pam_dev);
        return 0;
 }
 
-void
-cleanup_module(void) {
-       unregister_netdev(&pam_dev);
+void cleanup_module(void)
+{
+       unregister_netdev(pam_dev);
+       free_netdev(pam_dev);
 }
 
 #endif /* MODULE */
index 7f4c885..e462e2f 100644 (file)
@@ -371,26 +371,39 @@ static void *slow_memcpy( void *dst, const void *src, size_t len )
 }
 
 
-int __init atarilance_probe( struct net_device *dev )
-{      
+struct net_device * __init atarilance_probe(int unit)
+{
        int i;
        static int found;
-
-       SET_MODULE_OWNER(dev);
+       struct net_device *dev;
+       int err = -ENODEV;
 
        if (!MACH_IS_ATARI || found)
                /* Assume there's only one board possible... That seems true, since
                 * the Riebl/PAM board's address cannot be changed. */
-               return( ENODEV );
+               return ERR_PTR(-ENODEV);
+
+       dev = alloc_etherdev(sizeof(struct lance_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
+       SET_MODULE_OWNER(dev);
 
        for( i = 0; i < N_LANCE_ADDR; ++i ) {
                if (lance_probe1( dev, &lance_addr_list[i] )) {
                        found = 1;
-                       return( 0 );
+                       err = register_netdev(dev);
+                       if (!err)
+                               return dev;
+                       free_irq(dev->irq, dev);
+                       break;
                }
        }
-
-       return( ENODEV );
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 
@@ -511,12 +524,6 @@ static unsigned long __init lance_probe1( struct net_device *dev,
        return( 0 );
 
   probe_ok:
-       init_etherdev( dev, sizeof(struct lance_private) );
-       if (!dev->priv) {
-               dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
-               if (!dev->priv)
-                       return 0;
-       }
        lp = (struct lance_private *)dev->priv;
        MEM = (struct lance_memory *)memaddr;
        IO = lp->iobase = (struct lance_ioreg *)ioaddr;
@@ -1171,26 +1178,21 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
 
 \f
 #ifdef MODULE
-static struct net_device atarilance_dev;
+static struct net_device *atarilance_dev;
 
 int init_module(void)
-
-{      int err;
-
-       atarilance_dev.init = atarilance_probe;
-       if ((err = register_netdev( &atarilance_dev ))) {
-               if (err == -EIO)  {
-                       printk( "No Atari Lance board found. Module not loaded.\n");
-               }
-               return( err );
-       }
-       return( 0 );
+{
+       atarilance_dev = atarilance_probe(-1);
+       if (IS_ERR(atarilance_dev))
+               return PTR_ERR(atarilance_dev);
+       return 0;
 }
 
 void cleanup_module(void)
-
 {
-       unregister_netdev( &atarilance_dev );
+       unregister_netdev(atarilance_dev);
+       free_irq(atarilance_dev->irq, atarilance_dev);
+       free_netdev(atarilance_dev);
 }
 
 #endif /* MODULE */
index 9c36def..4bf3a84 100644 (file)
@@ -195,7 +195,7 @@ static void atp_timed_checker(unsigned long ignored);
 
 /* Index to functions, as function prototypes. */
 
-static int atp_probe1(struct net_device *dev, long ioaddr);
+static int atp_probe1(long ioaddr);
 static void get_node_ID(struct net_device *dev);
 static unsigned short eeprom_op(long ioaddr, unsigned int cmd);
 static int net_open(struct net_device *dev);
@@ -224,13 +224,13 @@ static struct net_device *root_atp_dev;
    
    FIXME: we should use the parport layer for this
    */
-static int __init atp_init(struct net_device *dev)
+static int __init atp_init(void)
 {
        int *port, ports[] = {0x378, 0x278, 0x3bc, 0};
-       int base_addr = dev ? dev->base_addr : io[0];
+       int base_addr = io[0];
 
        if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return atp_probe1(dev, base_addr);
+               return atp_probe1(base_addr);
        else if (base_addr == 1)        /* Don't probe at all. */
                return -ENXIO;
 
@@ -239,17 +239,19 @@ static int __init atp_init(struct net_device *dev)
                outb(0x57, ioaddr + PAR_DATA);
                if (inb(ioaddr + PAR_DATA) != 0x57)
                        continue;
-               if (atp_probe1(dev, ioaddr) == 0)
+               if (atp_probe1(ioaddr) == 0)
                        return 0;
        }
 
        return -ENODEV;
 }
 
-static int __init atp_probe1(struct net_device *dev, long ioaddr)
+static int __init atp_probe1(long ioaddr)
 {
+       struct net_device *dev = NULL;
        struct net_local *lp;
        int saved_ctrl_reg, status, i;
+       int res;
 
        outb(0xff, ioaddr + PAR_DATA);
        /* Save the original value of the Control register, in case we guessed
@@ -296,7 +298,7 @@ static int __init atp_probe1(struct net_device *dev, long ioaddr)
                return -ENODEV;
        }
 
-       dev = init_etherdev(dev, sizeof(struct net_local));
+       dev = alloc_etherdev(sizeof(struct net_local));
        if (!dev)
                return -ENOMEM;
        SET_MODULE_OWNER(dev);
@@ -331,24 +333,13 @@ static int __init atp_probe1(struct net_device *dev, long ioaddr)
                   dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 
        /* Reset the ethernet hardware and activate the printer pass-through. */
-    write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
-
-       /* Initialize the device structure. */
-       ether_setup(dev);
-       if (dev->priv == NULL)
-               dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev->priv == NULL)
-               return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct net_local));
+       write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
 
        lp = (struct net_local *)dev->priv;
        lp->chip_type = RTL8002;
        lp->addr_mode = CMR2h_Normal;
        spin_lock_init(&lp->lock);
 
-       lp->next_module = root_atp_dev;
-       root_atp_dev = dev;
-
        /* For the ATP adapter the "if_port" is really the data transfer mode. */
        if (xcvr[0])
                dev->if_port = xcvr[0];
@@ -366,6 +357,15 @@ static int __init atp_probe1(struct net_device *dev, long ioaddr)
        dev->tx_timeout         = tx_timeout;
        dev->watchdog_timeo     = TX_TIMEOUT;
 
+       res = register_netdev(dev);
+       if (res) {
+               free_netdev(dev);
+               return res;
+       }
+
+       lp->next_module = root_atp_dev;
+       root_atp_dev = dev;
+
        return 0;
 }
 
@@ -933,7 +933,7 @@ static void set_rx_mode_8012(struct net_device *dev)
 static int __init atp_init_module(void) {
        if (debug)                                      /* Emit version even if no cards detected. */
                printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
-       return atp_init(NULL);
+       return atp_init();
 }
 
 static void __exit atp_cleanup_module(void) {
index b0a8b37..2bd0ac9 100644 (file)
@@ -56,7 +56,7 @@ static void *dma_alloc(size_t, dma_addr_t *);
 static void dma_free(void *, size_t);
 static void hard_stop(struct net_device *);
 static void enable_rx_tx(struct net_device *dev);
-static int __init au1000_probe1(struct net_device *, long, int, int);
+static int __init au1000_probe1(long, int, int);
 static int au1000_init(struct net_device *);
 static int au1000_open(struct net_device *);
 static int au1000_close(struct net_device *);
@@ -644,17 +644,17 @@ static int __init au1000_init_module(void)
                }
                // check for valid entries, au1100 only has one entry
                if (base_addr && irq) {
-                       if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
+                       if (au1000_probe1(base_addr, irq, i) != 0)
                                return -ENODEV;
-                       }
                }
        }
        return 0;
 }
 
 static int __init
-au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
+au1000_probe1(long ioaddr, int irq, int port_num)
 {
+       struct net_device *dev;
        static unsigned version_printed = 0;
        struct au1000_private *aup = NULL;
        int i, retval = 0;
@@ -668,15 +668,16 @@ au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
        if (version_printed++ == 0)
                printk(version);
 
-       if (!dev)
-               dev = init_etherdev(NULL, sizeof(struct au1000_private));
+       retval = -ENOMEM;
 
+       dev = alloc_etherdev(sizeof(struct au1000_private));
        if (!dev) {
-               printk (KERN_ERR "au1000 eth: init_etherdev failed\n");  
-               release_region(ioaddr, MAC_IOSIZE);
-               return -ENODEV;
+               printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n");  
+               goto out;
        }
 
+       SET_MODULE_OWNER(dev);
+
        printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", 
               dev->name, ioaddr, irq);
 
@@ -685,10 +686,8 @@ au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
        /* Allocate the data buffers */
        aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
                        (NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
-       if (!aup->vaddr) {
-               retval = -ENOMEM;
-               goto free_region;
-       }
+       if (!aup->vaddr)
+               goto out1;
 
        /* aup->mac is the base address of the MAC's registers */
        aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
@@ -749,10 +748,11 @@ au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
                MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
        au_sync_delay(2);
 
-       if (mii_probe(dev) != 0) {
-                goto free_region;
-       }
+       retval = mii_probe(dev);
+       if (retval)
+                goto out2;
 
+       retval = -EINVAL;
        pDBfree = NULL;
        /* setup the data buffer descriptors and attach a buffer to each one */
        pDB = aup->db;
@@ -767,13 +767,13 @@ au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
 
        for (i=0; i<NUM_RX_DMA; i++) {
                pDB = GetFreeDB(aup);
-               if (!pDB) goto free_region;
+               if (!pDB) goto out2;
                aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
                aup->rx_db_inuse[i] = pDB;
        }
        for (i=0; i<NUM_TX_DMA; i++) {
                pDB = GetFreeDB(aup);
-               if (!pDB) goto free_region;
+               if (!pDB) goto out2;
                aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
                aup->tx_dma_ring[i]->len = 0;
                aup->tx_db_inuse[i] = pDB;
@@ -792,26 +792,25 @@ au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
        dev->tx_timeout = au1000_tx_timeout;
        dev->watchdog_timeo = ETH_TX_TIMEOUT;
 
-
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-
        /* 
         * The boot code uses the ethernet controller, so reset it to start 
         * fresh.  au1000_init() expects that the device is in reset state.
         */
        reset_mac(dev);
+
+       retval = register_netdev(dev);
+       if (retval)
+               goto out2;
        return 0;
 
-free_region:
+out2:
+       dma_free(aup->vaddr, MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
+out1:
+       free_netdev(dev);
+out:
        release_region(PHYSADDR(ioaddr), MAC_IOSIZE);
-       unregister_netdev(dev);
-       if (aup->vaddr) 
-               dma_free((void *)aup->vaddr, 
-                               MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
        printk(KERN_ERR "%s: au1000_probe1 failed.  Returns %d\n",
               dev->name, retval);
-       free_netdev(dev);
        return retval;
 }
 
@@ -933,15 +932,12 @@ static int au1000_open(struct net_device *dev)
        int retval;
        struct au1000_private *aup = (struct au1000_private *) dev->priv;
 
-       MOD_INC_USE_COUNT;
-
        if (au1000_debug > 4)
                printk("%s: open: dev=%p\n", dev->name, dev);
 
        if ((retval = au1000_init(dev))) {
                printk(KERN_ERR "%s: error in au1000_init\n", dev->name);
                free_irq(dev->irq, dev);
-               MOD_DEC_USE_COUNT;
                return retval;
        }
        netif_start_queue(dev);
@@ -950,7 +946,6 @@ static int au1000_open(struct net_device *dev)
                                        dev->name, dev))) {
                printk(KERN_ERR "%s: unable to get IRQ %d\n", 
                                dev->name, dev->irq);
-               MOD_DEC_USE_COUNT;
                return retval;
        }
 
@@ -984,8 +979,6 @@ static int au1000_close(struct net_device *dev)
        spin_unlock_irqrestore(&aup->lock, flags);
 
        reset_mac(dev);
-       kfree(dev);
-       MOD_DEC_USE_COUNT;
        return 0;
 }
 
index bc3d1f6..adf1451 100644 (file)
@@ -465,30 +465,43 @@ void *slow_memcpy( void *dst, const void *src, size_t len )
 }
 
 
-int __init bagetlance_probe( struct net_device *dev )
-
-{      int i;
+struct net_device * __init bagetlance_probe(int unit)
+{
+       struct net_device *dev;
+       int i;
        static int found;
-
-       SET_MODULE_OWNER(dev);
+       int err = -ENODEV;
 
        if (found)
                /* Assume there's only one board possible... That seems true, since
                 * the Riebl/PAM board's address cannot be changed. */
-               return( -ENODEV );
+               return ERR_PTR(-ENODEV);
+
+       dev = alloc_etherdev(sizeof(struct lance_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       SET_MODULE_OWNER(dev);
 
        for( i = 0; i < N_LANCE_ADDR; ++i ) {
                if (lance_probe1( dev, &lance_addr_list[i] )) {
                        found = 1;
-                       return( 0 );
+                       break;
                }
        }
-
-       return( -ENODEV );
+       if (!found)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       free_irq(dev->irq, dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
-
-
 /* Derived from hwreg_present() in vme/config.c: */
 
 static int __init addr_accessible( volatile void *regp, 
@@ -527,6 +540,7 @@ static int __init lance_probe1( struct net_device *dev,
        if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
 
        if ((unsigned long)memaddr >= KSEG2) {
+                       /* FIXME: do we need to undo that on cleanup paths? */
                        extern int kseg2_alloc_io (unsigned long addr, unsigned long size);
                        if (kseg2_alloc_io((unsigned long)memaddr, BAGET_LANCE_MEM_SIZE)) {
                                        printk("bagetlance: unable map lance memory\n");
@@ -580,12 +594,6 @@ static int __init lance_probe1( struct net_device *dev,
        return( 0 );
 
   probe_ok:
-       init_etherdev( dev, sizeof(struct lance_private) );
-       if (!dev->priv) {
-               dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
-               if (!dev->priv)
-                       return 0;
-       }
        lp = (struct lance_private *)dev->priv;
        MEM = (struct lance_memory *)memaddr;
        IO = lp->iobase = (struct lance_ioreg *)ioaddr;
@@ -617,8 +625,9 @@ static int __init lance_probe1( struct net_device *dev,
        if (lp->cardtype == PAM_CARD ||
                memaddr == (unsigned short *)0xffe00000) {
                /* PAMs card and Riebl on ST use level 5 autovector */
-               request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
-                           "PAM/Riebl-ST Ethernet", dev);
+               if (request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
+                           "PAM/Riebl-ST Ethernet", dev))
+                       goto probe_fail;
                dev->irq = (unsigned short)BAGET_LANCE_IRQ;
        }
        else {
@@ -629,10 +638,11 @@ static int __init lance_probe1( struct net_device *dev,
                unsigned long irq = BAGET_LANCE_IRQ; 
                if (!irq) {
                        printk( "Lance: request for VME interrupt failed\n" );
-                       return( 0 );
+                       goto probe_fail;
                }
-               request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
-                           "Riebl-VME Ethernet", dev);
+               if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
+                           "Riebl-VME Ethernet", dev))
+                       goto probe_fail;
                dev->irq = irq;
        }
 
@@ -1331,26 +1341,21 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
 
 
 #ifdef MODULE
-static struct net_device bagetlance_dev;
+static struct net_device *bagetlance_dev;
 
 int init_module(void)
-
-{      int err;
-
-       bagetlance_dev.init = bagetlance_probe;
-       if ((err = register_netdev( &bagetlance_dev ))) {
-               if (err == -EIO)  {
-                       printk( "No Vme Lance board found. Module not loaded.\n");
-               }
-               return( err );
-       }
-       return( 0 );
+{
+       bagetlance_dev = bagetlance_probe(-1);
+       if (IS_ERR(bagetlance_dev))
+               return PTR_ERR(bagetlance_dev);
+       return 0;
 }
 
 void cleanup_module(void)
-
 {
-       unregister_netdev( &bagetlance_dev );
+       unregister_netdev(bagetlance_dev);
+       free_irq(bagetlance_dev->irq, bagetlance_dev);
+       free_netdev(bagetlance_dev);
 }
 
 #endif /* MODULE */
index 3431b2e..f222d76 100644 (file)
  *     - Send LACPDU as highest priority packet to further fix the above
  *       problem on very high Tx traffic load where packets may get dropped
  *       by the slave.
+ *
+ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
+ *     - Code cleanup and style changes
  */
 
+//#define BONDING_DEBUG 1
+
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
 
 static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};
 static u16 ad_ticks_per_sec;
+static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
 
 // ================= 3AD api to bonding and kernel code ==================
 static u16 __get_link_speed(struct port *port);
@@ -196,13 +202,11 @@ static inline struct bonding *__get_bond_by_port(struct port *port)
  */
 static inline struct port *__get_first_port(struct bonding *bond)
 {
-       struct slave *slave = bond->next;
-
-       if (slave == (struct slave *)bond) {
+       if (bond->slave_cnt == 0) {
                return NULL;
        }
 
-       return &(SLAVE_AD_INFO(slave).port);
+       return &(SLAVE_AD_INFO(bond->first_slave).port);
 }
 
 /**
@@ -218,7 +222,7 @@ static inline struct port *__get_next_port(struct port *port)
        struct slave *slave = port->slave;
 
        // If there's no bond for this port, or this is the last slave
-       if ((bond == NULL) || (slave->next == bond->next)) {
+       if ((bond == NULL) || (slave->next == bond->first_slave)) {
                return NULL;
        }
 
@@ -236,12 +240,12 @@ static inline struct aggregator *__get_first_agg(struct port *port)
 {
        struct bonding *bond = __get_bond_by_port(port);
 
-       // If there's no bond for this port, or this is the last slave
-       if ((bond == NULL) || (bond->next == (struct slave *)bond)) {
+       // If there's no bond for this port, or bond has no slaves
+       if ((bond == NULL) || (bond->slave_cnt == 0)) {
                return NULL;
        }
 
-       return &(SLAVE_AD_INFO(bond->next).aggregator);
+       return &(SLAVE_AD_INFO(bond->first_slave).aggregator);
 }
 
 /**
@@ -257,7 +261,7 @@ static inline struct aggregator *__get_next_agg(struct aggregator *aggregator)
        struct bonding *bond = bond_get_bond_by_slave(slave);
 
        // If there's no bond for this aggregator, or this is the last slave
-       if ((bond == NULL) || (slave->next == bond->next)) {
+       if ((bond == NULL) || (slave->next == bond->first_slave)) {
                return NULL;
        }
 
@@ -392,7 +396,7 @@ static u16 __get_link_speed(struct port *port)
                }
        }
 
-       BOND_PRINT_DBG(("Port %d Received link speed %d update from adapter", port->actor_port_number, speed));
+       dprintk("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed);
        return speed;
 }
 
@@ -418,12 +422,12 @@ static u8 __get_duplex(struct port *port)
                switch (slave->duplex) {
                case DUPLEX_FULL:
                        retval=0x1;
-                       BOND_PRINT_DBG(("Port %d Received status full duplex update from adapter", port->actor_port_number));
+                       dprintk("Port %d Received status full duplex update from adapter\n", port->actor_port_number);
                        break;
                case DUPLEX_HALF:
                default:
                        retval=0x0;
-                       BOND_PRINT_DBG(("Port %d Received status NOT full duplex update from adapter", port->actor_port_number));
+                       dprintk("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number);
                        break;
                }
        }
@@ -1059,7 +1063,7 @@ static void ad_mux_machine(struct port *port)
 
        // check if the state machine was changed
        if (port->sm_mux_state != last_state) {
-               BOND_PRINT_DBG(("Mux Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_mux_state));
+               dprintk("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state);
                switch (port->sm_mux_state) {
                case AD_MUX_DETACHED:
                        __detach_bond_from_agg(port);
@@ -1158,7 +1162,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 
        // check if the State machine was changed or new lacpdu arrived
        if ((port->sm_rx_state != last_state) || (lacpdu)) {
-               BOND_PRINT_DBG(("Rx Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_rx_state));
+               dprintk("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_rx_state);
                switch (port->sm_rx_state) {
                case AD_RX_INITIALIZE:
                        if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
@@ -1204,7 +1208,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
                        // detect loopback situation
                        if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
                                // INFO_RECEIVED_LOOPBACK_FRAMES
-                               printk(KERN_ERR "bonding: An illegal loopback occurred on adapter (%s)\n",
+                               printk(KERN_ERR DRV_NAME ": An illegal loopback occurred on adapter (%s)\n",
                                                port->slave->dev->name);
                                printk(KERN_ERR "Check the configuration to verify that all Adapters "
                                                "are connected to 802.3ad compliant switch ports\n");
@@ -1245,7 +1249,7 @@ static void ad_tx_machine(struct port *port)
                        __update_lacpdu_from_port(port);
                        // send the lacpdu
                        if (ad_lacpdu_send(port) >= 0) {
-                               BOND_PRINT_DBG(("Sent LACPDU on port %d", port->actor_port_number));
+                               dprintk("Sent LACPDU on port %d\n", port->actor_port_number);
                                // mark ntt as false, so it will not be sent again until demanded
                                port->ntt = 0;
                        }
@@ -1318,7 +1322,7 @@ static void ad_periodic_machine(struct port *port)
 
        // check if the state machine was changed
        if (port->sm_periodic_state != last_state) {
-               BOND_PRINT_DBG(("Periodic Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_periodic_state));
+               dprintk("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state);
                switch (port->sm_periodic_state) {
                case AD_NO_PERIODIC:
                        port->sm_periodic_timer_counter = 0;       // zero timer
@@ -1375,7 +1379,7 @@ static void ad_port_selection_logic(struct port *port)
                                port->next_port_in_aggregator=NULL;
                                port->actor_port_aggregator_identifier=0;
 
-                               BOND_PRINT_DBG(("Port %d left LAG %d", port->actor_port_number, temp_aggregator->aggregator_identifier));
+                               dprintk("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier);
                                // if the aggregator is empty, clear its parameters, and set it ready to be attached
                                if (!temp_aggregator->lag_ports) {
                                        ad_clear_agg(temp_aggregator);
@@ -1384,7 +1388,7 @@ static void ad_port_selection_logic(struct port *port)
                        }
                }
                if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
-                       printk(KERN_WARNING "bonding: Warning: Port %d (on %s) was "
+                       printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
                               "related to aggregator %d but was not on its port list\n",
                               port->actor_port_number, port->slave->dev->name,
                               port->aggregator->aggregator_identifier);
@@ -1417,7 +1421,7 @@ static void ad_port_selection_logic(struct port *port)
                        port->next_port_in_aggregator=aggregator->lag_ports;
                        port->aggregator->num_of_ports++;
                        aggregator->lag_ports=port;
-                       BOND_PRINT_DBG(("Port %d joined LAG %d(existing LAG)", port->actor_port_number, port->aggregator->aggregator_identifier));
+                       dprintk("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
 
                        // mark this port as selected
                        port->sm_vars |= AD_PORT_SELECTED;
@@ -1454,9 +1458,9 @@ static void ad_port_selection_logic(struct port *port)
                        // mark this port as selected
                        port->sm_vars |= AD_PORT_SELECTED;
 
-                       BOND_PRINT_DBG(("Port %d joined LAG %d(new LAG)", port->actor_port_number, port->aggregator->aggregator_identifier));
+                       dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
                } else {
-                       printk(KERN_ERR "bonding: Port %d (on %s) did not find a suitable aggregator\n",
+                       printk(KERN_ERR DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
                               port->actor_port_number, port->slave->dev->name);
                }
        }
@@ -1580,30 +1584,30 @@ static void ad_agg_selection_logic(struct aggregator *aggregator)
                    aggregator;
                    aggregator = __get_next_agg(aggregator)) {
 
-                       BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d",
+                       dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
                                        aggregator->aggregator_identifier, aggregator->num_of_ports,
                                        aggregator->actor_oper_aggregator_key, aggregator->partner_oper_aggregator_key,
-                                       aggregator->is_individual, aggregator->is_active));
+                                       aggregator->is_individual, aggregator->is_active);
                }
 
                // check if any partner replys
                if (best_aggregator->is_individual) {
-                       printk(KERN_WARNING "bonding: Warning: No 802.3ad response from the link partner "
+                       printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
                                        "for any adapters in the bond\n");
                }
 
                // check if there are more than one aggregator
                if (num_of_aggs > 1) {
-                       BOND_PRINT_DBG(("Warning: More than one Link Aggregation Group was "
-                                       "found in the bond. Only one group will function in the bond"));
+                       dprintk("Warning: More than one Link Aggregation Group was "
+                               "found in the bond. Only one group will function in the bond\n");
                }
 
                best_aggregator->is_active = 1;
-               BOND_PRINT_DBG(("LAG %d choosed as the active LAG", best_aggregator->aggregator_identifier));
-               BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d",
+               dprintk("LAG %d choosed as the active LAG\n", best_aggregator->aggregator_identifier);
+               dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
                                best_aggregator->aggregator_identifier, best_aggregator->num_of_ports,
                                best_aggregator->actor_oper_aggregator_key, best_aggregator->partner_oper_aggregator_key,
-                               best_aggregator->is_individual, best_aggregator->is_active));
+                               best_aggregator->is_individual, best_aggregator->is_active);
 
                // disable the ports that were related to the former active_aggregator
                if (last_active_aggregator) {
@@ -1644,7 +1648,7 @@ static void ad_clear_agg(struct aggregator *aggregator)
                aggregator->lag_ports = NULL;
                aggregator->is_active = 0;
                aggregator->num_of_ports = 0;
-               BOND_PRINT_DBG(("LAG %d was cleared", aggregator->aggregator_identifier));
+               dprintk("LAG %d was cleared\n", aggregator->aggregator_identifier);
        }
 }
 
@@ -1729,7 +1733,7 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
 static void ad_enable_collecting_distributing(struct port *port)
 {
        if (port->aggregator->is_active) {
-               BOND_PRINT_DBG(("Enabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier));
+               dprintk("Enabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
                __enable_port(port);
        }
 }
@@ -1742,7 +1746,7 @@ static void ad_enable_collecting_distributing(struct port *port)
 static void ad_disable_collecting_distributing(struct port *port)
 {
        if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) {
-               BOND_PRINT_DBG(("Disabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier));
+               dprintk("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
                __disable_port(port);
        }
 }
@@ -1780,7 +1784,7 @@ static void ad_marker_info_send(struct port *port)
 
        // send the marker information
        if (ad_marker_send(port, &marker) >= 0) {
-               BOND_PRINT_DBG(("Sent Marker Information on port %d", port->actor_port_number));
+               dprintk("Sent Marker Information on port %d\n", port->actor_port_number);
        }
 }
 #endif
@@ -1803,7 +1807,7 @@ static void ad_marker_info_received(struct marker *marker_info,struct port *port
        // send the marker response
 
        if (ad_marker_send(port, &marker) >= 0) {
-               BOND_PRINT_DBG(("Sent Marker Response on port %d", port->actor_port_number));
+               dprintk("Sent Marker Response on port %d\n", port->actor_port_number);
        }
 }
 
@@ -1890,13 +1894,13 @@ static u16 aggregator_identifier;
 void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
 {                         
        // check that the bond is not initialized yet
-       if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->device->dev_addr))) {
+       if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
 
                aggregator_identifier = 0;
 
                BOND_AD_INFO(bond).lacp_fast = lacp_fast;
                BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
-               BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->device->dev_addr);
+               BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
 
                // initialize how many times this module is called in one second(should be about every 100ms)
                ad_ticks_per_sec = tick_resolution;
@@ -1921,7 +1925,7 @@ int bond_3ad_bind_slave(struct slave *slave)
        struct aggregator *aggregator;
 
        if (bond == NULL) {
-               printk(KERN_CRIT "The slave %s is not attached to its bond\n", slave->dev->name);
+               printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
                return -1;
        }
 
@@ -1964,7 +1968,7 @@ int bond_3ad_bind_slave(struct slave *slave)
 
                ad_initialize_agg(aggregator);
 
-               aggregator->aggregator_mac_address = *((struct mac_addr *)bond->device->dev_addr);
+               aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr);
                aggregator->aggregator_identifier = (++aggregator_identifier);
                aggregator->slave = slave;
                aggregator->is_active = 0;
@@ -1996,11 +2000,11 @@ void bond_3ad_unbind_slave(struct slave *slave)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-               printk(KERN_WARNING "bonding: Trying to unbind an uninitialized port on %s\n", slave->dev->name);
+               printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
                return;
        }
 
-       BOND_PRINT_DBG(("Unbinding Link Aggregation Group %d", aggregator->aggregator_identifier));
+       dprintk("Unbinding Link Aggregation Group %d\n", aggregator->aggregator_identifier);
 
        /* Tell the partner that this port is not suitable for aggregation */
        port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
@@ -2024,10 +2028,10 @@ void bond_3ad_unbind_slave(struct slave *slave)
                        // if new aggregator found, copy the aggregator's parameters
                        // and connect the related lag_ports to the new aggregator
                        if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
-                               BOND_PRINT_DBG(("Some port(s) related to LAG %d - replaceing with LAG %d", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier));
+                               dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
 
                                if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
-                                       printk(KERN_INFO "bonding: Removing an active aggregator\n");
+                                       printk(KERN_INFO DRV_NAME ": Removing an active aggregator\n");
                                        // select new active aggregator
                                         select_new_active_agg = 1;
                                }
@@ -2057,7 +2061,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
                                        ad_agg_selection_logic(__get_first_agg(port));
                                }
                        } else {
-                               printk(KERN_WARNING "bonding: Warning: unbinding aggregator, "
+                               printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
                                       "and could not find a new aggregator for its ports\n");
                        }
                } else { // in case that the only port related to this aggregator is the one we want to remove
@@ -2072,7 +2076,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
                }
        }
 
-       BOND_PRINT_DBG(("Unbinding port %d", port->actor_port_number));
+       dprintk("Unbinding port %d\n", port->actor_port_number);
        // find the aggregator that this port is connected to
        temp_aggregator = __get_first_agg(port);
        for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) {
@@ -2123,13 +2127,13 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
 
        read_lock(&bond->lock);
 
-       //check if there are any slaves
-       if (bond->next == (struct slave *)bond) {
-               goto end;
+       if (bond->kill_timers) {
+               goto out;
        }
 
-       if ((bond->device->flags & IFF_UP) != IFF_UP) {
-               goto end;
+       //check if there are any slaves
+       if (bond->slave_cnt == 0) {
+               goto re_arm;
        }
 
        // check if agg_select_timer timer after initialize is timed out
@@ -2137,8 +2141,8 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
                // select the active aggregator for the bond
                if ((port = __get_first_port(bond))) {
                        if (!port->slave) {
-                               printk(KERN_WARNING "bonding: Warning: bond's first port is uninitialized\n");
-                               goto end;
+                               printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
+                               goto re_arm;
                        }
 
                        aggregator = __get_first_agg(port);
@@ -2149,8 +2153,8 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
        // for each port run the state machines
        for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
                if (!port->slave) {
-                       printk(KERN_WARNING "bonding: Warning: Found an uninitialized port\n");
-                       goto end;
+                       printk(KERN_WARNING DRV_NAME ": Warning: Found an uninitialized port\n");
+                       goto re_arm;
                }
 
                ad_rx_machine(NULL, port);
@@ -2165,14 +2169,10 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
                }
        }
 
-end:
+re_arm:
+       mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + ad_delta_in_ticks);
+out:
        read_unlock(&bond->lock);
-
-
-       if ((bond->device->flags & IFF_UP) == IFF_UP) {
-               /* re-arm the timer */
-               mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + (AD_TIMER_INTERVAL * HZ / 1000));
-       }
 }
 
 /**
@@ -2194,14 +2194,14 @@ void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 leng
                port = &(SLAVE_AD_INFO(slave).port);
 
                if (!port->slave) {
-                       printk(KERN_WARNING "bonding: Warning: port of slave %s is uninitialized\n", slave->dev->name);
+                       printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
                        return;
                }
 
                switch (lacpdu->subtype) {
                case AD_TYPE_LACPDU:
                        __ntohs_lacpdu(lacpdu);
-                       BOND_PRINT_DBG(("Received LACPDU on port %d", port->actor_port_number));
+                       dprintk("Received LACPDU on port %d\n", port->actor_port_number);
                        ad_rx_machine(lacpdu, port);
                        break;
 
@@ -2210,17 +2210,17 @@ void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 leng
 
                        switch (((struct marker *)lacpdu)->tlv_type) {
                        case AD_MARKER_INFORMATION_SUBTYPE:
-                               BOND_PRINT_DBG(("Received Marker Information on port %d", port->actor_port_number));
+                               dprintk("Received Marker Information on port %d\n", port->actor_port_number);
                                ad_marker_info_received((struct marker *)lacpdu, port);
                                break;
 
                        case AD_MARKER_RESPONSE_SUBTYPE:
-                               BOND_PRINT_DBG(("Received Marker Response on port %d", port->actor_port_number));
+                               dprintk("Received Marker Response on port %d\n", port->actor_port_number);
                                ad_marker_response_received((struct marker *)lacpdu, port);
                                break;
 
                        default:
-                               BOND_PRINT_DBG(("Received an unknown Marker subtype on slot %d", port->actor_port_number));
+                               dprintk("Received an unknown Marker subtype on slot %d\n", port->actor_port_number);
                        }
                }
        }
@@ -2240,14 +2240,14 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-               printk(KERN_WARNING "bonding: Warning: speed changed for uninitialized port on %s\n",
+               printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
                       slave->dev->name);
                return;
        }
 
        port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
        port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
-       BOND_PRINT_DBG(("Port %d changed speed", port->actor_port_number));
+       dprintk("Port %d changed speed\n", port->actor_port_number);
        // there is no need to reselect a new aggregator, just signal the
        // state machines to reinitialize
        port->sm_vars |= AD_PORT_BEGIN;
@@ -2267,14 +2267,14 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-               printk(KERN_WARNING "bonding: Warning: duplex changed for uninitialized port on %s\n",
+               printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
                       slave->dev->name);
                return;
        }
 
        port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
        port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
-       BOND_PRINT_DBG(("Port %d changed duplex", port->actor_port_number));
+       dprintk("Port %d changed duplex\n", port->actor_port_number);
        // there is no need to reselect a new aggregator, just signal the
        // state machines to reinitialize
        port->sm_vars |= AD_PORT_BEGIN;
@@ -2295,10 +2295,8 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-#ifdef BONDING_DEBUG
-               printk(KERN_WARNING "bonding: Warning: link status changed for uninitialized port on %s\n",
-                      slave->dev->name);
-#endif
+               printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
+                       slave->dev->name);
                return;
        }
 
@@ -2356,41 +2354,27 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
 
 int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 {
-       slave_t *slave, *start_at;
-       struct bonding *bond = (struct bonding *) dev->priv;
+       struct slave *slave, *start_at;
+       struct bonding *bond = dev->priv;
        struct ethhdr *data = (struct ethhdr *)skb->data;
        int slave_agg_no;
        int slaves_in_agg;
        int agg_id;
+       int i;
        struct ad_info ad_info;
 
-       if (!IS_UP(dev)) { /* bond down */
-               dev_kfree_skb(skb);
-               return 0;
-       }
-
-       if (bond == NULL) {
-               printk(KERN_CRIT "bonding: Error: bond is NULL on device %s\n", dev->name);
-               dev_kfree_skb(skb);
-               return 0;
-       }
-
+       /* make sure that the slaves list will
+        * not change during tx
+        */
        read_lock(&bond->lock);
-       slave = bond->prev;
 
-       /* check if bond is empty */
-       if ((slave == (struct slave *) bond) || (bond->slave_cnt == 0)) {
-               printk(KERN_DEBUG "ERROR: bond is empty\n");
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
+       if (!BOND_IS_OK(bond)) {
+               goto free_out;
        }
 
        if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
                printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
+               goto free_out;
        }
 
        slaves_in_agg = ad_info.ports;
@@ -2399,21 +2383,12 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
        if (slaves_in_agg == 0) {
                /*the aggregator is empty*/
                printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
+               goto free_out;
        }
 
-       /* we're at the root, get the first slave */
-       if ((slave == NULL) || (slave->dev == NULL)) {
-               /* no suitable interface, frame not sent */
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
-       }
+       slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg;
 
-       slave_agg_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % slaves_in_agg;
-       while (slave != (slave_t *)bond) {
+       bond_for_each_slave(bond, slave, i) {
                struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
 
                if (agg && (agg->aggregator_identifier == agg_id)) {
@@ -2422,37 +2397,18 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
                                break;
                        }
                }
-
-               slave = slave->prev;
-               if (slave == NULL) {
-                       printk(KERN_ERR "bonding: Error: slave is NULL\n");
-                       dev_kfree_skb(skb);
-                       read_unlock(&bond->lock);
-                       return 0;
-               }
        }
 
-       if (slave == (slave_t *)bond) {
-               printk(KERN_ERR "bonding: Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
+       if (slave_agg_no >= 0) {
+               printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
+               goto free_out;
        }
 
        start_at = slave;
 
-       do {
+       bond_for_each_slave_from(bond, slave, i, start_at) {
                int slave_agg_id = 0;
-               struct aggregator *agg;
-
-               if (slave == NULL) {
-                       printk(KERN_ERR "bonding: Error: slave is NULL\n");
-                       dev_kfree_skb(skb);
-                       read_unlock(&bond->lock);
-                       return 0;
-               }
-
-               agg = SLAVE_AD_INFO(slave).port.aggregator;
+               struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
 
                if (agg) {
                        slave_agg_id = agg->aggregator_identifier;
@@ -2463,20 +2419,24 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
                        skb->dev = slave->dev;                  
                        skb->priority = 1;
                        dev_queue_xmit(skb);
-                       read_unlock(&bond->lock);
-                       return 0;
+
+                       goto out;
                }
-       } while ((slave = slave->next) != start_at);
+       }
 
-       /* no suitable interface, frame not sent */
-       dev_kfree_skb(skb);
+out:
        read_unlock(&bond->lock);
        return 0;
+
+free_out:
+       /* no suitable interface, frame not sent */
+       dev_kfree_skb(skb);
+       goto out;
 }
 
 int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype)
 {
-       struct bonding *bond = (struct bonding *)dev->priv;
+       struct bonding *bond = dev->priv;
        struct slave *slave = NULL;
        int ret = NET_RX_DROP;
 
index 12a5d20..1d53bfb 100644 (file)
@@ -28,6 +28,9 @@
  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
  *     - Renamed bond_3ad_link_status_changed() to
  *       bond_3ad_handle_link_change() for compatibility with TLB.
+ *
+ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
+ *     - Code cleanup and style changes
  */
 
 #ifndef __BOND_3AD_H__
index 544cbe4..a853d9e 100644 (file)
  * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
  *     - Add support for setting bond's MAC address with special
  *       handling required for ALB/TLB.
+ *
+ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
+ *     - Code cleanup and style changes
  */
 
+//#define BONDING_DEBUG 1
+
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 
 
 #define ALB_TIMER_TICKS_PER_SEC            10  /* should be a divisor of HZ */
-#define BOND_TLB_REBALANCE_INTERVAL 10 /* in seconds, periodic re-balancing
-                                        * used for division - never set
+#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing.
+                                        * Used for division - never set
                                         * to zero !!!
                                         */
-#define BOND_ALB_LP_INTERVAL       1   /* in seconds periodic send of
+#define BOND_ALB_LP_INTERVAL       1   /* In seconds, periodic send of
                                         * learning packets to the switch
                                         */
 
@@ -66,7 +71,7 @@
 
 #define TLB_HASH_TABLE_SIZE 256        /* The size of the clients hash table.
                                 * Note that this value MUST NOT be smaller
-                                * because the key hash table BYTE wide !
+                                * because the key hash table is BYTE wide !
                                 */
 
 
  */
 #define RLB_PROMISC_TIMEOUT    10*ALB_TIMER_TICKS_PER_SEC
 
+static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
+
 #pragma pack(1)
 struct learning_pkt {
        u8 mac_dst[ETH_ALEN];
        u8 mac_src[ETH_ALEN];
        u16 type;
-       u8 padding[ETH_ZLEN - (2*ETH_ALEN + 2)];
+       u8 padding[ETH_ZLEN - ETH_HLEN];
 };
 
 struct arp_pkt {
@@ -110,13 +118,12 @@ struct arp_pkt {
 /* Forward declaration */
 static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]);
 
-static inline u8
-_simple_hash(u8 *hash_start, int hash_size)
+static inline u8 _simple_hash(u8 *hash_start, int hash_size)
 {
        int i;
        u8 hash = 0;
 
-       for (i=0; i<hash_size; i++) {
+       for (i = 0; i < hash_size; i++) {
                hash ^= hash_start[i];
        }
 
@@ -125,193 +132,151 @@ _simple_hash(u8 *hash_start, int hash_size)
 
 /*********************** tlb specific functions ***************************/
 
-static inline void
-_lock_tx_hashtbl(struct bonding *bond)
+static inline void _lock_tx_hashtbl(struct bonding *bond)
 {
        spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
 }
 
-static inline void
-_unlock_tx_hashtbl(struct bonding *bond)
+static inline void _unlock_tx_hashtbl(struct bonding *bond)
 {
        spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
 }
 
 /* Caller must hold tx_hashtbl lock */
-static inline void
-tlb_init_table_entry(struct bonding *bond, u8 index, u8 save_load)
+static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load)
 {
-       struct tlb_client_info *entry;
-
-       if (BOND_ALB_INFO(bond).tx_hashtbl == NULL) {
-               return;
-       }
-
-       entry = &(BOND_ALB_INFO(bond).tx_hashtbl[index]);
-       /* at end of cycle, save the load that was transmitted to the client
-        * during the cycle, and set the tx_bytes counter to 0 for counting
-        * the load during the next cycle
-        */
        if (save_load) {
                entry->load_history = 1 + entry->tx_bytes /
-                       BOND_TLB_REBALANCE_INTERVAL;
+                                     BOND_TLB_REBALANCE_INTERVAL;
                entry->tx_bytes = 0;
        }
+
        entry->tx_slave = NULL;
        entry->next = TLB_NULL_INDEX;
        entry->prev = TLB_NULL_INDEX;
 }
 
-static inline void
-tlb_init_slave(struct slave *slave)
+static inline void tlb_init_slave(struct slave *slave)
 {
-       struct tlb_slave_info *slave_info = &(SLAVE_TLB_INFO(slave));
-
-       slave_info->load = 0;
-       slave_info->head = TLB_NULL_INDEX;
+       SLAVE_TLB_INFO(slave).load = 0;
+       SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX;
 }
 
 /* Caller must hold bond lock for read */
-static inline void
-tlb_clear_slave(struct bonding *bond, struct slave *slave, u8 save_load)
+static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_load)
 {
-       struct tlb_client_info *tx_hash_table = NULL;
-       u32 index, next_index;
+       struct tlb_client_info *tx_hash_table;
+       u32 index;
 
-       /* clear slave from tx_hashtbl */
        _lock_tx_hashtbl(bond);
+
+       /* clear slave from tx_hashtbl */
        tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
 
-       if (tx_hash_table) {
-               index = SLAVE_TLB_INFO(slave).head;
-               while (index != TLB_NULL_INDEX) {
-                       next_index = tx_hash_table[index].next;
-                       tlb_init_table_entry(bond, index, save_load);
-                       index = next_index;
-               }
+       index = SLAVE_TLB_INFO(slave).head;
+       while (index != TLB_NULL_INDEX) {
+               u32 next_index = tx_hash_table[index].next;
+               tlb_init_table_entry(&tx_hash_table[index], save_load);
+               index = next_index;
        }
+
        _unlock_tx_hashtbl(bond);
 
        tlb_init_slave(slave);
 }
 
 /* Must be called before starting the monitor timer */
-static int
-tlb_initialize(struct bonding *bond)
+static int tlb_initialize(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
        int i;
-       size_t size;
-
-#if(TLB_HASH_TABLE_SIZE != 256)
-       /* Key to the hash table is byte wide. Check the size! */
-       #error Hash Table size is wrong.
-#endif
 
        spin_lock_init(&(bond_info->tx_hashtbl_lock));
 
        _lock_tx_hashtbl(bond);
-       if (bond_info->tx_hashtbl != NULL) {
-               printk (KERN_ERR "%s: TLB hash table is not NULL\n",
-                       bond->device->name);
-               _unlock_tx_hashtbl(bond);
-               return -1;
-       }
 
-       size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
        bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
-       if (bond_info->tx_hashtbl == NULL) {
-               printk (KERN_ERR "%s: Failed to allocate TLB hash table\n",
-                       bond->device->name);
+       if (!bond_info->tx_hashtbl) {
+               printk(KERN_ERR DRV_NAME
+                      ": Error: %s: Failed to allocate TLB hash table\n",
+                      bond->dev->name);
                _unlock_tx_hashtbl(bond);
                return -1;
        }
 
        memset(bond_info->tx_hashtbl, 0, size);
-       for (i=0; i<TLB_HASH_TABLE_SIZE; i++) {
-               tlb_init_table_entry(bond, i, 1);
+
+       for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) {
+               tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1);
        }
+
        _unlock_tx_hashtbl(bond);
 
        return 0;
 }
 
 /* Must be called only after all slaves have been released */
-static void
-tlb_deinitialize(struct bonding *bond)
+static void tlb_deinitialize(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 
        _lock_tx_hashtbl(bond);
-       if (bond_info->tx_hashtbl == NULL) {
-               _unlock_tx_hashtbl(bond);
-               return;
-       }
+
        kfree(bond_info->tx_hashtbl);
        bond_info->tx_hashtbl = NULL;
+
        _unlock_tx_hashtbl(bond);
 }
 
 /* Caller must hold bond lock for read */
-static struct slave*
-tlb_get_least_loaded_slave(struct bonding *bond)
+static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
 {
-       struct slave *slave;
-       struct slave *least_loaded;
-       s64 curr_gap, max_gap;
+       struct slave *slave, *least_loaded;
+       s64 max_gap;
+       int i, found = 0;
 
        /* Find the first enabled slave */
-       slave = bond_get_first_slave(bond);
-       while (slave) {
+       bond_for_each_slave(bond, slave, i) {
                if (SLAVE_IS_OK(slave)) {
+                       found = 1;
                        break;
                }
-               slave = bond_get_next_slave(bond, slave);
        }
 
-       if (!slave) {
+       if (!found) {
                return NULL;
        }
 
        least_loaded = slave;
-       max_gap = (s64)(slave->speed * 1000000) -
-                       (s64)(SLAVE_TLB_INFO(slave).load * 8);
+       max_gap = (s64)(slave->speed << 20) - /* Convert to Megabit per sec */
+                       (s64)(SLAVE_TLB_INFO(slave).load << 3); /* Bytes to bits */
 
        /* Find the slave with the largest gap */
-       slave = bond_get_next_slave(bond, slave);
-       while (slave) {
+       bond_for_each_slave_from(bond, slave, i, least_loaded) {
                if (SLAVE_IS_OK(slave)) {
-                       curr_gap = (s64)(slave->speed * 1000000) -
-                                       (s64)(SLAVE_TLB_INFO(slave).load * 8);
-                       if (max_gap < curr_gap) {
+                       s64 gap = (s64)(slave->speed << 20) -
+                                       (s64)(SLAVE_TLB_INFO(slave).load << 3);
+                       if (max_gap < gap) {
                                least_loaded = slave;
-                               max_gap = curr_gap;
+                               max_gap = gap;
                        }
                }
-               slave = bond_get_next_slave(bond, slave);
        }
 
        return least_loaded;
 }
 
 /* Caller must hold bond lock for read */
-struct slave*
-tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
+struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-       struct tlb_client_info *hash_table = NULL;
-       struct slave *assigned_slave = NULL;
+       struct tlb_client_info *hash_table;
+       struct slave *assigned_slave;
 
        _lock_tx_hashtbl(bond);
 
        hash_table = bond_info->tx_hashtbl;
-       if (hash_table == NULL) {
-               printk (KERN_ERR "%s: TLB hash table is NULL\n",
-                       bond->device->name);
-               _unlock_tx_hashtbl(bond);
-               return NULL;
-       }
-
        assigned_slave = hash_table[hash_index].tx_slave;
        if (!assigned_slave) {
                assigned_slave = tlb_get_least_loaded_slave(bond);
@@ -345,14 +310,12 @@ tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
 }
 
 /*********************** rlb specific functions ***************************/
-static inline void
-_lock_rx_hashtbl(struct bonding *bond)
+static inline void _lock_rx_hashtbl(struct bonding *bond)
 {
        spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
 }
 
-static inline void
-_unlock_rx_hashtbl(struct bonding *bond)
+static inline void _unlock_rx_hashtbl(struct bonding *bond)
 {
        spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
 }
@@ -360,26 +323,20 @@ _unlock_rx_hashtbl(struct bonding *bond)
 /* when an ARP REPLY is received from a client update its info
  * in the rx_hashtbl
  */
-static void
-rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
+static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
 {
-       u32 hash_index;
-       struct rlb_client_info *client_info = NULL;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       struct rlb_client_info *client_info;
+       u32 hash_index;
 
        _lock_rx_hashtbl(bond);
 
-       if (bond_info->rx_hashtbl == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return;
-       }
-       hash_index = _simple_hash((u8*)&(arp->ip_src), 4);
+       hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src));
        client_info = &(bond_info->rx_hashtbl[hash_index]);
 
        if ((client_info->assigned) &&
            (client_info->ip_src == arp->ip_dst) &&
            (client_info->ip_dst == arp->ip_src)) {
-
                /* update the clients MAC address */
                memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
                client_info->ntt = 1;
@@ -389,66 +346,60 @@ rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
        _unlock_rx_hashtbl(bond);
 }
 
-static int
-rlb_arp_recv(struct sk_buff *skb,
-            struct net_device *dev,
-            struct packet_type* ptype)
+static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype)
 {
-       struct bonding *bond = (struct bonding *)dev->priv;
-       int ret = NET_RX_DROP;
+       struct bonding *bond = bond_dev->priv;
        struct arp_pkt *arp = (struct arp_pkt *)skb->data;
+       int res = NET_RX_DROP;
 
-       if (!(dev->flags & IFF_MASTER)) {
+       if (!(bond_dev->flags & IFF_MASTER)) {
                goto out;
        }
 
        if (!arp) {
-               printk(KERN_ERR "Packet has no ARP data\n");
+               dprintk("Packet has no ARP data\n");
                goto out;
        }
 
        if (skb->len < sizeof(struct arp_pkt)) {
-               printk(KERN_ERR "Packet is too small to be an ARP\n");
+               dprintk("Packet is too small to be an ARP\n");
                goto out;
        }
 
        if (arp->op_code == htons(ARPOP_REPLY)) {
                /* update rx hash table for this ARP */
                rlb_update_entry_from_arp(bond, arp);
-               BOND_PRINT_DBG(("Server received an ARP Reply from client"));
+               dprintk("Server received an ARP Reply from client\n");
        }
 
-       ret = NET_RX_SUCCESS;
+       res = NET_RX_SUCCESS;
 
 out:
        dev_kfree_skb(skb);
 
-       return ret;
+       return res;
 }
 
 /* Caller must hold bond lock for read */
-static struct slave*
-rlb_next_rx_slave(struct bonding *bond)
+static struct slave *rlb_next_rx_slave(struct bonding *bond)
 {
-       struct slave *rx_slave = NULL, *slave = NULL;
-       unsigned int i = 0;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       struct slave *rx_slave, *slave, *start_at;
+       int i = 0;
 
-       slave = bond_info->next_rx_slave;
-       if (slave == NULL) {
-               slave = bond->next;
+       if (bond_info->next_rx_slave) {
+               start_at = bond_info->next_rx_slave;
+       } else {
+               start_at = bond->first_slave;
        }
 
-       /* this loop uses the circular linked list property of the
-        * slave's list to go through all slaves
-        */
-       for (i = 0; i < bond->slave_cnt; i++, slave = slave->next) {
+       rx_slave = NULL;
 
+       bond_for_each_slave_from(bond, slave, i, start_at) {
                if (SLAVE_IS_OK(slave)) {
                        if (!rx_slave) {
                                rx_slave = slave;
-                       }
-                       else if (slave->speed > rx_slave->speed) {
+                       } else if (slave->speed > rx_slave->speed) {
                                rx_slave = slave;
                        }
                }
@@ -464,48 +415,41 @@ rlb_next_rx_slave(struct bonding *bond)
 /* teach the switch the mac of a disabled slave
  * on the primary for fault tolerance
  *
- * Caller must hold bond->ptrlock for write or bond lock for write
+ * Caller must hold bond->curr_slave_lock for write or bond lock for write
  */
-static void
-rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
+static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
 {
-       if (!bond->current_slave) {
+       if (!bond->curr_active_slave) {
                return;
        }
+
        if (!bond->alb_info.primary_is_promisc) {
                bond->alb_info.primary_is_promisc = 1;
-               dev_set_promiscuity(bond->current_slave->dev, 1);
+               dev_set_promiscuity(bond->curr_active_slave->dev, 1);
        }
+
        bond->alb_info.rlb_promisc_timeout_counter = 0;
 
-       alb_send_learning_packets(bond->current_slave, addr);
+       alb_send_learning_packets(bond->curr_active_slave, addr);
 }
 
 /* slave being removed should not be active at this point
  *
  * Caller must hold bond lock for read
  */
-static void
-rlb_clear_slave(struct bonding *bond, struct slave *slave)
+static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
 {
-       struct rlb_client_info *rx_hash_table = NULL;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-       u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+       struct rlb_client_info *rx_hash_table;
        u32 index, next_index;
 
        /* clear slave from rx_hashtbl */
        _lock_rx_hashtbl(bond);
-       rx_hash_table = bond_info->rx_hashtbl;
-
-       if (rx_hash_table == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return;
-       }
 
+       rx_hash_table = bond_info->rx_hashtbl;
        index = bond_info->rx_hashtbl_head;
        for (; index != RLB_NULL_INDEX; index = next_index) {
                next_index = rx_hash_table[index].next;
-
                if (rx_hash_table[index].slave == slave) {
                        struct slave *assigned_slave = rlb_next_rx_slave(bond);
 
@@ -533,23 +477,24 @@ rlb_clear_slave(struct bonding *bond, struct slave *slave)
 
        _unlock_rx_hashtbl(bond);
 
-       write_lock(&bond->ptrlock);
-       if (slave != bond->current_slave) {
+       write_lock(&bond->curr_slave_lock);
+
+       if (slave != bond->curr_active_slave) {
                rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr);
        }
-       write_unlock(&bond->ptrlock);
+
+       write_unlock(&bond->curr_slave_lock);
 }
 
-static void
-rlb_update_client(struct rlb_client_info *client_info)
+static void rlb_update_client(struct rlb_client_info *client_info)
 {
-       int i = 0;
+       int i;
 
-       if (client_info->slave == NULL) {
+       if (!client_info->slave) {
                return;
        }
 
-       for (i=0; i<RLB_ARP_BURST_SIZE; i++) {
+       for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
                arp_send(ARPOP_REPLY, ETH_P_ARP,
                         client_info->ip_dst,
                         client_info->slave->dev,
@@ -561,20 +506,14 @@ rlb_update_client(struct rlb_client_info *client_info)
 }
 
 /* sends ARP REPLIES that update the clients that need updating */
-static void
-rlb_update_rx_clients(struct bonding *bond)
+static void rlb_update_rx_clients(struct bonding *bond)
 {
-       u32 hash_index;
-       struct rlb_client_info *client_info = NULL;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       struct rlb_client_info *client_info;
+       u32 hash_index;
 
        _lock_rx_hashtbl(bond);
 
-       if (bond_info->rx_hashtbl == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return;
-       }
-
        hash_index = bond_info->rx_hashtbl_head;
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
                client_info = &(bond_info->rx_hashtbl[hash_index]);
@@ -595,22 +534,15 @@ rlb_update_rx_clients(struct bonding *bond)
 }
 
 /* The slave was assigned a new mac address - update the clients */
-static void
-rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave)
+static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave)
 {
-       u32 hash_index;
-       u8 ntt = 0;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-       u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
-       struct rlb_client_info* client_info = NULL;
+       struct rlb_client_info *client_info;
+       int ntt = 0;
+       u32 hash_index;
 
        _lock_rx_hashtbl(bond);
 
-       if (bond_info->rx_hashtbl == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return;
-       }
-
        hash_index = bond_info->rx_hashtbl_head;
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
                client_info = &(bond_info->rx_hashtbl[hash_index]);
@@ -633,37 +565,31 @@ rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave)
 }
 
 /* mark all clients using src_ip to be updated */
-static void
-rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
+static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
 {
-       u32 hash_index;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-       u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
-       struct rlb_client_info *client_info = NULL;
+       struct rlb_client_info *client_info;
+       u32 hash_index;
 
        _lock_rx_hashtbl(bond);
 
-       if (bond_info->rx_hashtbl == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return;
-       }
-
        hash_index = bond_info->rx_hashtbl_head;
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
                client_info = &(bond_info->rx_hashtbl[hash_index]);
 
                if (!client_info->slave) {
-                       printk(KERN_ERR "Bonding: Error: found a client with no"
-                              " channel in the client's hash table\n");
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: found a client with no channel in "
+                              "the client's hash table\n");
                        continue;
                }
                /*update all clients using this src_ip, that are not assigned
-                * to the team's address (current_slave) and have a known
+                * to the team's address (curr_active_slave) and have a known
                 * unicast mac address.
                 */
                if ((client_info->ip_src == src_ip) &&
                    memcmp(client_info->slave->dev->dev_addr,
-                          bond->device->dev_addr, ETH_ALEN) &&
+                          bond->dev->dev_addr, ETH_ALEN) &&
                    memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
                        client_info->ntt = 1;
                        bond_info->rx_ntt = 1;
@@ -674,30 +600,22 @@ rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
 }
 
 /* Caller must hold both bond and ptr locks for read */
-struct slave*
-rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
+struct slave *rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-       struct rlb_client_info *client_info = NULL;
+       struct slave *assigned_slave;
+       struct rlb_client_info *client_info;
        u32 hash_index = 0;
-       struct slave *assigned_slave = NULL;
-       u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
 
        _lock_rx_hashtbl(bond);
 
-       if (bond_info->rx_hashtbl == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return NULL;
-       }
-
-       hash_index = _simple_hash((u8 *)&arp->ip_dst, 4);
+       hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_src));
        client_info = &(bond_info->rx_hashtbl[hash_index]);
 
-       if (client_info->assigned == 1) {
+       if (client_info->assigned) {
                if ((client_info->ip_src == arp->ip_src) &&
                    (client_info->ip_dst == arp->ip_dst)) {
                        /* the entry is already assigned to this client */
-
                        if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) {
                                /* update mac address from arp */
                                memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
@@ -710,12 +628,12 @@ rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
                        }
                } else {
                        /* the entry is already assigned to some other client,
-                        * move the old client to primary (current_slave) so
+                        * move the old client to primary (curr_active_slave) so
                         * that the new client can be assigned to this entry.
                         */
-                       if (bond->current_slave &&
-                           client_info->slave != bond->current_slave) {
-                               client_info->slave = bond->current_slave;
+                       if (bond->curr_active_slave &&
+                           client_info->slave != bond->curr_active_slave) {
+                               client_info->slave = bond->curr_active_slave;
                                rlb_update_client(client_info);
                        }
                }
@@ -736,8 +654,7 @@ rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
                if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
                        client_info->ntt = 1;
                        bond->alb_info.rx_ntt = 1;
-               }
-               else {
+               } else {
                        client_info->ntt = 0;
                }
 
@@ -760,10 +677,9 @@ rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
 
 /* chooses (and returns) transmit channel for arp reply
  * does not choose channel for other arp types since they are
- * sent on the current_slave
+ * sent on the curr_active_slave
  */
-static struct slave*
-rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
+static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
 {
        struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw;
        struct slave *tx_slave = NULL;
@@ -776,9 +692,8 @@ rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
                if (tx_slave) {
                        memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN);
                }
-               BOND_PRINT_DBG(("Server sent ARP Reply packet"));
+               dprintk("Server sent ARP Reply packet\n");
        } else if (arp->op_code == __constant_htons(ARPOP_REQUEST)) {
-
                /* Create an entry in the rx_hashtbl for this client as a
                 * place holder.
                 * When the arp reply is received the entry will be updated
@@ -797,34 +712,29 @@ rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
                 * updated with their assigned mac.
                 */
                rlb_req_update_subnet_clients(bond, arp->ip_src);
-               BOND_PRINT_DBG(("Server sent ARP Request packet"));
+               dprintk("Server sent ARP Request packet\n");
        }
 
        return tx_slave;
 }
 
 /* Caller must hold bond lock for read */
-static void
-rlb_rebalance(struct bonding *bond)
+static void rlb_rebalance(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-       struct slave *assigned_slave = NULL;
+       struct slave *assigned_slave;
+       struct rlb_client_info *client_info;
+       int ntt;
        u32 hash_index;
-       struct rlb_client_info *client_info = NULL;
-       u8 ntt = 0;
 
        _lock_rx_hashtbl(bond);
 
-       if (bond_info->rx_hashtbl == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return;
-       }
-
+       ntt = 0;
        hash_index = bond_info->rx_hashtbl_head;
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
                client_info = &(bond_info->rx_hashtbl[hash_index]);
                assigned_slave = rlb_next_rx_slave(bond);
-               if (assigned_slave && (client_info->slave != assigned_slave)){
+               if (assigned_slave && (client_info->slave != assigned_slave)) {
                        client_info->slave = assigned_slave;
                        client_info->ntt = 1;
                        ntt = 1;
@@ -839,96 +749,83 @@ rlb_rebalance(struct bonding *bond)
 }
 
 /* Caller must hold rx_hashtbl lock */
-static inline void
-rlb_init_table_entry(struct rlb_client_info *entry)
+static void rlb_init_table_entry(struct rlb_client_info *entry)
 {
+       memset(entry, 0, sizeof(struct rlb_client_info));
        entry->next = RLB_NULL_INDEX;
        entry->prev = RLB_NULL_INDEX;
-       entry->assigned = 0;
-       entry->ntt = 0;
 }
 
-static int
-rlb_initialize(struct bonding *bond)
+static int rlb_initialize(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
        struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
+       int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
        int i;
-       size_t size;
 
        spin_lock_init(&(bond_info->rx_hashtbl_lock));
 
        _lock_rx_hashtbl(bond);
-       if (bond_info->rx_hashtbl != NULL) {
-               printk (KERN_ERR "%s: RLB hash table is not NULL\n",
-                       bond->device->name);
-               _unlock_rx_hashtbl(bond);
-               return -1;
-       }
 
-       size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
        bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
-       if (bond_info->rx_hashtbl == NULL) {
-               printk (KERN_ERR "%s: Failed to allocate"
-                       " RLB hash table\n", bond->device->name);
+       if (!bond_info->rx_hashtbl) {
+               printk(KERN_ERR DRV_NAME
+                      ": Error: %s: Failed to allocate RLB hash table\n",
+                      bond->dev->name);
                _unlock_rx_hashtbl(bond);
                return -1;
        }
 
        bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
 
-       for (i=0; i<RLB_HASH_TABLE_SIZE; i++) {
+       for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) {
                rlb_init_table_entry(bond_info->rx_hashtbl + i);
        }
-       _unlock_rx_hashtbl(bond);
 
-       /* register to receive ARPs */
+       _unlock_rx_hashtbl(bond);
 
        /*initialize packet type*/
        pk_type->type = __constant_htons(ETH_P_ARP);
-       pk_type->dev = bond->device;
+       pk_type->dev = bond->dev;
        pk_type->func = rlb_arp_recv;
 
+       /* register to receive ARPs */
        dev_add_pack(pk_type);
 
        return 0;
 }
 
-static void
-rlb_deinitialize(struct bonding *bond)
+static void rlb_deinitialize(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 
        dev_remove_pack(&(bond_info->rlb_pkt_type));
 
        _lock_rx_hashtbl(bond);
-       if (bond_info->rx_hashtbl == NULL) {
-               _unlock_rx_hashtbl(bond);
-               return;
-       }
+
        kfree(bond_info->rx_hashtbl);
        bond_info->rx_hashtbl = NULL;
+
        _unlock_rx_hashtbl(bond);
 }
 
 /*********************** tlb/rlb shared functions *********************/
 
-static void
-alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
+static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
 {
-       struct sk_buff *skb = NULL;
        struct learning_pkt pkt;
-       char *data = NULL;
+       int size = sizeof(struct learning_pkt);
        int i;
-       unsigned int size = sizeof(struct learning_pkt);
 
        memset(&pkt, 0, size);
        memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
        memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
        pkt.type = __constant_htons(ETH_P_LOOP);
 
-       for (i=0; i < MAX_LP_RETRY; i++) {
-               skb = NULL;
+       for (i = 0; i < MAX_LP_RETRY; i++) {
+               struct sk_buff *skb;
+               char *data;
+
                skb = dev_alloc_skb(size);
                if (!skb) {
                        return;
@@ -936,28 +833,26 @@ alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
 
                data = skb_put(skb, size);
                memcpy(data, &pkt, size);
+
                skb->mac.raw = data;
                skb->nh.raw = data + ETH_HLEN;
                skb->protocol = pkt.type;
                skb->priority = TC_PRIO_CONTROL;
                skb->dev = slave->dev;
+
                dev_queue_xmit(skb);
        }
-
 }
 
 /* hw is a boolean parameter that determines whether we should try and
  * set the hw address of the device as well as the hw address of the
  * net_device
  */
-static int
-alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
+static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
 {
-       struct net_device *dev = NULL;
+       struct net_device *dev = slave->dev;
        struct sockaddr s_addr;
 
-       dev = slave->dev;
-
        if (!hw) {
                memcpy(dev->dev_addr, addr, dev->addr_len);
                return 0;
@@ -968,26 +863,23 @@ alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
        memcpy(s_addr.sa_data, addr, dev->addr_len);
        s_addr.sa_family = dev->type;
        if (dev->set_mac_address(dev, &s_addr)) {
-               printk(KERN_DEBUG "bonding: Error: alb_set_slave_mac_addr:"
-                                 " dev->set_mac_address of dev %s failed!"
-                                 " ALB mode requires that the base driver"
-                                 " support setting the hw address also when"
-                                 " the network device's interface is open\n",
-                                 dev->name);
+               printk(KERN_ERR DRV_NAME
+                      ": Error: dev->set_mac_address of dev %s failed! ALB "
+                      "mode requires that the base driver support setting "
+                      "the hw address also when the network device's "
+                      "interface is open\n",
+                      dev->name);
                return -EOPNOTSUPP;
        }
        return 0;
 }
 
-/* Caller must hold bond lock for write or ptrlock for write*/
-static void
-alb_swap_mac_addr(struct bonding *bond,
-                 struct slave *slave1,
-                 struct slave *slave2)
+/* Caller must hold bond lock for write or curr_slave_lock for write*/
+static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2)
 {
-       u8 tmp_mac_addr[ETH_ALEN];
        struct slave *disabled_slave = NULL;
-       u8 slaves_state_differ;
+       u8 tmp_mac_addr[ETH_ALEN];
+       int slaves_state_differ;
 
        slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
 
@@ -1004,8 +896,7 @@ alb_swap_mac_addr(struct bonding *bond,
                         */
                        rlb_req_update_slave_clients(bond, slave1);
                }
-       }
-       else {
+       } else {
                disabled_slave = slave1;
        }
 
@@ -1017,15 +908,14 @@ alb_swap_mac_addr(struct bonding *bond,
                         */
                        rlb_req_update_slave_clients(bond, slave2);
                }
-       }
-       else {
+       } else {
                disabled_slave = slave2;
        }
 
        if (bond->alb_info.rlb_enabled && slaves_state_differ) {
-                       /* A disabled slave was assigned an active mac addr */
-                       rlb_teach_disabled_mac_on_primary(bond,
-                               disabled_slave->dev->dev_addr);
+               /* A disabled slave was assigned an active mac addr */
+               rlb_teach_disabled_mac_on_primary(bond,
+                                                 disabled_slave->dev->dev_addr);
        }
 }
 
@@ -1043,10 +933,8 @@ alb_swap_mac_addr(struct bonding *bond,
  *
  * Caller must hold bond lock
  */
-static void
-alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
+static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
 {
-       struct slave *tmp_slave;
        int perm_curr_diff;
        int perm_bond_diff;
 
@@ -1054,20 +942,23 @@ alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
                                slave->dev->dev_addr,
                                ETH_ALEN);
        perm_bond_diff = memcmp(slave->perm_hwaddr,
-                               bond->device->dev_addr,
+                               bond->dev->dev_addr,
                                ETH_ALEN);
+
        if (perm_curr_diff && perm_bond_diff) {
-               tmp_slave = bond_get_first_slave(bond);
-               while (tmp_slave) {
+               struct slave *tmp_slave;
+               int i, found = 0;
+
+               bond_for_each_slave(bond, tmp_slave, i) {
                        if (!memcmp(slave->perm_hwaddr,
-                                  tmp_slave->dev->dev_addr,
-                                  ETH_ALEN)) {
+                                   tmp_slave->dev->dev_addr,
+                                   ETH_ALEN)) {
+                               found = 1;
                                break;
                        }
-                       tmp_slave = bond_get_next_slave(bond, tmp_slave);
                }
 
-               if (tmp_slave) {
+               if (found) {
                        alb_swap_mac_addr(bond, slave, tmp_slave);
                }
        }
@@ -1098,10 +989,10 @@ alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
  * caller must hold the bond lock for write since the mac addresses are compared
  * and may be swapped.
  */
-static int
-alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
+static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
 {
-       struct slave *tmp_slave1, *tmp_slave2;
+       struct slave *tmp_slave1, *tmp_slave2, *free_mac_slave;
+       int i, j, found = 0;
 
        if (bond->slave_cnt == 0) {
                /* this is the first slave */
@@ -1112,65 +1003,68 @@ alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
         * check uniqueness of slave's mac address against the other
         * slaves in the bond.
         */
-       if (memcmp(slave->perm_hwaddr, bond->device->dev_addr, ETH_ALEN)) {
-               tmp_slave1 = bond_get_first_slave(bond);
-               for (; tmp_slave1; tmp_slave1 = bond_get_next_slave(bond, tmp_slave1)) {
+       if (memcmp(slave->perm_hwaddr, bond->dev->dev_addr, ETH_ALEN)) {
+               bond_for_each_slave(bond, tmp_slave1, i) {
                        if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr,
                                    ETH_ALEN)) {
+                               found = 1;
                                break;
                        }
                }
-               if (tmp_slave1) {
+
+               if (found) {
                        /* a slave was found that is using the mac address
                         * of the new slave
                         */
-                       printk(KERN_ERR "bonding: Warning: the hw address "
-                              "of slave %s is not unique - cannot enslave it!"
-                              , slave->dev->name);
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: the hw address of slave %s is not "
+                              "unique - cannot enslave it!",
+                              slave->dev->name);
                        return -EINVAL;
                }
+
                return 0;
        }
 
-       /* the slave's address is equal to the address of the bond
-        * search for a spare address in the bond for this slave.
+       /* The slave's address is equal to the address of the bond.
+        * Search for a spare address in the bond for this slave.
         */
-       tmp_slave1 = bond_get_first_slave(bond);
-       for (; tmp_slave1; tmp_slave1 = bond_get_next_slave(bond, tmp_slave1)) {
-
-               tmp_slave2 = bond_get_first_slave(bond);
-               for (; tmp_slave2; tmp_slave2 = bond_get_next_slave(bond, tmp_slave2)) {
+       free_mac_slave = NULL;
 
+       bond_for_each_slave(bond, tmp_slave1, i) {
+               found = 0;
+               bond_for_each_slave(bond, tmp_slave2, j) {
                        if (!memcmp(tmp_slave1->perm_hwaddr,
                                    tmp_slave2->dev->dev_addr,
                                    ETH_ALEN)) {
-
+                               found = 1;
                                break;
                        }
                }
 
-               if (!tmp_slave2) {
+               if (!found) {
                        /* no slave has tmp_slave1's perm addr
                         * as its curr addr
                         */
+                       free_mac_slave = tmp_slave1;
                        break;
                }
        }
 
-       if (tmp_slave1) {
-               alb_set_slave_mac_addr(slave, tmp_slave1->perm_hwaddr,
+       if (free_mac_slave) {
+               alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
                                       bond->alb_info.rlb_enabled);
 
-               printk(KERN_WARNING "bonding: Warning: the hw address "
-                      "of slave %s is in use by the bond; "
-                      "giving it the hw address of %s\n",
-                      slave->dev->name, tmp_slave1->dev->name);
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: the hw address of slave %s is in use by "
+                      "the bond; giving it the hw address of %s\n",
+                      slave->dev->name, free_mac_slave->dev->name);
        } else {
-               printk(KERN_CRIT "bonding: Error: the hw address "
-                      "of slave %s is in use by the bond; "
-                      "couldn't find a slave with a free hw "
-                      "address to give it (this should not have "
-                      "happened)\n", slave->dev->name);
+               printk(KERN_ERR DRV_NAME
+                      ": Error: the hw address of slave %s is in use by the "
+                      "bond; couldn't find a slave with a free hw address to "
+                      "give it (this should not have happened)\n",
+                      slave->dev->name);
                return -EFAULT;
        }
 
@@ -1188,37 +1082,36 @@ alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
  *
  * For each slave, this function sets the interface to the new address and then
  * changes its dev_addr field to its previous value.
- * 
+ *
  * Unwinding assumes bond's mac address has not yet changed.
  */
-static inline int
-alb_set_mac_address(struct bonding *bond, void *addr)
+static int alb_set_mac_address(struct bonding *bond, void *addr)
 {
        struct sockaddr sa;
-       struct slave *slave;
+       struct slave *slave, *stop_at;
        char tmp_addr[ETH_ALEN];
-       int error;
+       int res;
+       int i;
 
        if (bond->alb_info.rlb_enabled) {
                return 0;
        }
 
-       slave = bond_get_first_slave(bond);
-       for (; slave; slave = bond_get_next_slave(bond, slave)) {
+       bond_for_each_slave(bond, slave, i) {
                if (slave->dev->set_mac_address == NULL) {
-                       error = -EOPNOTSUPP;
+                       res = -EOPNOTSUPP;
                        goto unwind;
                }
 
                /* save net_device's current hw address */
                memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
 
-               error = slave->dev->set_mac_address(slave->dev, addr);
+               res = slave->dev->set_mac_address(slave->dev, addr);
 
                /* restore net_device's hw address */
                memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
 
-               if (error) {
+               if (res) {
                        goto unwind;
                }
        }
@@ -1226,22 +1119,23 @@ alb_set_mac_address(struct bonding *bond, void *addr)
        return 0;
 
 unwind:
-       memcpy(sa.sa_data, bond->device->dev_addr, bond->device->addr_len);
-       sa.sa_family = bond->device->type;
-       slave = bond_get_first_slave(bond);
-       for (; slave; slave = bond_get_next_slave(bond, slave)) {
+       memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len);
+       sa.sa_family = bond->dev->type;
+
+       /* unwind from head to the slave that failed */
+       stop_at = slave;
+       bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
                memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
                slave->dev->set_mac_address(slave->dev, &sa);
                memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
        }
 
-       return error;
+       return res;
 }
 
 /************************ exported alb funcions ************************/
 
-int
-bond_alb_initialize(struct bonding *bond, int rlb_enabled)
+int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
 {
        int res;
 
@@ -1263,8 +1157,7 @@ bond_alb_initialize(struct bonding *bond, int rlb_enabled)
        return 0;
 }
 
-void
-bond_alb_deinitialize(struct bonding *bond)
+void bond_alb_deinitialize(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 
@@ -1275,49 +1168,38 @@ bond_alb_deinitialize(struct bonding *bond)
        }
 }
 
-int
-bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
+int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct bonding *bond = (struct bonding *) dev->priv;
-       struct ethhdr *eth_data = (struct ethhdr *)skb->data;
+       struct bonding *bond = bond_dev->priv;
+       struct ethhdr *eth_data = (struct ethhdr *)skb->mac.raw = skb->data;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
        struct slave *tx_slave = NULL;
-       char do_tx_balance = 1;
+       static u32 ip_bcast = 0xffffffff;
        int hash_size = 0;
+       int do_tx_balance = 1;
        u32 hash_index = 0;
        u8 *hash_start = NULL;
-       u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
-
-       if (!IS_UP(dev)) { /* bond down */
-               dev_kfree_skb(skb);
-               return 0;
-       }
 
-       /* make sure that the current_slave and the slaves list do
+       /* make sure that the curr_active_slave and the slaves list do
         * not change during tx
         */
        read_lock(&bond->lock);
+       read_lock(&bond->curr_slave_lock);
 
-       if (bond->slave_cnt == 0) {
-               /* no suitable interface, frame not sent */
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
+       if (!BOND_IS_OK(bond)) {
+               goto free_out;
        }
 
-       read_lock(&bond->ptrlock);
-
        switch (ntohs(skb->protocol)) {
        case ETH_P_IP:
                if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
-                   (skb->nh.iph->daddr == 0xffffffff)) {
+                   (skb->nh.iph->daddr == ip_bcast)) {
                        do_tx_balance = 0;
                        break;
                }
                hash_start = (char*)&(skb->nh.iph->daddr);
-               hash_size = 4;
+               hash_size = sizeof(skb->nh.iph->daddr);
                break;
-
        case ETH_P_IPV6:
                if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
                        do_tx_balance = 0;
@@ -1325,9 +1207,8 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
                }
 
                hash_start = (char*)&(skb->nh.ipv6h->daddr);
-               hash_size = 16;
+               hash_size = sizeof(skb->nh.ipv6h->daddr);
                break;
-
        case ETH_P_IPX:
                if (ipx_hdr(skb)->ipx_checksum !=
                    __constant_htons(IPX_NO_CHECKSUM)) {
@@ -1349,14 +1230,12 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
                hash_start = (char*)eth_data->h_dest;
                hash_size = ETH_ALEN;
                break;
-
        case ETH_P_ARP:
                do_tx_balance = 0;
                if (bond_info->rlb_enabled) {
                        tx_slave = rlb_arp_xmit(skb, bond);
                }
                break;
-
        default:
                do_tx_balance = 0;
                break;
@@ -1369,16 +1248,16 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (!tx_slave) {
                /* unbalanced or unassigned, send through primary */
-               tx_slave = bond->current_slave;
+               tx_slave = bond->curr_active_slave;
                bond_info->unbalanced_load += skb->len;
        }
 
        if (tx_slave && SLAVE_IS_OK(tx_slave)) {
                skb->dev = tx_slave->dev;
-               if (tx_slave != bond->current_slave) {
+               if (tx_slave != bond->curr_active_slave) {
                        memcpy(eth_data->h_source,
-                               tx_slave->dev->dev_addr,
-                               ETH_ALEN);
+                              tx_slave->dev->dev_addr,
+                              ETH_ALEN);
                }
                dev_queue_xmit(skb);
        } else {
@@ -1386,26 +1265,35 @@ bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
                if (tx_slave) {
                        tlb_clear_slave(bond, tx_slave, 0);
                }
-               dev_kfree_skb(skb);
+               goto free_out;
        }
 
-       read_unlock(&bond->ptrlock);
+out:
+       read_unlock(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
        return 0;
+
+free_out:
+       dev_kfree_skb(skb);
+       goto out;
 }
 
-void
-bond_alb_monitor(struct bonding *bond)
+void bond_alb_monitor(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-       struct slave *slave = NULL;
+       struct slave *slave;
+       int i;
 
        read_lock(&bond->lock);
 
-       if ((bond->slave_cnt == 0) || !(bond->device->flags & IFF_UP)) {
+       if (bond->kill_timers) {
+               goto out;
+       }
+
+       if (bond->slave_cnt == 0) {
                bond_info->tx_rebalance_counter = 0;
                bond_info->lp_counter = 0;
-               goto out;
+               goto re_arm;
        }
 
        bond_info->tx_rebalance_counter++;
@@ -1413,51 +1301,53 @@ bond_alb_monitor(struct bonding *bond)
 
        /* send learning packets */
        if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
-               /* change of current_slave involves swapping of mac addresses.
+               /* change of curr_active_slave involves swapping of mac addresses.
                 * in order to avoid this swapping from happening while
-                * sending the learning packets, the ptrlock must be held for
+                * sending the learning packets, the curr_slave_lock must be held for
                 * read.
                 */
-               read_lock(&bond->ptrlock);
-               slave = bond_get_first_slave(bond);
-               while (slave) {
+               read_lock(&bond->curr_slave_lock);
+
+               bond_for_each_slave(bond, slave, i) {
                        alb_send_learning_packets(slave,slave->dev->dev_addr);
-                       slave = bond_get_next_slave(bond, slave);
                }
-               read_unlock(&bond->ptrlock);
+
+               read_unlock(&bond->curr_slave_lock);
 
                bond_info->lp_counter = 0;
        }
 
        /* rebalance tx traffic */
        if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) {
-               read_lock(&bond->ptrlock);
-               slave = bond_get_first_slave(bond);
-               while (slave) {
+
+               read_lock(&bond->curr_slave_lock);
+
+               bond_for_each_slave(bond, slave, i) {
                        tlb_clear_slave(bond, slave, 1);
-                       if (slave == bond->current_slave) {
+                       if (slave == bond->curr_active_slave) {
                                SLAVE_TLB_INFO(slave).load =
                                        bond_info->unbalanced_load /
                                                BOND_TLB_REBALANCE_INTERVAL;
                                bond_info->unbalanced_load = 0;
                        }
-                       slave = bond_get_next_slave(bond, slave);
                }
-               read_unlock(&bond->ptrlock);
+
+               read_unlock(&bond->curr_slave_lock);
+
                bond_info->tx_rebalance_counter = 0;
        }
 
        /* handle rlb stuff */
        if (bond_info->rlb_enabled) {
                /* the following code changes the promiscuity of the
-                * the current_slave. It needs to be locked with a
+                * the curr_active_slave. It needs to be locked with a
                 * write lock to protect from other code that also
                 * sets the promiscuity.
                 */
-               write_lock(&bond->ptrlock);
+               write_lock(&bond->curr_slave_lock);
+
                if (bond_info->primary_is_promisc &&
-                   (++bond_info->rlb_promisc_timeout_counter >=
-                       RLB_PROMISC_TIMEOUT)) {
+                   (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {
 
                        bond_info->rlb_promisc_timeout_counter = 0;
 
@@ -1465,12 +1355,13 @@ bond_alb_monitor(struct bonding *bond)
                         * because a slave was disabled then
                         * it can now leave promiscuous mode.
                         */
-                       dev_set_promiscuity(bond->current_slave->dev, -1);
+                       dev_set_promiscuity(bond->curr_active_slave->dev, -1);
                        bond_info->primary_is_promisc = 0;
                }
-               write_unlock(&bond->ptrlock);
 
-               if (bond_info->rlb_rebalance == 1) {
+               write_unlock(&bond->curr_slave_lock);
+
+               if (bond_info->rlb_rebalance) {
                        bond_info->rlb_rebalance = 0;
                        rlb_rebalance(bond);
                }
@@ -1490,28 +1381,23 @@ bond_alb_monitor(struct bonding *bond)
                }
        }
 
+re_arm:
+       mod_timer(&(bond_info->alb_timer), jiffies + alb_delta_in_ticks);
 out:
        read_unlock(&bond->lock);
-
-       if (bond->device->flags & IFF_UP) {
-               /* re-arm the timer */
-               mod_timer(&(bond_info->alb_timer),
-                       jiffies + (HZ/ALB_TIMER_TICKS_PER_SEC));
-       }
 }
 
-/* assumption: called before the slave is attched to the bond
+/* assumption: called before the slave is attached to the bond
  * and not locked by the bond lock
  */
-int
-bond_alb_init_slave(struct bonding *bond, struct slave *slave)
+int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
 {
-       int err = 0;
+       int res;
 
-       err = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
+       res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
                                     bond->alb_info.rlb_enabled);
-       if (err) {
-               return err;
+       if (res) {
+               return res;
        }
 
        /* caller must hold the bond lock for write since the mac addresses
@@ -1519,12 +1405,12 @@ bond_alb_init_slave(struct bonding *bond, struct slave *slave)
         */
        write_lock_bh(&bond->lock);
 
-       err = alb_handle_addr_collision_on_attach(bond, slave);
+       res = alb_handle_addr_collision_on_attach(bond, slave);
 
        write_unlock_bh(&bond->lock);
 
-       if (err) {
-               return err;
+       if (res) {
+               return res;
        }
 
        tlb_init_slave(slave);
@@ -1540,8 +1426,7 @@ bond_alb_init_slave(struct bonding *bond, struct slave *slave)
 }
 
 /* Caller must hold bond lock for write */
-void
-bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
+void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
 {
        if (bond->slave_cnt > 1) {
                alb_change_hw_addr_on_detach(bond, slave);
@@ -1556,9 +1441,7 @@ bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
 }
 
 /* Caller must hold bond lock for read */
-void
-bond_alb_handle_link_change(struct bonding *bond, struct slave *slave,
-                           char link)
+void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 
@@ -1582,109 +1465,111 @@ bond_alb_handle_link_change(struct bonding *bond, struct slave *slave,
 }
 
 /**
- * bond_alb_assign_current_slave - assign new current_slave
+ * bond_alb_handle_active_change - assign new curr_active_slave
  * @bond: our bonding struct
  * @new_slave: new slave to assign
  *
- * Set the bond->current_slave to @new_slave and handle
+ * Set the bond->curr_active_slave to @new_slave and handle
  * mac address swapping and promiscuity changes as needed.
  *
- * Caller must hold bond ptrlock for write (or bond lock for write)
+ * Caller must hold bond curr_slave_lock for write (or bond lock for write)
  */
-void
-bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave)
+void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
 {
-       struct slave *swap_slave = bond->current_slave;
+       struct slave *swap_slave;
+       int i;
 
-       if (bond->current_slave == new_slave) {
+       if (bond->curr_active_slave == new_slave) {
                return;
        }
 
-       if (bond->current_slave && bond->alb_info.primary_is_promisc) {
-               dev_set_promiscuity(bond->current_slave->dev, -1);
+       if (bond->curr_active_slave && bond->alb_info.primary_is_promisc) {
+               dev_set_promiscuity(bond->curr_active_slave->dev, -1);
                bond->alb_info.primary_is_promisc = 0;
                bond->alb_info.rlb_promisc_timeout_counter = 0;
        }
 
-       bond->current_slave = new_slave;
+       swap_slave = bond->curr_active_slave;
+       bond->curr_active_slave = new_slave;
 
        if (!new_slave || (bond->slave_cnt == 0)) {
                return;
        }
 
-       /* set the new current_slave to the bonds mac address
-        * i.e. swap mac addresses of old current_slave and new current_slave
+       /* set the new curr_active_slave to the bonds mac address
+        * i.e. swap mac addresses of old curr_active_slave and new curr_active_slave
         */
        if (!swap_slave) {
+               struct slave *tmp_slave;
                /* find slave that is holding the bond's mac address */
-               swap_slave = bond_get_first_slave(bond);
-               while (swap_slave) {
-                       if (!memcmp(swap_slave->dev->dev_addr,
-                               bond->device->dev_addr, ETH_ALEN)) {
+               bond_for_each_slave(bond, tmp_slave, i) {
+                       if (!memcmp(tmp_slave->dev->dev_addr,
+                                   bond->dev->dev_addr, ETH_ALEN)) {
+                               swap_slave = tmp_slave;
                                break;
                        }
-                       swap_slave = bond_get_next_slave(bond, swap_slave);
                }
        }
 
-       /* current_slave must be set before calling alb_swap_mac_addr */
+       /* curr_active_slave must be set before calling alb_swap_mac_addr */
        if (swap_slave) {
                /* swap mac address */
                alb_swap_mac_addr(bond, swap_slave, new_slave);
        } else {
                /* set the new_slave to the bond mac address */
-               alb_set_slave_mac_addr(new_slave, bond->device->dev_addr,
+               alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
                                       bond->alb_info.rlb_enabled);
                /* fasten bond mac on new current slave */
-               alb_send_learning_packets(new_slave, bond->device->dev_addr);
+               alb_send_learning_packets(new_slave, bond->dev->dev_addr);
        }
 }
 
-int
-bond_alb_set_mac_address(struct net_device *dev, void *addr)
+int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
 {
-       struct bonding *bond = dev->priv;
+       struct bonding *bond = bond_dev->priv;
        struct sockaddr *sa = addr;
-       struct slave *swap_slave = NULL;
-       int error = 0;
+       struct slave *slave, *swap_slave;
+       int res;
+       int i;
 
        if (!is_valid_ether_addr(sa->sa_data)) {
                return -EADDRNOTAVAIL;
        }
 
-       error = alb_set_mac_address(bond, addr);
-       if (error) {
-               return error;
+       res = alb_set_mac_address(bond, addr);
+       if (res) {
+               return res;
        }
 
-       memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+       memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len);
 
-       /* If there is no current_slave there is nothing else to do.
+       /* If there is no curr_active_slave there is nothing else to do.
         * Otherwise we'll need to pass the new address to it and handle
         * duplications.
         */
-       if (bond->current_slave == NULL) {
+       if (!bond->curr_active_slave) {
                return 0;
        }
 
-       swap_slave = bond_get_first_slave(bond);
-       while (swap_slave) {
-               if (!memcmp(swap_slave->dev->dev_addr, dev->dev_addr, ETH_ALEN)) {
+       swap_slave = NULL;
+
+       bond_for_each_slave(bond, slave, i) {
+               if (!memcmp(slave->dev->dev_addr, bond_dev->dev_addr, ETH_ALEN)) {
+                       swap_slave = slave;
                        break;
                }
-               swap_slave = bond_get_next_slave(bond, swap_slave);
        }
 
        if (swap_slave) {
-               alb_swap_mac_addr(bond, swap_slave, bond->current_slave);
+               alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
        } else {
-               alb_set_slave_mac_addr(bond->current_slave, dev->dev_addr,
+               alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
                                       bond->alb_info.rlb_enabled);
 
-               alb_send_learning_packets(bond->current_slave, dev->dev_addr);
+               alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr);
                if (bond->alb_info.rlb_enabled) {
                        /* inform clients mac address has changed */
-                       rlb_req_update_slave_clients(bond, bond->current_slave);
+                       rlb_req_update_slave_clients(bond, bond->curr_active_slave);
                }
        }
 
index d3f4291..9dc848d 100644 (file)
@@ -24,6 +24,9 @@
  * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
  *     - Add support for setting bond's MAC address with special
  *       handling required for ALB/TLB.
+ *
+ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
+ *     - Code cleanup and style changes
  */
 
 #ifndef __BOND_ALB_H__
@@ -126,10 +129,10 @@ void bond_alb_deinitialize(struct bonding *bond);
 int bond_alb_init_slave(struct bonding *bond, struct slave *slave);
 void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
 void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
-void bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave);
-int bond_alb_xmit(struct sk_buff *skb, struct net_device *dev);
+void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
+int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
 void bond_alb_monitor(struct bonding *bond);
-int bond_alb_set_mac_address(struct net_device *dev, void *addr);
+int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
 
 #endif /* __BOND_ALB_H__ */
 
index 5bed209..9360c8b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * originally based on the dummy device.
  *
- * Copyright 1999, Thomas Davis, tadavis@lbl.gov.  
+ * Copyright 1999, Thomas Davis, tadavis@lbl.gov.
  * Licensed under the GPL. Based on dummy.c, and eql.c devices.
  *
  * bonding.c: an Ethernet Bonding driver
@@ -15,9 +15,9 @@
  *
  * How it works:
  *    ifconfig bond0 ipaddress netmask up
- *      will setup a network device, with an ip address.  No mac address 
- *     will be assigned at this time.  The hw mac address will come from 
- *     the first slave bonded to the channel.  All slaves will then use 
+ *      will setup a network device, with an ip address.  No mac address
+ *     will be assigned at this time.  The hw mac address will come from
+ *     the first slave bonded to the channel.  All slaves will then use
  *     this hw mac address.
  *
  *    ifconfig bond0 down
@@ -26,7 +26,7 @@
  *    ifenslave bond0 eth0
  *     will attach eth0 to bond0 as a slave.  eth0 hw mac address will either
  *     a: be used as initial mac address
- *     b: if a hw mac address already is there, eth0's hw mac address 
+ *     b: if a hw mac address already is there, eth0's hw mac address
  *        will then be set from bond0.
  *
  * v0.1 - first working version.
  *
  * 2001/4/5 - Chad N. Tindel <ctindel at ieee dot org>
  *     - Ported to 2.4 Kernel
- * 
+ *
  * 2001/5/2 - Jeffrey E. Mast <jeff at mastfamily dot com>
  *     - When a device is detached from a bond, the slave device is no longer
  *       left thinking that is has a master.
  *
  * 2001/5/16 - Jeffrey E. Mast <jeff at mastfamily dot com>
- *     - memset did not appropriately initialized the bond rw_locks. Used 
- *       rwlock_init to initialize to unlocked state to prevent deadlock when 
+ *     - memset did not appropriately initialized the bond rw_locks. Used
+ *       rwlock_init to initialize to unlocked state to prevent deadlock when
  *       first attempting a lock
  *     - Called SET_MODULE_OWNER for bond device
  *
  *
  * 2001/6/01 - Chad N. Tindel <ctindel at ieee dot org>
  *     - Added /proc support for getting bond and slave information.
- *       Information is in /proc/net/<bond device>/info. 
+ *       Information is in /proc/net/<bond device>/info.
  *     - Changed the locking when calling bond_close to prevent deadlock.
  *
  * 2001/8/05 - Janice Girouard <girouard at us.ibm.com>
  *       but only for an up link.
  *
  * 2001/9/20 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Add the device field to bonding_t.  Previously the net_device 
- *       corresponding to a bond wasn't available from the bonding_t 
+ *     - Add the device field to bonding_t.  Previously the net_device
+ *       corresponding to a bond wasn't available from the bonding_t
  *       structure.
  *
  * 2001/9/25 - Janice Girouard <girouard at us.ibm.com>
  *     - Various memory leak fixes
  *
  * 2001/11/5 - Mark Huth <mark dot huth at mvista dot com>
- *     - Don't take rtnl lock in bond_mii_monitor as it deadlocks under 
- *       certain hotswap conditions.  
+ *     - Don't take rtnl lock in bond_mii_monitor as it deadlocks under
+ *       certain hotswap conditions.
  *       Note:  this same change may be required in bond_arp_monitor ???
- *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr 
+ *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
  *     - Handle hot swap ethernet interface deregistration events to remove
  *       kernel oops following hot swap of enslaved interface
  *
  *     - fix deletion of multicast groups after unloading module
  *
  * 2002/11/06 - Kameshwara Rayaprolu <kameshwara.rao * wipro_com>
- *     - Changes to prevent panic from closing the device twice; if we close 
- *       the device in bond_release, we must set the original_flags to down 
+ *     - Changes to prevent panic from closing the device twice; if we close
+ *       the device in bond_release, we must set the original_flags to down
  *       so it won't be closed again by the network layer.
  *
  * 2002/11/07 - Tony Cureington <tony.cureington * hp_com>
  *     - Fix arp_target_hw_addr memory leak
- *     - Created activebackup_arp_monitor function to handle arp monitoring 
- *       in active backup mode - the bond_arp_monitor had several problems... 
- *       such as allowing slaves to tx arps sequentially without any delay 
+ *     - Created activebackup_arp_monitor function to handle arp monitoring
+ *       in active backup mode - the bond_arp_monitor had several problems...
+ *       such as allowing slaves to tx arps sequentially without any delay
  *       for a response
  *     - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote
  *       this function to just handle arp monitoring in load-balancing mode;
  *       it is a lot more compact now
- *     - Changes to ensure one and only one slave transmits in active-backup 
+ *     - Changes to ensure one and only one slave transmits in active-backup
  *       mode
- *     - Robustesize parameters; warn users about bad combinations of 
- *       parameters; also if miimon is specified and a network driver does 
+ *     - Robustesize parameters; warn users about bad combinations of
+ *       parameters; also if miimon is specified and a network driver does
  *       not support MII or ETHTOOL, inform the user of this
  *     - Changes to support link_failure_count when in arp monitoring mode
  *     - Fix up/down delay reported in /proc
  *
  * 2002/11/16 - Laurent Deniel <laurent.deniel at free.fr>
  *     - fix multicast handling in activebackup_arp_monitor
- *     - remove one unnecessary and confusing current_slave == slave test 
+ *     - remove one unnecessary and confusing curr_active_slave == slave test
  *      in activebackup_arp_monitor
  *
  *  2002/11/17 - Laurent Deniel <laurent.deniel at free.fr>
  *       One change: an invalid choice will cause module load failure,
  *       rather than the previous behavior of just picking one.
  *     - Minor cleanups; got rid of dup ctype stuff, atoi function
- * 
+ *
  * 2003/02/07 - Jay Vosburgh <fubar at us dot ibm dot com>
  *     - Added use_carrier module parameter that causes miimon to
  *       use netif_carrier_ok() test instead of MII/ETHTOOL ioctls.
  *       new/old ifenslave and new/old bonding.
  *
  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Fixed bug in bond_release_all(): save old value of current_slave
+ *     - Fixed bug in bond_release_all(): save old value of curr_active_slave
  *       before setting it to NULL.
  *     - Changed driver versioning scheme to include version number instead
  *       of release date (that is already in another field). There are 3
  *
  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
  *     - Added support for Transmit load balancing mode.
- *     - Concentrate all assignments of current_slave to a single point
+ *     - Concentrate all assignments of curr_active_slave to a single point
  *       so specific modes can take actions when the primary adapter is
  *       changed.
  *     - Take the updelay parameter into consideration during bond_enslave
  *     - Convert /proc to seq_file interface.
  *       Change /proc/net/bondX/info to /proc/net/bonding/bondX.
  *       Set version to 2.4.1.
+ *
+ * 2003/11/20 - Amir Noam <amir.noam at intel dot com>
+ *     - Fix /proc creation/destruction.
+ *
+ * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
+ *     - Massive cleanup - Set version to 2.5.0
+ *       Code changes:
+ *       o Consolidate format of prints and debug prints.
+ *       o Remove bonding_t/slave_t typedefs and consolidate all casts.
+ *       o Remove dead code and unnecessary checks.
+ *       o Consolidate starting/stopping timers.
+ *       o Consolidate handling of primary module param throughout the code.
+ *       o Removed multicast module param support - all settings are done
+ *         according to mode.
+ *       o Slave list iteration - bond is no longer part of the list,
+ *         added cyclic list iteration macros.
+ *       o Consolidate error handling in all xmit functions.
+ *       Style changes:
+ *       o Consolidate function naming and declarations.
+ *       o Consolidate function params and local variables names.
+ *       o Consolidate return values.
+ *       o Consolidate curly braces.
+ *       o Consolidate conditionals format.
+ *       o Change struct member names and types.
+ *       o Chomp trailing spaces, remove empty lines, fix indentations.
+ *       o Re-organize code according to context.
  */
 
+//#define BONDING_DEBUG 1
+
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
 #include <linux/errno.h>
-
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-
-#include <linux/if_bonding.h>
 #include <linux/smp.h>
 #include <linux/if_ether.h>
 #include <net/arp.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/if_bonding.h>
 #include "bonding.h"
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION    "2.4.1"
-#define DRV_RELDATE    "September 15, 2003"
-#define DRV_NAME       "bonding"
-#define DRV_DESCRIPTION        "Ethernet Channel Bonding Driver"
-
-static const char *version =
-DRV_NAME ".c:v" DRV_VERSION " (" DRV_RELDATE ")\n";
+/*---------------------------- Module parameters ----------------------------*/
 
 /* monitor all links that often (in milliseconds). <=0 disables monitoring */
-#ifndef BOND_LINK_MON_INTERV
 #define BOND_LINK_MON_INTERV   0
-#endif
-
-#ifndef BOND_LINK_ARP_INTERV
 #define BOND_LINK_ARP_INTERV   0
-#endif
+#define MAX_ARP_IP_TARGETS     16
 
-#ifndef MAX_ARP_IP_TARGETS
-#define MAX_ARP_IP_TARGETS 16
-#endif
+static int max_bonds   = BOND_DEFAULT_MAX_BONDS;
+static int miimon      = BOND_LINK_MON_INTERV;
+static int updelay     = 0;
+static int downdelay   = 0;
+static int use_carrier = 1;
+static char *mode      = NULL;
+static char *primary   = NULL;
+static char *lacp_rate = NULL;
+static int arp_interval = BOND_LINK_ARP_INTERV;
+static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, };
+
+MODULE_PARM(max_bonds, "i");
+MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
+MODULE_PARM(miimon, "i");
+MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
+MODULE_PARM(updelay, "i");
+MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
+MODULE_PARM(downdelay, "i");
+MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
+MODULE_PARM(use_carrier, "i");
+MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
+MODULE_PARM(mode, "s");
+MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
+MODULE_PARM(primary, "s");
+MODULE_PARM_DESC(primary, "Primary network device to use");
+MODULE_PARM(lacp_rate, "s");
+MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
+MODULE_PARM(arp_interval, "i");
+MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
+MODULE_PARM(arp_ip_target, "1-" __MODULE_STRING(MAX_ARP_IP_TARGETS) "s");
+MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
 
-#define USES_PRIMARY(mode) \
-               (((mode) == BOND_MODE_ACTIVEBACKUP) || \
-                ((mode) == BOND_MODE_TLB) || \
-                ((mode) == BOND_MODE_ALB))
+/*----------------------------- Global variables ----------------------------*/
 
-struct bond_parm_tbl {
-       char *modename;
-       int mode;
-};
+static const char *version =
+       DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
-static int arp_interval = BOND_LINK_ARP_INTERV;
-static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, };
-static u32 arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
-static int arp_ip_count = 0;
-static u32 my_ip = 0;
-char *arp_target_hw_addr = NULL;
+static LIST_HEAD(bond_dev_list);
 
-static char *primary= NULL;
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *bond_proc_dir = NULL;
+#endif
 
-static int app_abi_ver = 0;
+static u32 arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
+static int arp_ip_count        = 0;
+static u32 my_ip       = 0;
+static int bond_mode   = BOND_MODE_ROUNDROBIN;
+static int lacp_fast   = 0;
+static int app_abi_ver = 0;
 static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
                                   * we receive from the application. Once set,
                                   * it won't be changed, and the module will
@@ -521,14 +562,16 @@ static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
                                   * another ABI version.
                                   */
 
-static int max_bonds   = BOND_DEFAULT_MAX_BONDS;
-static int miimon      = BOND_LINK_MON_INTERV;
-static int use_carrier = 1;
-static int bond_mode   = BOND_MODE_ROUNDROBIN;
-static int updelay     = 0;
-static int downdelay   = 0;
+struct bond_parm_tbl {
+       char *modename;
+       int mode;
+};
 
-static char *mode      = NULL;
+static struct bond_parm_tbl bond_lacp_tbl[] = {
+{      "slow",         AD_LACP_SLOW},
+{      "fast",         AD_LACP_FAST},
+{      NULL,           -1},
+};
 
 static struct bond_parm_tbl bond_mode_tbl[] = {
 {      "balance-rr",           BOND_MODE_ROUNDROBIN},
@@ -541,101 +584,9 @@ static struct bond_parm_tbl bond_mode_tbl[] = {
 {      NULL,                   -1},
 };
 
-static int multicast_mode      = BOND_MULTICAST_ALL;
-static char *multicast         = NULL;
-
-static struct bond_parm_tbl bond_mc_tbl[] = {
-{      "disabled",             BOND_MULTICAST_DISABLED},
-{      "active",               BOND_MULTICAST_ACTIVE},
-{      "all",                  BOND_MULTICAST_ALL},
-{      NULL,                   -1},
-};
-
-static int lacp_fast           = 0;
-static char *lacp_rate         = NULL;
-
-static struct bond_parm_tbl bond_lacp_tbl[] = {
-{      "slow",         AD_LACP_SLOW},
-{      "fast",         AD_LACP_FAST},
-{      NULL,           -1},
-};
-
-static LIST_HEAD(bond_dev_list);
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *bond_proc_dir = NULL;
-#endif
-
-MODULE_PARM(max_bonds, "i");
-MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
-MODULE_PARM(miimon, "i");
-MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
-MODULE_PARM(use_carrier, "i");
-MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
-MODULE_PARM(mode, "s");
-MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
-MODULE_PARM(arp_interval, "i");
-MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
-MODULE_PARM(arp_ip_target, "1-" __MODULE_STRING(MAX_ARP_IP_TARGETS) "s");
-MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
-MODULE_PARM(updelay, "i");
-MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
-MODULE_PARM(downdelay, "i");
-MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
-MODULE_PARM(primary, "s");
-MODULE_PARM_DESC(primary, "Primary network device to use");
-MODULE_PARM(multicast, "s");
-MODULE_PARM_DESC(multicast, "Mode for multicast support : 0 for none, 1 for active slave, 2 for all slaves (default)");
-MODULE_PARM(lacp_rate, "s");
-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
-
-static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev);
-static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *bond_get_stats(struct net_device *dev);
-static void bond_mii_monitor(struct net_device *dev);
-static void loadbalance_arp_monitor(struct net_device *dev);
-static void activebackup_arp_monitor(struct net_device *dev);
-static void bond_mc_list_destroy(struct bonding *bond);
-static void bond_mc_add(bonding_t *bond, void *addr, int alen);
-static void bond_mc_delete(bonding_t *bond, void *addr, int alen);
-static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst, int gpf_flag);
-static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2);
-static void bond_set_promiscuity(bonding_t *bond, int inc);
-static void bond_set_allmulti(bonding_t *bond, int inc);
-static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list);
-static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old);
-static int bond_enslave(struct net_device *master, struct net_device *slave);
-static int bond_release(struct net_device *master, struct net_device *slave);
-static int bond_release_all(struct net_device *master);
-static int bond_sethwaddr(struct net_device *master, struct net_device *slave);
-static void change_active_interface(struct bonding *bond, struct slave *new);
-static void reselect_active_interface(struct bonding *bond);
-static struct slave *find_best_interface(struct bonding *bond);
-
-
-/* #define BONDING_DEBUG 1 */
-#ifdef BONDING_DEBUG
-#define dprintk(x...) printk(x...)
-#else /* BONDING_DEBUG */
-#define dprintk(x...) do {} while (0)
-#endif /* BONDING_DEBUG */
-
-/* several macros */
-
-static void arp_send_all(slave_t *slave)
-{      
-       int i; 
-
-       for (i = 0; (i<MAX_ARP_IP_TARGETS) && arp_target[i]; i++) { 
-               arp_send(ARPOP_REQUEST, ETH_P_ARP, arp_target[i], slave->dev, 
-                        my_ip, arp_target_hw_addr, slave->dev->dev_addr,
-                        arp_target_hw_addr); 
-       } 
-}
+/*---------------------------- General routines -----------------------------*/
 
-static const char *
-bond_mode_name(void)
+static const char *bond_mode_name(void)
 {
        switch (bond_mode) {
        case BOND_MODE_ROUNDROBIN :
@@ -657,149 +608,7 @@ bond_mode_name(void)
        }
 }
 
-static const char *
-multicast_mode_name(void)
-{
-       switch(multicast_mode) {
-       case BOND_MULTICAST_DISABLED :
-               return "disabled";
-       case BOND_MULTICAST_ACTIVE :
-               return "active slave only";
-       case BOND_MULTICAST_ALL :
-               return "all slaves";
-       default :
-               return "unknown";
-       }
-}
-
-void bond_set_slave_inactive_flags(slave_t *slave)
-{
-       slave->state = BOND_STATE_BACKUP;
-       slave->dev->flags |= IFF_NOARP;
-}
-
-void bond_set_slave_active_flags(slave_t *slave)
-{
-       slave->state = BOND_STATE_ACTIVE;
-       slave->dev->flags &= ~IFF_NOARP;
-}
-
-/*
- * This function counts and verifies the the number of attached
- * slaves, checking the count against the expected value (given that incr
- * is either 1 or -1, for add or removal of a slave).  Only
- * bond_xmit_xor() uses the slave_cnt value, but this is still a good
- * consistency check.
- */
-static inline void
-update_slave_cnt(bonding_t *bond, int incr)
-{
-       slave_t *slave = NULL;
-       int expect = bond->slave_cnt + incr;
-
-       bond->slave_cnt = 0;
-       for (slave = bond->prev; slave != (slave_t*)bond;
-            slave = slave->prev) {
-               bond->slave_cnt++;
-       }
-
-       if (expect != bond->slave_cnt)
-               BUG();
-}
-
-/* 
- * This function detaches the slave <slave> from the list <bond>.
- * WARNING: no check is made to verify if the slave effectively
- * belongs to <bond>. It returns <slave> in case it's needed.
- * Nothing is freed on return, structures are just unchained.
- * If the bond->current_slave pointer was pointing to <slave>,
- * it should be changed by the calling function.
- *
- * bond->lock held for writing by caller.
- */
-static slave_t *
-bond_detach_slave(bonding_t *bond, slave_t *slave)
-{
-       if ((bond == NULL) || (slave == NULL) ||
-          ((void *)bond == (void *)slave)) {
-               printk(KERN_ERR
-                       "bond_detach_slave(): trying to detach "
-                       "slave %p from bond %p\n", bond, slave);
-               return slave;
-       }
-
-       if (bond->next == slave) {  /* is the slave at the head ? */
-               if (bond->prev == slave) {  /* is the slave alone ? */
-                       bond->prev = bond->next = (slave_t *)bond;
-               } else { /* not alone */
-                       bond->next        = slave->next;
-                       slave->next->prev = (slave_t *)bond;
-                       bond->prev->next  = slave->next;
-               }
-       } else {
-               slave->prev->next = slave->next;
-               if (bond->prev == slave) {  /* is this slave the last one ? */
-                       bond->prev = slave->prev;
-               } else {
-                       slave->next->prev = slave->prev;
-               }
-       }
-
-       update_slave_cnt(bond, -1);
-
-       return slave;
-}
-
-/*
- * This function attaches the slave <slave> to the list <bond>.
- *
- * bond->lock held for writing by caller.
- */
-static void
-bond_attach_slave(struct bonding *bond, struct slave *new_slave)
-{
-       /* 
-        * queue to the end of the slaves list, make the first element its
-        * successor, the last one its predecessor, and make it the bond's
-        * predecessor. 
-        *
-        * Just to clarify, so future bonding driver hackers don't go through
-        * the same confusion stage I did trying to figure this out, the
-        * slaves are stored in a double linked circular list, sortof.
-        * In the ->next direction, the last slave points to the first slave,
-        * bypassing bond; only the slaves are in the ->next direction.
-        * In the ->prev direction, however, the first slave points to bond
-        * and bond points to the last slave.
-        *
-        * It looks like a circle with a little bubble hanging off one side
-        * in the ->prev direction only.
-        *
-        * When going through the list once, its best to start at bond->prev
-        * and go in the ->prev direction, testing for bond.  Doing this
-        * in the ->next direction doesn't work.  Trust me, I know this now.
-        * :)  -mts 2002.03.14
-        */
-       new_slave->prev       = bond->prev;
-       new_slave->prev->next = new_slave;
-       bond->prev            = new_slave;
-       new_slave->next       = bond->next;
-
-       update_slave_cnt(bond, 1);
-}
-
-
-/*
- * Less bad way to call ioctl from within the kernel; this needs to be
- * done some other way to get the call out of interrupt context.
- * Needs "ioctl" variable to be supplied by calling context.
- */
-#define IOCTL(dev, arg, cmd) ({                \
-       int ret;                        \
-       mm_segment_t fs = get_fs();     \
-       set_fs(get_ds());               \
-       ret = ioctl(dev, arg, cmd);     \
-       set_fs(fs);                     \
-       ret; })
+/*------------------------------- Link status -------------------------------*/
 
 /*
  * Get link speed and duplex from the slave's base driver
@@ -809,16 +618,16 @@ bond_attach_slave(struct bonding *bond, struct slave *new_slave)
  */
 static int bond_update_speed_duplex(struct slave *slave)
 {
-       struct net_device *dev = slave->dev;
+       struct net_device *slave_dev = slave->dev;
        static int (* ioctl)(struct net_device *, struct ifreq *, int);
        struct ifreq ifr;
        struct ethtool_cmd etool;
 
-       ioctl = dev->do_ioctl;
+       ioctl = slave_dev->do_ioctl;
        if (ioctl) {
                etool.cmd = ETHTOOL_GSET;
                ifr.ifr_data = (char*)&etool;
-               if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) {
+               if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) {
                        slave->speed = etool.speed;
                        slave->duplex = etool.duplex;
                } else {
@@ -829,20 +638,20 @@ static int bond_update_speed_duplex(struct slave *slave)
        }
 
        switch (slave->speed) {
-               case SPEED_10:
-               case SPEED_100:
-               case SPEED_1000:
-                       break;
-               default:
-                       goto err_out;
+       case SPEED_10:
+       case SPEED_100:
+       case SPEED_1000:
+               break;
+       default:
+               goto err_out;
        }
 
        switch (slave->duplex) {
-               case DUPLEX_FULL:
-               case DUPLEX_HALF:
-                       break;
-               default:
-                       goto err_out;
+       case DUPLEX_FULL:
+       case DUPLEX_HALF:
+               break;
+       default:
+               goto err_out;
        }
 
        return 0;
@@ -854,7 +663,7 @@ err_out:
        return -1;
 }
 
-/* 
+/*
  * if <dev> supports MII link status reporting, check its link status.
  *
  * We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(),
@@ -870,8 +679,7 @@ err_out:
  * It'd be nice if there was a good way to tell if a driver supports
  * netif_carrier, but there really isn't.
  */
-static int
-bond_check_dev_link(struct net_device *dev, int reporting)
+static int bond_check_dev_link(struct net_device *slave_dev, int reporting)
 {
        static int (* ioctl)(struct net_device *, struct ifreq *, int);
        struct ifreq ifr;
@@ -879,10 +687,10 @@ bond_check_dev_link(struct net_device *dev, int reporting)
        struct ethtool_value etool;
 
        if (use_carrier) {
-               return netif_carrier_ok(dev) ? BMSR_LSTATUS : 0;
+               return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
        }
 
-       ioctl = dev->do_ioctl;
+       ioctl = slave_dev->do_ioctl;
        if (ioctl) {
                /* TODO: set pointer to correct ioctl on a per team member */
                /*       bases to make this more efficient. that is, once  */
@@ -898,476 +706,495 @@ bond_check_dev_link(struct net_device *dev, int reporting)
 
                /* Yes, the mii is overlaid on the ifreq.ifr_ifru */
                mii = (struct mii_ioctl_data *)&ifr.ifr_data;
-               if (IOCTL(dev, &ifr, SIOCGMIIPHY) == 0) {
+               if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
                        mii->reg_num = MII_BMSR;
-                       if (IOCTL(dev, &ifr, SIOCGMIIREG) == 0) {
-                               return mii->val_out & BMSR_LSTATUS;
+                       if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) {
+                               return (mii->val_out & BMSR_LSTATUS);
                        }
                }
 
                /* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */
                /* for a period of time so we attempt to get link status   */
                /* from it last if the above MII ioctls fail...            */
-               etool.cmd = ETHTOOL_GLINK;
-               ifr.ifr_data = (char*)&etool;
-               if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) {
+               etool.cmd = ETHTOOL_GLINK;
+               ifr.ifr_data = (char*)&etool;
+               if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) {
                        if (etool.data == 1) {
                                return BMSR_LSTATUS;
-                       } else { 
-#ifdef BONDING_DEBUG
-                               printk(KERN_INFO 
-                                       ":: SIOCETHTOOL shows link down \n");
-#endif
+                       } else {
+                               dprintk("SIOCETHTOOL shows link down\n");
                                return 0;
-                       } 
+                       }
                }
-
        }
+
        /*
         * If reporting, report that either there's no dev->do_ioctl,
         * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we
         * cannot report link status).  If not reporting, pretend
         * we're ok.
         */
-       return reporting ? -1 : BMSR_LSTATUS;
+       return (reporting ? -1 : BMSR_LSTATUS);
 }
 
-static u16 bond_check_mii_link(bonding_t *bond)
-{
-       int has_active_interface = 0;
-
-       read_lock_bh(&bond->lock);
-       read_lock(&bond->ptrlock);
-       has_active_interface = (bond->current_slave != NULL);
-       read_unlock(&bond->ptrlock);
-       read_unlock_bh(&bond->lock);
+/*----------------------------- Multicast list ------------------------------*/
 
-       return (has_active_interface ? BMSR_LSTATUS : 0);
+/*
+ * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
+ */
+static inline int bond_is_dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
+{
+       return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
+                       dmi1->dmi_addrlen == dmi2->dmi_addrlen;
 }
 
-/* register to receive lacpdus on a bond */
-static void bond_register_lacpdu(struct bonding *bond)
+/*
+ * returns dmi entry if found, NULL otherwise
+ */
+static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list)
 {
-       struct packet_type* pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
+       struct dev_mc_list *idmi;
 
-       /* initialize packet type */
-       pk_type->type = PKT_TYPE_LACPDU;
-       pk_type->dev = bond->device;
-       pk_type->func = bond_3ad_lacpdu_recv;
+       for (idmi = mc_list; idmi; idmi = idmi->next) {
+               if (bond_is_dmi_same(dmi, idmi)) {
+                       return idmi;
+               }
+       }
 
-       dev_add_pack(pk_type);
+       return NULL;
 }
 
-/* unregister to receive lacpdus on a bond */
-static void bond_unregister_lacpdu(struct bonding *bond)
+/*
+ * Push the promiscuity flag down to appropriate slaves
+ */
+static void bond_set_promiscuity(struct bonding *bond, int inc)
 {
-       dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
+       if (USES_PRIMARY(bond_mode)) {
+               /* write lock already acquired */
+               if (bond->curr_active_slave) {
+                       dev_set_promiscuity(bond->curr_active_slave->dev, inc);
+               }
+       } else {
+               struct slave *slave;
+               int i;
+               bond_for_each_slave(bond, slave, i) {
+                       dev_set_promiscuity(slave->dev, inc);
+               }
+       }
 }
 
-static int bond_open(struct net_device *dev)
+/*
+ * Push the allmulti flag down to all slaves
+ */
+static void bond_set_allmulti(struct bonding *bond, int inc)
 {
-       struct bonding *bond = (struct bonding *)(dev->priv);
-       struct timer_list *timer = &((struct bonding *)(dev->priv))->mii_timer;
-       struct timer_list *arp_timer = &((struct bonding *)(dev->priv))->arp_timer;
-
-       if ((bond_mode == BOND_MODE_TLB) ||
-           (bond_mode == BOND_MODE_ALB)) {
-               struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer);
-
-               /* bond_alb_initialize must be called before the timer
-                * is started.
-                */
-               if (bond_alb_initialize(bond, (bond_mode == BOND_MODE_ALB))) {
-                       /* something went wrong - fail the open operation */
-                       return -1;
+       if (USES_PRIMARY(bond_mode)) {
+               /* write lock already acquired */
+               if (bond->curr_active_slave) {
+                       dev_set_allmulti(bond->curr_active_slave->dev, inc);
+               }
+       } else {
+               struct slave *slave;
+               int i;
+               bond_for_each_slave(bond, slave, i) {
+                       dev_set_allmulti(slave->dev, inc);
                }
-
-               init_timer(alb_timer);
-               alb_timer->expires  = jiffies + 1;
-               alb_timer->data     = (unsigned long)bond;
-               alb_timer->function = (void *)&bond_alb_monitor;
-               add_timer(alb_timer);
-       }
-
-       if (miimon > 0) {  /* link check interval, in milliseconds. */
-               init_timer(timer);
-               timer->expires  = jiffies + (miimon * HZ / 1000);
-               timer->data     = (unsigned long)dev;
-               timer->function = (void *)&bond_mii_monitor;
-               add_timer(timer);
        }
+}
 
-       if (arp_interval> 0) {  /* arp interval, in milliseconds. */
-               init_timer(arp_timer);
-               arp_timer->expires  = jiffies + (arp_interval * HZ / 1000);
-               arp_timer->data     = (unsigned long)dev;
-               if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
-                       arp_timer->function = (void *)&activebackup_arp_monitor;
-               } else {
-                       arp_timer->function = (void *)&loadbalance_arp_monitor;
+/*
+ * Add a Multicast address to slaves
+ * according to mode
+ */
+static void bond_mc_add(struct bonding *bond, void *addr, int alen)
+{
+       if (USES_PRIMARY(bond_mode)) {
+               /* write lock already acquired */
+               if (bond->curr_active_slave) {
+                       dev_mc_add(bond->curr_active_slave->dev, addr, alen, 0);
+               }
+       } else {
+               struct slave *slave;
+               int i;
+               bond_for_each_slave(bond, slave, i) {
+                       dev_mc_add(slave->dev, addr, alen, 0);
                }
-               add_timer(arp_timer);
        }
-
-       if (bond_mode == BOND_MODE_8023AD) {
-               struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer);
-               init_timer(ad_timer);
-               ad_timer->expires  = jiffies + (AD_TIMER_INTERVAL * HZ / 1000);
-               ad_timer->data     = (unsigned long)bond;
-               ad_timer->function = (void *)&bond_3ad_state_machine_handler;
-               add_timer(ad_timer);
-
-               /* register to receive LACPDUs */
-               bond_register_lacpdu(bond);
-       }
-
-       return 0;
 }
 
-static int bond_close(struct net_device *master)
+/*
+ * Remove a multicast address from slave
+ * according to mode
+ */
+static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
 {
-       bonding_t *bond = (struct bonding *) master->priv;
-
-       write_lock_bh(&bond->lock);
-
-       if (miimon > 0) {  /* link check interval, in milliseconds. */
-               del_timer(&bond->mii_timer);
-       }
-       if (arp_interval> 0) {  /* arp interval, in milliseconds. */
-               del_timer(&bond->arp_timer);
-                if (arp_target_hw_addr != NULL) {
-                       kfree(arp_target_hw_addr); 
-                       arp_target_hw_addr = NULL;
+       if (USES_PRIMARY(bond_mode)) {
+               /* write lock already acquired */
+               if (bond->curr_active_slave) {
+                       dev_mc_delete(bond->curr_active_slave->dev, addr, alen, 0);
+               }
+       } else {
+               struct slave *slave;
+               int i;
+               bond_for_each_slave(bond, slave, i) {
+                       dev_mc_delete(slave->dev, addr, alen, 0);
                }
        }
+}
 
-       if (bond_mode == BOND_MODE_8023AD) {
-               del_timer_sync(&(BOND_AD_INFO(bond).ad_timer));
+/*
+ * Totally destroys the mc_list in bond
+ */
+static void bond_mc_list_destroy(struct bonding *bond)
+{
+       struct dev_mc_list *dmi;
 
-               /* Unregister the receive of LACPDUs */
-               bond_unregister_lacpdu(bond);
+       dmi = bond->mc_list;
+       while (dmi) {
+               bond->mc_list = dmi->next;
+               kfree(dmi);
+               dmi = bond->mc_list;
        }
+}
 
-       bond_mc_list_destroy (bond);
-
-       write_unlock_bh(&bond->lock);
+/*
+ * Copy all the Multicast addresses from src to the bonding device dst
+ */
+static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond, int gpf_flag)
+{
+       struct dev_mc_list *dmi, *new_dmi;
 
-       /* Release the bonded slaves */
-       bond_release_all(master);
+       for (dmi = mc_list; dmi; dmi = dmi->next) {
+               new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag);
 
-       if ((bond_mode == BOND_MODE_TLB) ||
-           (bond_mode == BOND_MODE_ALB)) {
-               del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer));
+               if (!new_dmi) {
+                       /* FIXME: Potential memory leak !!! */
+                       return -ENOMEM;
+               }
 
-               bond_alb_deinitialize(bond);
+               new_dmi->next = bond->mc_list;
+               bond->mc_list = new_dmi;
+               new_dmi->dmi_addrlen = dmi->dmi_addrlen;
+               memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen);
+               new_dmi->dmi_users = dmi->dmi_users;
+               new_dmi->dmi_gusers = dmi->dmi_gusers;
        }
 
        return 0;
 }
 
-/* 
+/*
  * flush all members of flush->mc_list from device dev->mc_list
  */
-static void bond_mc_list_flush(struct net_device *dev, struct net_device *flush)
-{ 
-       struct dev_mc_list *dmi; 
-       for (dmi = flush->mc_list; dmi != NULL; dmi = dmi->next) 
-               dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *slave_dev)
+{
+       struct dev_mc_list *dmi;
+
+       for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
+               dev_mc_delete(slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+       }
 
        if (bond_mode == BOND_MODE_8023AD) {
                /* del lacpdu mc addr from mc list */
                u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
 
-               dev_mc_delete(dev, lacpdu_multicast, ETH_ALEN, 0);
+               dev_mc_delete(slave_dev, lacpdu_multicast, ETH_ALEN, 0);
        }
 }
 
+/*--------------------------- Active slave change ---------------------------*/
+
 /*
- * Totally destroys the mc_list in bond
+ * Update the mc list and multicast-related flags for the new and
+ * old active slaves (if any) according to the multicast mode, and
+ * promiscuous flags unconditionally.
  */
-static void bond_mc_list_destroy(struct bonding *bond)
+static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct slave *old_active)
 {
        struct dev_mc_list *dmi;
 
-       dmi = bond->mc_list; 
-       while (dmi) { 
-               bond->mc_list = dmi->next; 
-               kfree(dmi); 
-               dmi = bond->mc_list; 
-       }
-}
-
-/*
- * Add a Multicast address to every slave in the bonding group
- */
-static void bond_mc_add(bonding_t *bond, void *addr, int alen)
-{ 
-       slave_t *slave;
-       switch (multicast_mode) {
-       case BOND_MULTICAST_ACTIVE :
-               /* write lock already acquired */
-               if (bond->current_slave != NULL)
-                       dev_mc_add(bond->current_slave->dev, addr, alen, 0);
-               break;
-       case BOND_MULTICAST_ALL :
-               for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
-                       dev_mc_add(slave->dev, addr, alen, 0);
-               break;
-       case BOND_MULTICAST_DISABLED :
-               break;
+       if (!USES_PRIMARY(bond_mode)) {
+               /* nothing to do -  mc list is already up-to-date on
+                * all slaves
+                */
+               return;
        }
-} 
 
-/*
- * Remove a multicast address from every slave in the bonding group
- */
-static void bond_mc_delete(bonding_t *bond, void *addr, int alen)
-{ 
-       slave_t *slave; 
-       switch (multicast_mode) {
-       case BOND_MULTICAST_ACTIVE :
-               /* write lock already acquired */
-               if (bond->current_slave != NULL)
-                       dev_mc_delete(bond->current_slave->dev, addr, alen, 0);
-               break;
-       case BOND_MULTICAST_ALL :
-               for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
-                       dev_mc_delete(slave->dev, addr, alen, 0);
-               break;
-       case BOND_MULTICAST_DISABLED :
-               break;
-       }
-} 
+       if (old_active) {
+               if (bond->dev->flags & IFF_PROMISC) {
+                       dev_set_promiscuity(old_active->dev, -1);
+               }
 
-/*
- * Copy all the Multicast addresses from src to the bonding device dst
- */
-static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst,
- int gpf_flag)
-{
-       struct dev_mc_list *dmi, *new_dmi;
+               if (bond->dev->flags & IFF_ALLMULTI) {
+                       dev_set_allmulti(old_active->dev, -1);
+               }
 
-       for (dmi = src; dmi != NULL; dmi = dmi->next) { 
-               new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag);
+               for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
+                       dev_mc_delete(old_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+               }
+       }
 
-               if (new_dmi == NULL) {
-                       return -ENOMEM; 
+       if (new_active) {
+               if (bond->dev->flags & IFF_PROMISC) {
+                       dev_set_promiscuity(new_active->dev, 1);
                }
 
-               new_dmi->next = dst->mc_list; 
-               dst->mc_list = new_dmi;
+               if (bond->dev->flags & IFF_ALLMULTI) {
+                       dev_set_allmulti(new_active->dev, 1);
+               }
 
-               new_dmi->dmi_addrlen = dmi->dmi_addrlen; 
-               memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen); 
-               new_dmi->dmi_users = dmi->dmi_users;
-               new_dmi->dmi_gusers = dmi->dmi_gusers; 
-       } 
-       return 0;
+               for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
+                       dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+               }
+       }
 }
 
-/*
- * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
- */
-static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
-{ 
-       return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
-        dmi1->dmi_addrlen == dmi2->dmi_addrlen;
-} 
-
-/*
- * Push the promiscuity flag down to appropriate slaves
+/**
+ * find_best_interface - select the best available slave to be the active one
+ * @bond: our bonding struct
+ *
+ * Warning: Caller must hold curr_slave_lock for writing.
  */
-static void bond_set_promiscuity(bonding_t *bond, int inc)
-{ 
-       slave_t *slave; 
+static struct slave *bond_find_best_slave(struct bonding *bond)
+{
+       struct slave *new_active, *old_active;
+       struct slave *bestslave = NULL;
+       int mintime;
+       int i;
 
-       if (USES_PRIMARY(bond_mode)) {
-               if (bond->current_slave) {
-                       dev_set_promiscuity(bond->current_slave->dev, inc);
-               }
+       new_active = old_active = bond->curr_active_slave;
 
-       } else { 
-               for (slave = bond->prev; slave != (slave_t*)bond;
-                    slave = slave->prev) {
-                       dev_set_promiscuity(slave->dev, inc);
+       if (!new_active) { /* there were no active slaves left */
+               if (bond->slave_cnt > 0) {  /* found one slave */
+                       new_active = bond->first_slave;
+               } else {
+                       return NULL; /* still no slave, return NULL */
                }
        }
-} 
 
-/*
- * Push the allmulti flag down to all slaves
- */
-static void bond_set_allmulti(bonding_t *bond, int inc)
-{ 
-       slave_t *slave; 
-       switch (multicast_mode) {
-       case BOND_MULTICAST_ACTIVE : 
-               /* write lock already acquired */
-               if (bond->current_slave != NULL)
-                       dev_set_allmulti(bond->current_slave->dev, inc);
-               break;
-       case BOND_MULTICAST_ALL :
-               for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
-                       dev_set_allmulti(slave->dev, inc);
-               break;
-       case BOND_MULTICAST_DISABLED :
-               break;
+       mintime = updelay;
+
+       /* first try the primary link; if arping, a link must tx/rx traffic
+        * before it can be considered the curr_active_slave - also, we would skip
+        * slaves between the curr_active_slave and primary_slave that may be up
+        * and able to arp
+        */
+       if ((bond->primary_slave) &&
+           (!arp_interval) &&
+           (IS_UP(bond->primary_slave->dev))) {
+               new_active = bond->primary_slave;
        }
-} 
 
-/* 
- * returns dmi entry if found, NULL otherwise 
- */
-static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi,
- struct dev_mc_list *mc_list)
-{ 
-       struct dev_mc_list *idmi;
+       /* remember where to stop iterating over the slaves */
+       old_active = new_active;
 
-       for (idmi = mc_list; idmi != NULL; idmi = idmi->next) {
-               if (dmi_same(dmi, idmi)) {
-                       return idmi; 
+       bond_for_each_slave_from(bond, new_active, i, old_active) {
+               if (IS_UP(new_active->dev)) {
+                       if (new_active->link == BOND_LINK_UP) {
+                               return new_active;
+                       } else if (new_active->link == BOND_LINK_BACK) {
+                               /* link up, but waiting for stabilization */
+                               if (new_active->delay < mintime) {
+                                       mintime = new_active->delay;
+                                       bestslave = new_active;
+                               }
+                       }
                }
        }
-       return NULL;
-} 
 
-static void set_multicast_list(struct net_device *master)
+       return bestslave;
+}
+
+/**
+ * change_active_interface - change the active slave into the specified one
+ * @bond: our bonding struct
+ * @new: the new slave to make the active one
+ *
+ * Set the new slave to the bond's settings and unset them on the old
+ * curr_active_slave.
+ * Setting include flags, mc-list, promiscuity, allmulti, etc.
+ *
+ * If @new's link state is %BOND_LINK_BACK we'll set it to %BOND_LINK_UP,
+ * because it is apparently the best available slave we have, even though its
+ * updelay hasn't timed out yet.
+ *
+ * Warning: Caller must hold curr_slave_lock for writing.
+ */
+static void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 {
-       bonding_t *bond = master->priv;
-       struct dev_mc_list *dmi;
+       struct slave *old_active = bond->curr_active_slave;
 
-       write_lock_bh(&bond->lock);
+       if (old_active == new_active) {
+               return;
+       }
 
-       /*
-        * Do promisc before checking multicast_mode
-        */
-       if ( (master->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC) )
-               bond_set_promiscuity(bond, 1); 
+       if (new_active) {
+               if (new_active->link == BOND_LINK_BACK) {
+                       if (USES_PRIMARY(bond_mode)) {
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: making interface %s the new "
+                                      "active one %d ms earlier.\n",
+                                      bond->dev->name, new_active->dev->name,
+                                      (updelay - new_active->delay) * miimon);
+                       }
 
-       if ( !(master->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC) ) 
-               bond_set_promiscuity(bond, -1); 
+                       new_active->delay = 0;
+                       new_active->link = BOND_LINK_UP;
+                       new_active->jiffies = jiffies;
 
-       if (multicast_mode == BOND_MULTICAST_DISABLED) {
-               bond->flags = master->flags;
-               write_unlock_bh(&bond->lock);
-               return;
+                       if (bond_mode == BOND_MODE_8023AD) {
+                               bond_3ad_handle_link_change(new_active, BOND_LINK_UP);
+                       }
+
+                       if ((bond_mode == BOND_MODE_TLB) ||
+                           (bond_mode == BOND_MODE_ALB)) {
+                               bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
+                       }
+               } else {
+                       if (USES_PRIMARY(bond_mode)) {
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: making interface %s the new "
+                                      "active one.\n",
+                                      bond->dev->name, new_active->dev->name);
+                       }
+               }
        }
 
-       /* set allmulti flag to slaves */ 
-       if ( (master->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI) ) 
-               bond_set_allmulti(bond, 1); 
+       if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+               if (old_active) {
+                       bond_set_slave_inactive_flags(old_active);
+               }
+
+               if (new_active) {
+                       bond_set_slave_active_flags(new_active);
+               }
+       }
 
-       if ( !(master->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI) )
-               bond_set_allmulti(bond, -1); 
+       if (USES_PRIMARY(bond_mode)) {
+               bond_mc_swap(bond, new_active, old_active);
+       }
 
-       bond->flags = master->flags; 
+       if ((bond_mode == BOND_MODE_TLB) ||
+           (bond_mode == BOND_MODE_ALB)) {
+               bond_alb_handle_active_change(bond, new_active);
+       } else {
+               bond->curr_active_slave = new_active;
+       }
+}
 
-       /* looking for addresses to add to slaves' mc list */ 
-       for (dmi = master->mc_list; dmi != NULL; dmi = dmi->next) { 
-               if (bond_mc_list_find_dmi(dmi, bond->mc_list) == NULL) 
-                bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen); 
-       } 
+/**
+ * bond_select_active_slave - select a new active slave, if needed
+ * @bond: our bonding struct
+ *
+ * This functions shoud be called when one of the following occurs:
+ * - The old curr_active_slave has been released or lost its link.
+ * - The primary_slave has got its link back.
+ * - A slave has got its link back and there's no old curr_active_slave.
+ *
+ * Warning: Caller must hold curr_slave_lock for writing.
+ */
+static void bond_select_active_slave(struct bonding *bond)
+{
+       struct slave *best_slave;
 
-       /* looking for addresses to delete from slaves' list */ 
-       for (dmi = bond->mc_list; dmi != NULL; dmi = dmi->next) { 
-               if (bond_mc_list_find_dmi(dmi, master->mc_list) == NULL) 
-                bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen); 
+       best_slave = bond_find_best_slave(bond);
+       if (best_slave != bond->curr_active_slave) {
+               bond_change_active_slave(bond, best_slave);
        }
+}
 
+/*--------------------------- slave list handling ---------------------------*/
 
-       /* save master's multicast list */ 
-       bond_mc_list_destroy (bond);
-       bond_mc_list_copy (master->mc_list, bond, GFP_ATOMIC);
+/*
+ * This function attaches the slave to the end of list.
+ *
+ * bond->lock held for writing by caller.
+ */
+static void bond_attach_slave(struct bonding *bond, struct slave *new_slave)
+{
+       if (bond->first_slave == NULL) { /* attaching the first slave */
+               new_slave->next = new_slave;
+               new_slave->prev = new_slave;
+               bond->first_slave = new_slave;
+       } else {
+               new_slave->next = bond->first_slave;
+               new_slave->prev = bond->first_slave->prev;
+               new_slave->next->prev = new_slave;
+               new_slave->prev->next = new_slave;
+       }
 
-       write_unlock_bh(&bond->lock);
+       bond->slave_cnt++;
 }
 
 /*
- * Update the mc list and multicast-related flags for the new and 
- * old active slaves (if any) according to the multicast mode, and
- * promiscuous flags unconditionally.
+ * This function detaches the slave from the list.
+ * WARNING: no check is made to verify if the slave effectively
+ * belongs to <bond>.
+ * Nothing is freed on return, structures are just unchained.
+ * If any slave pointer in bond was pointing to <slave>,
+ * it should be changed by the calling function.
+ *
+ * bond->lock held for writing by caller.
  */
-static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old)
+static void bond_detach_slave(struct bonding *bond, struct slave *slave)
 {
-       struct dev_mc_list *dmi;
+       if (slave->next) {
+               slave->next->prev = slave->prev;
+       }
 
-       if (USES_PRIMARY(bond_mode)) {
-               if (bond->device->flags & IFF_PROMISC) {
-                       if (old)
-                               dev_set_promiscuity(old->dev, -1);
-                       if (new)
-                               dev_set_promiscuity(new->dev, 1);
-               }
+       if (slave->prev) {
+               slave->prev->next = slave->next;
        }
 
-       switch(multicast_mode) {
-       case BOND_MULTICAST_ACTIVE :            
-               if (bond->device->flags & IFF_ALLMULTI) {
-                       if (old)
-                               dev_set_allmulti(old->dev, -1);
-                       if (new)
-                               dev_set_allmulti(new->dev, 1);
-               }
-               /* first remove all mc addresses from old slave if any,
-                  and _then_ add them to new active slave */
-               if (old) {
-                       for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
-                               dev_mc_delete(old->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
-               }
-               if (new) {
-                       for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
-                               dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+       if (bond->first_slave == slave) { /* slave is the first slave */
+               if (bond->slave_cnt > 1) { /* there are more slave */
+                       bond->first_slave = slave->next;
+               } else {
+                       bond->first_slave = NULL; /* slave was the last one */
                }
-               break;
-       case BOND_MULTICAST_ALL :
-               /* nothing to do: mc list is already up-to-date on all slaves */
-               break;
-       case BOND_MULTICAST_DISABLED :
-               break;
        }
+
+       slave->next = NULL;
+       slave->prev = NULL;
+       bond->slave_cnt--;
+}
+
+/*---------------------------------- IOCTL ----------------------------------*/
+
+static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+{
+       dprintk("bond_dev=%p\n", bond_dev);
+       dprintk("slave_dev=%p\n", slave_dev);
+       dprintk("slave_dev->addr_len=%d\n", slave_dev->addr_len);
+       memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len);
+       return 0;
 }
 
 /* enslave device <slave> to bond device <master> */
-static int bond_enslave(struct net_device *master_dev, 
-                        struct net_device *slave_dev)
+static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 {
-       bonding_t *bond = NULL;
-       slave_t *new_slave = NULL;
-       unsigned long rflags = 0;
-       int err = 0;
+       struct bonding *bond = bond_dev->priv;
+       struct slave *new_slave = NULL;
        struct dev_mc_list *dmi;
-       struct in_ifaddr **ifap;
-       struct in_ifaddr *ifa;
-       int link_reporting;
        struct sockaddr addr;
-
-       if (master_dev == NULL || slave_dev == NULL) {
-               return -ENODEV;
-       }
-       bond = (struct bonding *) master_dev->priv;
+       int link_reporting;
+       int res = 0;
 
        if (slave_dev->do_ioctl == NULL) {
-               printk(KERN_DEBUG
-                       "Warning : no link monitoring support for %s\n",
-                       slave_dev->name);
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning : no link monitoring support for %s\n",
+                      slave_dev->name);
        }
 
-
        /* bond must be initialized by bond_open() before enslaving */
-       if (!(master_dev->flags & IFF_UP)) {
-#ifdef BONDING_DEBUG
-               printk(KERN_CRIT "Error, master_dev is not up\n");
-#endif
+       if (!(bond_dev->flags & IFF_UP)) {
+               dprintk("Error, master_dev is not up\n");
                return -EPERM;
        }
 
        /* already enslaved */
-       if (master_dev->flags & IFF_SLAVE || slave_dev->flags & IFF_SLAVE) {
-#ifdef BONDING_DEBUG
-               printk(KERN_CRIT "Error, Device was already enslaved\n");
-#endif
+       if (slave_dev->flags & IFF_SLAVE) {
+               dprintk("Error, Device was already enslaved\n");
                return -EBUSY;
        }
 
@@ -1376,19 +1203,19 @@ static int bond_enslave(struct net_device *master_dev,
                 * slave interface to be closed.
                 */
                if ((slave_dev->flags & IFF_UP)) {
-#ifdef BONDING_DEBUG
-                       printk(KERN_CRIT "Error, slave_dev is up\n");
-#endif
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: %s is up\n",
+                              slave_dev->name);
                        return -EPERM;
                }
 
                if (slave_dev->set_mac_address == NULL) {
-                       printk(KERN_CRIT
-                              "The slave device you specified does not support"
-                              " setting the MAC address.\n");
-                       printk(KERN_CRIT
-                              "Your kernel likely does not support slave"
-                              " devices.\n");
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: The slave device you specified does "
+                              "not support setting the MAC address.\n");
+                       printk(KERN_ERR
+                              "Your kernel likely does not support slave "
+                              "devices.\n");
 
                        return -EOPNOTSUPP;
                }
@@ -1397,26 +1224,29 @@ static int bond_enslave(struct net_device *master_dev,
                 * slave interface to be open.
                 */
                if (!(slave_dev->flags & IFF_UP)) {
-#ifdef BONDING_DEBUG
-                       printk(KERN_CRIT "Error, slave_dev is not running\n");
-#endif
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: %s is not running\n",
+                              slave_dev->name);
                        return -EINVAL;
                }
 
                if ((bond_mode == BOND_MODE_8023AD) ||
-                   (bond_mode == BOND_MODE_TLB) ||
+                   (bond_mode == BOND_MODE_TLB)    ||
                    (bond_mode == BOND_MODE_ALB)) {
-                       printk(KERN_ERR
-                              "bonding: Error: to use %s mode, you must "
-                              "upgrade ifenslave.\n", bond_mode_name());
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: to use %s mode, you must upgrade "
+                              "ifenslave.\n",
+                              bond_mode_name());
                        return -EOPNOTSUPP;
                }
        }
 
-       if ((new_slave = kmalloc(sizeof(slave_t), GFP_KERNEL)) == NULL) {
+       new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL);
+       if (!new_slave) {
                return -ENOMEM;
        }
-       memset(new_slave, 0, sizeof(slave_t));
+
+       memset(new_slave, 0, sizeof(struct slave));
 
        /* save slave's original flags before calling
         * netdev_set_master and dev_open
@@ -1430,37 +1260,29 @@ static int bond_enslave(struct net_device *master_dev,
                 */
                memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
 
-               if (bond->slave_cnt > 0) {
-                       /* set slave to master's mac address
-                        * The application already set the master's
-                        * mac address to that of the first slave
-                        */
-                       memcpy(addr.sa_data, master_dev->dev_addr, master_dev->addr_len);
-                       addr.sa_family = slave_dev->type;
-                       err = slave_dev->set_mac_address(slave_dev, &addr);
-                       if (err) {
-#ifdef BONDING_DEBUG
-                               printk(KERN_CRIT "Error %d calling set_mac_address\n", err);
-#endif
-                               goto err_free;
-                       }
+               /* set slave to master's mac address
+                * The application already set the master's
+                * mac address to that of the first slave
+                */
+               memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
+               addr.sa_family = slave_dev->type;
+               res = slave_dev->set_mac_address(slave_dev, &addr);
+               if (res) {
+                       dprintk("Error %d calling set_mac_address\n", res);
+                       goto err_free;
                }
 
                /* open the slave since the application closed it */
-               err = dev_open(slave_dev);
-               if (err) {
-#ifdef BONDING_DEBUG
-                       printk(KERN_CRIT "Openning slave %s failed\n", slave_dev->name);
-#endif
+               res = dev_open(slave_dev);
+               if (res) {
+                       dprintk("Openning slave %s failed\n", slave_dev->name);
                        goto err_restore_mac;
                }
        }
 
-       err = netdev_set_master(slave_dev, master_dev);
-       if (err) {
-#ifdef BONDING_DEBUG
-               printk(KERN_CRIT "Error %d calling netdev_set_master\n", err);
-#endif
+       res = netdev_set_master(slave_dev, bond_dev);
+       if (res) {
+               dprintk("Error %d calling netdev_set_master\n", res);
                if (app_abi_ver < 1) {
                        goto err_free;
                } else {
@@ -1475,32 +1297,32 @@ static int bond_enslave(struct net_device *master_dev,
                /* bond_alb_init_slave() must be called before all other stages since
                 * it might fail and we do not want to have to undo everything
                 */
-               err = bond_alb_init_slave(bond, new_slave);
-               if (err) {
+               res = bond_alb_init_slave(bond, new_slave);
+               if (res) {
                        goto err_unset_master;
                }
        }
 
-       /* set promiscuity level to new slave */ 
-       if (master_dev->flags & IFF_PROMISC) {
-               /* If the mode USES_PRIMARY, then the new slave gets the
-                * master's promisc (and mc) settings only if it becomes the
-                * current_slave, and that is taken care of later when calling
-                * bond_change_active()
-                */
-               if (!USES_PRIMARY(bond_mode)) {
-                       dev_set_promiscuity(slave_dev, 1); 
+       /* If the mode USES_PRIMARY, then the new slave gets the
+        * master's promisc (and mc) settings only if it becomes the
+        * curr_active_slave, and that is taken care of later when calling
+        * bond_change_active()
+        */
+       if (!USES_PRIMARY(bond_mode)) {
+               /* set promiscuity level to new slave */
+               if (bond_dev->flags & IFF_PROMISC) {
+                       dev_set_promiscuity(slave_dev, 1);
                }
-       }
-       if (multicast_mode == BOND_MULTICAST_ALL) {
+
                /* set allmulti level to new slave */
-               if (master_dev->flags & IFF_ALLMULTI) 
-                       dev_set_allmulti(slave_dev, 1); 
-               
-               /* upload master's mc_list to new slave */ 
-               for (dmi = master_dev->mc_list; dmi != NULL; dmi = dmi->next) 
-                       dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+               if (bond_dev->flags & IFF_ALLMULTI) {
+                       dev_set_allmulti(slave_dev, 1);
+               }
+
+               /* upload master's mc_list to new slave */
+               for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
+                       dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+               }
        }
 
        if (bond_mode == BOND_MODE_8023AD) {
@@ -1511,15 +1333,16 @@ static int bond_enslave(struct net_device *master_dev,
        }
 
        write_lock_bh(&bond->lock);
-       
+
        bond_attach_slave(bond, new_slave);
+
        new_slave->delay = 0;
        new_slave->link_failure_count = 0;
 
-       if (miimon > 0 && !use_carrier) {
+       if (miimon && !use_carrier) {
                link_reporting = bond_check_dev_link(slave_dev, 1);
 
-               if ((link_reporting == -1) && (arp_interval == 0)) {
+               if ((link_reporting == -1) && !arp_interval) {
                        /*
                         * miimon is set but a bonded network driver
                         * does not support ETHTOOL/MII and
@@ -1528,115 +1351,97 @@ static int bond_enslave(struct net_device *master_dev,
                         * here (because netif_carrier is always
                         * supported); thus, we don't need to change
                         * the messages for netif_carrier.
-                        */ 
-                       printk(KERN_ERR
-                               "bond_enslave(): MII and ETHTOOL support not "
-                               "available for interface %s, and "
-                               "arp_interval/arp_ip_target module parameters "
-                               "not specified, thus bonding will not detect "
-                               "link failures! see bonding.txt for details.\n",
-                               slave_dev->name);
+                        */
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: MII and ETHTOOL support not "
+                              "available for interface %s, and "
+                              "arp_interval/arp_ip_target module parameters "
+                              "not specified, thus bonding will not detect "
+                              "link failures! see bonding.txt for details.\n",
+                              slave_dev->name);
                } else if (link_reporting == -1) {
-                       /* unable  get link status using mii/ethtool */
-                       printk(KERN_WARNING 
-                              "bond_enslave: can't get link status from "
+                       /* unable get link status using mii/ethtool */
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: can't get link status from "
                               "interface %s; the network driver associated "
-                              "with this interface does not support "
-                              "MII or ETHTOOL link status reporting, thus "
-                              "miimon has no effect on this interface.\n", 
+                              "with this interface does not support MII or "
+                              "ETHTOOL link status reporting, thus miimon "
+                              "has no effect on this interface.\n",
                               slave_dev->name);
                }
        }
 
        /* check for initial state */
-       if ((miimon <= 0) ||
+       if (!miimon ||
            (bond_check_dev_link(slave_dev, 0) == BMSR_LSTATUS)) {
                if (updelay) {
-#ifdef BONDING_DEBUG
-                       printk(KERN_CRIT "Initial state of slave_dev is "
-                              "BOND_LINK_BACK\n");
-#endif
+                       dprintk("Initial state of slave_dev is "
+                               "BOND_LINK_BACK\n");
                        new_slave->link  = BOND_LINK_BACK;
                        new_slave->delay = updelay;
-               }
-               else {
-#ifdef BONDING_DEBUG
-                       printk(KERN_DEBUG "Initial state of slave_dev is "
+               } else {
+                       dprintk("Initial state of slave_dev is "
                                "BOND_LINK_UP\n");
-#endif
                        new_slave->link  = BOND_LINK_UP;
                }
                new_slave->jiffies = jiffies;
-       }
-       else {
-#ifdef BONDING_DEBUG
-               printk(KERN_CRIT "Initial state of slave_dev is "
+       } else {
+               dprintk("Initial state of slave_dev is "
                        "BOND_LINK_DOWN\n");
-#endif
                new_slave->link  = BOND_LINK_DOWN;
        }
 
        if (bond_update_speed_duplex(new_slave) &&
            (new_slave->link != BOND_LINK_DOWN)) {
-
-               printk(KERN_WARNING
-                      "bond_enslave(): failed to get speed/duplex from %s, "
-                      "speed forced to 100Mbps, duplex forced to Full.\n",
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: failed to get speed/duplex from %s, speed "
+                      "forced to 100Mbps, duplex forced to Full.\n",
                       new_slave->dev->name);
+
                if (bond_mode == BOND_MODE_8023AD) {
                        printk(KERN_WARNING
-                              "Operation of 802.3ad mode requires ETHTOOL support "
-                              "in base driver for proper aggregator selection.\n");
+                              "Operation of 802.3ad mode requires ETHTOOL "
+                              "support in base driver for proper aggregator "
+                              "selection.\n");
                }
        }
 
-       /* if we're in active-backup mode, we need one and only one active
-        * interface. The backup interfaces will have their NOARP flag set
-        * because we need them to be completely deaf and not to respond to
-        * any ARP request on the network to avoid fooling a switch. Thus,
-        * since we guarantee that current_slave always point to the last
-        * usable interface, we just have to verify this interface's flag.
-        */
-       if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
-               if (((bond->current_slave == NULL)
-                       || (bond->current_slave->dev->flags & IFF_NOARP))
-                       && (new_slave->link != BOND_LINK_DOWN)) {
-#ifdef BONDING_DEBUG
-                       printk(KERN_CRIT "This is the first active slave\n");
-#endif
+       if (USES_PRIMARY(bond_mode) && primary) {
+               /* if there is a primary slave, remember it */
+               if (strcmp(primary, new_slave->dev->name) == 0) {
+                       bond->primary_slave = new_slave;
+               }
+       }
+
+       switch (bond_mode) {
+       case BOND_MODE_ACTIVEBACKUP:
+               /* if we're in active-backup mode, we need one and only one active
+                * interface. The backup interfaces will have their NOARP flag set
+                * because we need them to be completely deaf and not to respond to
+                * any ARP request on the network to avoid fooling a switch. Thus,
+                * since we guarantee that curr_active_slave always point to the last
+                * usable interface, we just have to verify this interface's flag.
+                */
+               if (((!bond->curr_active_slave) ||
+                    (bond->curr_active_slave->dev->flags & IFF_NOARP)) &&
+                   (new_slave->link != BOND_LINK_DOWN)) {
+                       dprintk("This is the first active slave\n");
                        /* first slave or no active slave yet, and this link
                           is OK, so make this interface the active one */
-                       change_active_interface(bond, new_slave);
-               }
-               else {
-#ifdef BONDING_DEBUG
-                       printk(KERN_CRIT "This is just a backup slave\n");
-#endif
+                       bond_change_active_slave(bond, new_slave);
+               } else {
+                       dprintk("This is just a backup slave\n");
                        bond_set_slave_inactive_flags(new_slave);
                }
-               if (((struct in_device *)slave_dev->ip_ptr) != NULL) {
-                       read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
-                       ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list);
-                       ifa = *ifap;
-                       if (ifa != NULL)
-                               my_ip = ifa->ifa_address;
-                       read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
-               }
-
-               /* if there is a primary slave, remember it */
-               if (primary != NULL) {
-                       if (strcmp(primary, new_slave->dev->name) == 0) {
-                               bond->primary_slave = new_slave;
-                       }
-               }
-       } else if (bond_mode == BOND_MODE_8023AD) {
+               break;
+       case BOND_MODE_8023AD:
                /* in 802.3ad mode, the internal mechanism
                 * will activate the slaves in the selected
                 * aggregator
                 */
                bond_set_slave_inactive_flags(new_slave);
                /* if this is the first slave */
-               if (new_slave == bond->next) {
+               if (bond->slave_cnt == 1) {
                        SLAVE_AD_INFO(new_slave).id = 1;
                        /* Initialize AD with the number of times that the AD timer is called in 1 second
                         * can be called only after the mac address of the bond is set
@@ -1645,40 +1450,37 @@ static int bond_enslave(struct net_device *master_dev,
                                            lacp_fast);
                } else {
                        SLAVE_AD_INFO(new_slave).id =
-                       SLAVE_AD_INFO(new_slave->prev).id + 1;
+                               SLAVE_AD_INFO(new_slave->prev).id + 1;
                }
 
                bond_3ad_bind_slave(new_slave);
-       } else if ((bond_mode == BOND_MODE_TLB) ||
-                  (bond_mode == BOND_MODE_ALB)) {
+               break;
+       case BOND_MODE_TLB:
+       case BOND_MODE_ALB:
                new_slave->state = BOND_STATE_ACTIVE;
-               if ((bond->current_slave == NULL) && (new_slave->link != BOND_LINK_DOWN)) {
+               if ((!bond->curr_active_slave) &&
+                   (new_slave->link != BOND_LINK_DOWN)) {
                        /* first slave or no active slave yet, and this link
                         * is OK, so make this interface the active one
                         */
-                       change_active_interface(bond, new_slave);
+                       bond_change_active_slave(bond, new_slave);
                }
+               break;
+       default:
+               dprintk("This slave is always active in trunk mode\n");
 
-               /* if there is a primary slave, remember it */
-               if (primary != NULL) {
-                       if (strcmp(primary, new_slave->dev->name) == 0) {
-                               bond->primary_slave = new_slave;
-                       }
-               }
-       } else {
-#ifdef BONDING_DEBUG
-               printk(KERN_CRIT "This slave is always active in trunk mode\n");
-#endif
                /* always active in trunk mode */
                new_slave->state = BOND_STATE_ACTIVE;
 
-               /* In trunking mode there is little meaning to current_slave
+               /* In trunking mode there is little meaning to curr_active_slave
                 * anyway (it holds no special properties of the bond device),
                 * so we can change it without calling change_active_interface()
                 */
-               if (bond->current_slave == NULL) 
-                       bond->current_slave = new_slave;
-       }
+               if (!bond->curr_active_slave) {
+                       bond->curr_active_slave = new_slave;
+               }
+               break;
+       } /* switch(bond_mode) */
 
        write_unlock_bh(&bond->lock);
 
@@ -1692,38 +1494,34 @@ static int bond_enslave(struct net_device *master_dev,
                 */
                int ndx = 0;
 
-               for (ndx = 0; ndx < slave_dev->addr_len; ndx++) {
-#ifdef BONDING_DEBUG
-                       printk(KERN_DEBUG
-                              "Checking ndx=%d of master_dev->dev_addr\n", ndx);
-#endif
-                       if (master_dev->dev_addr[ndx] != 0) {
-#ifdef BONDING_DEBUG
-                               printk(KERN_DEBUG
-                                      "Found non-zero byte at ndx=%d\n", ndx);
-#endif
+               for (ndx = 0; ndx < bond_dev->addr_len; ndx++) {
+                       dprintk("Checking ndx=%d of bond_dev->dev_addr\n",
+                               ndx);
+                       if (bond_dev->dev_addr[ndx] != 0) {
+                               dprintk("Found non-zero byte at ndx=%d\n",
+                                       ndx);
                                break;
                        }
                }
-               if (ndx == slave_dev->addr_len) {
+
+               if (ndx == bond_dev->addr_len) {
                        /*
                         * We got all the way through the address and it was
                         * all 0's.
                         */
-#ifdef BONDING_DEBUG
-                       printk(KERN_DEBUG "%s doesn't have a MAC address yet.  ",
-                              master_dev->name);
-                       printk(KERN_DEBUG "Going to give assign it from %s.\n",
-                              slave_dev->name);
-#endif
-                       bond_sethwaddr(master_dev, slave_dev);
+                       dprintk("%s doesn't have a MAC address yet.  \n",
+                               bond_dev->name);
+                       dprintk("Going to give assign it from %s.\n",
+                               slave_dev->name);
+                       bond_sethwaddr(bond_dev, slave_dev);
                }
        }
 
-       printk (KERN_INFO "%s: enslaving %s as a%s interface with a%s link.\n",
-               master_dev->name, slave_dev->name,
-               new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
-               new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
+       printk(KERN_INFO DRV_NAME
+              ": %s: enslaving %s as a%s interface with a%s link.\n",
+              bond_dev->name, slave_dev->name,
+              new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
+              new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
 
        /* enslave is successful */
        return 0;
@@ -1742,227 +1540,12 @@ err_restore_mac:
 
 err_free:
        kfree(new_slave);
-       return err;
-}
-
-/* 
- * This function changes the active slave to slave <slave_dev>.
- * It returns -EINVAL in the following cases.
- *  - <slave_dev> is not found in the list.
- *  - There is not active slave now.
- *  - <slave_dev> is already active.
- *  - The link state of <slave_dev> is not BOND_LINK_UP.
- *  - <slave_dev> is not running.
- * In these cases, this fuction does nothing.
- * In the other cases, currnt_slave pointer is changed and 0 is returned.
- */
-static int bond_change_active(struct net_device *master_dev, struct net_device *slave_dev)
-{
-       bonding_t *bond;
-       slave_t *slave;
-       slave_t *oldactive = NULL;
-       slave_t *newactive = NULL;
-       int ret = 0;
-
-       if (master_dev == NULL || slave_dev == NULL) {
-               return -ENODEV;
-       }
-
-       /* Verify that master_dev is indeed the master of slave_dev */
-       if (!(slave_dev->flags & IFF_SLAVE) ||
-           (slave_dev->master != master_dev)) {
-
-               return -EINVAL;
-       }
-
-       bond = (struct bonding *) master_dev->priv;
-       write_lock_bh(&bond->lock);
-       slave = (slave_t *)bond;
-       oldactive = bond->current_slave;
-
-       while ((slave = slave->prev) != (slave_t *)bond) {
-               if(slave_dev == slave->dev) {
-                       newactive = slave;
-                       break;
-               }
-       }
-
-       /*
-        * Changing to the current active: do nothing; return success.
-        */
-       if (newactive && (newactive == oldactive)) {
-               write_unlock_bh(&bond->lock);
-               return 0;
-       }
-
-       if ((newactive != NULL)&&
-           (oldactive != NULL)&&
-           (newactive->link == BOND_LINK_UP)&&
-           IS_UP(newactive->dev)) {
-               change_active_interface(bond, newactive);
-       } else {
-               ret = -EINVAL;
-       }
-       write_unlock_bh(&bond->lock);
-       return ret;
-}
-
-/**
- * find_best_interface - select the best available slave to be the active one
- * @bond: our bonding struct
- *
- * Warning: Caller must hold ptrlock for writing.
- */
-static struct slave *find_best_interface(struct bonding *bond)
-{
-       struct slave *newslave, *oldslave;
-       struct slave *bestslave = NULL;
-       int mintime;
-
-       newslave = oldslave = bond->current_slave;
-
-       if (newslave == NULL) { /* there were no active slaves left */
-               if (bond->next != (slave_t *)bond) {  /* found one slave */
-                       newslave = bond->next;
-               } else {
-                       return NULL; /* still no slave, return NULL */
-               }
-       }
-
-       mintime = updelay;
-
-       /* first try the primary link; if arping, a link must tx/rx traffic 
-        * before it can be considered the current_slave - also, we would skip 
-        * slaves between the current_slave and primary_slave that may be up 
-        * and able to arp
-        */
-       if ((bond->primary_slave != NULL) && (arp_interval == 0)) {
-               if (IS_UP(bond->primary_slave->dev)) 
-                       newslave = bond->primary_slave;
-       }
-
-       /* remember where to stop iterating over the slaves */
-       oldslave = newslave;
-
-       do {
-               if (IS_UP(newslave->dev)) {
-                       if (newslave->link == BOND_LINK_UP) {
-                               return newslave;
-                       }
-                       else if (newslave->link == BOND_LINK_BACK) {
-                               /* link up, but waiting for stabilization */
-                               if (newslave->delay < mintime) {
-                                       mintime = newslave->delay;
-                                       bestslave = newslave;
-                               }
-                       }
-               }
-       } while ((newslave = newslave->next) != oldslave);
-
-       return bestslave;
-}
-
-/**
- * change_active_interface - change the active slave into the specified one
- * @bond: our bonding struct
- * @new: the new slave to make the active one
- * 
- * Set the new slave to the bond's settings and unset them on the old
- * current_slave.
- * Setting include flags, mc-list, promiscuity, allmulti, etc.
- *
- * If @new's link state is %BOND_LINK_BACK we'll set it to %BOND_LINK_UP,
- * because it is apparently the best available slave we have, even though its
- * updelay hasn't timed out yet.
- *
- * Warning: Caller must hold ptrlock for writing.
- */
-static void change_active_interface(struct bonding *bond, struct slave *new)
-{
-       struct slave *old = bond->current_slave;
-
-       if (old == new) {
-               return;
-       }
-
-       if (new) {
-               if (new->link == BOND_LINK_BACK) {
-                       if (USES_PRIMARY(bond_mode)) {
-                               printk (KERN_INFO
-                                       "%s: making interface %s the new "
-                                       "active one %d ms earlier.\n",
-                                       bond->device->name, new->dev->name,
-                                       (updelay - new->delay) * miimon);
-                       }
-
-                       new->delay = 0;
-                       new->link = BOND_LINK_UP;
-                       new->jiffies = jiffies;
-
-                       if (bond_mode == BOND_MODE_8023AD) {
-                               bond_3ad_handle_link_change(new, BOND_LINK_UP);
-                       }
-
-                       if ((bond_mode == BOND_MODE_TLB) ||
-                           (bond_mode == BOND_MODE_ALB)) {
-                               bond_alb_handle_link_change(bond, new, BOND_LINK_UP);
-                       }
-               } else {
-                       if (USES_PRIMARY(bond_mode)) {
-                               printk (KERN_INFO
-                                       "%s: making interface %s the new active one.\n",
-                                       bond->device->name, new->dev->name);
-                       }
-               }
-       }
-
-       if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
-               if (old) {
-                       bond_set_slave_inactive_flags(old);
-               }
-
-               if (new) {
-                       bond_set_slave_active_flags(new);
-               }
-       }
-
-       if (USES_PRIMARY(bond_mode)) {
-               bond_mc_update(bond, new, old);
-       }
-
-       if ((bond_mode == BOND_MODE_TLB) ||
-           (bond_mode == BOND_MODE_ALB)) {
-               bond_alb_assign_current_slave(bond, new);
-       } else {
-               bond->current_slave = new;
-       }
-}
-
-/**
- * reselect_active_interface - select a new active slave, if needed
- * @bond: our bonding struct
- *
- * This functions shoud be called when one of the following occurs:
- * - The old current_slave has been released or lost its link.
- * - The primary_slave has got its link back.
- * - A slave has got its link back and there's no old current_slave.
- *
- * Warning: Caller must hold ptrlock for writing.
- */
-static void reselect_active_interface(struct bonding *bond)
-{
-       struct slave *best_slave;
-
-       best_slave = find_best_interface(bond);
-
-       if (best_slave != bond->current_slave) {
-               change_active_interface(bond, best_slave);
-       }
+       return res;
 }
 
 /*
  * Try to release the slave device <slave> from the bond device <master>
- * It is legal to access current_slave without a lock because all the function
+ * It is legal to access curr_active_slave without a lock because all the function
  * is write-locked.
  *
  * The rules for slave state should be:
@@ -1971,206 +1554,190 @@ static void reselect_active_interface(struct bonding *bond)
  *   for Bonded connections:
  *     The first up interface should be left on and all others downed.
  */
-static int bond_release(struct net_device *master, struct net_device *slave)
+static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 {
-       bonding_t *bond;
-       slave_t *our_slave, *old_current;
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave;
        struct sockaddr addr;
-       
-       if (master == NULL || slave == NULL)  {
-               return -ENODEV;
-       }
-
-       bond = (struct bonding *) master->priv;
+       int mac_addr_differ;
 
-       /* master already enslaved, or slave not enslaved,
-          or no slave for this master */
-       if ((master->flags & IFF_SLAVE) || !(slave->flags & IFF_SLAVE)) {
-               printk (KERN_DEBUG "%s: cannot release %s.\n", master->name, slave->name);
+       /* slave is not a slave or master is not master of this slave */
+       if (!(slave_dev->flags & IFF_SLAVE) ||
+           (slave_dev->master != bond_dev)) {
+               printk(KERN_ERR DRV_NAME
+                      ": Error: %s: cannot release %s.\n",
+                      bond_dev->name, slave_dev->name);
                return -EINVAL;
        }
 
        write_lock_bh(&bond->lock);
-       bond->current_arp_slave = NULL;
-       our_slave = (slave_t *)bond;
-       old_current = bond->current_slave;
-       while ((our_slave = our_slave->prev) != (slave_t *)bond) {
-               if (our_slave->dev == slave) {
-                       int mac_addr_differ = memcmp(bond->device->dev_addr,
-                                                our_slave->perm_hwaddr,
-                                                ETH_ALEN);
-                       if (!mac_addr_differ && (bond->slave_cnt > 1)) {
-                               printk(KERN_WARNING "WARNING: the permanent HWaddr of %s "
-                               "- %02X:%02X:%02X:%02X:%02X:%02X - "
-                               "is still in use by %s. Set the HWaddr "
-                               "of %s to a different address "
-                               "to avoid conflicts.\n",
-                                      slave->name,
-                                      our_slave->perm_hwaddr[0],
-                                      our_slave->perm_hwaddr[1],
-                                      our_slave->perm_hwaddr[2],
-                                      our_slave->perm_hwaddr[3],
-                                      our_slave->perm_hwaddr[4],
-                                      our_slave->perm_hwaddr[5],
-                                      bond->device->name,
-                                      slave->name);
-                       }
 
-                       /* Inform AD package of unbinding of slave. */
-                       if (bond_mode == BOND_MODE_8023AD) {
-                               /* must be called before the slave is
-                                * detached from the list
-                                */
-                               bond_3ad_unbind_slave(our_slave);
-                       }
+       slave = bond_get_slave_by_dev(bond, slave_dev);
+       if (!slave) {
+               /* not a slave of this bond */
+               printk(KERN_INFO DRV_NAME
+                      ": %s: %s not enslaved\n",
+                      bond_dev->name, slave_dev->name);
+               return -EINVAL;
+       }
 
-                       printk (KERN_INFO "%s: releasing %s interface %s\n",
-                               master->name,
-                               (our_slave->state == BOND_STATE_ACTIVE) ? "active" : "backup",
-                               slave->name);
+       mac_addr_differ = memcmp(bond_dev->dev_addr,
+                                slave->perm_hwaddr,
+                                ETH_ALEN);
+       if (!mac_addr_differ && (bond->slave_cnt > 1)) {
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: the permanent HWaddr of %s "
+                      "- %02X:%02X:%02X:%02X:%02X:%02X - is "
+                      "still in use by %s. Set the HWaddr of "
+                      "%s to a different address to avoid "
+                      "conflicts.\n",
+                      slave_dev->name,
+                      slave->perm_hwaddr[0],
+                      slave->perm_hwaddr[1],
+                      slave->perm_hwaddr[2],
+                      slave->perm_hwaddr[3],
+                      slave->perm_hwaddr[4],
+                      slave->perm_hwaddr[5],
+                      bond_dev->name,
+                      slave_dev->name);
+       }
+
+       /* Inform AD package of unbinding of slave. */
+       if (bond_mode == BOND_MODE_8023AD) {
+               /* must be called before the slave is
+                * detached from the list
+                */
+               bond_3ad_unbind_slave(slave);
+       }
 
-                       /* release the slave from its bond */
-                       bond_detach_slave(bond, our_slave);
+       printk(KERN_INFO DRV_NAME
+              ": %s: releasing %s interface %s\n",
+              bond_dev->name,
+              (slave->state == BOND_STATE_ACTIVE)
+              ? "active" : "backup",
+              slave_dev->name);
 
-                       if (bond->primary_slave == our_slave) {
-                               bond->primary_slave = NULL;
-                       }
+       bond->current_arp_slave = NULL;
 
-                       if (bond->current_slave == our_slave) {
-                               change_active_interface(bond, NULL);
-                               reselect_active_interface(bond);
-                       }
+       /* release the slave from its bond */
+       bond_detach_slave(bond, slave);
 
-                       if (bond->current_slave == NULL) {
-                               printk(KERN_INFO
-                                       "%s: now running without any active interface !\n",
-                                       master->name);
-                       }
+       if (bond->primary_slave == slave) {
+               bond->primary_slave = NULL;
+       }
 
-                       if ((bond_mode == BOND_MODE_TLB) ||
-                           (bond_mode == BOND_MODE_ALB)) {
-                               /* must be called only after the slave has been
-                                * detached from the list and the current_slave
-                                * has been replaced (if our_slave == old_current)
-                                */
-                               bond_alb_deinit_slave(bond, our_slave);
-                       }
+       if (bond->curr_active_slave == slave) {
+               bond_change_active_slave(bond, NULL);
+               bond_select_active_slave(bond);
+       }
 
-                       break;
-               }
+       if (!bond->curr_active_slave) {
+               printk(KERN_INFO DRV_NAME
+                      ": %s: now running without any active "
+                      "interface !\n",
+                      bond_dev->name);
+       }
 
+       if ((bond_mode == BOND_MODE_TLB) ||
+           (bond_mode == BOND_MODE_ALB)) {
+               /* must be called only after the slave has been
+                * detached from the list and the curr_active_slave
+                * has been replaced (if our_slave == old_current)
+                */
+               bond_alb_deinit_slave(bond, slave);
        }
+
        write_unlock_bh(&bond->lock);
-       
-       if (our_slave == (slave_t *)bond) {
-               /* if we get here, it's because the device was not found */
-               printk (KERN_INFO "%s: %s not enslaved\n", master->name, slave->name);
-               return -EINVAL;
-       }
 
-       /* unset promiscuity level from slave */
-       if (master->flags & IFF_PROMISC) {
-               /* If the mode USES_PRIMARY, then we should only remove its
-                * promisc settings if it was the current_slave, but that was
-                * already taken care of above when we detached the slave
-                */
-               if (!USES_PRIMARY(bond_mode)) {
-                       dev_set_promiscuity(slave, -1); 
+       /* If the mode USES_PRIMARY, then we should only remove its
+        * promisc and mc settings if it was the curr_active_slave, but that was
+        * already taken care of above when we detached the slave
+        */
+       if (!USES_PRIMARY(bond_mode)) {
+               /* unset promiscuity level from slave */
+               if (bond_dev->flags & IFF_PROMISC) {
+                       dev_set_promiscuity(slave_dev, -1);
                }
-       }
 
-       /* undo settings and restore original values */
-       if (multicast_mode == BOND_MULTICAST_ALL) {
-               /* flush master's mc_list from slave */ 
-               bond_mc_list_flush (slave, master); 
+               /* unset allmulti level from slave */
+               if (bond_dev->flags & IFF_ALLMULTI) {
+                       dev_set_allmulti(slave_dev, -1);
+               }
 
-               /* unset allmulti level from slave */ 
-               if (master->flags & IFF_ALLMULTI)
-                       dev_set_allmulti(slave, -1); 
+               /* flush master's mc_list from slave */
+               bond_mc_list_flush(bond_dev, slave_dev);
        }
 
-       netdev_set_master(slave, NULL);
+       netdev_set_master(slave_dev, NULL);
 
        /* close slave before restoring its mac address */
-       dev_close(slave);
+       dev_close(slave_dev);
 
        if (app_abi_ver >= 1) {
                /* restore original ("permanent") mac address */
-               memcpy(addr.sa_data, our_slave->perm_hwaddr, ETH_ALEN);
-               addr.sa_family = slave->type;
-               slave->set_mac_address(slave, &addr);
+               memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+               addr.sa_family = slave_dev->type;
+               slave_dev->set_mac_address(slave_dev, &addr);
        }
 
        /* restore the original state of the
         * IFF_NOARP flag that might have been
         * set by bond_set_slave_inactive_flags()
         */
-       if ((our_slave->original_flags & IFF_NOARP) == 0) {
-               slave->flags &= ~IFF_NOARP;
+       if ((slave->original_flags & IFF_NOARP) == 0) {
+               slave_dev->flags &= ~IFF_NOARP;
        }
 
-       kfree(our_slave);
+       kfree(slave);
 
        /* if the last slave was removed, zero the mac address
         * of the master so it will be set by the application
         * to the mac address of the first slave
         */
-       if (bond->next == (slave_t*)bond) {
-               memset(master->dev_addr, 0, master->addr_len);
+       if (bond->slave_cnt == 0) {
+               memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
        }
 
        return 0;  /* deletion OK */
 }
 
-/* 
+/*
  * This function releases all slaves.
  */
-static int bond_release_all(struct net_device *master)
+static int bond_release_all(struct net_device *bond_dev)
 {
-       bonding_t *bond;
-       slave_t *our_slave, *old_current;
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave;
        struct net_device *slave_dev;
        struct sockaddr addr;
-       int err = 0;
-
-       if (master == NULL)  {
-               return -ENODEV;
-       }
-
-       if (master->flags & IFF_SLAVE) {
-               return -EINVAL;
-       }
-
-       bond = (struct bonding *) master->priv;
 
        write_lock_bh(&bond->lock);
-       if (bond->next == (struct slave *) bond) {
-               err = -EINVAL;
+
+       if (bond->slave_cnt == 0) {
                goto out;
        }
 
-       old_current = bond->current_slave;
-       change_active_interface(bond, NULL);
        bond->current_arp_slave = NULL;
        bond->primary_slave = NULL;
+       bond_change_active_slave(bond, NULL);
 
-       while ((our_slave = bond->prev) != (slave_t *)bond) {
+       while ((slave = bond->first_slave) != NULL) {
                /* Inform AD package of unbinding of slave
                 * before slave is detached from the list.
                 */
                if (bond_mode == BOND_MODE_8023AD) {
-                       bond_3ad_unbind_slave(our_slave);
+                       bond_3ad_unbind_slave(slave);
                }
 
-               slave_dev = our_slave->dev;
-               bond_detach_slave(bond, our_slave);
+               slave_dev = slave->dev;
+               bond_detach_slave(bond, slave);
 
                if ((bond_mode == BOND_MODE_TLB) ||
                    (bond_mode == BOND_MODE_ALB)) {
                        /* must be called only after the slave
                         * has been detached from the list
                         */
-                       bond_alb_deinit_slave(bond, our_slave);
+                       bond_alb_deinit_slave(bond, slave);
                }
 
                /* now that the slave is detached, unlock and perform
@@ -2179,20 +1746,23 @@ static int bond_release_all(struct net_device *master)
                 */
                write_unlock_bh(&bond->lock);
 
-               /* unset promiscuity level from slave */
-               if (master->flags & IFF_PROMISC) {
-                       if (!USES_PRIMARY(bond_mode)) {
-                               dev_set_promiscuity(slave_dev, -1); 
+               /* If the mode USES_PRIMARY, then we should only remove its
+                * promisc and mc settings if it was the curr_active_slave, but that was
+                * already taken care of above when we detached the slave
+                */
+               if (!USES_PRIMARY(bond_mode)) {
+                       /* unset promiscuity level from slave */
+                       if (bond_dev->flags & IFF_PROMISC) {
+                               dev_set_promiscuity(slave_dev, -1);
                        }
-               }
 
-               if (multicast_mode == BOND_MULTICAST_ALL) {
-                       /* flush master's mc_list from slave */ 
-                       bond_mc_list_flush (slave_dev, master); 
+                       /* unset allmulti level from slave */
+                       if (bond_dev->flags & IFF_ALLMULTI) {
+                               dev_set_allmulti(slave_dev, -1);
+                       }
 
-                       /* unset allmulti level from slave */ 
-                       if (master->flags & IFF_ALLMULTI)
-                               dev_set_allmulti(slave_dev, -1); 
+                       /* flush master's mc_list from slave */
+                       bond_mc_list_flush(bond_dev, slave_dev);
                }
 
                netdev_set_master(slave_dev, NULL);
@@ -2202,7 +1772,7 @@ static int bond_release_all(struct net_device *master)
 
                if (app_abi_ver >= 1) {
                        /* restore original ("permanent") mac address*/
-                       memcpy(addr.sa_data, our_slave->perm_hwaddr, ETH_ALEN);
+                       memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
                        addr.sa_family = slave_dev->type;
                        slave_dev->set_mac_address(slave_dev, &addr);
                }
@@ -2210,11 +1780,11 @@ static int bond_release_all(struct net_device *master)
                /* restore the original state of the IFF_NOARP flag that might have
                 * been set by bond_set_slave_inactive_flags()
                 */
-               if ((our_slave->original_flags & IFF_NOARP) == 0) {
+               if ((slave->original_flags & IFF_NOARP) == 0) {
                        slave_dev->flags &= ~IFF_NOARP;
                }
 
-               kfree(our_slave);
+               kfree(slave);
 
                /* re-acquire the lock before getting the next slave */
                write_lock_bh(&bond->lock);
@@ -2224,72 +1794,234 @@ static int bond_release_all(struct net_device *master)
         * set by the application to the mac address of the
         * first slave
         */
-       memset(master->dev_addr, 0, master->addr_len);
+       memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-       printk (KERN_INFO "%s: released all slaves\n", master->name);
+       printk(KERN_INFO DRV_NAME
+              ": %s: released all slaves\n",
+              bond_dev->name);
 
 out:
        write_unlock_bh(&bond->lock);
 
-       return err;
+       return 0;
 }
 
+/*
+ * This function changes the active slave to slave <slave_dev>.
+ * It returns -EINVAL in the following cases.
+ *  - <slave_dev> is not found in the list.
+ *  - There is not active slave now.
+ *  - <slave_dev> is already active.
+ *  - The link state of <slave_dev> is not BOND_LINK_UP.
+ *  - <slave_dev> is not running.
+ * In these cases, this fuction does nothing.
+ * In the other cases, currnt_slave pointer is changed and 0 is returned.
+ */
+static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
+{
+       struct bonding *bond = bond_dev->priv;
+       struct slave *old_active = NULL;
+       struct slave *new_active = NULL;
+       int res = 0;
+
+       /* Verify that master_dev is indeed the master of slave_dev */
+       if (!(slave_dev->flags & IFF_SLAVE) ||
+           (slave_dev->master != bond_dev)) {
+               return -EINVAL;
+       }
+
+       write_lock_bh(&bond->lock);
+
+       old_active = bond->curr_active_slave;
+       new_active = bond_get_slave_by_dev(bond, slave_dev);
+
+       /*
+        * Changing to the current active: do nothing; return success.
+        */
+       if (new_active && (new_active == old_active)) {
+               write_unlock_bh(&bond->lock);
+               return 0;
+       }
+
+       if ((new_active) &&
+           (old_active) &&
+           (new_active->link == BOND_LINK_UP) &&
+           IS_UP(new_active->dev)) {
+               bond_change_active_slave(bond, new_active);
+       } else {
+               res = -EINVAL;
+       }
+
+       write_unlock_bh(&bond->lock);
+
+       return res;
+}
+
+static int bond_ethtool_ioctl(struct net_device *bond_dev, struct ifreq *ifr)
+{
+       struct ethtool_drvinfo info;
+       void *addr = ifr->ifr_data;
+       uint32_t cmd;
+
+       if (get_user(cmd, (uint32_t *)addr)) {
+               return -EFAULT;
+       }
+
+       switch (cmd) {
+       case ETHTOOL_GDRVINFO:
+               if (copy_from_user(&info, addr, sizeof(info))) {
+                       return -EFAULT;
+               }
+
+               if (strcmp(info.driver, "ifenslave") == 0) {
+                       int new_abi_ver;
+                       char *endptr;
+
+                       new_abi_ver = simple_strtoul(info.fw_version,
+                                                    &endptr, 0);
+                       if (*endptr) {
+                               printk(KERN_ERR DRV_NAME
+                                      ": Error: got invalid ABI "
+                                      "version from application\n");
+
+                               return -EINVAL;
+                       }
+
+                       if (orig_app_abi_ver == -1) {
+                               orig_app_abi_ver  = new_abi_ver;
+                       }
+
+                       app_abi_ver = new_abi_ver;
+               }
+
+               strncpy(info.driver,  DRV_NAME, 32);
+               strncpy(info.version, DRV_VERSION, 32);
+               snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
+
+               if (copy_to_user(addr, &info, sizeof(info))) {
+                       return -EFAULT;
+               }
+
+               return 0;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
+{
+       struct bonding *bond = bond_dev->priv;
+
+       info->bond_mode = bond_mode;
+       info->miimon = miimon;
+
+       read_lock_bh(&bond->lock);
+       info->num_slaves = bond->slave_cnt;
+       read_unlock_bh(&bond->lock);
+
+       return 0;
+}
+
+static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *info)
+{
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave;
+       int i, found = 0;
+
+       if (info->slave_id < 0) {
+               return -ENODEV;
+       }
+
+       read_lock_bh(&bond->lock);
+
+       bond_for_each_slave(bond, slave, i) {
+               if (i == (int)info->slave_id) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       read_unlock_bh(&bond->lock);
+
+       if (found) {
+               strcpy(info->slave_name, slave->dev->name);
+               info->link = slave->link;
+               info->state = slave->state;
+               info->link_failure_count = slave->link_failure_count;
+       } else {
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+/*-------------------------------- Monitoring -------------------------------*/
+
 /* this function is called regularly to monitor each slave's link. */
-static void bond_mii_monitor(struct net_device *master)
+static void bond_mii_monitor(struct net_device *bond_dev)
 {
-       bonding_t *bond = (struct bonding *) master->priv;
-       slave_t *slave, *oldcurrent;
-       int slave_died = 0;
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave, *oldcurrent;
        int do_failover = 0;
+       int delta_in_ticks = (miimon * HZ) / 1000;
+       int i;
 
        read_lock(&bond->lock);
 
+       if (bond->kill_timers) {
+               goto out;
+       }
+
+       if (bond->slave_cnt == 0) {
+               goto re_arm;
+       }
+
        /* we will try to read the link status of each of our slaves, and
         * set their IFF_RUNNING flag appropriately. For each slave not
         * supporting MII status, we won't do anything so that a user-space
         * program could monitor the link itself if needed.
         */
 
-       slave = (slave_t *)bond;
-
-       read_lock(&bond->ptrlock);
-       oldcurrent = bond->current_slave;
-       read_unlock(&bond->ptrlock);
+       read_lock(&bond->curr_slave_lock);
+       oldcurrent = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
 
-       while ((slave = slave->prev) != (slave_t *)bond) {
-               struct net_device *dev = slave->dev;
+       bond_for_each_slave(bond, slave, i) {
+               struct net_device *slave_dev = slave->dev;
                int link_state;
                u16 old_speed = slave->speed;
                u8 old_duplex = slave->duplex;
-               
-               link_state = bond_check_dev_link(dev, 0);
+
+               link_state = bond_check_dev_link(slave_dev, 0);
 
                switch (slave->link) {
                case BOND_LINK_UP:      /* the link was up */
                        if (link_state == BMSR_LSTATUS) {
                                /* link stays up, nothing more to do */
                                break;
-                       }
-                       else { /* link going down */
+                       } else { /* link going down */
                                slave->link  = BOND_LINK_FAIL;
                                slave->delay = downdelay;
+
                                if (slave->link_failure_count < UINT_MAX) {
                                        slave->link_failure_count++;
                                }
-                               if (downdelay > 0) {
-                                       printk (KERN_INFO
-                                               "%s: link status down for %sinterface "
-                                               "%s, disabling it in %d ms.\n",
-                                               master->name,
-                                               IS_UP(dev)
-                                               ? ((bond_mode == BOND_MODE_ACTIVEBACKUP)
-                                                  ? ((slave == oldcurrent)
-                                                     ? "active " : "backup ")
-                                                  : "")
-                                               : "idle ",
-                                               dev->name,
-                                               downdelay * miimon);
-                                       }
+
+                               if (downdelay) {
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: link status down for %s "
+                                              "interface %s, disabling it in "
+                                              "%d ms.\n",
+                                              bond_dev->name,
+                                              IS_UP(slave_dev)
+                                              ? ((bond_mode == BOND_MODE_ACTIVEBACKUP)
+                                                 ? ((slave == oldcurrent)
+                                                    ? "active " : "backup ")
+                                                 : "")
+                                              : "idle ",
+                                              slave_dev->name,
+                                              downdelay * miimon);
+                               }
                        }
                        /* no break ! fall through the BOND_LINK_FAIL test to
                           ensure proper action to be taken
@@ -2300,6 +2032,7 @@ static void bond_mii_monitor(struct net_device *master)
                                if (slave->delay <= 0) {
                                        /* link down for too long time */
                                        slave->link = BOND_LINK_DOWN;
+
                                        /* in active/backup mode, we must
                                         * completely disable this interface
                                         */
@@ -2308,11 +2041,12 @@ static void bond_mii_monitor(struct net_device *master)
                                                bond_set_slave_inactive_flags(slave);
                                        }
 
-                                       printk(KERN_INFO
-                                               "%s: link status definitely down "
-                                               "for interface %s, disabling it",
-                                               master->name,
-                                               dev->name);
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: link status definitely "
+                                              "down for interface %s, "
+                                              "disabling it\n",
+                                              bond_dev->name,
+                                              slave_dev->name);
 
                                        /* notify ad that the link status has changed */
                                        if (bond_mode == BOND_MODE_8023AD) {
@@ -2327,8 +2061,6 @@ static void bond_mii_monitor(struct net_device *master)
                                        if (slave == oldcurrent) {
                                                do_failover = 1;
                                        }
-
-                                       slave_died = 1;
                                } else {
                                        slave->delay--;
                                }
@@ -2336,12 +2068,12 @@ static void bond_mii_monitor(struct net_device *master)
                                /* link up again */
                                slave->link  = BOND_LINK_UP;
                                slave->jiffies = jiffies;
-                               printk(KERN_INFO
-                                       "%s: link status up again after %d ms "
-                                       "for interface %s.\n",
-                                       master->name,
-                                       (downdelay - slave->delay) * miimon,
-                                       dev->name);
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: link status up again after %d "
+                                      "ms for interface %s.\n",
+                                      bond_dev->name,
+                                      (downdelay - slave->delay) * miimon,
+                                      slave_dev->name);
                        }
                        break;
                case BOND_LINK_DOWN:    /* the link was down */
@@ -2351,16 +2083,17 @@ static void bond_mii_monitor(struct net_device *master)
                        } else {        /* link going up */
                                slave->link  = BOND_LINK_BACK;
                                slave->delay = updelay;
-                               
-                               if (updelay > 0) {
+
+                               if (updelay) {
                                        /* if updelay == 0, no need to
                                           advertise about a 0 ms delay */
-                                       printk (KERN_INFO
-                                               "%s: link status up for interface"
-                                               " %s, enabling it in %d ms.\n",
-                                               master->name,
-                                               dev->name,
-                                               updelay * miimon);
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: link status up for "
+                                              "interface %s, enabling it "
+                                              "in %d ms.\n",
+                                              bond_dev->name,
+                                              slave_dev->name,
+                                              updelay * miimon);
                                }
                        }
                        /* no break ! fall through the BOND_LINK_BACK state in
@@ -2370,12 +2103,13 @@ static void bond_mii_monitor(struct net_device *master)
                        if (link_state != BMSR_LSTATUS) {
                                /* link down again */
                                slave->link  = BOND_LINK_DOWN;
-                               printk(KERN_INFO
-                                       "%s: link status down again after %d ms "
-                                       "for interface %s.\n",
-                                       master->name,
-                                       (updelay - slave->delay) * miimon,
-                                       dev->name);
+
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: link status down again after %d "
+                                      "ms for interface %s.\n",
+                                      bond_dev->name,
+                                      (updelay - slave->delay) * miimon,
+                                      slave_dev->name);
                        } else {
                                /* link stays up */
                                if (slave->delay == 0) {
@@ -2386,8 +2120,7 @@ static void bond_mii_monitor(struct net_device *master)
                                        if (bond_mode == BOND_MODE_8023AD) {
                                                /* prevent it from being the active one */
                                                slave->state = BOND_STATE_BACKUP;
-                                       }
-                                       else if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
+                                       } else if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
                                                /* make it immediately active */
                                                slave->state = BOND_STATE_ACTIVE;
                                        } else if (slave != bond->primary_slave) {
@@ -2395,12 +2128,12 @@ static void bond_mii_monitor(struct net_device *master)
                                                slave->state = BOND_STATE_BACKUP;
                                        }
 
-                                       printk(KERN_INFO
-                                               "%s: link status definitely up "
-                                               "for interface %s.\n",
-                                               master->name,
-                                               dev->name);
-       
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: link status definitely "
+                                              "up for interface %s.\n",
+                                              bond_dev->name,
+                                              slave_dev->name);
+
                                        /* notify ad that the link status has changed */
                                        if (bond_mode == BOND_MODE_8023AD) {
                                                bond_3ad_handle_link_change(slave, BOND_LINK_UP);
@@ -2411,7 +2144,7 @@ static void bond_mii_monitor(struct net_device *master)
                                                bond_alb_handle_link_change(bond, slave, BOND_LINK_UP);
                                        }
 
-                                       if ((oldcurrent == NULL) ||
+                                       if ((!oldcurrent) ||
                                            (slave == bond->primary_slave)) {
                                                do_failover = 1;
                                        }
@@ -2420,7 +2153,12 @@ static void bond_mii_monitor(struct net_device *master)
                                }
                        }
                        break;
-               } /* end of switch */
+               default:
+                       /* Should not happen */
+                       printk(KERN_ERR "bonding: Error: %s  Illegal value (link=%d)\n",
+                              slave->dev->name, slave->link);
+                       goto out;
+               } /* end of switch (slave->link) */
 
                bond_update_speed_duplex(slave);
 
@@ -2428,112 +2166,110 @@ static void bond_mii_monitor(struct net_device *master)
                        if (old_speed != slave->speed) {
                                bond_3ad_adapter_speed_changed(slave);
                        }
+
                        if (old_duplex != slave->duplex) {
                                bond_3ad_adapter_duplex_changed(slave);
                        }
                }
 
-       } /* end of while */
+       } /* end of for */
 
        if (do_failover) {
-               write_lock(&bond->ptrlock);
+               write_lock(&bond->curr_slave_lock);
 
-               reselect_active_interface(bond);
-               if (oldcurrent && !bond->current_slave) {
-                       printk(KERN_INFO
-                               "%s: now running without any active interface !\n",
-                               master->name);
+               bond_select_active_slave(bond);
+
+               if (oldcurrent && !bond->curr_active_slave) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: now running without any active "
+                              "interface !\n",
+                              bond_dev->name);
                }
 
-               write_unlock(&bond->ptrlock);
+               write_unlock(&bond->curr_slave_lock);
        }
 
+re_arm:
+       mod_timer(&bond->mii_timer, jiffies + delta_in_ticks);
+out:
        read_unlock(&bond->lock);
-       /* re-arm the timer */
-       mod_timer(&bond->mii_timer, jiffies + (miimon * HZ / 1000));
 }
 
-/* 
- * this function is called regularly to monitor each slave's link 
+static void bond_arp_send_all(struct slave *slave)
+{
+       int i;
+
+       for (i = 0; (i<MAX_ARP_IP_TARGETS) && arp_target[i]; i++) {
+               arp_send(ARPOP_REQUEST, ETH_P_ARP, arp_target[i], slave->dev,
+                        my_ip, NULL, slave->dev->dev_addr,
+                        NULL);
+       }
+}
+
+/*
+ * this function is called regularly to monitor each slave's link
  * ensuring that traffic is being sent and received when arp monitoring
- * is used in load-balancing mode. if the adapter has been dormant, then an 
- * arp is transmitted to generate traffic. see activebackup_arp_monitor for 
- * arp monitoring in active backup mode. 
+ * is used in load-balancing mode. if the adapter has been dormant, then an
+ * arp is transmitted to generate traffic. see activebackup_arp_monitor for
+ * arp monitoring in active backup mode.
  */
-static void loadbalance_arp_monitor(struct net_device *master)
+static void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 {
-       bonding_t *bond;
-       slave_t *slave, *oldcurrent;
-       int the_delta_in_ticks =  arp_interval * HZ / 1000;
-       int next_timer = jiffies + (arp_interval * HZ / 1000);
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave, *oldcurrent;
        int do_failover = 0;
+       int delta_in_ticks = (arp_interval * HZ) / 1000;
+       int i;
 
-       bond = (struct bonding *) master->priv; 
-       if (master->priv == NULL) {
-               mod_timer(&bond->arp_timer, next_timer);
-               return;
-       }
+       read_lock(&bond->lock);
 
-       /* TODO: investigate why rtnl_shlock_nowait and rtnl_exlock_nowait
-        * are called below and add comment why they are required... 
-        */
-       if ((!IS_UP(master)) || rtnl_shlock_nowait()) {
-               mod_timer(&bond->arp_timer, next_timer);
-               return;
+       if (bond->kill_timers) {
+               goto out;
        }
 
-       if (rtnl_exlock_nowait()) {
-               rtnl_shunlock();
-               mod_timer(&bond->arp_timer, next_timer);
-               return;
+       if (bond->slave_cnt == 0) {
+               goto re_arm;
        }
 
-       read_lock(&bond->lock);
-
-       read_lock(&bond->ptrlock);
-       oldcurrent = bond->current_slave;
-       read_unlock(&bond->ptrlock);
+       read_lock(&bond->curr_slave_lock);
+       oldcurrent = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
 
        /* see if any of the previous devices are up now (i.e. they have
-        * xmt and rcv traffic). the current_slave does not come into
+        * xmt and rcv traffic). the curr_active_slave does not come into
         * the picture unless it is null. also, slave->jiffies is not needed
         * here because we send an arp on each slave and give a slave as
         * long as it needs to get the tx/rx within the delta.
         * TODO: what about up/down delay in arp mode? it wasn't here before
-        *       so it can wait 
+        *       so it can wait
         */
-       slave = (slave_t *)bond;
-       while ((slave = slave->prev) != (slave_t *)bond)  {
-
-               if (slave->link != BOND_LINK_UP) {
-
-                       if (((jiffies - slave->dev->trans_start) <= 
-                                               the_delta_in_ticks) &&  
-                            ((jiffies - slave->dev->last_rx) <= 
-                                               the_delta_in_ticks)) {
+       bond_for_each_slave(bond, slave, i) {
+               if (slave->link != BOND_LINK_UP) {
+                       if (((jiffies - slave->dev->trans_start) <= delta_in_ticks) &&
+                           ((jiffies - slave->dev->last_rx) <= delta_in_ticks)) {
 
                                slave->link  = BOND_LINK_UP;
                                slave->state = BOND_STATE_ACTIVE;
 
                                /* primary_slave has no meaning in round-robin
-                                * mode. the window of a slave being up and 
-                                * current_slave being null after enslaving
+                                * mode. the window of a slave being up and
+                                * curr_active_slave being null after enslaving
                                 * is closed.
                                 */
-                               if (oldcurrent == NULL) {
-                                       printk(KERN_INFO
-                                               "%s: link status definitely up "
-                                               "for interface %s, ",
-                                               master->name,
-                                               slave->dev->name);
+                               if (!oldcurrent) {
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: link status definitely "
+                                              "up for interface %s, ",
+                                              bond_dev->name,
+                                              slave->dev->name);
                                        do_failover = 1;
                                } else {
-                                       printk(KERN_INFO
-                                               "%s: interface %s is now up\n",
-                                               master->name,
-                                               slave->dev->name);
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: interface %s is now up\n",
+                                              bond_dev->name,
+                                              slave->dev->name);
                                }
-                       } 
+                       }
                } else {
                        /* slave->link == BOND_LINK_UP */
 
@@ -2541,224 +2277,233 @@ static void loadbalance_arp_monitor(struct net_device *master)
                         * when the source ip is 0, so don't take the link down
                         * if we don't know our ip yet
                         */
-                       if (((jiffies - slave->dev->trans_start) >= 
-                             (2*the_delta_in_ticks)) ||
-                            (((jiffies - slave->dev->last_rx) >= 
-                              (2*the_delta_in_ticks)) && my_ip !=0)) {
+                       if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
+                           (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
+                            my_ip)) {
+
                                slave->link  = BOND_LINK_DOWN;
                                slave->state = BOND_STATE_BACKUP;
+
                                if (slave->link_failure_count < UINT_MAX) {
                                        slave->link_failure_count++;
                                }
-                               printk(KERN_INFO
-                                      "%s: interface %s is now down.\n",
-                                      master->name,
+
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: interface %s is now down.\n",
+                                      bond_dev->name,
                                       slave->dev->name);
 
                                if (slave == oldcurrent) {
                                        do_failover = 1;
                                }
                        }
-               } 
+               }
 
-               /* note: if switch is in round-robin mode, all links 
+               /* note: if switch is in round-robin mode, all links
                 * must tx arp to ensure all links rx an arp - otherwise
-                * links may oscillate or not come up at all; if switch is 
-                * in something like xor mode, there is nothing we can 
-                * do - all replies will be rx'ed on same link causing slaves 
+                * links may oscillate or not come up at all; if switch is
+                * in something like xor mode, there is nothing we can
+                * do - all replies will be rx'ed on same link causing slaves
                 * to be unstable during low/no traffic periods
                 */
                if (IS_UP(slave->dev)) {
-                       arp_send_all(slave);
+                       bond_arp_send_all(slave);
                }
        }
 
        if (do_failover) {
-               write_lock(&bond->ptrlock);
+               write_lock(&bond->curr_slave_lock);
+
+               bond_select_active_slave(bond);
 
-               reselect_active_interface(bond);
-               if (oldcurrent && !bond->current_slave) {
-                       printk(KERN_INFO
-                               "%s: now running without any active interface !\n",
-                               master->name);
+               if (oldcurrent && !bond->curr_active_slave) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: now running without any active "
+                              "interface !\n",
+                              bond_dev->name);
                }
 
-               write_unlock(&bond->ptrlock);
+               write_unlock(&bond->curr_slave_lock);
        }
 
+re_arm:
+       mod_timer(&bond->arp_timer, jiffies + delta_in_ticks);
+out:
        read_unlock(&bond->lock);
-       rtnl_exunlock();
-       rtnl_shunlock();
-
-       /* re-arm the timer */
-       mod_timer(&bond->arp_timer, next_timer);
 }
 
-/* 
+/*
  * When using arp monitoring in active-backup mode, this function is
  * called to determine if any backup slaves have went down or a new
  * current slave needs to be found.
- * The backup slaves never generate traffic, they are considered up by merely 
- * receiving traffic. If the current slave goes down, each backup slave will 
- * be given the opportunity to tx/rx an arp before being taken down - this 
- * prevents all slaves from being taken down due to the current slave not 
+ * The backup slaves never generate traffic, they are considered up by merely
+ * receiving traffic. If the current slave goes down, each backup slave will
+ * be given the opportunity to tx/rx an arp before being taken down - this
+ * prevents all slaves from being taken down due to the current slave not
  * sending any traffic for the backups to receive. The arps are not necessarily
- * necessary, any tx and rx traffic will keep the current slave up. While any 
- * rx traffic will keep the backup slaves up, the current slave is responsible 
- * for generating traffic to keep them up regardless of any other traffic they 
+ * necessary, any tx and rx traffic will keep the current slave up. While any
+ * rx traffic will keep the backup slaves up, the current slave is responsible
+ * for generating traffic to keep them up regardless of any other traffic they
  * may have received.
  * see loadbalance_arp_monitor for arp monitoring in load balancing mode
  */
-static void activebackup_arp_monitor(struct net_device *master)
+static void bond_activebackup_arp_mon(struct net_device *bond_dev)
 {
-       bonding_t *bond;
-       slave_t *slave;
-       int the_delta_in_ticks =  arp_interval * HZ / 1000;
-       int next_timer = jiffies + (arp_interval * HZ / 1000);
-
-       bond = (struct bonding *) master->priv; 
-       if (master->priv == NULL) {
-               mod_timer(&bond->arp_timer, next_timer);
-               return;
-       }
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave;
+       int delta_in_ticks = (arp_interval * HZ) / 1000;
+       int i;
 
-       if (!IS_UP(master)) {
-               mod_timer(&bond->arp_timer, next_timer);
-               return;
+       read_lock(&bond->lock);
+
+       if (bond->kill_timers) {
+               goto out;
        }
 
-       read_lock(&bond->lock);
+       if (bond->slave_cnt == 0) {
+               goto re_arm;
+       }
 
-       /* determine if any slave has come up or any backup slave has 
-        * gone down 
+       /* determine if any slave has come up or any backup slave has
+        * gone down
         * TODO: what about up/down delay in arp mode? it wasn't here before
-        *       so it can wait 
+        *       so it can wait
         */
-       slave = (slave_t *)bond;
-       while ((slave = slave->prev) != (slave_t *)bond)  {
-
-               if (slave->link != BOND_LINK_UP) {
-                       if ((jiffies - slave->dev->last_rx) <=
-                           the_delta_in_ticks) {
+       bond_for_each_slave(bond, slave, i) {
+               if (slave->link != BOND_LINK_UP) {
+                       if ((jiffies - slave->dev->last_rx) <= delta_in_ticks) {
 
                                slave->link = BOND_LINK_UP;
-                               write_lock(&bond->ptrlock);
-                               if ((bond->current_slave == NULL) &&
-                                   ((jiffies - slave->dev->trans_start) <=
-                                    the_delta_in_ticks)) {
-                                       change_active_interface(bond, slave);
+
+                               write_lock(&bond->curr_slave_lock);
+
+                               if ((!bond->curr_active_slave) &&
+                                   ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) {
+                                       bond_change_active_slave(bond, slave);
                                        bond->current_arp_slave = NULL;
-                               } else if (bond->current_slave != slave) {
-                                       /* this slave has just come up but we 
+                               } else if (bond->curr_active_slave != slave) {
+                                       /* this slave has just come up but we
                                         * already have a current slave; this
                                         * can also happen if bond_enslave adds
-                                        * a new slave that is up while we are 
+                                        * a new slave that is up while we are
                                         * searching for a new slave
                                         */
                                        bond_set_slave_inactive_flags(slave);
                                        bond->current_arp_slave = NULL;
                                }
 
-                               if (slave == bond->current_slave) {
-                                       printk(KERN_INFO
-                                               "%s: %s is up and now the "
-                                               "active interface\n",
-                                               master->name,
-                                               slave->dev->name);
+                               if (slave == bond->curr_active_slave) {
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: %s is up and now the "
+                                              "active interface\n",
+                                              bond_dev->name,
+                                              slave->dev->name);
                                } else {
-                                       printk(KERN_INFO
-                                               "%s: backup interface %s is "
-                                               "now up\n",
-                                               master->name,
-                                               slave->dev->name);
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: backup interface %s is "
+                                              "now up\n",
+                                              bond_dev->name,
+                                              slave->dev->name);
                                }
 
-                               write_unlock(&bond->ptrlock);
+                               write_unlock(&bond->curr_slave_lock);
                        }
                } else {
-                       read_lock(&bond->ptrlock);
-                       if ((slave != bond->current_slave) &&
-                           (bond->current_arp_slave == NULL) &&
-                           (((jiffies - slave->dev->last_rx) >=
-                            3*the_delta_in_ticks) && (my_ip != 0))) {
-                               /* a backup slave has gone down; three times 
-                                * the delta allows the current slave to be 
+                       read_lock(&bond->curr_slave_lock);
+
+                       if ((slave != bond->curr_active_slave) &&
+                           (!bond->current_arp_slave) &&
+                           (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) &&
+                            my_ip)) {
+                               /* a backup slave has gone down; three times
+                                * the delta allows the current slave to be
                                 * taken out before the backup slave.
                                 * note: a non-null current_arp_slave indicates
-                                * the current_slave went down and we are 
-                                * searching for a new one; under this 
-                                * condition we only take the current_slave 
-                                * down - this gives each slave a chance to 
+                                * the curr_active_slave went down and we are
+                                * searching for a new one; under this
+                                * condition we only take the curr_active_slave
+                                * down - this gives each slave a chance to
                                 * tx/rx traffic before being taken out
                                 */
-                               read_unlock(&bond->ptrlock);
+
+                               read_unlock(&bond->curr_slave_lock);
+
                                slave->link  = BOND_LINK_DOWN;
+
                                if (slave->link_failure_count < UINT_MAX) {
                                        slave->link_failure_count++;
                                }
+
                                bond_set_slave_inactive_flags(slave);
-                               printk(KERN_INFO
-                                       "%s: backup interface %s is now down\n",
-                                       master->name,
-                                       slave->dev->name);
+
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: backup interface %s is now down\n",
+                                      bond_dev->name,
+                                      slave->dev->name);
                        } else {
-                               read_unlock(&bond->ptrlock);
+                               read_unlock(&bond->curr_slave_lock);
                        }
                }
        }
 
-       read_lock(&bond->ptrlock);
-       slave = bond->current_slave;
-       read_unlock(&bond->ptrlock);
-
-       if (slave != NULL) {
+       read_lock(&bond->curr_slave_lock);
+       slave = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
 
+       if (slave) {
                /* if we have sent traffic in the past 2*arp_intervals but
-                * haven't xmit and rx traffic in that time interval, select 
+                * haven't xmit and rx traffic in that time interval, select
                 * a different slave. slave->jiffies is only updated when
-                * a slave first becomes the current_slave - not necessarily
-                * after every arp; this ensures the slave has a full 2*delta 
-                * before being taken out. if a primary is being used, check 
-                * if it is up and needs to take over as the current_slave
+                * a slave first becomes the curr_active_slave - not necessarily
+                * after every arp; this ensures the slave has a full 2*delta
+                * before being taken out. if a primary is being used, check
+                * if it is up and needs to take over as the curr_active_slave
                 */
-               if ((((jiffies - slave->dev->trans_start) >= 
-                      (2*the_delta_in_ticks)) ||
-                    (((jiffies - slave->dev->last_rx) >= 
-                      (2*the_delta_in_ticks)) && (my_ip != 0))) &&
-                   ((jiffies - slave->jiffies) >= 2*the_delta_in_ticks)) {
+               if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
+                    (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
+                     my_ip)) &&
+                   ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) {
 
                        slave->link  = BOND_LINK_DOWN;
+
                        if (slave->link_failure_count < UINT_MAX) {
                                slave->link_failure_count++;
                        }
-                       printk(KERN_INFO "%s: link status down for "
-                                        "active interface %s, disabling it",
-                              master->name,
+
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: link status down for active interface "
+                              "%s, disabling it\n",
+                              bond_dev->name,
                               slave->dev->name);
-                       write_lock(&bond->ptrlock);
-                       reselect_active_interface(bond);
-                       slave = bond->current_slave;
-                       write_unlock(&bond->ptrlock);
+
+                       write_lock(&bond->curr_slave_lock);
+
+                       bond_select_active_slave(bond);
+                       slave = bond->curr_active_slave;
+
+                       write_unlock(&bond->curr_slave_lock);
+
                        bond->current_arp_slave = slave;
-                       if (slave != NULL) {
+
+                       if (slave) {
                                slave->jiffies = jiffies;
                        }
-
-               } else if ((bond->primary_slave != NULL) && 
-                          (bond->primary_slave != slave) && 
+               } else if ((bond->primary_slave) &&
+                          (bond->primary_slave != slave) &&
                           (bond->primary_slave->link == BOND_LINK_UP)) {
-                       /* at this point, slave is the current_slave */
-                       printk(KERN_INFO 
-                              "%s: changing from interface %s to primary "
+                       /* at this point, slave is the curr_active_slave */
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: changing from interface %s to primary "
                               "interface %s\n",
-                              master->name, 
-                              slave->dev->name, 
+                              bond_dev->name,
+                              slave->dev->name,
                               bond->primary_slave->dev->name);
-                              
+
                        /* primary is up so switch to it */
-                       write_lock(&bond->ptrlock);
-                       change_active_interface(bond, bond->primary_slave);
-                       write_unlock(&bond->ptrlock);
+                       write_lock(&bond->curr_slave_lock);
+                       bond_change_active_slave(bond, bond->primary_slave);
+                       write_unlock(&bond->curr_slave_lock);
+
                        slave = bond->primary_slave;
                        slave->jiffies = jiffies;
                } else {
@@ -2768,567 +2513,606 @@ static void activebackup_arp_monitor(struct net_device *master)
                /* the current slave must tx an arp to ensure backup slaves
                 * rx traffic
                 */
-               if ((slave != NULL) && (my_ip != 0)) {
-                       arp_send_all(slave);
+               if (slave && my_ip) {
+                       bond_arp_send_all(slave);
                }
        }
 
-       /* if we don't have a current_slave, search for the next available 
-        * backup slave from the current_arp_slave and make it the candidate 
-        * for becoming the current_slave
+       /* if we don't have a curr_active_slave, search for the next available
+        * backup slave from the current_arp_slave and make it the candidate
+        * for becoming the curr_active_slave
         */
-       if (slave == NULL) { 
-
-               if ((bond->current_arp_slave == NULL) ||
-                   (bond->current_arp_slave == (slave_t *)bond)) {
-                       bond->current_arp_slave = bond->prev;
-               } 
+       if (!slave) {
+               if (!bond->current_arp_slave) {
+                       bond->current_arp_slave = bond->first_slave;
+               }
 
-               if (bond->current_arp_slave != (slave_t *)bond) {
+               if (bond->current_arp_slave) {
                        bond_set_slave_inactive_flags(bond->current_arp_slave);
-                       slave = bond->current_arp_slave->next;
 
                        /* search for next candidate */
-                       do {
+                       bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave) {
                                if (IS_UP(slave->dev)) {
                                        slave->link = BOND_LINK_BACK;
                                        bond_set_slave_active_flags(slave);
-                                       arp_send_all(slave);
+                                       bond_arp_send_all(slave);
                                        slave->jiffies = jiffies;
                                        bond->current_arp_slave = slave;
                                        break;
                                }
 
-                               /* if the link state is up at this point, we 
-                                * mark it down - this can happen if we have 
-                                * simultaneous link failures and 
-                                * reselect_active_interface doesn't make this 
-                                * one the current slave so it is still marked 
+                               /* if the link state is up at this point, we
+                                * mark it down - this can happen if we have
+                                * simultaneous link failures and
+                                * reselect_active_interface doesn't make this
+                                * one the current slave so it is still marked
                                 * up when it is actually down
                                 */
                                if (slave->link == BOND_LINK_UP) {
                                        slave->link  = BOND_LINK_DOWN;
-                                       if (slave->link_failure_count < 
-                                                       UINT_MAX) {
+                                       if (slave->link_failure_count < UINT_MAX) {
                                                slave->link_failure_count++;
                                        }
 
                                        bond_set_slave_inactive_flags(slave);
-                                       printk(KERN_INFO
-                                               "%s: backup interface "
-                                               "%s is now down.\n",
-                                               master->name,
-                                               slave->dev->name);
+
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: backup interface %s is "
+                                              "now down.\n",
+                                              bond_dev->name,
+                                              slave->dev->name);
                                }
-                       } while ((slave = slave->next) != 
-                                       bond->current_arp_slave->next);
+                       }
                }
        }
 
+re_arm:
+       mod_timer(&bond->arp_timer, jiffies + delta_in_ticks);
+out:
        read_unlock(&bond->lock);
-       mod_timer(&bond->arp_timer, next_timer);
 }
 
-static int bond_sethwaddr(struct net_device *master, struct net_device *slave)
-{
-#ifdef BONDING_DEBUG
-       printk(KERN_CRIT "bond_sethwaddr: master=%x\n", (unsigned int)master);
-       printk(KERN_CRIT "bond_sethwaddr: slave=%x\n", (unsigned int)slave);
-       printk(KERN_CRIT "bond_sethwaddr: slave->addr_len=%d\n", slave->addr_len);
-#endif
-       memcpy(master->dev_addr, slave->dev_addr, slave->addr_len);
-       return 0;
-}
+/*------------------------------ proc/seq_file-------------------------------*/
 
-static int bond_info_query(struct net_device *master, struct ifbond *info)
-{
-       bonding_t *bond = (struct bonding *) master->priv;
-       slave_t *slave;
+#ifdef CONFIG_PROC_FS
 
-       info->bond_mode = bond_mode;
-       info->num_slaves = 0;
-       info->miimon = miimon;
+#define SEQ_START_TOKEN ((void *)1)
+
+static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       struct bonding *bond = seq->private;
+       loff_t off = 0;
+       struct slave *slave;
+       int i;
 
+       /* make sure the bond won't be taken away */
+       read_lock(&dev_base_lock);
        read_lock_bh(&bond->lock);
-       for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) {
-               info->num_slaves++;
+
+       if (*pos == 0) {
+               return SEQ_START_TOKEN;
        }
-       read_unlock_bh(&bond->lock);
 
-       return 0;
+       bond_for_each_slave(bond, slave, i) {
+               if (++off == *pos) {
+                       return slave;
+               }
+       }
+
+       return NULL;
 }
 
-static int bond_slave_info_query(struct net_device *master, 
-                                       struct ifslave *info)
+static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       bonding_t *bond = (struct bonding *) master->priv;
-       slave_t *slave;
-       int cur_ndx = 0;
-
-       if (info->slave_id < 0) {
-               return -ENODEV;
-       }
+       struct bonding *bond = seq->private;
+       struct slave *slave = v;
 
-       read_lock_bh(&bond->lock);
-       for (slave = bond->prev; 
-                slave != (slave_t *)bond && cur_ndx < info->slave_id; 
-                slave = slave->prev) {
-               cur_ndx++;
+       ++*pos;
+       if (v == SEQ_START_TOKEN) {
+               return bond->first_slave;
        }
-       read_unlock_bh(&bond->lock);
 
-       if (slave != (slave_t *)bond) {
-               strcpy(info->slave_name, slave->dev->name);
-               info->link = slave->link;
-               info->state = slave->state;
-               info->link_failure_count = slave->link_failure_count;
-       } else {
-               return -ENODEV;
-       }
+       slave = slave->next;
 
-       return 0;
+       return (slave == bond->first_slave) ? NULL : slave;
 }
 
-static int bond_ethtool_ioctl(struct net_device *master_dev, struct ifreq *ifr)
+static void bond_info_seq_stop(struct seq_file *seq, void *v)
 {
-       void *addr = ifr->ifr_data;
-       uint32_t cmd;
+       struct bonding *bond = seq->private;
 
-       if (get_user(cmd, (uint32_t *) addr))
-               return -EFAULT;
+       read_unlock_bh(&bond->lock);
+       read_unlock(&dev_base_lock);
+}
 
-       switch (cmd) {
+static void bond_info_show_master(struct seq_file *seq, struct bonding *bond)
+{
+       struct slave *curr;
 
-       case ETHTOOL_GDRVINFO:
-               {
-                       struct ethtool_drvinfo info;
-                       char *endptr;
+       read_lock(&bond->curr_slave_lock);
+       curr = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
 
-                       if (copy_from_user(&info, addr, sizeof(info)))
-                               return -EFAULT;
+       seq_printf(seq, "Bonding Mode: %s\n", bond_mode_name());
 
-                       if (strcmp(info.driver, "ifenslave") == 0) {
-                               int new_abi_ver;
+       if (USES_PRIMARY(bond_mode)) {
+               if (curr) {
+                       seq_printf(seq,
+                                  "Currently Active Slave: %s\n",
+                                  curr->dev->name);
+               }
+       }
 
-                               new_abi_ver = simple_strtoul(info.fw_version,
-                                                            &endptr, 0);
-                               if (*endptr) {
-                                       printk(KERN_ERR
-                                              "bonding: Error: got invalid ABI"
-                                              " version from application\n");
+       seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down");
+       seq_printf(seq, "MII Polling Interval (ms): %d\n", miimon);
+       seq_printf(seq, "Up Delay (ms): %d\n", updelay * miimon);
+       seq_printf(seq, "Down Delay (ms): %d\n", downdelay * miimon);
 
-                                       return -EINVAL;
-                               }
+       if (bond_mode == BOND_MODE_8023AD) {
+               struct ad_info ad_info;
 
-                               if (orig_app_abi_ver == -1) {
-                                       orig_app_abi_ver  = new_abi_ver;
-                               }
+               seq_puts(seq, "\n802.3ad info\n");
 
-                               app_abi_ver = new_abi_ver;
-                       }
+               if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
+                       seq_printf(seq, "bond %s has no active aggregator\n",
+                                  bond->dev->name);
+               } else {
+                       seq_printf(seq, "Active Aggregator Info:\n");
+
+                       seq_printf(seq, "\tAggregator ID: %d\n",
+                                  ad_info.aggregator_id);
+                       seq_printf(seq, "\tNumber of ports: %d\n",
+                                  ad_info.ports);
+                       seq_printf(seq, "\tActor Key: %d\n",
+                                  ad_info.actor_key);
+                       seq_printf(seq, "\tPartner Key: %d\n",
+                                  ad_info.partner_key);
+                       seq_printf(seq, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                                  ad_info.partner_system[0],
+                                  ad_info.partner_system[1],
+                                  ad_info.partner_system[2],
+                                  ad_info.partner_system[3],
+                                  ad_info.partner_system[4],
+                                  ad_info.partner_system[5]);
+               }
+       }
+}
 
-                       strncpy(info.driver,  DRV_NAME, 32);
-                       strncpy(info.version, DRV_VERSION, 32);
-                       snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
+static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
+{
+       seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
+       seq_printf(seq, "MII Status: %s\n",
+                  (slave->link == BOND_LINK_UP) ?  "up" : "down");
+       seq_printf(seq, "Link Failure Count: %d\n",
+                  slave->link_failure_count);
 
-                       if (copy_to_user(addr, &info, sizeof(info)))
-                               return -EFAULT;
+       if (app_abi_ver >= 1) {
+               seq_printf(seq,
+                          "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                          slave->perm_hwaddr[0],
+                          slave->perm_hwaddr[1],
+                          slave->perm_hwaddr[2],
+                          slave->perm_hwaddr[3],
+                          slave->perm_hwaddr[4],
+                          slave->perm_hwaddr[5]);
+       }
 
-                       return 0;
+       if (bond_mode == BOND_MODE_8023AD) {
+               const struct aggregator *agg
+                       = SLAVE_AD_INFO(slave).port.aggregator;
+
+               if (agg) {
+                       seq_printf(seq, "Aggregator ID: %d\n",
+                                  agg->aggregator_identifier);
+               } else {
+                       seq_puts(seq, "Aggregator ID: N/A\n");
                }
-               break;
-       default:
-               return -EOPNOTSUPP;
        }
 }
 
-static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd)
+static int bond_info_seq_show(struct seq_file *seq, void *v)
 {
-       struct net_device *slave_dev = NULL;
-       struct ifbond *u_binfo = NULL, k_binfo;
-       struct ifslave *u_sinfo = NULL, k_sinfo;
-       struct mii_ioctl_data *mii = NULL;
-       int prev_abi_ver = orig_app_abi_ver;
-       int ret = 0;
+       if (v == SEQ_START_TOKEN) {
+               seq_printf(seq, "%s\n", version);
+               bond_info_show_master(seq, seq->private);
+       } else {
+               bond_info_show_slave(seq, v);
+       }
 
-#ifdef BONDING_DEBUG
-       printk(KERN_INFO "bond_ioctl: master=%s, cmd=%d\n", 
-               master_dev->name, cmd);
-#endif
+       return 0;
+}
 
-       switch (cmd) {
-       case SIOCETHTOOL:
-               return bond_ethtool_ioctl(master_dev, ifr);
+static struct seq_operations bond_info_seq_ops = {
+       .start = bond_info_seq_start,
+       .next  = bond_info_seq_next,
+       .stop  = bond_info_seq_stop,
+       .show  = bond_info_seq_show,
+};
 
-       case SIOCGMIIPHY:
-               mii = (struct mii_ioctl_data *)&ifr->ifr_data;
-               if (mii == NULL) {
-                       return -EINVAL;
-               }
-               mii->phy_id = 0;
-               /* Fall Through */
-       case SIOCGMIIREG:
-               /* 
-                * We do this again just in case we were called by SIOCGMIIREG
-                * instead of SIOCGMIIPHY.
-                */
-               mii = (struct mii_ioctl_data *)&ifr->ifr_data;
-               if (mii == NULL) {
-                       return -EINVAL;
-               }
-               if (mii->reg_num == 1) {
-                       mii->val_out = bond_check_mii_link(
-                               (struct bonding *)master_dev->priv);
-               }
-               return 0;
-       case BOND_INFO_QUERY_OLD:
-       case SIOCBONDINFOQUERY:
-               u_binfo = (struct ifbond *)ifr->ifr_data;
-               if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
-                       return -EFAULT;
-               }
-               ret = bond_info_query(master_dev, &k_binfo);
-               if (ret == 0) {
-                       if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {
-                               return -EFAULT;
-                       }
+static int bond_info_open(struct inode *inode, struct file *file)
+{
+       struct seq_file *seq;
+       struct proc_dir_entry *proc;
+       int res;
+
+       res = seq_open(file, &bond_info_seq_ops);
+       if (!res) {
+               /* recover the pointer buried in proc_dir_entry data */
+               seq = file->private_data;
+               proc = PDE(inode);
+               seq->private = proc->data;
+       }
+
+       return res;
+}
+
+static struct file_operations bond_info_fops = {
+       .owner   = THIS_MODULE,
+       .open    = bond_info_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+
+static int bond_create_proc_entry(struct bonding *bond)
+{
+       struct net_device *bond_dev = bond->dev;
+
+       if (bond_proc_dir) {
+               bond->proc_entry = create_proc_entry(bond_dev->name,
+                                                    S_IRUGO,
+                                                    bond_proc_dir);
+               if (bond->proc_entry == NULL) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: Cannot create /proc/net/%s/%s\n",
+                              DRV_NAME, bond_dev->name);
+               } else {
+                       bond->proc_entry->data = bond;
+                       bond->proc_entry->proc_fops = &bond_info_fops;
+                       bond->proc_entry->owner = THIS_MODULE;
+                       memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
                }
-               return ret;
-       case BOND_SLAVE_INFO_QUERY_OLD:
-       case SIOCBONDSLAVEINFOQUERY:
-               u_sinfo = (struct ifslave *)ifr->ifr_data;
-               if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
-                       return -EFAULT;
+       }
+
+       return 0;
+}
+
+static void bond_remove_proc_entry(struct bonding *bond)
+{
+       if (bond_proc_dir && bond->proc_entry) {
+               remove_proc_entry(bond->proc_file_name, bond_proc_dir);
+               memset(bond->proc_file_name, 0, IFNAMSIZ);
+               bond->proc_entry = NULL;
+       }
+}
+
+/* Create the bonding directory under /proc/net, if doesn't exist yet.
+ * Caller must hold rtnl_lock.
+ */
+static void bond_create_proc_dir(void)
+{
+       int len = strlen(DRV_NAME);
+
+       for (bond_proc_dir = proc_net->subdir; bond_proc_dir;
+            bond_proc_dir = bond_proc_dir->next) {
+               if ((bond_proc_dir->namelen == len) &&
+                   !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
+                       break;
                }
-               ret = bond_slave_info_query(master_dev, &k_sinfo);
-               if (ret == 0) {
-                       if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {
-                               return -EFAULT;
-                       }
+       }
+
+       if (!bond_proc_dir) {
+               bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
+               if (bond_proc_dir) {
+                       bond_proc_dir->owner = THIS_MODULE;
+               } else {
+                       printk(KERN_WARNING DRV_NAME
+                               ": Warning: cannot create /proc/net/%s\n",
+                               DRV_NAME);
                }
-               return ret;
        }
+}
 
-       if (!capable(CAP_NET_ADMIN)) {
-               return -EPERM;
+/* Destroy the bonding directory under /proc/net, if empty.
+ * Caller must hold rtnl_lock.
+ */
+static void bond_destroy_proc_dir(void)
+{
+       struct proc_dir_entry *de;
+
+       if (!bond_proc_dir) {
+               return;
        }
 
-       if (orig_app_abi_ver == -1) {
-               /* no orig_app_abi_ver was provided yet, so we'll use the
-                * current one from now on, even if it's 0
-                */
-               orig_app_abi_ver = app_abi_ver;
+       /* verify that the /proc dir is empty */
+       for (de = bond_proc_dir->subdir; de; de = de->next) {
+               /* ignore . and .. */
+               if (*(de->name) != '.') {
+                       break;
+               }
+       }
 
-       } else if (orig_app_abi_ver != app_abi_ver) {
-               printk(KERN_ERR
-                      "bonding: Error: already using ifenslave ABI "
-                      "version %d; to upgrade ifenslave to version %d, "
-                      "you must first reload bonding.\n",
-                      orig_app_abi_ver, app_abi_ver);
-               return -EINVAL;
+       if (de) {
+               if (bond_proc_dir->owner == THIS_MODULE) {
+                       bond_proc_dir->owner = NULL;
+               }
+       } else {
+               remove_proc_entry(DRV_NAME, proc_net);
+               bond_proc_dir = NULL;
        }
+}
+#endif /* CONFIG_PROC_FS */
 
-       slave_dev = dev_get_by_name(ifr->ifr_slave);
+/*-------------------------- netdev event handling --------------------------*/
 
-#ifdef BONDING_DEBUG
-       printk(KERN_INFO "slave_dev=%x: \n", (unsigned int)slave_dev);
-       printk(KERN_INFO "slave_dev->name=%s: \n", slave_dev->name);
+/*
+ * Change device name
+ */
+static int bond_event_changename(struct bonding *bond)
+{
+#ifdef CONFIG_PROC_FS
+       bond_remove_proc_entry(bond);
+       bond_create_proc_entry(bond);
 #endif
 
-       if (slave_dev == NULL) {
-               ret = -ENODEV;
-       } else {
-               switch (cmd) {
-               case BOND_ENSLAVE_OLD:
-               case SIOCBONDENSLAVE:           
-                       ret = bond_enslave(master_dev, slave_dev);
-                       break;
-               case BOND_RELEASE_OLD:                  
-               case SIOCBONDRELEASE:   
-                       ret = bond_release(master_dev, slave_dev); 
-                       break;
-               case BOND_SETHWADDR_OLD:
-               case SIOCBONDSETHWADDR:
-                       ret = bond_sethwaddr(master_dev, slave_dev);
-                       break;
-               case BOND_CHANGE_ACTIVE_OLD:
-               case SIOCBONDCHANGEACTIVE:
-                       if (USES_PRIMARY(bond_mode)) {
-                               ret = bond_change_active(master_dev, slave_dev);
-                       }
-                       else {
-                               ret = -EINVAL;
-                       }
-                       break;
-               default:
-                       ret = -EOPNOTSUPP;
-               }
-               dev_put(slave_dev);
+       return NOTIFY_DONE;
+}
+
+static int bond_master_netdev_event(unsigned long event, struct net_device *bond_dev)
+{
+       struct bonding *event_bond = bond_dev->priv;
+
+       switch (event) {
+       case NETDEV_CHANGENAME:
+               return bond_event_changename(event_bond);
+       case NETDEV_UNREGISTER:
+               /*
+                * TODO: remove a bond from the list?
+                */
+               break;
+       default:
+               break;
        }
 
-       if (ret < 0) {
-               /* The ioctl failed, so there's no point in changing the
-                * orig_app_abi_ver. We'll restore it's value just in case
-                * we've changed it earlier in this function.
+       return NOTIFY_DONE;
+}
+
+static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
+{
+       struct net_device *bond_dev = slave_dev->master;
+
+       switch (event) {
+       case NETDEV_UNREGISTER:
+               if (bond_dev) {
+                       bond_release(bond_dev, slave_dev);
+               }
+               break;
+       case NETDEV_CHANGE:
+               /*
+                * TODO: is this what we get if somebody
+                * sets up a hierarchical bond, then rmmod's
+                * one of the slave bonding devices?
+                */
+               break;
+       case NETDEV_DOWN:
+               /*
+                * ... Or is it this?
+                */
+               break;
+       case NETDEV_CHANGEMTU:
+               /*
+                * TODO: Should slaves be allowed to
+                * independently alter their MTU?  For
+                * an active-backup bond, slaves need
+                * not be the same type of device, so
+                * MTUs may vary.  For other modes,
+                * slaves arguably should have the
+                * same MTUs. To do this, we'd need to
+                * take over the slave's change_mtu
+                * function for the duration of their
+                * servitude.
+                */
+               break;
+       case NETDEV_CHANGENAME:
+               /*
+                * TODO: handle changing the primary's name
                 */
-               orig_app_abi_ver = prev_abi_ver;
+               break;
+       default:
+               break;
        }
 
-       return ret;
-}
-
-#ifdef CONFIG_NET_FASTROUTE
-static int bond_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
-{
-       return -1;
+       return NOTIFY_DONE;
 }
-#endif
 
-/* 
- * in broadcast mode, we send everything to all usable interfaces.
+/*
+ * bond_netdev_event: handle netdev notifier chain events.
+ *
+ * This function receives events for the netdev chain.  The caller (an
+ * ioctl handler calling notifier_call_chain) holds the necessary
+ * locks for us to safely manipulate the slave devices (RTNL lock,
+ * dev_probe_lock).
  */
-static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *dev)
+static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
-       slave_t *slave, *start_at;
-       struct bonding *bond = (struct bonding *) dev->priv;
-       struct net_device *device_we_should_send_to = 0;
+       struct net_device *event_dev = (struct net_device *)ptr;
 
-       if (!IS_UP(dev)) { /* bond down */
-               dev_kfree_skb(skb);
-               return 0;
+       dprintk("event_dev: %s, event: %lx\n",
+               (event_dev ? event_dev->name : "None"),
+               event);
+
+       if (event_dev->flags & IFF_MASTER) {
+               dprintk("IFF_MASTER\n");
+               return bond_master_netdev_event(event, event_dev);
        }
 
-       read_lock(&bond->lock);
+       if (event_dev->flags & IFF_SLAVE) {
+               dprintk("IFF_SLAVE\n");
+               return bond_slave_netdev_event(event, event_dev);
+       }
 
-       read_lock(&bond->ptrlock);
-       slave = start_at = bond->current_slave;
-       read_unlock(&bond->ptrlock);
+       return NOTIFY_DONE;
+}
 
-       if (slave == NULL) { /* we're at the root, get the first slave */
-               /* no suitable interface, frame not sent */
-               read_unlock(&bond->lock);
-               dev_kfree_skb(skb);
-               return 0;
-       }
+static struct notifier_block bond_netdev_notifier = {
+       .notifier_call = bond_netdev_event,
+};
 
-       do {
-               if (IS_UP(slave->dev)
-                   && (slave->link == BOND_LINK_UP)
-                   && (slave->state == BOND_STATE_ACTIVE)) {
-                       if (device_we_should_send_to) {
-                               struct sk_buff *skb2;
-                               if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
-                                       printk(KERN_ERR "bond_xmit_broadcast: skb_clone() failed\n");
-                                       continue;
-                               }
+/*-------------------------- Packet type handling ---------------------------*/
 
-                               skb2->dev = device_we_should_send_to;
-                               skb2->priority = 1;
-                               dev_queue_xmit(skb2);
-                       }
-                       device_we_should_send_to = slave->dev;
-               }
-       } while ((slave = slave->next) != start_at);
+/* register to receive lacpdus on a bond */
+static void bond_register_lacpdu(struct bonding *bond)
+{
+       struct packet_type *pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
 
-       if (device_we_should_send_to) {
-               skb->dev = device_we_should_send_to;
-               skb->priority = 1;
-               dev_queue_xmit(skb);
-       } else
-               dev_kfree_skb(skb);
+       /* initialize packet type */
+       pk_type->type = PKT_TYPE_LACPDU;
+       pk_type->dev = bond->dev;
+       pk_type->func = bond_3ad_lacpdu_recv;
 
-       /* frame sent to all suitable interfaces */
-       read_unlock(&bond->lock);
-       return 0;
+       dev_add_pack(pk_type);
 }
 
-static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev)
+/* unregister to receive lacpdus on a bond */
+static void bond_unregister_lacpdu(struct bonding *bond)
 {
-       slave_t *slave, *start_at;
-       struct bonding *bond = (struct bonding *) dev->priv;
+       dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
+}
 
-       if (!IS_UP(dev)) { /* bond down */
-               dev_kfree_skb(skb);
-               return 0;
-       }
+/*-------------------------- Device entry points ----------------------------*/
 
-       read_lock(&bond->lock);
+static int bond_open(struct net_device *bond_dev)
+{
+       struct bonding *bond = bond_dev->priv;
+       struct timer_list *mii_timer = &bond->mii_timer;
+       struct timer_list *arp_timer = &bond->arp_timer;
 
-       read_lock(&bond->ptrlock);
-       slave = start_at = bond->current_slave;
-       read_unlock(&bond->ptrlock);
+       bond->kill_timers = 0;
 
-       if (slave == NULL) { /* we're at the root, get the first slave */
-               /* no suitable interface, frame not sent */
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
-       }
+       if ((bond_mode == BOND_MODE_TLB) ||
+           (bond_mode == BOND_MODE_ALB)) {
+               struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer);
 
-       do {
-               if (IS_UP(slave->dev)
-                   && (slave->link == BOND_LINK_UP)
-                   && (slave->state == BOND_STATE_ACTIVE)) {
+               /* bond_alb_initialize must be called before the timer
+                * is started.
+                */
+               if (bond_alb_initialize(bond, (bond_mode == BOND_MODE_ALB))) {
+                       /* something went wrong - fail the open operation */
+                       return -1;
+               }
 
-                       skb->dev = slave->dev;
-                       skb->priority = 1;
-                       dev_queue_xmit(skb);
+               init_timer(alb_timer);
+               alb_timer->expires  = jiffies + 1;
+               alb_timer->data     = (unsigned long)bond;
+               alb_timer->function = (void *)&bond_alb_monitor;
+               add_timer(alb_timer);
+       }
 
-                       write_lock(&bond->ptrlock);
-                       bond->current_slave = slave->next;
-                       write_unlock(&bond->ptrlock);
+       if (miimon) {  /* link check interval, in milliseconds. */
+               init_timer(mii_timer);
+               mii_timer->expires  = jiffies + 1;
+               mii_timer->data     = (unsigned long)bond_dev;
+               mii_timer->function = (void *)&bond_mii_monitor;
+               add_timer(mii_timer);
+       }
 
-                       read_unlock(&bond->lock);
-                       return 0;
+       if (arp_interval) {  /* arp interval, in milliseconds. */
+               init_timer(arp_timer);
+               arp_timer->expires  = jiffies + 1;
+               arp_timer->data     = (unsigned long)bond_dev;
+               if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+                       arp_timer->function = (void *)&bond_activebackup_arp_mon;
+               } else {
+                       arp_timer->function = (void *)&bond_loadbalance_arp_mon;
                }
-       } while ((slave = slave->next) != start_at);
+               add_timer(arp_timer);
+       }
+
+       if (bond_mode == BOND_MODE_8023AD) {
+               struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer);
+               init_timer(ad_timer);
+               ad_timer->expires  = jiffies + 1;
+               ad_timer->data     = (unsigned long)bond;
+               ad_timer->function = (void *)&bond_3ad_state_machine_handler;
+               add_timer(ad_timer);
+
+               /* register to receive LACPDUs */
+               bond_register_lacpdu(bond);
+       }
 
-       /* no suitable interface, frame not sent */
-       dev_kfree_skb(skb);
-       read_unlock(&bond->lock);
        return 0;
 }
 
-/* 
- * in XOR mode, we determine the output device by performing xor on
- * the source and destination hw adresses.  If this device is not 
- * enabled, find the next slave following this xor slave. 
- */
-static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev)
+static int bond_close(struct net_device *bond_dev)
 {
-       slave_t *slave, *start_at;
-       struct bonding *bond = (struct bonding *) dev->priv;
-       struct ethhdr *data = (struct ethhdr *)skb->data;
-       int slave_no;
+       struct bonding *bond = bond_dev->priv;
 
-       if (!IS_UP(dev)) { /* bond down */
-               dev_kfree_skb(skb);
-               return 0;
-       }
+       write_lock_bh(&bond->lock);
 
-       read_lock(&bond->lock);
-       slave = bond->prev;
+       bond_mc_list_destroy(bond);
 
-       /* we're at the root, get the first slave */
-       if (bond->slave_cnt == 0) {
-               /* no suitable interface, frame not sent */
-               dev_kfree_skb(skb);
-               read_unlock(&bond->lock);
-               return 0;
+       if (bond_mode == BOND_MODE_8023AD) {
+               /* Unregister the receive of LACPDUs */
+               bond_unregister_lacpdu(bond);
        }
 
-       slave_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % bond->slave_cnt;
+       /* signal timers not to re-arm */
+       bond->kill_timers = 1;
 
-       while ( (slave_no > 0) && (slave != (slave_t *)bond) ) {
-               slave = slave->prev;
-               slave_no--;
-       } 
-       start_at = slave;
-
-       do {
-               if (IS_UP(slave->dev)
-                   && (slave->link == BOND_LINK_UP)
-                   && (slave->state == BOND_STATE_ACTIVE)) {
-
-                       skb->dev = slave->dev;
-                       skb->priority = 1;
-                       dev_queue_xmit(skb);
-
-                       read_unlock(&bond->lock);
-                       return 0;
-               }
-       } while ((slave = slave->next) != start_at);
-
-       /* no suitable interface, frame not sent */
-       dev_kfree_skb(skb);
-       read_unlock(&bond->lock);
-       return 0;
-}
+       write_unlock_bh(&bond->lock);
 
-/* 
- * in active-backup mode, we know that bond->current_slave is always valid if
- * the bond has a usable interface.
- */
-static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev)
-{
-       struct bonding *bond = (struct bonding *) dev->priv;
-       int ret;
+       /* del_timer_sync must run without holding the bond->lock
+        * because a running timer might be trying to hold it too
+        */
 
-       if (!IS_UP(dev)) { /* bond down */
-               dev_kfree_skb(skb);
-               return 0;
+       if (miimon) {  /* link check interval, in milliseconds. */
+               del_timer_sync(&bond->mii_timer);
        }
 
-       /* if we are sending arp packets, try to at least 
-          identify our own ip address */
-       if ( (arp_interval > 0) && (my_ip == 0) &&
-               (skb->protocol == __constant_htons(ETH_P_ARP) ) ) {
-               char *the_ip = (((char *)skb->data)) 
-                               + sizeof(struct ethhdr)  
-                               + sizeof(struct arphdr) + 
-                               ETH_ALEN;
-               memcpy(&my_ip, the_ip, 4);
+       if (arp_interval) {  /* arp interval, in milliseconds. */
+               del_timer_sync(&bond->arp_timer);
        }
 
-       /* if we are sending arp packets and don't know 
-        * the target hw address, save it so we don't need 
-        * to use a broadcast address.
-        * don't do this if in active backup mode because the slaves must 
-        * receive packets to stay up, and the only ones they receive are 
-        * broadcasts. 
-        */
-       if ( (bond_mode != BOND_MODE_ACTIVEBACKUP) && 
-             (arp_ip_count == 1) &&
-            (arp_interval > 0) && (arp_target_hw_addr == NULL) &&
-            (skb->protocol == __constant_htons(ETH_P_IP) ) ) {
-               struct ethhdr *eth_hdr = 
-                       (struct ethhdr *) (((char *)skb->data));
-               struct iphdr *ip_hdr = (struct iphdr *)(eth_hdr + 1);
-
-               if (arp_target[0] == ip_hdr->daddr) {
-                       arp_target_hw_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
-                       if (arp_target_hw_addr != NULL)
-                               memcpy(arp_target_hw_addr, eth_hdr->h_dest, ETH_ALEN);
-               }
+       switch (bond_mode) {
+       case BOND_MODE_8023AD:
+               del_timer_sync(&(BOND_AD_INFO(bond).ad_timer));
+               break;
+       case BOND_MODE_TLB:
+       case BOND_MODE_ALB:
+               del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer));
+               break;
+       default:
+               break;
        }
 
-       read_lock(&bond->lock);
+       /* Release the bonded slaves */
+       bond_release_all(bond_dev);
 
-       read_lock(&bond->ptrlock);
-       if (bond->current_slave != NULL) { /* one usable interface */
-               skb->dev = bond->current_slave->dev;
-               read_unlock(&bond->ptrlock);
-               skb->priority = 1;
-               ret = dev_queue_xmit(skb);
-               read_unlock(&bond->lock);
-               return 0;
-       }
-       else {
-               read_unlock(&bond->ptrlock);
+       if ((bond_mode == BOND_MODE_TLB) ||
+           (bond_mode == BOND_MODE_ALB)) {
+               /* Must be called only after all
+                * slaves have been released
+                */
+               bond_alb_deinitialize(bond);
        }
 
-       /* no suitable interface, frame not sent */
-#ifdef BONDING_DEBUG
-       printk(KERN_INFO "There was no suitable interface, so we don't transmit\n");
-#endif
-       dev_kfree_skb(skb);
-       read_unlock(&bond->lock);
        return 0;
 }
 
-static struct net_device_stats *bond_get_stats(struct net_device *dev)
+static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
 {
-       bonding_t *bond = dev->priv;
+       struct bonding *bond = bond_dev->priv;
        struct net_device_stats *stats = &(bond->stats), *sstats;
-       slave_t *slave;
+       struct slave *slave;
+       int i;
 
        memset(stats, 0, sizeof(struct net_device_stats));
 
        read_lock_bh(&bond->lock);
 
-       for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) {
+       bond_for_each_slave(bond, slave, i) {
                sstats = slave->dev->get_stats(slave->dev);
+
                stats->rx_packets += sstats->rx_packets;
                stats->rx_bytes += sstats->rx_bytes;
                stats->rx_errors += sstats->rx_errors;
@@ -3346,290 +3130,294 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev)
                stats->rx_over_errors += sstats->rx_over_errors;
                stats->rx_crc_errors += sstats->rx_crc_errors;
                stats->rx_frame_errors += sstats->rx_frame_errors;
-               stats->rx_fifo_errors += sstats->rx_fifo_errors;        
+               stats->rx_fifo_errors += sstats->rx_fifo_errors;
                stats->rx_missed_errors += sstats->rx_missed_errors;
-       
+
                stats->tx_aborted_errors += sstats->tx_aborted_errors;
                stats->tx_carrier_errors += sstats->tx_carrier_errors;
                stats->tx_fifo_errors += sstats->tx_fifo_errors;
                stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
                stats->tx_window_errors += sstats->tx_window_errors;
-
        }
 
        read_unlock_bh(&bond->lock);
+
        return stats;
 }
 
-#ifdef CONFIG_PROC_FS
-
-#define SEQ_START_TOKEN ((void *)1)
-
-static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
+static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
 {
-       struct bonding *bond = seq->private;
-       loff_t off = 0;
-       struct slave *slave;
-
-       /* make sure the bond won't be taken away */
-       read_lock(&dev_base_lock);
-       read_lock_bh(&bond->lock);
-
-       if (*pos == 0) {
-               return SEQ_START_TOKEN;
-       }
+       struct net_device *slave_dev = NULL;
+       struct ifbond *u_binfo = NULL, k_binfo;
+       struct ifslave *u_sinfo = NULL, k_sinfo;
+       struct mii_ioctl_data *mii = NULL;
+       int prev_abi_ver = orig_app_abi_ver;
+       int res = 0;
 
-       for (slave = bond->prev; slave != (slave_t *)bond;
-            slave = slave->prev) {
+       dprintk("bond_ioctl: master=%s, cmd=%d\n",
+               bond_dev->name, cmd);
 
-               if (++off == *pos) {
-                       return slave;
+       switch (cmd) {
+       case SIOCETHTOOL:
+               return bond_ethtool_ioctl(bond_dev, ifr);
+       case SIOCGMIIPHY:
+               mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+               if (!mii) {
+                       return -EINVAL;
+               }
+               mii->phy_id = 0;
+               /* Fall Through */
+       case SIOCGMIIREG:
+               /*
+                * We do this again just in case we were called by SIOCGMIIREG
+                * instead of SIOCGMIIPHY.
+                */
+               mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+               if (!mii) {
+                       return -EINVAL;
                }
-       }
-
-       return NULL;
-}
-
-static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-       struct bonding *bond = seq->private;
-       struct slave *slave = v;
-
-       ++*pos;
-       if (v == SEQ_START_TOKEN) {
-               slave = bond->prev;
-       } else {
-               slave = slave->prev;
-       }
-
-       return (slave == (struct slave *) bond) ? NULL : slave;
-}
-
-static void bond_info_seq_stop(struct seq_file *seq, void *v)
-{
-       struct bonding *bond = seq->private;
-
-       read_unlock_bh(&bond->lock);
-       read_unlock(&dev_base_lock);
-}
-
-static void bond_info_show_master(struct seq_file *seq, struct bonding *bond)
-{
-       struct slave *curr;
 
-       read_lock(&bond->ptrlock);
-       curr = bond->current_slave;
-       read_unlock(&bond->ptrlock);
+               if (mii->reg_num == 1) {
+                       struct bonding *bond = bond_dev->priv;
+                       mii->val_out = 0;
+                       read_lock_bh(&bond->lock);
+                       read_lock(&bond->curr_slave_lock);
+                       if (bond->curr_active_slave) {
+                               mii->val_out = BMSR_LSTATUS;
+                       }
+                       read_unlock(&bond->curr_slave_lock);
+                       read_unlock_bh(&bond->lock);
+               }
 
-       seq_printf(seq, "Bonding Mode: %s\n", bond_mode_name());
+               return 0;
+       case BOND_INFO_QUERY_OLD:
+       case SIOCBONDINFOQUERY:
+               u_binfo = (struct ifbond *)ifr->ifr_data;
 
-       if (USES_PRIMARY(bond_mode)) {
-               if (curr) {
-                       seq_printf(seq,
-                                  "Currently Active Slave: %s\n",
-                                  curr->dev->name);
+               if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
+                       return -EFAULT;
                }
-       }
-
-       seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down");
-       seq_printf(seq, "MII Polling Interval (ms): %d\n", miimon);
-       seq_printf(seq, "Up Delay (ms): %d\n", updelay * miimon);
-       seq_printf(seq, "Down Delay (ms): %d\n", downdelay * miimon);
-       seq_printf(seq, "Multicast Mode: %s\n", multicast_mode_name());
 
-       if (bond_mode == BOND_MODE_8023AD) {
-               struct ad_info ad_info;
+               res = bond_info_query(bond_dev, &k_binfo);
+               if (res == 0) {
+                       if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {
+                               return -EFAULT;
+                       }
+               }
 
-               seq_puts(seq, "\n802.3ad info\n");
+               return res;
+       case BOND_SLAVE_INFO_QUERY_OLD:
+       case SIOCBONDSLAVEINFOQUERY:
+               u_sinfo = (struct ifslave *)ifr->ifr_data;
 
-               if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
-                       seq_printf(seq, "bond %s has no active aggregator\n",
-                                  bond->device->name);
-               } else {
-                       seq_printf(seq, "Active Aggregator Info:\n");
+               if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
+                       return -EFAULT;
+               }
 
-                       seq_printf(seq, "\tAggregator ID: %d\n",
-                                  ad_info.aggregator_id);
-                       seq_printf(seq, "\tNumber of ports: %d\n",
-                                  ad_info.ports);
-                       seq_printf(seq, "\tActor Key: %d\n",
-                                  ad_info.actor_key);
-                       seq_printf(seq, "\tPartner Key: %d\n",
-                                  ad_info.partner_key);
-                       seq_printf(seq, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                  ad_info.partner_system[0],
-                                  ad_info.partner_system[1],
-                                  ad_info.partner_system[2],
-                                  ad_info.partner_system[3],
-                                  ad_info.partner_system[4],
-                                  ad_info.partner_system[5]);
+               res = bond_slave_info_query(bond_dev, &k_sinfo);
+               if (res == 0) {
+                       if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {
+                               return -EFAULT;
+                       }
                }
+
+               return res;
+       default:
+               /* Go on */
+               break;
        }
-}
 
-static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
-{
-       seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
-       seq_printf(seq, "MII Status: %s\n",
-                  (slave->link == BOND_LINK_UP) ?  "up" : "down");
-       seq_printf(seq, "Link Failure Count: %d\n",
-                  slave->link_failure_count);
+       if (!capable(CAP_NET_ADMIN)) {
+               return -EPERM;
+       }
 
-       if (app_abi_ver >= 1) {
-               seq_printf(seq,
-                          "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                          slave->perm_hwaddr[0],
-                          slave->perm_hwaddr[1],
-                          slave->perm_hwaddr[2],
-                          slave->perm_hwaddr[3],
-                          slave->perm_hwaddr[4],
-                          slave->perm_hwaddr[5]);
+       if (orig_app_abi_ver == -1) {
+               /* no orig_app_abi_ver was provided yet, so we'll use the
+                * current one from now on, even if it's 0
+                */
+               orig_app_abi_ver = app_abi_ver;
+
+       } else if (orig_app_abi_ver != app_abi_ver) {
+               printk(KERN_ERR DRV_NAME
+                      ": Error: already using ifenslave ABI version %d; to "
+                      "upgrade ifenslave to version %d, you must first "
+                      "reload bonding.\n",
+                      orig_app_abi_ver, app_abi_ver);
+               return -EINVAL;
        }
 
-       if (bond_mode == BOND_MODE_8023AD) {
-               const struct aggregator *agg
-                       = SLAVE_AD_INFO(slave).port.aggregator;
+       slave_dev = dev_get_by_name(ifr->ifr_slave);
 
-               if (agg) {
-                       seq_printf(seq, "Aggregator ID: %d\n",
-                                  agg->aggregator_identifier);
-               } else {
-                       seq_puts(seq, "Aggregator ID: N/A\n");
+       dprintk("slave_dev=%p: \n", slave_dev);
+
+       if (!slave_dev) {
+               res = -ENODEV;
+       } else {
+               dprintk("slave_dev->name=%s: \n", slave_dev->name);
+               switch (cmd) {
+               case BOND_ENSLAVE_OLD:
+               case SIOCBONDENSLAVE:
+                       res = bond_enslave(bond_dev, slave_dev);
+                       break;
+               case BOND_RELEASE_OLD:
+               case SIOCBONDRELEASE:
+                       res = bond_release(bond_dev, slave_dev);
+                       break;
+               case BOND_SETHWADDR_OLD:
+               case SIOCBONDSETHWADDR:
+                       res = bond_sethwaddr(bond_dev, slave_dev);
+                       break;
+               case BOND_CHANGE_ACTIVE_OLD:
+               case SIOCBONDCHANGEACTIVE:
+                       if (USES_PRIMARY(bond_mode)) {
+                               res = bond_ioctl_change_active(bond_dev, slave_dev);
+                       } else {
+                               res = -EINVAL;
+                       }
+                       break;
+               default:
+                       res = -EOPNOTSUPP;
                }
+
+               dev_put(slave_dev);
        }
-}
 
-static int bond_info_seq_show(struct seq_file *seq, void *v)
-{
-       if (v == SEQ_START_TOKEN) {
-               seq_printf(seq, "%s\n", version);
-               bond_info_show_master(seq, seq->private);
-       } else {
-               bond_info_show_slave(seq, v);
+       if (res < 0) {
+               /* The ioctl failed, so there's no point in changing the
+                * orig_app_abi_ver. We'll restore it's value just in case
+                * we've changed it earlier in this function.
+                */
+               orig_app_abi_ver = prev_abi_ver;
        }
 
-       return 0;
+       return res;
 }
 
-static struct seq_operations bond_info_seq_ops = {
-       .start = bond_info_seq_start,
-       .next  = bond_info_seq_next,
-       .stop  = bond_info_seq_stop,
-       .show  = bond_info_seq_show,
-};
-
-static int bond_info_open(struct inode *inode, struct file *file)
+static void bond_set_multicast_list(struct net_device *bond_dev)
 {
-       struct seq_file *seq;
-       struct proc_dir_entry *proc;
-       int rc;
-
-       rc = seq_open(file, &bond_info_seq_ops);
-       if (!rc) {
-               /* recover the pointer buried in proc_dir_entry data */
-               seq = file->private_data;
-               proc = PDE(inode);
-               seq->private = proc->data;
-       }
-       return rc;
-}
+       struct bonding *bond = bond_dev->priv;
+       struct dev_mc_list *dmi;
 
-static struct file_operations bond_info_fops = {
-       .owner   = THIS_MODULE,
-       .open    = bond_info_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = seq_release,
-};
+       write_lock_bh(&bond->lock);
 
-static int bond_create_proc_info(struct bonding *bond)
-{
-       struct net_device *dev = bond->device;
+       /*
+        * Do promisc before checking multicast_mode
+        */
+       if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
+               bond_set_promiscuity(bond, 1);
+       }
 
-       if (bond_proc_dir) {
-               bond->bond_proc_file = create_proc_entry(dev->name,
-                                                        S_IRUGO, 
-                                                        bond_proc_dir);
-               if (bond->bond_proc_file == NULL) {
-                       printk(KERN_WARNING
-                              "%s: Cannot create /proc/net/bonding/%s\n", 
-                              dev->name, dev->name);
-               } else {
-                       bond->bond_proc_file->data = bond;
-                       bond->bond_proc_file->proc_fops = &bond_info_fops;
-                       bond->bond_proc_file->owner = THIS_MODULE;
-                       memcpy(bond->procdir_name, dev->name, IFNAMSIZ);
-               }
+       if (!(bond_dev->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC)) {
+               bond_set_promiscuity(bond, -1);
        }
 
-       return 0;
-}
+       /* set allmulti flag to slaves */
+       if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) {
+               bond_set_allmulti(bond, 1);
+       }
 
-static void bond_destroy_proc_info(struct bonding *bond)
-{
-       if (bond_proc_dir && bond->bond_proc_file) {
-               remove_proc_entry(bond->procdir_name, bond_proc_dir);
-               memset(bond->procdir_name, 0, IFNAMSIZ);
-               bond->bond_proc_file = NULL;
+       if (!(bond_dev->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI)) {
+               bond_set_allmulti(bond, -1);
        }
-}
 
-/* Create the bonding directory under /proc/net, if doesn't exist yet.
- * Caller must hold rtnl_lock.
- */
-static void bond_create_proc_dir(void)
-{
-       int len = strlen(DRV_NAME);
+       bond->flags = bond_dev->flags;
 
-       for (bond_proc_dir = proc_net->subdir; bond_proc_dir;
-            bond_proc_dir = bond_proc_dir->next) {
-               if ((bond_proc_dir->namelen == len) &&
-                   !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
-                       break;
+       /* looking for addresses to add to slaves' mc list */
+       for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
+               if (!bond_mc_list_find_dmi(dmi, bond->mc_list)) {
+                       bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen);
                }
        }
 
-       if (!bond_proc_dir) {
-               bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
-               if (bond_proc_dir) {
-                       bond_proc_dir->owner = THIS_MODULE;
-               } else {
-                       printk(KERN_WARNING DRV_NAME
-                               ": Warning: cannot create /proc/net/%s\n",
-                               DRV_NAME);
+       /* looking for addresses to delete from slaves' list */
+       for (dmi = bond->mc_list; dmi; dmi = dmi->next) {
+               if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list)) {
+                       bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen);
                }
        }
+
+       /* save master's multicast list */
+       bond_mc_list_destroy(bond);
+       bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC);
+
+       write_unlock_bh(&bond->lock);
 }
 
-/* Destroy the bonding directory under /proc/net, if empty.
- * Caller must hold rtnl_lock.
+/*
+ * Change the MTU of all of a master's slaves to match the master
  */
-static void bond_destroy_proc_dir(void)
+static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
 {
-       struct proc_dir_entry *de;
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave, *stop_at;
+       int res = 0;
+       int i;
 
-       if (!bond_proc_dir) {
-               return;
-       }
+       dprintk("bond=%p, name=%s, new_mtu=%d\n", bond,
+               (bond_dev ? bond_dev->name : "None"), new_mtu);
+
+       /* Can't hold bond->lock with bh disabled here since
+        * some base drivers panic. On the other hand we can't
+        * hold bond->lock without bh disabled because we'll
+        * deadlock. The only solution is to rely on the fact
+        * that we're under rtnl_lock here, and the slaves
+        * list won't change. This doesn't solve the problem
+        * of setting the slave's MTU while it is
+        * transmitting, but the assumption is that the base
+        * driver can handle that.
+        *
+        * TODO: figure out a way to safely iterate the slaves
+        * list, but without holding a lock around the actual
+        * call to the base driver.
+        */
 
-       /* verify that the /proc dir is empty */
-       for (de = bond_proc_dir->subdir; de; de = de->next) {
-               /* ignore . and .. */
-               if (*(de->name) != '.') {
-                       break;
+       bond_for_each_slave(bond, slave, i) {
+               dprintk("s %p s->p %p c_m %p\n", slave,
+                       slave->prev, slave->dev->change_mtu);
+               if (slave->dev->change_mtu) {
+                       res = slave->dev->change_mtu(slave->dev, new_mtu);
+               } else {
+                       slave->dev->mtu = new_mtu;
+                       res = 0;
+               }
+
+               if (res) {
+                       /* If we failed to set the slave's mtu to the new value
+                        * we must abort the operation even in ACTIVE_BACKUP
+                        * mode, because if we allow the backup slaves to have
+                        * different mtu values than the active slave we'll
+                        * need to change their mtu when doing a failover. That
+                        * means changing their mtu from timer context, which
+                        * is probably not a good idea.
+                        */
+                       dprintk("err %d %s\n", res, slave->dev->name);
+                       goto unwind;
                }
        }
 
-       if (de) {
-               if (bond_proc_dir->owner == THIS_MODULE) {
-                       bond_proc_dir->owner = NULL;
+       bond_dev->mtu = new_mtu;
+
+       return 0;
+
+unwind:
+       /* unwind from head to the slave that failed */
+       stop_at = slave;
+       bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
+               int tmp_res;
+
+               if (slave->dev->change_mtu) {
+                       tmp_res = slave->dev->change_mtu(slave->dev, bond_dev->mtu);
+                       if (tmp_res) {
+                               dprintk("unwind err %d dev %s\n", tmp_res,
+                                       slave->dev->name);
+                       }
+               } else {
+                       slave->dev->mtu = bond_dev->mtu;
                }
-       } else {
-               remove_proc_entry(DRV_NAME, proc_net);
-               bond_proc_dir = NULL;
        }
+
+       return res;
 }
-#endif /* CONFIG_PROC_FS */
 
 /*
  * Change HW address
@@ -3638,352 +3426,366 @@ static void bond_destroy_proc_dir(void)
  * downing the master releases all slaves.  We can make bonds full of
  * bonding devices to test this, however.
  */
-static inline int
-bond_set_mac_address(struct net_device *dev, void *addr)
+static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
 {
-       struct bonding *bond = dev->priv;
+       struct bonding *bond = bond_dev->priv;
        struct sockaddr *sa = addr, tmp_sa;
-       struct slave *slave;
-       int error;
+       struct slave *slave, *stop_at;
+       int res = 0;
+       int i;
 
-       dprintk(KERN_INFO "bond_set_mac_address %p %s\n", dev,
-              dev->name);
+       dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
 
        if (!is_valid_ether_addr(sa->sa_data)) {
                return -EADDRNOTAVAIL;
        }
 
-       for (slave = bond->prev; slave != (struct slave *)bond;
-            slave = slave->prev) {
-               dprintk(KERN_INFO "bond_set_mac: slave %p %s\n", slave,
-                       slave->dev->name);
+       /* Can't hold bond->lock with bh disabled here since
+        * some base drivers panic. On the other hand we can't
+        * hold bond->lock without bh disabled because we'll
+        * deadlock. The only solution is to rely on the fact
+        * that we're under rtnl_lock here, and the slaves
+        * list won't change. This doesn't solve the problem
+        * of setting the slave's hw address while it is
+        * transmitting, but the assumption is that the base
+        * driver can handle that.
+        *
+        * TODO: figure out a way to safely iterate the slaves
+        * list, but without holding a lock around the actual
+        * call to the base driver.
+        */
+
+       bond_for_each_slave(bond, slave, i) {
+               dprintk("slave %p %s\n", slave, slave->dev->name);
+
                if (slave->dev->set_mac_address == NULL) {
-                       error = -EOPNOTSUPP;
-                       dprintk(KERN_INFO "bond_set_mac EOPNOTSUPP %s\n",
-                               slave->dev->name);
+                       res = -EOPNOTSUPP;
+                       dprintk("EOPNOTSUPP %s\n", slave->dev->name);
                        goto unwind;
                }
 
-               error = slave->dev->set_mac_address(slave->dev, addr);
-               if (error) {
-                       /* TODO: consider downing the slave 
+               res = slave->dev->set_mac_address(slave->dev, addr);
+               if (res) {
+                       /* TODO: consider downing the slave
                         * and retry ?
                         * User should expect communications
                         * breakage anyway until ARP finish
                         * updating, so...
                         */
-                       dprintk(KERN_INFO "bond_set_mac err %d %s\n",
-                               error, slave->dev->name);
+                       dprintk("err %d %s\n", res, slave->dev->name);
                        goto unwind;
                }
        }
 
        /* success */
-       memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+       memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len);
        return 0;
 
 unwind:
-       memcpy(tmp_sa.sa_data, dev->dev_addr, dev->addr_len);
-       tmp_sa.sa_family = dev->type;
-
-       for (slave = slave->next; slave != bond->next;
-            slave = slave->next) {
-               int tmp_error;
-
-               tmp_error = slave->dev->set_mac_address(slave->dev, &tmp_sa);
-               if (tmp_error) {
-                       dprintk(KERN_INFO "bond_set_mac_address: "
-                               "unwind err %d dev %s\n",
-                               tmp_error, slave->dev->name);
+       memcpy(tmp_sa.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
+       tmp_sa.sa_family = bond_dev->type;
+
+       /* unwind from head to the slave that failed */
+       stop_at = slave;
+       bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
+               int tmp_res;
+
+               tmp_res = slave->dev->set_mac_address(slave->dev, &tmp_sa);
+               if (tmp_res) {
+                       dprintk("unwind err %d dev %s\n", tmp_res,
+                               slave->dev->name);
                }
        }
 
-       return error;
+       return res;
 }
 
-/*
- * Change the MTU of all of a master's slaves to match the master
- */
-static inline int
-bond_change_mtu(struct net_device *dev, int newmtu)
+static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       bonding_t *bond = dev->priv;
-       slave_t *slave;
-       int error;
-
-       dprintk(KERN_INFO "CM: b %p nm %d\n", bond, newmtu);
-       for (slave = bond->prev; slave != (slave_t *)bond;
-            slave = slave->prev) {
-               dprintk(KERN_INFO "CM: s %p s->p %p c_m %p\n", slave,
-                       slave->prev, slave->dev->change_mtu);
-               if (slave->dev->change_mtu) {
-                       error = slave->dev->change_mtu(slave->dev, newmtu);
-               } else {
-                       slave->dev->mtu = newmtu;
-                       error = 0;
-               }
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave, *start_at;
+       int i;
 
-               if (error) {
-                       /* If we failed to set the slave's mtu to the new value
-                        * we must abort the operation even in ACTIVE_BACKUP
-                        * mode, because if we allow the backup slaves to have
-                        * different mtu values than the active slave we'll
-                        * need to change their mtu when doing a failover. That
-                        * means changing their mtu from timer context, which
-                        * is probably not a good idea.
-                        */
-                       dprintk(KERN_INFO "bond_change_mtu err %d %s\n",
-                              error, slave->dev->name);
-                       goto unwind;
-               }
+       read_lock(&bond->lock);
+
+       if (!BOND_IS_OK(bond)) {
+               goto free_out;
        }
 
-       dev->mtu = newmtu;
-       return 0;
+       read_lock(&bond->curr_slave_lock);
+       slave = start_at = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
 
+       if (!slave) {
+               goto free_out;
+       }
 
-unwind:
-       for (slave = slave->next; slave != bond->next;
-            slave = slave->next) {
+       bond_for_each_slave_from(bond, slave, i, start_at) {
+               if (IS_UP(slave->dev) &&
+                   (slave->link == BOND_LINK_UP) &&
+                   (slave->state == BOND_STATE_ACTIVE)) {
+                       skb->dev = slave->dev;
+                       skb->priority = 1;
+                       dev_queue_xmit(skb);
 
-               if (slave->dev->change_mtu) {
-                       slave->dev->change_mtu(slave->dev, dev->mtu);
-               } else {
-                       slave->dev->mtu = dev->mtu;
+                       write_lock(&bond->curr_slave_lock);
+                       bond->curr_active_slave = slave->next;
+                       write_unlock(&bond->curr_slave_lock);
+
+                       goto out;
                }
        }
 
-       return error;
+out:
+       read_unlock(&bond->lock);
+       return 0;
+
+free_out:
+       /* no suitable interface, frame not sent */
+       dev_kfree_skb(skb);
+       goto out;
 }
 
 /*
- * Change device name
+ * in active-backup mode, we know that bond->curr_active_slave is always valid if
+ * the bond has a usable interface.
  */
-static inline int bond_event_changename(struct bonding *bond)
+static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_dev)
 {
-#ifdef CONFIG_PROC_FS
-       bond_destroy_proc_info(bond);
-       bond_create_proc_info(bond);
-#endif
+       struct bonding *bond = bond_dev->priv;
 
-       return NOTIFY_DONE;
+       /* if we are sending arp packets, try to at least
+          identify our own ip address */
+       if (arp_interval && !my_ip &&
+               (skb->protocol == __constant_htons(ETH_P_ARP))) {
+               char *the_ip = (char *)skb->data +
+                               sizeof(struct ethhdr) +
+                               sizeof(struct arphdr) +
+                               ETH_ALEN;
+               memcpy(&my_ip, the_ip, 4);
+       }
+
+       read_lock(&bond->lock);
+       read_lock(&bond->curr_slave_lock);
+
+       if (!BOND_IS_OK(bond)) {
+               goto free_out;
+       }
+
+       if (bond->curr_active_slave) { /* one usable interface */
+               skb->dev = bond->curr_active_slave->dev;
+               skb->priority = 1;
+               dev_queue_xmit(skb);
+               goto out;
+       } else {
+               goto free_out;
+       }
+out:
+       read_unlock(&bond->curr_slave_lock);
+       read_unlock(&bond->lock);
+       return 0;
+
+free_out:
+       /* no suitable interface, frame not sent */
+       dev_kfree_skb(skb);
+       goto out;
 }
 
-static int bond_master_netdev_event(unsigned long event, struct net_device *event_dev)
+/*
+ * in XOR mode, we determine the output device by performing xor on
+ * the source and destination hw adresses.  If this device is not
+ * enabled, find the next slave following this xor slave.
+ */
+static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct bonding *bond, *event_bond = NULL;
+       struct bonding *bond = bond_dev->priv;
+       struct ethhdr *data = (struct ethhdr *)skb->data;
+       struct slave *slave, *start_at;
+       int slave_no;
+       int i;
 
-       list_for_each_entry(bond, &bond_dev_list, bond_list) {
-               if (bond == event_dev->priv) {
-                       event_bond = bond;
-                       break;
-               }
-       }
+       read_lock(&bond->lock);
 
-       if (event_bond == NULL) {
-               return NOTIFY_DONE;
+       if (!BOND_IS_OK(bond)) {
+               goto free_out;
        }
 
-       switch (event) {
-       case NETDEV_CHANGENAME:
-               return bond_event_changename(event_bond);
-       case NETDEV_UNREGISTER:
-               /*
-                * TODO: remove a bond from the list?
-                */
-               break;
-       default:
-               break;
+       slave_no = (data->h_dest[5]^bond_dev->dev_addr[5]) % bond->slave_cnt;
+
+       bond_for_each_slave(bond, slave, i) {
+               slave_no--;
+               if (slave_no < 0) {
+                       break;
+               }
        }
 
-       return NOTIFY_DONE;
-}
+       start_at = slave;
 
-static int bond_slave_netdev_event(unsigned long event, struct net_device *event_dev)
-{
-       struct net_device *master = event_dev->master;
+       bond_for_each_slave_from(bond, slave, i, start_at) {
+               if (IS_UP(slave->dev) &&
+                   (slave->link == BOND_LINK_UP) &&
+                   (slave->state == BOND_STATE_ACTIVE)) {
+                       skb->dev = slave->dev;
+                       skb->priority = 1;
+                       dev_queue_xmit(skb);
 
-       switch (event) {
-       case NETDEV_UNREGISTER:
-               if (master != NULL) {
-                       bond_release(master, event_dev);
+                       goto out;
                }
-               break;
-       case NETDEV_CHANGE:
-               /*
-                * TODO: is this what we get if somebody
-                * sets up a hierarchical bond, then rmmod's
-                * one of the slave bonding devices?
-                */
-               break;
-       case NETDEV_DOWN:
-               /*
-                * ... Or is it this?
-                */
-               break;
-       case NETDEV_CHANGEMTU:
-               /*
-                * TODO: Should slaves be allowed to
-                * independently alter their MTU?  For
-                * an active-backup bond, slaves need
-                * not be the same type of device, so
-                * MTUs may vary.  For other modes,
-                * slaves arguably should have the
-                * same MTUs. To do this, we'd need to
-                * take over the slave's change_mtu
-                * function for the duration of their
-                * servitude.
-                */
-               break;
-       case NETDEV_CHANGENAME:
-               /*
-                * TODO: handle changing the primary's name
-                */
-               break;
-       default:
-               break;
        }
 
-       return NOTIFY_DONE;
+out:
+       read_unlock(&bond->lock);
+       return 0;
+
+free_out:
+       /* no suitable interface, frame not sent */
+       dev_kfree_skb(skb);
+       goto out;
 }
 
 /*
- * bond_netdev_event: handle netdev notifier chain events.
- *
- * This function receives events for the netdev chain.  The caller (an
- * ioctl handler calling notifier_call_chain) holds the necessary
- * locks for us to safely manipulate the slave devices (RTNL lock,
- * dev_probe_lock).
+ * in broadcast mode, we send everything to all usable interfaces.
  */
-static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct net_device *event_dev = (struct net_device *)ptr;
-       unsigned short flags;
-       int res = NOTIFY_DONE;
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave, *start_at;
+       struct net_device *tx_dev = NULL;
+       int i;
 
-       dprintk(KERN_INFO "bond_netdev_event n_b %p ev %lx ptr %p\n",
-               this, event, ptr);
+       read_lock(&bond->lock);
 
-       flags = event_dev->flags & (IFF_MASTER | IFF_SLAVE);
-       switch (flags) {
-       case IFF_MASTER:
-               res = bond_master_netdev_event(event, event_dev);
-               break;
-       case IFF_SLAVE:
-               res = bond_slave_netdev_event(event, event_dev);
-               break;
-       default:
-               /* A master that is also a slave ? */
-               break;
+       if (!BOND_IS_OK(bond)) {
+               goto free_out;
        }
 
-       return res;
-}
-
-static struct notifier_block bond_netdev_notifier = {
-       .notifier_call = bond_netdev_event,
-};
+       read_lock(&bond->curr_slave_lock);
+       start_at = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
 
-/* De-initialize device specific data.
- * Caller must hold rtnl_lock.
- */
-static inline void bond_deinit(struct net_device *dev)
-{
-       struct bonding *bond = dev->priv;
+       if (!start_at) {
+               goto free_out;
+       }
 
-       list_del(&bond->bond_list);
+       bond_for_each_slave_from(bond, slave, i, start_at) {
+               if (IS_UP(slave->dev) &&
+                   (slave->link == BOND_LINK_UP) &&
+                   (slave->state == BOND_STATE_ACTIVE)) {
+                       if (tx_dev) {
+                               struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+                               if (!skb2) {
+                                       printk(KERN_ERR DRV_NAME
+                                              ": Error: bond_xmit_broadcast(): "
+                                              "skb_clone() failed\n");
+                                       continue;
+                               }
 
-#ifdef CONFIG_PROC_FS
-       bond_destroy_proc_info(bond);
-#endif
-}
+                               skb2->dev = tx_dev;
+                               skb2->priority = 1;
+                               dev_queue_xmit(skb2);
+                       }
+                       tx_dev = slave->dev;
+               }
+       }
 
-/* Unregister and free all bond devices.
- * Caller must hold rtnl_lock.
- */
-static void bond_free_all(void)
-{
-       struct bonding *bond, *nxt;
+       if (tx_dev) {
+               skb->dev = tx_dev;
+               skb->priority = 1;
+               dev_queue_xmit(skb);
+       } else {
+               goto free_out;
+       }
 
-       list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
-               struct net_device *dev = bond->device;
+out:
+       /* frame sent to all suitable interfaces */
+       read_unlock(&bond->lock);
+       return 0;
 
-               unregister_netdevice(dev);
-               bond_deinit(dev);
-       }
+free_out:
+       /* no suitable interface, frame not sent */
+       dev_kfree_skb(skb);
+       goto out;
+}
 
-#ifdef CONFIG_PROC_FS
-       bond_destroy_proc_dir();
-#endif
+#ifdef CONFIG_NET_FASTROUTE
+static int bond_accept_fastpath(struct net_device *bond_dev, struct dst_entry *dst)
+{
+       return -1;
 }
+#endif
+
+/*------------------------- Device initialization ---------------------------*/
 
 /*
  * Does not allocate but creates a /proc entry.
  * Allowed to fail.
  */
-static int __init bond_init(struct net_device *dev)
+static int __init bond_init(struct net_device *bond_dev)
 {
-       struct bonding *bond;
+       struct bonding *bond = bond_dev->priv;
        int count;
 
-#ifdef BONDING_DEBUG
-       printk (KERN_INFO "Begin bond_init for %s\n", dev->name);
-#endif
-       bond = dev->priv;
+       dprintk("Begin bond_init for %s\n", bond_dev->name);
 
        /* initialize rwlocks */
        rwlock_init(&bond->lock);
-       rwlock_init(&bond->ptrlock);
+       rwlock_init(&bond->curr_slave_lock);
 
        /* Initialize pointers */
-       bond->next = bond->prev = (slave_t *)bond;
-       bond->current_slave = NULL;
+       bond->first_slave = NULL;
+       bond->curr_active_slave = NULL;
        bond->current_arp_slave = NULL;
-       bond->device = dev;
+       bond->primary_slave = NULL;
+       bond->dev = bond_dev;
 
-       /* Initialize the device structure. */
-       dev->set_mac_address = bond_set_mac_address;
+       /* Initialize the device entry points */
+       bond_dev->open = bond_open;
+       bond_dev->stop = bond_close;
+       bond_dev->get_stats = bond_get_stats;
+       bond_dev->do_ioctl = bond_do_ioctl;
+       bond_dev->set_multicast_list = bond_set_multicast_list;
+       bond_dev->change_mtu = bond_change_mtu;
+       bond_dev->set_mac_address = bond_set_mac_address;
 
        switch (bond_mode) {
-       case BOND_MODE_ACTIVEBACKUP:
-               dev->hard_start_xmit = bond_xmit_activebackup;
-               break;
        case BOND_MODE_ROUNDROBIN:
-               dev->hard_start_xmit = bond_xmit_roundrobin;
+               bond_dev->hard_start_xmit = bond_xmit_roundrobin;
+               break;
+       case BOND_MODE_ACTIVEBACKUP:
+               bond_dev->hard_start_xmit = bond_xmit_activebackup;
                break;
        case BOND_MODE_XOR:
-               dev->hard_start_xmit = bond_xmit_xor;
+               bond_dev->hard_start_xmit = bond_xmit_xor;
                break;
        case BOND_MODE_BROADCAST:
-               dev->hard_start_xmit = bond_xmit_broadcast;
+               bond_dev->hard_start_xmit = bond_xmit_broadcast;
                break;
        case BOND_MODE_8023AD:
-               dev->hard_start_xmit = bond_3ad_xmit_xor;
+               bond_dev->hard_start_xmit = bond_3ad_xmit_xor; /* extern */
                break;
        case BOND_MODE_TLB:
        case BOND_MODE_ALB:
-               dev->hard_start_xmit = bond_alb_xmit;
-               dev->set_mac_address = bond_alb_set_mac_address;
+               bond_dev->hard_start_xmit = bond_alb_xmit; /* extern */
+               bond_dev->set_mac_address = bond_alb_set_mac_address; /* extern */
                break;
        default:
-               printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode);
+               printk(KERN_ERR DRV_NAME
+                      ": Error: Unknown bonding mode %d\n",
+                      bond_mode);
                return -EINVAL;
        }
 
-       dev->get_stats = bond_get_stats;
-       dev->open = bond_open;
-       dev->stop = bond_close;
-       dev->set_multicast_list = set_multicast_list;
-       dev->do_ioctl = bond_ioctl;
-       dev->change_mtu = bond_change_mtu;
-       dev->tx_queue_len = 0;
-       dev->flags |= IFF_MASTER|IFF_MULTICAST;
+       bond_dev->destructor = free_netdev;
 #ifdef CONFIG_NET_FASTROUTE
-       dev->accept_fastpath = bond_accept_fastpath;
+       bond_dev->accept_fastpath = bond_accept_fastpath;
 #endif
 
-       printk(KERN_INFO "%s registered with", dev->name);
-       if (miimon > 0) {
+       /* Initialize the device options */
+       bond_dev->tx_queue_len = 0;
+       bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
+
+       printk(KERN_INFO DRV_NAME ": %s registered with", bond_dev->name);
+       if (miimon) {
                printk(" MII link monitoring set to %d ms", miimon);
                updelay /= miimon;
                downdelay /= miimon;
@@ -3992,50 +3794,75 @@ static int __init bond_init(struct net_device *dev)
        }
        printk(", in %s mode.\n", bond_mode_name());
 
-       printk(KERN_INFO "%s registered with", dev->name);
+       printk(KERN_INFO DRV_NAME ": %s registered with", bond_dev->name);
        if (arp_interval > 0) {
-               printk(" ARP monitoring set to %d ms with %d target(s):", 
-                       arp_interval, arp_ip_count);
-               for (count=0 ; count<arp_ip_count ; count++)
-                        printk (" %s", arp_ip_target[count]);
+               printk(" ARP monitoring set to %d ms with %d target(s):",
+                      arp_interval, arp_ip_count);
+               for (count=0 ; count<arp_ip_count ; count++) {
+                       printk(" %s", arp_ip_target[count]);
+               }
                printk("\n");
        } else {
                printk("out ARP monitoring\n");
        }
+
 #ifdef CONFIG_PROC_FS
-       bond_create_proc_info(bond);
+       bond_create_proc_entry(bond);
 #endif
 
-       dev->destructor = free_netdev;
-
        list_add_tail(&bond->bond_list, &bond_dev_list);
 
        return 0;
 }
 
-/*
-static int __init bond_probe(struct net_device *dev)
+/* De-initialize device specific data.
+ * Caller must hold rtnl_lock.
+ */
+static inline void bond_deinit(struct net_device *bond_dev)
 {
-       bond_init(dev);
-       return 0;
+       struct bonding *bond = bond_dev->priv;
+
+       list_del(&bond->bond_list);
+
+#ifdef CONFIG_PROC_FS
+       bond_remove_proc_entry(bond);
+#endif
 }
+
+/* Unregister and free all bond devices.
+ * Caller must hold rtnl_lock.
  */
+static void bond_free_all(void)
+{
+       struct bonding *bond, *nxt;
+
+       list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+               struct net_device *bond_dev = bond->dev;
+
+               unregister_netdevice(bond_dev);
+               bond_deinit(bond_dev);
+       }
+
+#ifdef CONFIG_PROC_FS
+       bond_destroy_proc_dir();
+#endif
+}
+
+/*------------------------- Module initialization ---------------------------*/
 
 /*
  * Convert string input module parms.  Accept either the
  * number of the mode or its string name.
  */
-static inline int
-bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+static inline int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
 {
        int i;
 
-       for (i = 0; tbl[i].modename != NULL; i++) {
+       for (i = 0; tbl[i].modename; i++) {
                if ((isdigit(*mode_arg) &&
-                   tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
-                   (0 == strncmp(mode_arg, tbl[i].modename,
-                                 strlen(tbl[i].modename)))) {
+                    tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
+                   (strncmp(mode_arg, tbl[i].modename,
+                            strlen(tbl[i].modename)) == 0)) {
                        return tbl[i].mode;
                }
        }
@@ -4043,88 +3870,64 @@ bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
        return -1;
 }
 
-
-static int __init bonding_init(void)
+static int bond_check_params(void)
 {
-       int no;
-       int err;
-
-       printk(KERN_INFO "%s", version);
-
        /*
         * Convert string parameters.
         */
        if (mode) {
                bond_mode = bond_parse_parm(mode, bond_mode_tbl);
                if (bond_mode == -1) {
-                       printk(KERN_WARNING
-                              "bonding_init(): Invalid bonding mode \"%s\"\n",
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: Invalid bonding mode \"%s\"\n",
                               mode == NULL ? "NULL" : mode);
                        return -EINVAL;
                }
        }
 
-       if (USES_PRIMARY(bond_mode)) {
-               multicast_mode = BOND_MULTICAST_ACTIVE;
-       } else {
-               multicast_mode = BOND_MULTICAST_ALL;
-       }
-
-       if (multicast) {
-               multicast_mode = bond_parse_parm(multicast, bond_mc_tbl);
-               if (multicast_mode == -1) {
-                       printk(KERN_WARNING 
-                      "bonding_init(): Invalid multicast mode \"%s\"\n",
-                              multicast == NULL ? "NULL" : multicast);
-                       return -EINVAL;
-               }
-       }
-
        if (lacp_rate) {
                if (bond_mode != BOND_MODE_8023AD) {
-                       printk(KERN_WARNING
-                              "lacp_rate param is irrelevant in mode %s\n",
+                       printk(KERN_INFO DRV_NAME
+                              ": lacp_rate param is irrelevant in mode %s\n",
                               bond_mode_name());
                } else {
                        lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
                        if (lacp_fast == -1) {
-                               printk(KERN_WARNING
-                                      "bonding_init(): Invalid lacp rate "
-                                      "\"%s\"\n",
+                               printk(KERN_ERR DRV_NAME
+                                      ": Error: Invalid lacp rate \"%s\"\n",
                                       lacp_rate == NULL ? "NULL" : lacp_rate);
-
                                return -EINVAL;
                        }
                }
        }
 
        if (max_bonds < 1 || max_bonds > INT_MAX) {
-               printk(KERN_WARNING 
-                      "bonding_init(): max_bonds (%d) not in range %d-%d, "
-                      "so it was reset to BOND_DEFAULT_MAX_BONDS (%d)",
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: max_bonds (%d) not in range %d-%d, so it "
+                      "was reset to BOND_DEFAULT_MAX_BONDS (%d)",
                       max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
                max_bonds = BOND_DEFAULT_MAX_BONDS;
        }
 
        if (miimon < 0) {
-               printk(KERN_WARNING 
-                      "bonding_init(): miimon module parameter (%d), "
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: miimon module parameter (%d), "
                       "not in range 0-%d, so it was reset to %d\n",
                       miimon, INT_MAX, BOND_LINK_MON_INTERV);
                miimon = BOND_LINK_MON_INTERV;
        }
 
        if (updelay < 0) {
-               printk(KERN_WARNING 
-                      "bonding_init(): updelay module parameter (%d), "
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: updelay module parameter (%d), "
                       "not in range 0-%d, so it was reset to 0\n",
                       updelay, INT_MAX);
                updelay = 0;
        }
 
        if (downdelay < 0) {
-               printk(KERN_WARNING 
-                      "bonding_init(): downdelay module parameter (%d), "
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: downdelay module parameter (%d), "
                       "not in range 0-%d, so it was reset to 0\n",
                       downdelay, INT_MAX);
                downdelay = 0;
@@ -4132,82 +3935,69 @@ static int __init bonding_init(void)
 
        /* reset values for 802.3ad */
        if (bond_mode == BOND_MODE_8023AD) {
-               if (arp_interval != 0) {
-                       printk(KERN_WARNING "bonding_init(): ARP monitoring"
-                              "can't be used simultaneously with 802.3ad, "
-                              "disabling ARP monitoring\n");
+               if (arp_interval) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: ARP monitoring can't be used "
+                              "simultaneously with 802.3ad, disabling ARP "
+                              "monitoring\n");
                        arp_interval = 0;
                }
 
-               if (miimon == 0) {
-                       printk(KERN_ERR
-                              "bonding_init(): miimon must be specified, "
-                              "otherwise bonding will not detect link failure, "
-                              "speed and duplex which are essential "
-                              "for 802.3ad operation\n");
-                       printk(KERN_ERR "Forcing miimon to 100msec\n");
+               if (miimon) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: miimon must be specified, "
+                              "otherwise bonding will not detect link "
+                              "failure, speed and duplex which are "
+                              "essential for 802.3ad operation\n");
+                       printk(KERN_WARNING "Forcing miimon to 100msec\n");
                        miimon = 100;
                }
-
-               if (multicast_mode != BOND_MULTICAST_ALL) {
-                       printk(KERN_ERR
-                              "bonding_init(): Multicast mode must "
-                              "be set to ALL for 802.3ad\n");
-                       printk(KERN_ERR "Forcing Multicast mode to ALL\n");
-                       multicast_mode = BOND_MULTICAST_ALL;
-               }
        }
 
        /* reset values for TLB/ALB */
        if ((bond_mode == BOND_MODE_TLB) ||
            (bond_mode == BOND_MODE_ALB)) {
-               if (miimon == 0) {
-                       printk(KERN_ERR
-                              "bonding_init(): miimon must be specified, "
-                              "otherwise bonding will not detect link failure "
-                              "and link speed which are essential "
+               if (!miimon) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: miimon must be specified, "
+                              "otherwise bonding will not detect link "
+                              "failure and link speed which are essential "
                               "for TLB/ALB load balancing\n");
-                       printk(KERN_ERR "Forcing miimon to 100msec\n");
+                       printk(KERN_WARNING "Forcing miimon to 100msec\n");
                        miimon = 100;
                }
-
-               if (multicast_mode != BOND_MULTICAST_ACTIVE) {
-                       printk(KERN_ERR
-                              "bonding_init(): Multicast mode must "
-                              "be set to ACTIVE for TLB/ALB\n");
-                       printk(KERN_ERR "Forcing Multicast mode to ACTIVE\n");
-                       multicast_mode = BOND_MULTICAST_ACTIVE;
-               }
        }
 
        if (bond_mode == BOND_MODE_ALB) {
-               printk(KERN_INFO
-                      "In ALB mode you might experience client disconnections"
-                      " upon reconnection of a link if the bonding module"
-                      " updelay parameter (%d msec) is incompatible with the"
-                      " forwarding delay time of the switch\n", updelay);
+               printk(KERN_NOTICE DRV_NAME
+                      ": In ALB mode you might experience client "
+                      "disconnections upon reconnection of a link if the "
+                      "bonding module updelay parameter (%d msec) is "
+                      "incompatible with the forwarding delay time of the "
+                      "switch\n",
+                      updelay);
        }
 
-       if (miimon == 0) {
-               if ((updelay != 0) || (downdelay != 0)) {
+       if (!miimon) {
+               if (updelay || downdelay) {
                        /* just warn the user the up/down delay will have
                         * no effect since miimon is zero...
                         */
-                       printk(KERN_WARNING 
-                              "bonding_init(): miimon module parameter not "
-                              "set and updelay (%d) or downdelay (%d) module "
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: miimon module parameter not set "
+                              "and updelay (%d) or downdelay (%d) module "
                               "parameter is set; updelay and downdelay have "
                               "no effect unless miimon is set\n",
-                              updelay, downdelay);
+                              updelay, downdelay);
                }
        } else {
                /* don't allow arp monitoring */
-               if (arp_interval != 0) {
-                       printk(KERN_WARNING 
-                              "bonding_init(): miimon (%d) and arp_interval "
-                              "(%d) can't be used simultaneously, "
-                              "disabling ARP monitoring\n",
-                              miimon, arp_interval);
+               if (arp_interval) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: miimon (%d) and arp_interval (%d) "
+                              "can't be used simultaneously, disabling ARP "
+                              "monitoring\n",
+                              miimon, arp_interval);
                        arp_interval = 0;
                }
 
@@ -4215,103 +4005,114 @@ static int __init bonding_init(void)
                        /* updelay will be rounded in bond_init() when it
                         * is divided by miimon, we just inform user here
                         */
-                       printk(KERN_WARNING 
-                              "bonding_init(): updelay (%d) is not a multiple "
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: updelay (%d) is not a multiple "
                               "of miimon (%d), updelay rounded to %d ms\n",
-                              updelay, miimon, (updelay / miimon) * miimon);
+                              updelay, miimon, (updelay / miimon) * miimon);
                }
 
                if ((downdelay % miimon) != 0) {
                        /* downdelay will be rounded in bond_init() when it
                         * is divided by miimon, we just inform user here
                         */
-                       printk(KERN_WARNING 
-                              "bonding_init(): downdelay (%d) is not a "
-                              "multiple of miimon (%d), downdelay rounded "
-                              "to %d ms\n",
-                              downdelay, miimon, 
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: downdelay (%d) is not a multiple "
+                              "of miimon (%d), downdelay rounded to %d ms\n",
+                              downdelay, miimon,
                               (downdelay / miimon) * miimon);
                }
        }
 
        if (arp_interval < 0) {
-               printk(KERN_WARNING 
-                      "bonding_init(): arp_interval module parameter (%d), "
-                      "not in range 0-%d, so it was reset to %d\n",
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: arp_interval module parameter (%d) "
+                      ", not in range 0-%d, so it was reset to %d\n",
                       arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
                arp_interval = BOND_LINK_ARP_INTERV;
        }
 
-        for (arp_ip_count=0 ;
-             (arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count];
-              arp_ip_count++ ) {
+       for (arp_ip_count = 0;
+            (arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count];
+            arp_ip_count++) {
                /* not complete check, but should be good enough to
                   catch mistakes */
-               if (!isdigit(arp_ip_target[arp_ip_count][0])) { 
-                        printk(KERN_WARNING
-                               "bonding_init(): bad arp_ip_target module "
-                               "parameter (%s), ARP monitoring will not be "
-                               "performed\n",
-                               arp_ip_target[arp_ip_count]);
-                        arp_interval = 0;
-               } else { 
-                       u32 ip = in_aton(arp_ip_target[arp_ip_count]); 
+               if (!isdigit(arp_ip_target[arp_ip_count][0])) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": Warning: bad arp_ip_target module parameter "
+                              "(%s), ARP monitoring will not be performed\n",
+                              arp_ip_target[arp_ip_count]);
+                       arp_interval = 0;
+               } else {
+                       u32 ip = in_aton(arp_ip_target[arp_ip_count]);
                        arp_target[arp_ip_count] = ip;
                }
-        }
-
+       }
 
-       if ( (arp_interval > 0) && (arp_ip_count==0)) {
+       if (arp_interval && !arp_ip_count) {
                /* don't allow arping if no arp_ip_target given... */
-               printk(KERN_WARNING 
-                      "bonding_init(): arp_interval module parameter "
-                      "(%d) specified without providing an arp_ip_target "
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: arp_interval module parameter (%d) "
+                      "specified without providing an arp_ip_target "
                       "parameter, arp_interval was reset to 0\n",
                       arp_interval);
                arp_interval = 0;
        }
 
-       if ((miimon == 0) && (arp_interval == 0)) {
+       if (!miimon && !arp_interval) {
                /* miimon and arp_interval not set, we need one so things
                 * work as expected, see bonding.txt for details
                 */
-               printk(KERN_ERR 
-                      "bonding_init(): either miimon or "
-                      "arp_interval and arp_ip_target module parameters "
-                      "must be specified, otherwise bonding will not detect "
-                      "link failures! see bonding.txt for details.\n");
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: either miimon or arp_interval and "
+                      "arp_ip_target module parameters must be specified, "
+                      "otherwise bonding will not detect link failures! see "
+                      "bonding.txt for details.\n");
        }
 
-       if ((primary != NULL) && !USES_PRIMARY(bond_mode)) {
+       if (primary && !USES_PRIMARY(bond_mode)) {
                /* currently, using a primary only makes sense
                 * in active backup, TLB or ALB modes
                 */
-               printk(KERN_WARNING 
-                      "bonding_init(): %s primary device specified but has "
-                      "no effect in %s mode\n",
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: %s primary device specified but has no "
+                      "effect in %s mode\n",
                       primary, bond_mode_name());
                primary = NULL;
        }
 
+       return 0;
+}
+
+static int __init bonding_init(void)
+{
+       int i;
+       int res;
+
+       printk(KERN_INFO "%s", version);
+
+       res = bond_check_params();
+       if (res) {
+               return res;
+       }
+
        rtnl_lock();
 
 #ifdef CONFIG_PROC_FS
        bond_create_proc_dir();
 #endif
 
-       err = 0;
-       for (no = 0; no < max_bonds; no++) {
-               struct net_device *dev;
+       for (i = 0; i < max_bonds; i++) {
+               struct net_device *bond_dev;
 
-               dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
-               if (!dev) {
-                       err = -ENOMEM;
+               bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
+               if (!bond_dev) {
+                       res = -ENOMEM;
                        goto out_err;
                }
 
-               err = dev_alloc_name(dev, "bond%d");
-               if (err < 0) {
-                       free_netdev(dev);
+               res = dev_alloc_name(bond_dev, "bond%d");
+               if (res < 0) {
+                       free_netdev(bond_dev);
                        goto out_err;
                }
 
@@ -4319,18 +4120,18 @@ static int __init bonding_init(void)
                 * /proc files), but before register_netdevice(), because we
                 * need to set function pointers.
                 */
-               err = bond_init(dev);
-               if (err < 0) {
-                       free_netdev(dev);
+               res = bond_init(bond_dev);
+               if (res < 0) {
+                       free_netdev(bond_dev);
                        goto out_err;
                }
 
-               SET_MODULE_OWNER(dev);
+               SET_MODULE_OWNER(bond_dev);
 
-               err = register_netdevice(dev);
-               if (err < 0) {
-                       bond_deinit(dev);
-                       free_netdev(dev);
+               res = register_netdevice(bond_dev);
+               if (res < 0) {
+                       bond_deinit(bond_dev);
+                       free_netdev(bond_dev);
                        goto out_err;
                }
        }
@@ -4346,7 +4147,7 @@ out_err:
 
        rtnl_unlock();
 
-       return err;
+       return res;
 }
 
 static void __exit bonding_exit(void)
@@ -4362,6 +4163,8 @@ module_init(bonding_init);
 module_exit(bonding_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
+MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
+MODULE_SUPPORTED_DEVICE("most ethernet devices");
 
 /*
  * Local variables:
@@ -4370,3 +4173,4 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
  *  tab-width: 8
  * End:
  */
+
index 8358c80..26a67de 100644 (file)
@@ -9,7 +9,7 @@
  *
  *     This software may be used and distributed according to the terms
  *     of the GNU Public License, incorporated herein by reference.
- * 
+ *
  *
  * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
  *             Tsippy Mendelson <tsippy.mendelson at intel dot com> and
  *
  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
  *     - Added support for Transmit load balancing mode.
+ *
+ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
+ *     - Code cleanup and style changes
  */
+
 #ifndef _LINUX_BONDING_H
 #define _LINUX_BONDING_H
 
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
+#include <linux/if_bonding.h>
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#ifdef BONDING_DEBUG
-
-// use this like so: BOND_PRINT_DBG(("foo = %d, bar = %d", foo, bar));
-#define BOND_PRINT_DBG(X)                                     \
-do {                                                          \
-       printk(KERN_DEBUG "%s (%d)", __FUNCTION__, __LINE__); \
-       printk X;                                             \
-       printk("\n");                                         \
-} while(0)
+#define DRV_VERSION    "2.5.0"
+#define DRV_RELDATE    "December 1, 2003"
+#define DRV_NAME       "bonding"
+#define DRV_DESCRIPTION        "Ethernet Channel Bonding Driver"
 
+#ifdef BONDING_DEBUG
+#define dprintk(fmt, args...) \
+       printk(KERN_DEBUG     \
+              DRV_NAME ": %s() %d: " fmt, __FUNCTION__, __LINE__ , ## args )
 #else
-#define BOND_PRINT_DBG(X)
+#define dprintk(fmt, args...)
 #endif /* BONDING_DEBUG */
 
-#define IS_UP(dev)  ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \
-                    (netif_running(dev) && netif_carrier_ok(dev)))
+#define IS_UP(dev)                                        \
+             ((((dev)->flags & IFF_UP) == IFF_UP)      && \
+              netif_running(dev)                       && \
+              netif_carrier_ok(dev))
+
+/*
+ * Checks whether bond is ready for transmit.
+ *
+ * Caller must hold bond->lock
+ */
+#define BOND_IS_OK(bond)                            \
+                  (((bond)->dev->flags & IFF_UP) && \
+                   netif_running((bond)->dev)    && \
+                   ((bond)->slave_cnt > 0))
 
-/* Checks whether the dev is ready for transmit. We do not check netif_running
- * since a device can be stopped by the driver for short periods of time for
- * maintainance. dev_queue_xmit() handles this by queing the packet until the
- * the dev is running again. Keeping packets ordering requires sticking the
- * same dev as much as possible
+/*
+ * Checks whether slave is ready for transmit.
  */
-#define SLAVE_IS_OK(slave) \
-                    ((((slave)->dev->flags & (IFF_UP)) == (IFF_UP)) && \
-                    netif_carrier_ok((slave)->dev) && \
+#define SLAVE_IS_OK(slave)                             \
+                   (((slave)->dev->flags & IFF_UP)  && \
+                    netif_running((slave)->dev)     && \
                     ((slave)->link == BOND_LINK_UP) && \
                     ((slave)->state == BOND_STATE_ACTIVE))
 
 
-typedef struct slave {
+#define USES_PRIMARY(mode)                             \
+               (((mode) == BOND_MODE_ACTIVEBACKUP) ||  \
+                ((mode) == BOND_MODE_TLB)          ||  \
+                ((mode) == BOND_MODE_ALB))
+
+/*
+ * Less bad way to call ioctl from within the kernel; this needs to be
+ * done some other way to get the call out of interrupt context.
+ * Needs "ioctl" variable to be supplied by calling context.
+ */
+#define IOCTL(dev, arg, cmd) ({                \
+       int res = 0;                    \
+       mm_segment_t fs = get_fs();     \
+       set_fs(get_ds());               \
+       res = ioctl(dev, arg, cmd);     \
+       set_fs(fs);                     \
+       res; })
+
+/**
+ * bond_for_each_slave_from - iterate the slaves list from a starting point
+ * @bond:      the bond holding this list.
+ * @pos:       current slave.
+ * @cnt:       counter for max number of moves
+ * @start:     starting point.
+ *
+ * Caller must hold bond->lock
+ */
+#define bond_for_each_slave_from(bond, pos, cnt, start)        \
+       for (cnt = 0, pos = start;                              \
+            cnt < (bond)->slave_cnt;                           \
+             cnt++, pos = (pos)->next)
+
+/**
+ * bond_for_each_slave_from_to - iterate the slaves list from start point to stop point
+ * @bond:      the bond holding this list.
+ * @pos:       current slave.
+ * @cnt:       counter for number max of moves
+ * @start:     start point.
+ * @stop:      stop point.
+ *
+ * Caller must hold bond->lock
+ */
+#define bond_for_each_slave_from_to(bond, pos, cnt, start, stop)       \
+       for (cnt = 0, pos = start;                                      \
+            ((cnt < (bond)->slave_cnt) && (pos != (stop)->next));      \
+             cnt++, pos = (pos)->next)
+
+/**
+ * bond_for_each_slave - iterate the slaves list from head
+ * @bond:      the bond holding this list.
+ * @pos:       current slave.
+ * @cnt:       counter for max number of moves
+ *
+ * Caller must hold bond->lock
+ */
+#define bond_for_each_slave(bond, pos, cnt)    \
+               bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave)
+
+
+struct slave {
+       struct net_device *dev; /* first - usefull for panic debug */
        struct slave *next;
        struct slave *prev;
-       struct net_device *dev;
-       short  delay;
-       unsigned long jiffies;
-       char   link;    /* one of BOND_LINK_XXXX */
-       char   state;   /* one of BOND_STATE_XXXX */
-       unsigned short original_flags;
-       u32 link_failure_count;
+       s16    delay;
+       u32    jiffies;
+       s8     link;    /* one of BOND_LINK_XXXX */
+       s8     state;   /* one of BOND_STATE_XXXX */
+       u32    original_flags;
+       u32    link_failure_count;
        u16    speed;
        u8     duplex;
        u8     perm_hwaddr[ETH_ALEN];
        struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
        struct tlb_slave_info tlb_info;
-} slave_t;
+};
 
 /*
  * Here are the locking policies for the two bonding locks:
  *
  * 1) Get bond->lock when reading/writing slave list.
- * 2) Get bond->ptrlock when reading/writing bond->current_slave.
+ * 2) Get bond->curr_slave_lock when reading/writing bond->curr_active_slave.
  *    (It is unnecessary when the write-lock is put with bond->lock.)
- * 3) When we lock with bond->ptrlock, we must lock with bond->lock
+ * 3) When we lock with bond->curr_slave_lock, we must lock with bond->lock
  *    beforehand.
  */
-typedef struct bonding {
-       slave_t *next;
-       slave_t *prev;
-       slave_t *current_slave;
-       slave_t *primary_slave;
-       slave_t *current_arp_slave;
-       __s32 slave_cnt;
+struct bonding {
+       struct   net_device *dev; /* first - usefull for panic debug */
+       struct   slave *first_slave;
+       struct   slave *curr_active_slave;
+       struct   slave *current_arp_slave;
+       struct   slave *primary_slave;
+       s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
        rwlock_t lock;
-       rwlock_t ptrlock;
-       struct timer_list mii_timer;
-       struct timer_list arp_timer;
-       struct net_device_stats stats;
+       rwlock_t curr_slave_lock;
+       struct   timer_list mii_timer;
+       struct   timer_list arp_timer;
+       s8       kill_timers;
+       struct   net_device_stats stats;
 #ifdef CONFIG_PROC_FS
-       struct proc_dir_entry *bond_proc_file;
-       char procdir_name[IFNAMSIZ];
+       struct   proc_dir_entry *proc_entry;
+       char     proc_file_name[IFNAMSIZ];
 #endif /* CONFIG_PROC_FS */
-       struct list_head bond_list;
-       struct net_device *device;
-       struct dev_mc_list *mc_list;
-       unsigned short flags;
-       struct ad_bond_info ad_info;
-       struct alb_bond_info alb_info;
-} bonding_t;
-
-/* Forward declarations */
-void bond_set_slave_active_flags(slave_t *slave);
-void bond_set_slave_inactive_flags(slave_t *slave);
-
-/**
- * These functions can be used for iterating the slave list
- * (which is circular)
- * Caller must hold bond lock for read
- */
-extern inline struct slave*
-bond_get_first_slave(struct bonding *bond)
-{
-       /* if there are no slaves return NULL */
-       if (bond->next == (slave_t *)bond) {
-               return NULL;
-       }
-       return bond->next;
-}
-
-/**
- * Caller must hold bond lock for read
- */
-extern inline struct slave*
-bond_get_next_slave(struct bonding *bond, struct slave *slave)
-{
-       /* If we have reached the last slave return NULL */
-       if (slave->next == bond->next) {
-               return NULL;
-       }
-       return slave->next;
-}
+       struct   list_head bond_list;
+       struct   dev_mc_list *mc_list;
+       u16      flags;
+       struct   ad_bond_info ad_info;
+       struct   alb_bond_info alb_info;
+};
 
 /**
  * Returns NULL if the net_device does not belong to any of the bond's slaves
  *
  * Caller must hold bond lock for read
  */
-extern inline struct slave*
-bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
+extern inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
 {
-       struct slave *our_slave = bond->next;
+       struct slave *slave = NULL;
+       int i;
 
-       /* check if the list of slaves is empty */
-       if (our_slave == (slave_t *)bond) {
-               return NULL;
-       }
-
-       for (; our_slave; our_slave = bond_get_next_slave(bond, our_slave)) {
-               if (our_slave->dev == slave_dev) {
+       bond_for_each_slave(bond, slave, i) {
+               if (slave->dev == slave_dev) {
                        break;
                }
        }
-       return our_slave;
+
+       return slave;
 }
 
-extern inline struct bonding*
-bond_get_bond_by_slave(struct slave *slave)
+extern inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
 {
        if (!slave || !slave->dev->master) {
                return NULL;
        }
 
-       return (struct bonding *)(slave->dev->master->priv);
+       return (struct bonding *)slave->dev->master->priv;
+}
+
+extern inline void bond_set_slave_inactive_flags(struct slave *slave)
+{
+       slave->state = BOND_STATE_BACKUP;
+       slave->dev->flags |= IFF_NOARP;
+}
+
+extern inline void bond_set_slave_active_flags(struct slave *slave)
+{
+       slave->state = BOND_STATE_ACTIVE;
+       slave->dev->flags &= ~IFF_NOARP;
 }
 
 #endif /* _LINUX_BONDING_H */
index dd2abd4..f28091e 100644 (file)
@@ -212,9 +212,7 @@ struct net_local {
 
 /* Index to functions, as function prototypes. */
 
-extern int cs89x0_probe(struct net_device *dev);
-
-static int cs89x0_probe1(struct net_device *dev, int ioaddr);
+static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
 static int net_open(struct net_device *dev);
 static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -274,27 +272,51 @@ __setup("cs89x0_media=", media_fn);
    Return 0 on success.
    */
 
-int __init cs89x0_probe(struct net_device *dev)
+struct net_device * __init cs89x0_probe(int unit)
 {
-       int i;
-       int base_addr = dev ? dev->base_addr : 0;
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       unsigned *port;
+       int err = 0;
+       int irq;
+       int io;
 
-       SET_MODULE_OWNER(dev);
+       if (!dev)
+               return ERR_PTR(-ENODEV);
 
-       if (net_debug)
-               printk("cs89x0:cs89x0_probe(0x%x)\n", base_addr);
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+       io = dev->base_addr;
+       irq = dev->irq;
 
-       if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return cs89x0_probe1(dev, base_addr);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
+       if (net_debug)
+               printk("cs89x0:cs89x0_probe(0x%x)\n", io);
 
-       for (i = 0; netcard_portlist[i]; i++) {
-               if (cs89x0_probe1(dev, netcard_portlist[i]) == 0)
-                       return 0;
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = cs89x0_probe1(dev, io, 0);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = netcard_portlist; *port; port++) {
+                       if (cs89x0_probe1(dev, *port, 0) == 0)
+                               break;
+                       dev->irq = irq;
+               }
+               if (!*port)
+                       err = -ENODEV;
        }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       outw(PP_ChipID, dev->base_addr + ADD_PORT);
+       release_region(dev->base_addr, NETCARD_IO_EXTENT);
+out:
+       free_netdev(dev);
        printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
-       return -ENODEV;
+       return ERR_PTR(err);
 }
 
 static int
@@ -375,39 +397,34 @@ get_eeprom_cksum(int off, int len, int *buffer)
  */
 
 static int __init
-cs89x0_probe1(struct net_device *dev, int ioaddr)
+cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
 {
-       struct net_local *lp;
+       struct net_local *lp = (struct net_local *)dev->priv;
        static unsigned version_printed;
        int i;
        unsigned rev_type = 0;
        int eeprom_buff[CHKSUM_LEN];
        int retval;
 
+       SET_MODULE_OWNER(dev);
        /* Initialize the device structure. */
-       if (dev->priv == NULL) {
-               dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-               if (dev->priv == 0) {
-                       retval = -ENOMEM;
-                       goto out;
-               }
-               lp = (struct net_local *)dev->priv;
+       if (!modular) {
                memset(lp, 0, sizeof(*lp));
                spin_lock_init(&lp->lock);
-#if !defined(MODULE) && (ALLOW_DMA != 0)
+#ifndef MODULE
+#if ALLOW_DMA
                if (g_cs89x0_dma) {
                        lp->use_dma = 1;
                        lp->dma = g_cs89x0_dma;
                        lp->dmasize = 16;       /* Could make this an option... */
                }
 #endif
-#ifndef MODULE
                lp->force = g_cs89x0_media__force;
 #endif
         }
-       lp = (struct net_local *)dev->priv;
 
        /* Grab the region so we can find another board if autoIRQ fails. */
+       /* WTF is going on here? */
        if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) {
                printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
                                dev->name, ioaddr, NETCARD_IO_EXTENT);
@@ -696,9 +713,6 @@ printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
        dev->set_multicast_list = set_multicast_list;
        dev->set_mac_address    = set_mac_address;
 
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-
        printk("\n");
        if (net_debug)
                printk("cs89x0_probe1() successful\n");
@@ -706,9 +720,6 @@ printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
 out2:
        release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
 out1:
-       kfree(dev->priv);
-       dev->priv = 0;
-out:
        return retval;
 }
 
@@ -1655,7 +1666,7 @@ static int set_mac_address(struct net_device *dev, void *p)
 
 #ifdef MODULE
 
-static struct net_device dev_cs89x0;
+static struct net_device *dev_cs89x0;
 
 /*
  * Support the 'debug' module parm even if we're compiled for non-debug to 
@@ -1733,6 +1744,7 @@ MODULE_LICENSE("GPL");
 int
 init_module(void)
 {
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
        struct net_local *lp;
        int ret = 0;
 
@@ -1741,18 +1753,12 @@ init_module(void)
 #else
        debug = 0;
 #endif
-
-       dev_cs89x0.irq = irq;
-       dev_cs89x0.base_addr = io;
-
-        dev_cs89x0.init = cs89x0_probe;
-        dev_cs89x0.priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev_cs89x0.priv == 0) {
-               printk(KERN_ERR "cs89x0.c: Out of memory.\n");
+       if (!dev)
                return -ENOMEM;
-       }
-       memset(dev_cs89x0.priv, 0, sizeof(struct net_local));
-       lp = (struct net_local *)dev_cs89x0.priv;
+
+       dev->irq = irq;
+       dev->base_addr = io;
+       lp = dev->priv;
 
 #if ALLOW_DMA
        if (use_dma) {
@@ -1782,7 +1788,10 @@ init_module(void)
                 printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n");
                 ret = -EPERM;
                goto out;
-        }
+        } else if (io <= 0x1ff) {
+               ret = -ENXIO;
+               goto out;
+       }
 
 #if ALLOW_DMA
        if (use_dma && dmasize != 16 && dmasize != 64) {
@@ -1791,30 +1800,31 @@ init_module(void)
                goto out;
        }
 #endif
+       ret = cs89x0_probe1(dev, io, 1);
+       if (ret)
+               goto out;
 
-        if (register_netdev(&dev_cs89x0) != 0) {
+        if (register_netdev(dev) != 0) {
                 printk(KERN_ERR "cs89x0.c: No card found at 0x%x\n", io);
                 ret = -ENXIO;
+               outw(PP_ChipID, dev->base_addr + ADD_PORT);
+               release_region(dev->base_addr, NETCARD_IO_EXTENT);
                goto out;
         }
+       dev_cs89x0 = dev;
+       return 0;
 out:
-       if (ret)
-               kfree(dev_cs89x0.priv);
+       free_netdev(dev);
        return ret;
 }
 
 void
 cleanup_module(void)
 {
-        if (dev_cs89x0.priv != NULL) {
-                /* Free up the private structure, or leak memory :-)  */
-                unregister_netdev(&dev_cs89x0);
-               outw(PP_ChipID, dev_cs89x0.base_addr + ADD_PORT);
-                kfree(dev_cs89x0.priv);
-                dev_cs89x0.priv = NULL;        /* gets re-allocated by cs89x0_probe1 */
-                /* If we don't do this, we can't re-insmod it later. */
-                release_region(dev_cs89x0.base_addr, NETCARD_IO_EXTENT);
-        }
+       unregister_netdev(dev_cs89x0);
+       outw(PP_ChipID, dev_cs89x0->base_addr + ADD_PORT);
+       release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
+       free_netdev(dev_cs89x0);
 }
 #endif /* MODULE */
 \f
index 62c70b4..0e8b077 100644 (file)
@@ -99,7 +99,7 @@ static volatile int           tx_fifo_in;
 static volatile int            tx_fifo_out;
 static volatile int            free_tx_pages = TX_PAGES;
 static int                     was_down;
-static spinlock_t              de600_lock;
+static spinlock_t              de600_lock = SPIN_LOCK_UNLOCKED;
 
 static inline u8 de600_read_status(struct net_device *dev)
 {
@@ -398,20 +398,31 @@ static void de600_rx_intr(struct net_device *dev)
         */
 }
 
-int __init de600_probe(struct net_device *dev)
+static struct net_device * __init de600_probe(void)
 {
        int     i;
-       static struct net_device_stats de600_netstats;
-       /*dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);*/
+       struct net_device *dev;
+       int err;
+
+       dev = alloc_etherdev(sizeof(struct net_device_stats));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
        SET_MODULE_OWNER(dev);
 
+       if (!request_region(DE600_IO, 3, "de600")) {
+               printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
+               err = -EBUSY;
+               goto out;
+       }
+
        printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
        /* Alpha testers must have the version number to report bugs. */
        if (de600_debug > 1)
                printk(version);
 
        /* probe for adapter */
+       err = -ENODEV;
        rx_page = 0;
        select_nic();
        (void)de600_read_status(dev);
@@ -419,7 +430,7 @@ int __init de600_probe(struct net_device *dev)
        de600_put_command(STOP_RESET);
        if (de600_read_status(dev) & 0xf0) {
                printk(": not at I/O %#3x.\n", DATA_PORT);
-               return -ENODEV;
+               goto out1;
        }
 
        /*
@@ -444,12 +455,7 @@ int __init de600_probe(struct net_device *dev)
                dev->dev_addr[3] |= 0x70;
        } else {
                printk(" not identified in the printer port\n");
-               return -ENODEV;
-       }
-
-       if (!request_region(DE600_IO, 3, "de600")) {
-               printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
-               return -EBUSY;
+               goto out1;
        }
 
        printk(", Ethernet Address: %02X", dev->dev_addr[0]);
@@ -457,22 +463,27 @@ int __init de600_probe(struct net_device *dev)
                printk(":%02X",dev->dev_addr[i]);
        printk("\n");
 
-       /* Initialize the device structure. */
-       dev->priv = &de600_netstats;
-
-       memset(dev->priv, 0, sizeof(struct net_device_stats));
        dev->get_stats = get_stats;
 
        dev->open = de600_open;
        dev->stop = de600_close;
        dev->hard_start_xmit = &de600_start_xmit;
 
-       ether_setup(dev);
-
        dev->flags&=~IFF_MULTICAST;
 
        select_prn();
-       return 0;
+
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+
+       return dev;
+
+out1:
+       release_region(DE600_IO, 3);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int adapter_init(struct net_device *dev)
@@ -527,21 +538,21 @@ static int adapter_init(struct net_device *dev)
        return 0; /* OK */
 }
 
-static struct net_device de600_dev;
+static struct net_device *de600_dev;
 
 static int __init de600_init(void)
 {
-       spin_lock_init(&de600_lock);
-       de600_dev.init = de600_probe;
-       if (register_netdev(&de600_dev) != 0)
-               return -EIO;
+       de600_dev = de600_probe();
+       if (IS_ERR(de600_dev))
+               return PTR_ERR(de600_dev);
        return 0;
 }
 
 static void __exit de600_exit(void)
 {
-       unregister_netdev(&de600_dev);
+       unregister_netdev(de600_dev);
        release_region(DE600_IO, 3);
+       free_netdev(de600_dev);
 }
 
 module_init(de600_init);
index 269aa4b..e407301 100644 (file)
@@ -131,7 +131,6 @@ static void de600_rx_intr(struct net_device *dev);
 
 /* Initialization */
 static void    trigger_interrupt(struct net_device *dev);
-int            de600_probe(struct net_device *dev);
 static int     adapter_init(struct net_device *dev);
 
 /*
index 2c24105..3623c7d 100644 (file)
@@ -226,7 +226,6 @@ static int  de620_rx_intr(struct net_device *);
 
 /* Initialization */
 static int     adapter_init(struct net_device *);
-int            de620_probe(struct net_device *);
 static int     read_eeprom(struct net_device *);
 
 
@@ -814,11 +813,16 @@ static int adapter_init(struct net_device *dev)
  *
  * Check if there is a DE-620 connected
  */
-int __init de620_probe(struct net_device *dev)
+struct net_device * __init de620_probe(int unit)
 {
-       static struct net_device_stats de620_netstats;
-       int i;
        byte checkbyte = 0xa5;
+       struct net_device *dev;
+       int err = -ENOMEM;
+       int i;
+
+       dev = alloc_etherdev(sizeof(struct net_device_stats));
+       if (!dev)
+               goto out;
 
        SET_MODULE_OWNER(dev);
 
@@ -831,11 +835,23 @@ int __init de620_probe(struct net_device *dev)
        dev->base_addr = io;
        dev->irq       = irq;
 
+       /* allow overriding parameters on command line */
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
+       
        if (de620_debug)
                printk(version);
 
        printk(KERN_INFO "D-Link DE-620 pocket adapter");
 
+       if (!request_region(dev->base_addr, 3, "de620")) {
+               printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
+               err = -EBUSY;
+               goto out1;
+       }
+
        /* Initially, configure basic nibble mode, so we can read the EEPROM */
        NIC_Cmd = DEF_NIC_CMD;
        de620_set_register(dev, W_EIP, EIPRegister);
@@ -846,12 +862,8 @@ int __init de620_probe(struct net_device *dev)
 
        if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
                printk(" not identified in the printer port\n");
-               return -ENODEV;
-       }
-
-       if (!request_region(dev->base_addr, 3, "de620")) {
-               printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr);
-               return -EBUSY;
+               err = -ENODEV;
+               goto out2;
        }
 
        /* else, got it! */
@@ -870,10 +882,6 @@ int __init de620_probe(struct net_device *dev)
        else
                printk(" UTP)\n");
 
-       /* Initialize the device structure. */
-       dev->priv = &de620_netstats;
-
-       memset(dev->priv, 0, sizeof(struct net_device_stats));
        dev->get_stats          = get_stats;
        dev->open               = de620_open;
        dev->stop               = de620_close;
@@ -884,8 +892,6 @@ int __init de620_probe(struct net_device *dev)
        
        /* base_addr and irq are already set, see above! */
 
-       ether_setup(dev);
-
        /* dump eeprom */
        if (de620_debug) {
                printk("\nEEPROM contents:\n");
@@ -899,7 +905,17 @@ int __init de620_probe(struct net_device *dev)
                printk("SCR = 0x%02x\n", nic_data.SCR);
        }
 
-       return 0;
+       err = register_netdev(dev);
+       if (err)
+               goto out2;
+       return dev;
+
+out2:
+       release_region(dev->base_addr, 3);
+out1:
+       free_netdev(dev);
+out:
+       return ERR_PTR(err);
 }
 \f
 /**********************************
@@ -994,20 +1010,21 @@ static int __init read_eeprom(struct net_device *dev)
  *
  */
 #ifdef MODULE
-static struct net_device de620_dev;
+static struct net_device *de620_dev;
 
 int init_module(void)
 {
-       de620_dev.init = de620_probe;
-       if (register_netdev(&de620_dev) != 0)
-               return -EIO;
+       de620_dev = de620_probe(-1);
+       if (IS_ERR(de620_dev))
+               return PTR_ERR(de620_dev);
        return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev(&de620_dev);
-       release_region(de620_dev.base_addr, 3);
+       unregister_netdev(de620_dev);
+       release_region(de620_dev->base_addr, 3);
+       free_netdev(de620_dev);
 }
 #endif /* MODULE */
 MODULE_LICENSE("GPL");
index 905f92d..19d5c40 100644 (file)
@@ -1039,13 +1039,13 @@ static int __init dec_lance_init(const int type, const int slot)
        if (dec_lance_debug && version_printed++ == 0)
                printk(version);
 
-       dev = init_etherdev(NULL, sizeof(struct lance_private));
+       dev = alloc_etherdev(sizeof(struct lance_private));
        if (!dev)
                return -ENOMEM;
        SET_MODULE_OWNER(dev);
 
        /*
-        * init_etherdev ensures the data structures used by the LANCE
+        * alloc_etherdev ensures the data structures used by the LANCE
         * are aligned.
         */
        lp = (struct lance_private *) dev->priv;
@@ -1188,9 +1188,6 @@ static int __init dec_lance_init(const int type, const int slot)
                }
        }
 
-       lp->next = root_lance_dev;
-       root_lance_dev = dev;
-
        /* Copy the ethernet address to the device structure, later to the
         * lance initialization block so the lance gets it every time it's
         * (re)initialized.
@@ -1239,11 +1236,14 @@ static int __init dec_lance_init(const int type, const int slot)
        init_timer(&lp->multicast_timer);
        lp->multicast_timer.data = (unsigned long) dev;
        lp->multicast_timer.function = &lance_set_multicast_retry;
-
+       ret = register_netdev(dev);
+       if (ret)
+               goto err_out;
+       lp->next = root_lance_dev;
+       root_lance_dev = dev;
        return 0;
 
 err_out:
-       unregister_netdev(dev);
        free_netdev(dev);
        return ret;
 }
@@ -1288,13 +1288,12 @@ static void __exit dec_lance_cleanup(void)
        while (root_lance_dev) {
                struct net_device *dev = root_lance_dev;
                struct lance_private *lp = (struct lance_private *)dev->priv;
-
+               unregister_netdev(dev);
 #ifdef CONFIG_TC
                if (lp->slot >= 0)
                        release_tc_card(lp->slot);
 #endif
                root_lance_dev = lp->next;
-               unregister_netdev(dev);
                free_netdev(dev);
        }
 }
index 014df26..cada0c6 100644 (file)
@@ -491,7 +491,7 @@ err_out_kfree:
 err_out_region:
        release_region(ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN);
 err_out:
-       kfree(dev);
+       free_netdev(dev);
        return err;
 }
 
index e9700be..7dfb0c6 100644 (file)
@@ -681,8 +681,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
        lp->sh_mem = ioremap(mem_start, mem_len);
        if (lp->sh_mem == NULL) {
                printk(KERN_ERR "depca: cannot remap ISA memory, aborting\n");
-               release_mem_region (mem_start, mem_len);
-               goto out_priv;
+               goto out1;
        }
 
        lp->mem_start = mem_start;
@@ -771,7 +770,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
                status = -ENXIO;
                if (!irqnum) {
                        printk(" and failed to detect IRQ line.\n");
-                       goto out_priv;
+                       goto out2;
                } else {
                        for (dev->irq = 0, i = 0; (depca_irq[i]) && (!dev->irq); i++)
                                if (irqnum == depca_irq[i]) {
@@ -781,7 +780,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
 
                        if (!dev->irq) {
                                printk(" but incorrect IRQ line detected.\n");
-                               return -ENXIO;
+                               goto out2;
                        }
                }
        } else {
@@ -807,11 +806,14 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
        device->driver_data = dev;
        SET_NETDEV_DEV (dev, device);
        
-       register_netdev (dev);
-       return 0;
-
- out_priv:
-       
+       status = register_netdev(dev);
+       if (status == 0)
+               return 0;
+out2:
+       iounmap(lp->sh_mem);
+out1:
+       release_mem_region (mem_start, mem_len);
+out_priv:
        return status;
 }
 \f
index 67322f6..c9b7e9c 100644 (file)
@@ -103,7 +103,7 @@ static int __init dummy_init_one(int index)
                return -ENOMEM;
 
        if ((err = register_netdev(dev_dummy))) {
-               kfree(dev_dummy);
+               free_netdev(dev_dummy);
                dev_dummy = NULL;
        } else {
                dummies[index] = dev_dummy; 
index 45f539e..a6c60cc 100644 (file)
@@ -95,7 +95,6 @@ static inline void mem_off(short port)
 #define E21_BIG_RX_STOP_PG     0xF0    /* Last page +1 of RX ring */
 #define E21_TX_START_PG                E21_RX_STOP_PG  /* First page of TX buffer */
 
-int e2100_probe(struct net_device *dev);
 static int e21_probe1(struct net_device *dev, int ioaddr);
 
 static int e21_open(struct net_device *dev);
@@ -117,10 +116,11 @@ static int e21_close(struct net_device *dev);
        station address).
  */
 
-int  __init e2100_probe(struct net_device *dev)
+static int  __init do_e2100_probe(struct net_device *dev)
 {
        int *port;
        int base_addr = dev->base_addr;
+       int irq = dev->irq;
 
        SET_MODULE_OWNER(dev);
 
@@ -129,13 +129,46 @@ int  __init e2100_probe(struct net_device *dev)
        else if (base_addr != 0)        /* Don't probe at all. */
                return -ENXIO;
 
-       for (port = e21_probe_list; *port; port++)
+       for (port = e21_probe_list; *port; port++) {
+               dev->irq = irq;
                if (e21_probe1(dev, *port) == 0)
                        return 0;
+       }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       /* NB: e21_close() handles free_irq */
+       release_region(dev->base_addr, E21_IO_EXTENT);
+}
+
+struct net_device * __init e2100_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_e2100_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init e21_probe1(struct net_device *dev, int ioaddr)
 {
        int i, status, retval;
@@ -175,13 +208,6 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr)
        for (i = 0; i < 6; i++)
                printk(" %02X", station_addr[i]);
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (" unable to get memory for dev->priv.\n");
-               retval = -ENOMEM;
-               goto out;
-       }
-
        if (dev->irq < 2) {
                int irqlist[] = {15,11,10,12,5,9,3,4}, i;
                for (i = 0; i < 8; i++)
@@ -191,8 +217,6 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr)
                        }
                if (i >= 8) {
                        printk(" unable to get IRQ %d.\n", dev->irq);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
                        retval = -EAGAIN;
                        goto out;
                }
@@ -376,7 +400,7 @@ e21_close(struct net_device *dev)
 \f
 #ifdef MODULE
 #define MAX_E21_CARDS  4       /* Max number of E21 cards per module */
-static struct net_device dev_e21[MAX_E21_CARDS];
+static struct net_device *dev_e21[MAX_E21_CARDS];
 static int io[MAX_E21_CARDS];
 static int irq[MAX_E21_CARDS];
 static int mem[MAX_E21_CARDS];
@@ -398,29 +422,35 @@ ISA device autoprobes on a running machine are not recommended. */
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
-               struct net_device *dev = &dev_e21[this_dev];
-               dev->irq = irq[this_dev];
-               dev->base_addr = io[this_dev];
-               dev->mem_start = mem[this_dev];
-               dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
-               dev->init = e2100_probe;
                if (io[this_dev] == 0)  {
                        if (this_dev != 0) break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               dev->mem_start = mem[this_dev];
+               dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
+               if (do_e2100_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_e21[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -429,13 +459,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
-               struct net_device *dev = &dev_e21[this_dev];
-               if (dev->priv != NULL) {
-                       void *priv = dev->priv;
-                       /* NB: e21_close() handles free_irq */
-                       release_region(dev->base_addr, E21_IO_EXTENT);
+               struct net_device *dev = dev_e21[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index a9a45c1..e9cf1c6 100644 (file)
@@ -302,9 +302,7 @@ struct eepro_local {
 
 /* Index to functions, as function prototypes. */
 
-extern int eepro_probe(struct net_device *dev);
-
-static int     eepro_probe1(struct net_device *dev, short ioaddr);
+static int     eepro_probe1(struct net_device *dev, int autoprobe);
 static int     eepro_open(struct net_device *dev);
 static int     eepro_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -527,10 +525,11 @@ buffer (transmit-buffer = 32K - receive-buffer).
    If dev->base_addr == 2, allocate space for the device and return success
    (detachable devices only).
    */
-int __init eepro_probe(struct net_device *dev)
+static int __init do_eepro_probe(struct net_device *dev)
 {
        int i;
        int base_addr = dev->base_addr;
+       int irq = dev->irq;
 
        SET_MODULE_OWNER(dev);
 
@@ -563,24 +562,48 @@ int __init eepro_probe(struct net_device *dev)
 #endif
 
        if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return eepro_probe1(dev, base_addr);
+               return eepro_probe1(dev, 0);
 
        else if (base_addr != 0)        /* Don't probe at all. */
                return -ENXIO;
 
-
        for (i = 0; eepro_portlist[i]; i++) {
-               int ioaddr = eepro_portlist[i];
-
-               if (check_region(ioaddr, EEPRO_IO_EXTENT))
-                       continue;
-               if (eepro_probe1(dev, ioaddr) == 0)
+               dev->base_addr = eepro_portlist[i];
+               dev->irq = irq;
+               if (eepro_probe1(dev, 1) == 0)
                        return 0;
        }
 
        return -ENODEV;
 }
 
+struct net_device * __init eepro_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct eepro_local));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       SET_MODULE_OWNER(dev);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_eepro_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, EEPRO_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
 {
        unsigned short Word;
@@ -713,83 +736,75 @@ static void eepro_print_info (struct net_device *dev)
    probes on the ISA bus.  A good device probe avoids doing writes, and
    verifies that the correct device exists and functions.  */
 
-static int __init eepro_probe1(struct net_device *dev, short ioaddr)
+static int __init eepro_probe1(struct net_device *dev, int autoprobe)
 {
        unsigned short station_addr[6], id, counter;
-       int i, j, irqMask, retval = 0;
+       int i;
        struct eepro_local *lp;
        enum iftype { AUI=0, BNC=1, TPE=2 };
+       int ioaddr = dev->base_addr;
+
+       /* Grab the region so we can find another board if autoIRQ fails. */
+       if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) { 
+               if (!autoprobe)
+                       printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
+                               ioaddr);
+               return -EBUSY;
+       }
 
        /* Now, we are going to check for the signature of the
           ID_REG (register 2 of bank 0) */
 
-       id=inb(ioaddr + ID_REG);
+       id = inb(ioaddr + ID_REG);
 
-       if (((id) & ID_REG_MASK) != ID_REG_SIG) {
-               retval = -ENODEV;
+       if ((id & ID_REG_MASK) != ID_REG_SIG)
                goto exit;
-       }
-
-               /* We seem to have the 82595 signature, let's
-                  play with its counter (last 2 bits of
-                  register 2 of bank 0) to be sure. */
 
-               counter = (id & R_ROBIN_BITS);
+       /* We seem to have the 82595 signature, let's
+          play with its counter (last 2 bits of
+          register 2 of bank 0) to be sure. */
 
-       if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS)!=(counter + 0x40)) {
-               retval = -ENODEV;
-               goto exit;
-       }
+       counter = id & R_ROBIN_BITS;
 
-                       /* Initialize the device structure */
-                       dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL);
-       if (!dev->priv) {
-               retval = -ENOMEM;
+       if ((inb(ioaddr + ID_REG) & R_ROBIN_BITS) != (counter + 0x40))
                goto exit;
-       }
 
-                       memset(dev->priv, 0, sizeof(struct eepro_local));
-
-                       lp = (struct eepro_local *)dev->priv;
-
-       /* default values */
-       lp->eepro = 0;
+       lp = (struct eepro_local *)dev->priv;
+       memset(lp, 0, sizeof(struct eepro_local));
        lp->xmt_bar = XMT_BAR_PRO;
        lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
        lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
        lp->eeprom_reg = EEPROM_REG_PRO;
+       spin_lock_init(&lp->lock);
 
-                       /* Now, get the ethernet hardware address from
-                          the EEPROM */
-                       station_addr[0] = read_eeprom(ioaddr, 2, dev);
+       /* Now, get the ethernet hardware address from
+          the EEPROM */
+       station_addr[0] = read_eeprom(ioaddr, 2, dev);
 
-                       /* FIXME - find another way to know that we've found
-                        * an Etherexpress 10
-                        */
-                       if (station_addr[0] == 0x0000 ||
-                           station_addr[0] == 0xffff) {
-                               lp->eepro = LAN595FX_10ISA;
+       /* FIXME - find another way to know that we've found
+        * an Etherexpress 10
+        */
+       if (station_addr[0] == 0x0000 || station_addr[0] == 0xffff) {
+               lp->eepro = LAN595FX_10ISA;
                lp->eeprom_reg = EEPROM_REG_10;
                lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
                lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
                lp->xmt_bar = XMT_BAR_10;
-                               station_addr[0] = read_eeprom(ioaddr, 2, dev);
-                       }
-                       station_addr[1] = read_eeprom(ioaddr, 3, dev);
-                       station_addr[2] = read_eeprom(ioaddr, 4, dev);
+               station_addr[0] = read_eeprom(ioaddr, 2, dev);
+       }
+       station_addr[1] = read_eeprom(ioaddr, 3, dev);
+       station_addr[2] = read_eeprom(ioaddr, 4, dev);
 
        if (!lp->eepro) {
                if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ)
                        lp->eepro = 2;
                else if (station_addr[2] == SA_ADDR1)
                        lp->eepro = 1;
-                       }
-
-                       /* Fill in the 'dev' fields. */
-                       dev->base_addr = ioaddr;
+       }
 
+       /* Fill in the 'dev' fields. */
        for (i=0; i < 6; i++)
-                               dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
+               dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
 
        /* RX buffer must be more than 3K and less than 29K */
        if (dev->mem_end < 3072 || dev->mem_end > 29696)
@@ -798,65 +813,49 @@ static int __init eepro_probe1(struct net_device *dev, short ioaddr)
        /* calculate {xmt,rcv}_{lower,upper}_limit */
        eepro_recalc(dev);
 
-
-                       if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
-                               dev->if_port = BNC;
+       if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
+               dev->if_port = BNC;
        else
                dev->if_port = TPE;
 
-       if ((dev->irq < 2) && (lp->eepro!=0)) {
-                               i = read_eeprom(ioaddr, 1, dev);
-                               irqMask = read_eeprom(ioaddr, 7, dev);
-                               i &= 0x07; /* Mask off INT number */
-
-                               for (j=0; ((j<16) && (i>=0)); j++) {
-                                       if ((irqMask & (1<<j))!=0) {
-                                               if (i==0) {
-                                                       dev->irq = j;
-                                                       break; /* found bit corresponding to irq */
-                                               }
-                                               i--; /* count bits set in irqMask */
-                                       }
-                               }
-                               if (dev->irq < 2) {
-                       printk(KERN_ERR " Duh! invalid interrupt vector stored in EEPROM.\n");
-                       retval = -ENODEV;
-                       goto freeall;
-                               } else
-                       if (dev->irq==2) dev->irq = 9;
-                       }
-
-                       /* Grab the region so we can find another board if autoIRQ fails. */
-                       if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) { 
-                               printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n", ioaddr);
-                               goto freeall;
-                       }
-                       ((struct eepro_local *)dev->priv)->lock = SPIN_LOCK_UNLOCKED;
-
-                       dev->open               = eepro_open;
-                       dev->stop               = eepro_close;
-                       dev->hard_start_xmit    = eepro_send_packet;
-                       dev->get_stats          = eepro_get_stats;
-                       dev->set_multicast_list = &set_multicast_list;
-                       dev->tx_timeout         = eepro_tx_timeout;
-                       dev->watchdog_timeo     = TX_TIMEOUT;
-
-                       /* Fill in the fields of the device structure with
-                          ethernet generic values */
-                       ether_setup(dev);
-
+       if (dev->irq < 2 && lp->eepro != 0) {
+               /* Mask off INT number */
+               int count = read_eeprom(ioaddr, 1, dev) & 7;
+               unsigned irqMask = read_eeprom(ioaddr, 7, dev);
+               while (count--)
+                       irqMask &= irqMask - 1;
+               count = ffs(irqMask);
+               if (count)
+                       dev->irq = count - 1;
+               if (dev->irq < 2) {
+                       printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
+                       goto exit;
+               } else if (dev->irq == 2) {
+                       dev->irq = 9;
+               }
+       }
+       dev->open               = eepro_open;
+       dev->stop               = eepro_close;
+       dev->hard_start_xmit    = eepro_send_packet;
+       dev->get_stats          = eepro_get_stats;
+       dev->set_multicast_list = &set_multicast_list;
+       dev->tx_timeout         = eepro_tx_timeout;
+       dev->watchdog_timeo     = TX_TIMEOUT;
        /* print boot time info */
        eepro_print_info(dev);
 
        /* reset 82595 */
-                       eepro_reset(ioaddr);
-
+       eepro_reset(ioaddr);
+       return 0;
 exit:
-       return retval;
-freeall:
-       kfree(dev->priv);
-       goto exit;
-
+       release_region(dev->base_addr, EEPRO_IO_EXTENT);
+       return -ENODEV;
 }
 
 /* Open/initialize the board.  This is called (in the current kernel)
@@ -1701,7 +1700,7 @@ eepro_transmit_interrupt(struct net_device *dev)
 #ifdef MODULE
 
 #define MAX_EEPRO 8
-static struct net_device dev_eepro[MAX_EEPRO];
+static struct net_device *dev_eepro[MAX_EEPRO];
 
 static int io[MAX_EEPRO];
 static int irq[MAX_EEPRO];
@@ -1729,6 +1728,7 @@ MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)
 int
 init_module(void)
 {
+       struct net_device *dev;
        int i;
        if (io[0] == 0 && autodetect == 0) {
                printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
@@ -1743,17 +1743,24 @@ init_module(void)
        }
 
        for (i = 0; i < MAX_EEPRO; i++) {
-               struct net_device *d = &dev_eepro[n_eepro];
-               d->mem_end      = mem[i];
-               d->base_addr    = io[i];
-               d->irq          = irq[i];
-               d->init         = eepro_probe;
-
-                       if (register_netdev(d) == 0)
-                               n_eepro++;
-                       else
-                               break;
+               dev = alloc_etherdev(sizeof(struct eepro_local));
+               if (!dev)
+                       break;
+
+               dev->mem_end = mem[i];
+               dev->base_addr = io[i];
+               dev->irq = irq[i];
+
+               if (do_eepro_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_eepro[n_eepro++] = dev;
+                               continue;
+                       }
+                       release_region(dev->base_addr, EEPRO_IO_EXTENT);
                }
+               free_netdev(dev);
+               break;
+       }
 
        if (n_eepro)
                printk(KERN_INFO "%s", version);
@@ -1767,15 +1774,10 @@ cleanup_module(void)
        int i;
 
        for (i=0; i<n_eepro; i++) {
-               struct net_device *d = &dev_eepro[i];
-               unregister_netdev(d);
-
-               kfree(d->priv);
-               d->priv=NULL;
-
-               /* If we don't do this, we can't re-insmod it later. */
-               release_region(d->base_addr, EEPRO_IO_EXTENT);
-
+               struct net_device *dev = dev_eepro[i];
+               unregister_netdev(dev);
+               release_region(dev->base_addr, EEPRO_IO_EXTENT);
+               free_netdev(dev);
        }
 }
 #endif /* MODULE */
index 603956e..7e8ff09 100644 (file)
@@ -244,7 +244,6 @@ static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 };
  * Prototypes for Linux interface
  */
 
-extern int express_probe(struct net_device *dev);
 static int eexp_open(struct net_device *dev);
 static int eexp_close(struct net_device *dev);
 static void eexp_timeout(struct net_device *dev);
@@ -334,11 +333,13 @@ static inline unsigned short int SHADOW(short int addr)
  * checks for presence of EtherExpress card
  */
 
-int __init express_probe(struct net_device *dev)
+static int __init do_express_probe(struct net_device *dev)
 {
        unsigned short *port;
        static unsigned short ports[] = { 0x240,0x300,0x310,0x270,0x320,0x340,0 };
        unsigned short ioaddr = dev->base_addr;
+       int dev_irq = dev->irq;
+       int err;
 
        SET_MODULE_OWNER(dev);
 
@@ -391,27 +392,58 @@ int __init express_probe(struct net_device *dev)
                }
        }
 #endif
-       if (ioaddr&0xfe00)
-               return eexp_hw_probe(dev,ioaddr);
-       else if (ioaddr)
+       if (ioaddr&0xfe00) {
+               if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"))
+                       return -EBUSY;
+               err = eexp_hw_probe(dev,ioaddr);
+               release_region(ioaddr, EEXP_IO_EXTENT);
+               return err;
+       } else if (ioaddr)
                return -ENXIO;
 
        for (port=&ports[0] ; *port ; port++ )
        {
                unsigned short sum = 0;
                int i;
+               if (!request_region(*port, EEXP_IO_EXTENT, "EtherExpress"))
+                       continue;
                for ( i=0 ; i<4 ; i++ )
                {
                        unsigned short t;
                        t = inb(*port + ID_PORT);
                        sum |= (t>>4) << ((t & 0x03)<<2);
                }
-               if (sum==0xbaba && !eexp_hw_probe(dev,*port))
+               if (sum==0xbaba && !eexp_hw_probe(dev,*port)) {
+                       release_region(*port, EEXP_IO_EXTENT);
                        return 0;
+               }
+               release_region(*port, EEXP_IO_EXTENT);
+               dev->irq = dev_irq;
        }
        return -ENODEV;
 }
 
+struct net_device * __init express_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_express_probe(dev);
+       if (!err) {
+               err = register_netdev(dev);
+               if (!err)
+                       return dev;
+       }
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 /*
  * open and initialize the adapter, ready for use
  */
@@ -1058,7 +1090,7 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
        unsigned int memory_size;
        int i;
        unsigned short xsum = 0;
-       struct net_local *lp;
+       struct net_local *lp = dev->priv;
 
        printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
 
@@ -1108,17 +1140,18 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
                buswidth = !((setupval & 0x400) >> 10);
        }
 
-       dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (!dev->priv)
-               return -ENOMEM;
-
-       memset(dev->priv, 0, sizeof(struct net_local));
+       memset(lp, 0, sizeof(struct net_local));
        spin_lock_init(&lp->lock);
 
        printk("(IRQ %d, %s connector, %d-bit bus", dev->irq, 
               eexp_ifmap[dev->if_port], buswidth?8:16);
  
+       if (!request_region(dev->base_addr + 0x300e, 1, "EtherExpress"))
+               return -EBUSY;
+
        eexp_hw_set_interface(dev);
+       release_region(dev->base_addr + 0x300e, 1);
   
        /* Find out how much RAM we have on the card */
        outw(0, dev->base_addr + WRITE_PTR);
@@ -1156,7 +1189,6 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
                break;
        default:
                printk(") bad memory size (%dk).\n", memory_size);
-               kfree(dev->priv);
                return -ENODEV;
                break;
        }
@@ -1171,7 +1203,6 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
        dev->set_multicast_list = &eexp_set_multicast;
        dev->tx_timeout = eexp_timeout;
        dev->watchdog_timeo = 2*HZ;
-       ether_setup(dev);
        return 0;
 }
 
@@ -1654,7 +1685,7 @@ eexp_set_multicast(struct net_device *dev)
 
 #define EEXP_MAX_CARDS     4    /* max number of cards to support */
 
-static struct net_device dev_eexp[EEXP_MAX_CARDS];
+static struct net_device *dev_eexp[EEXP_MAX_CARDS];
 static int irq[EEXP_MAX_CARDS];
 static int io[EEXP_MAX_CARDS];
 
@@ -1671,25 +1702,30 @@ MODULE_LICENSE("GPL");
  */
 int init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
-               struct net_device *dev = &dev_eexp[this_dev];
+               dev = alloc_etherdev(sizeof(struct net_local));
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
-               dev->init = express_probe;
                if (io[this_dev] == 0) {
-                       if (this_dev) break;
+                       if (this_dev)
+                               break;
                        printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
-                       if (found != 0) return 0;
-                       return -ENXIO;
+               if (do_express_probe(dev) == 0 && register_netdev(dev) == 0) {
+                       dev_eexp[this_dev] = dev;
+                       found++;
+                       continue;
                }
-               found++;
+               printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
+               free_netdev(dev);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void cleanup_module(void)
@@ -1697,11 +1733,10 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
-               struct net_device *dev = &dev_eexp[this_dev];
-               if (dev->priv != NULL) {
+               struct net_device *dev = dev_eexp[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
+                       free_netdev(dev);
                }
        }
 }
index 6f82a2d..0ee18be 100644 (file)
@@ -600,7 +600,7 @@ static int __init eql_init_module(void)
 
        err = register_netdev(dev_eql);
        if (err) 
-               kfree(dev_eql);
+               free_netdev(dev_eql);
        return err;
 }
 
index a46ee65..0063813 100644 (file)
@@ -62,7 +62,6 @@ static const char version[] =
 
 #include "8390.h"
 
-int es_probe(struct net_device *dev);
 static int es_probe1(struct net_device *dev, int ioaddr);
 
 static int es_open(struct net_device *dev);
@@ -125,9 +124,11 @@ static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15};
  *     PROM for a match against the Racal-Interlan assigned value.
  */
 
-int __init es_probe(struct net_device *dev)
+static int __init do_es_probe(struct net_device *dev)
 {
        unsigned short ioaddr = dev->base_addr;
+       int irq = dev->irq;
+       int mem_start = dev->mem_start;
 
        SET_MODULE_OWNER(dev);
 
@@ -144,13 +145,47 @@ int __init es_probe(struct net_device *dev)
        }
 
        /* EISA spec allows for up to 16 slots, but 8 is typical. */
-       for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
+       for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
                if (es_probe1(dev, ioaddr) == 0)
                        return 0;
+               dev->irq = irq;
+               dev->mem_start = mem_start;
+       }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, ES_IO_EXTENT);
+}
+
+struct net_device * __init es_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_es_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init es_probe1(struct net_device *dev, int ioaddr)
 {
        int i, retval;
@@ -240,13 +275,6 @@ static int __init es_probe1(struct net_device *dev, int ioaddr)
 
        printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1);
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (" unable to allocate memory for dev->priv.\n");
-               retval = -ENOMEM;
-               goto out1;
-       }
-
 #if ES_DEBUG & ES_D_PROBE
        if (inb(ioaddr + ES_CFG5))
                printk("es3210: Warning - DMA channel enabled, but not used here.\n");
@@ -376,7 +404,7 @@ static int es_close(struct net_device *dev)
 #ifdef MODULE
 #define MAX_ES_CARDS   4       /* Max number of ES3210 cards per module */
 #define NAMELEN                8       /* # of chars for storing dev->name */
-static struct net_device dev_es3210[MAX_ES_CARDS];
+static struct net_device *dev_es3210[MAX_ES_CARDS];
 static int io[MAX_ES_CARDS];
 static int irq[MAX_ES_CARDS];
 static int mem[MAX_ES_CARDS];
@@ -393,26 +421,32 @@ MODULE_LICENSE("GPL");
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
-               struct net_device *dev = &dev_es3210[this_dev];
+               if (io[this_dev] == 0 && this_dev != 0)
+                       break;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
-               dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
-               dev->init = es_probe;
-               /* Default is to only install one card. */
-               if (io[this_dev] == 0 && this_dev != 0) break;
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               dev->mem_start = mem[this_dev];
+               if (do_es_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_es3210[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -421,13 +455,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
-               struct net_device *dev = &dev_es3210[this_dev];
-               if (dev->priv != NULL) {
-                       void *priv = dev->priv;
-                       free_irq(dev->irq, dev);
-                       release_region(dev->base_addr, ES_IO_EXTENT);
+               struct net_device *dev = dev_es3210[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index 4662cb7..0d6c604 100644 (file)
@@ -369,7 +369,6 @@ static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15, 0
 #define NUM_OF_EISA_IRQS   8
 
 static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
-static unsigned int boot = 1;
 
 /* Use 0 for production, 1 for verification, >2 for debug */
 #ifndef ETH16I_DEBUG
@@ -395,8 +394,6 @@ struct eth16i_local {
 
 /* Function prototypes */
 
-extern int     eth16i_probe(struct net_device *dev);
-
 static int     eth16i_probe1(struct net_device *dev, int ioaddr);
 static int     eth16i_check_signature(int ioaddr);
 static int     eth16i_probe_port(int ioaddr);
@@ -418,7 +415,7 @@ static void    eth16i_timeout(struct net_device *dev);
 static void    eth16i_skip_packet(struct net_device *dev);
 static void    eth16i_multicast(struct net_device *dev); 
 static void    eth16i_select_regbank(unsigned char regbank, int ioaddr);
-static void    eth16i_initialize(struct net_device *dev);
+static void    eth16i_initialize(struct net_device *dev, int boot);
 
 #if 0
 static int     eth16i_set_irq(struct net_device *dev);
@@ -432,7 +429,7 @@ static struct net_device_stats *eth16i_get_stats(struct net_device *dev);
 
 static char cardname[] __initdata = "ICL EtherTeam 16i/32";
 
-int __init eth16i_probe(struct net_device *dev)
+static int __init do_eth16i_probe(struct net_device *dev)
 {
        int i;
        int ioaddr;
@@ -461,14 +458,38 @@ int __init eth16i_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+struct net_device * __init eth16i_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_eth16i_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, ETH16I_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
 {
-       struct eth16i_local *lp;
+       struct eth16i_local *lp = dev->priv;
        static unsigned version_printed;
        int retval;
 
-       boot = 1;  /* To inform initilization that we are in boot probe */
-
        /* Let's grab the region */
        if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name))
                return -EBUSY;
@@ -531,22 +552,13 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
        eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
        outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); 
 
-       eth16i_initialize(dev);   /* Initialize rest of the chip's registers */
+       eth16i_initialize(dev, 1); /* Initialize rest of the chip's registers */
 
        /* Now let's same some energy by shutting down the chip ;) */
        BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
 
        /* Initialize the device structure */
-       if(dev->priv == NULL) {
-               dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
-               if(dev->priv == NULL) {
-                       free_irq(dev->irq, dev);
-                       retval = -ENOMEM;
-                       goto out;
-               }
-       }
-
-       memset(dev->priv, 0, sizeof(struct eth16i_local));
+       memset(lp, 0, sizeof(struct eth16i_local));
        dev->open               = eth16i_open;
        dev->stop               = eth16i_close;
        dev->hard_start_xmit    = eth16i_tx;
@@ -554,15 +566,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
        dev->set_multicast_list = eth16i_multicast;
        dev->tx_timeout         = eth16i_timeout;
        dev->watchdog_timeo     = TX_TIMEOUT;
-
-       lp = (struct eth16i_local *)dev->priv;
        spin_lock_init(&lp->lock);
-
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-
-       boot = 0;
-
        return 0;
 out:
        release_region(ioaddr, ETH16I_IO_EXTENT);
@@ -570,7 +574,7 @@ out:
 }
 
 
-static void eth16i_initialize(struct net_device *dev)
+static void eth16i_initialize(struct net_device *dev, int boot)
 {
        int ioaddr = dev->base_addr;
        int i, node_w = 0;
@@ -953,7 +957,7 @@ static int eth16i_open(struct net_device *dev)
        outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
 
        /* Initialize the chip */
-       eth16i_initialize(dev);  
+       eth16i_initialize(dev, 0);  
 
        /* Set the transmit buffer size */
        lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
@@ -1401,7 +1405,7 @@ static ushort eth16i_parse_mediatype(const char* s)
 
 #define MAX_ETH16I_CARDS 4  /* Max number of Eth16i cards per module */
 
-static struct net_device dev_eth16i[MAX_ETH16I_CARDS];
+static struct net_device *dev_eth16i[MAX_ETH16I_CARDS];
 static int io[MAX_ETH16I_CARDS];
 #if 0
 static int irq[MAX_ETH16I_CARDS];
@@ -1431,14 +1435,14 @@ MODULE_PARM_DESC(debug, "eth16i debug level (0-6)");
 int init_module(void)
 {
        int this_dev, found = 0;
+       struct net_device *dev;
+
+       for (this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
+               dev = alloc_etherdev(sizeof(struct eth16i_local));
+               if (!dev)
+                       break;
 
-       for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
-       {
-               struct net_device *dev = &dev_eth16i[this_dev];
-       
-               dev->irq = 0; /* irq[this_dev]; */
                dev->base_addr = io[this_dev];
-               dev->init = eth16i_probe;
 
                if(debug != -1)
                        eth16i_debug = debug;
@@ -1448,44 +1452,43 @@ int init_module(void)
 
                dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
 
-               if(io[this_dev] == 0)
-               {
-                       if(this_dev != 0) break; /* Only autoprobe 1st one */
+               if(io[this_dev] == 0) {
+                       if(this_dev != 0) /* Only autoprobe 1st one */
+                               break;
 
                        printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
                }
 
-               if(register_netdev(dev) != 0)
-               {
-                       printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
-                              io[this_dev]);
-           
-                       if(found != 0) return 0;
-                       return -ENXIO;
+               if (do_eth16i_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_eth16i[found++] = dev;
+                               continue;
+                       }
+                       free_irq(dev->irq, dev);
+                       release_region(dev->base_addr, ETH16I_IO_EXTENT);
                }
-
-               found++;
+               printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
+                      io[this_dev]);
+               free_netdev(dev);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
        
 void cleanup_module(void)
 {
        int this_dev;
 
-       for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
-       {
-               struct net_device* dev = &dev_eth16i[this_dev];
+       for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
+               struct net_device *dev = dev_eth16i[this_dev];
                
-               if(dev->priv != NULL)
-               {
+               if(dev->priv) {
                        unregister_netdev(dev);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
-                       
                        free_irq(dev->irq, dev);
                        release_region(dev->base_addr, ETH16I_IO_EXTENT);
-                       
+                       free_netdev(dev);
                }
        }
 }
index 7f4f4ae..6f2de52 100644 (file)
@@ -72,8 +72,7 @@ static int  __init ethertap_probe(int unit)
        struct net_device *dev;
        int err = -ENOMEM;
 
-       dev = alloc_netdev(sizeof(struct net_local), "tap%d",
-                          ether_setup);
+       dev = alloc_etherdev(sizeof(struct net_local));
 
        if (!dev)
                goto out;
index af7e100..3bf2273 100644 (file)
@@ -324,25 +324,14 @@ static int Read_EEPROM(u_long iobase, u_char eaddr);
 static int Write_EEPROM(short data, u_long iobase, u_char eaddr);
 static u_char get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType);
 
-static void isa_probe(struct net_device *dev, u_long iobase);
-static void eisa_probe(struct net_device *dev, u_long iobase);
-static struct net_device *alloc_device(struct net_device *dev, u_long iobase);
-static int ewrk3_dev_index(char *s);
-static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *));
+static int ewrk3_probe1(struct net_device *dev, u_long iobase, int irq);
+static int isa_probe(struct net_device *dev, u_long iobase);
+static int eisa_probe(struct net_device *dev, u_long iobase);
 
-
-#ifdef MODULE
-static int autoprobed = 1, loading_module = 1;
-
-#else
-static u_char irq[] =
-{5, 0, 10, 3, 11, 9, 15, 12};
-static int autoprobed, loading_module;
-
-#endif                         /* MODULE */
+static u_char irq[MAX_NUM_EWRK3S+1] = {5, 0, 10, 3, 11, 9, 15, 12};
 
 static char name[EWRK3_STRLEN + 1];
-static int num_ewrk3s, num_eth;
+static int num_ewrks3s;
 
 /*
    ** Miscellaneous defines...
@@ -352,38 +341,50 @@ static int num_ewrk3s, num_eth;
     mdelay(1);\
 }
 
-int __init ewrk3_probe(struct net_device *dev)
+struct net_device * __init ewrk3_probe(int unit)
 {
-       int tmp = num_ewrk3s, status = -ENODEV;
-       u_long iobase = dev->base_addr;
+       struct net_device *dev = alloc_etherdev(sizeof(struct ewrk3_private));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
        SET_MODULE_OWNER(dev);
 
-       if ((iobase == 0) && loading_module) {
-               printk("Autoprobing is not supported when loading a module based driver.\n");
-               status = -EIO;
-       } else {                /* First probe for the Ethernet */
-               /* Address PROM pattern */
-               isa_probe(dev, iobase);
-               eisa_probe(dev, iobase);
-
-               if ((tmp == num_ewrk3s) && (iobase != 0) && loading_module) {
-                       printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name,
-                              iobase);
-               }
-               /*
-                  ** Walk the device list to check that at least one device
-                  ** initialised OK
-                */
-               for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
+       err = ewrk3_probe1(dev, dev->base_addr, dev->irq);
+       if (err) 
+               goto out;
+       return dev;
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+       
+}
 
-               if (dev->priv)
-                       status = 0;
-               if (iobase == 0)
-                       autoprobed = 1;
-       }
+static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
+{
+       int err;
 
-       return status;
+       dev->base_addr = iobase;
+       dev->irq = irq;
+
+       /* Address PROM pattern */
+       err = isa_probe(dev, iobase);
+       if (err != 0) 
+               err = eisa_probe(dev, iobase);
+
+       if (err)
+               return err;
+
+       err = register_netdev(dev);
+       if (err)
+               release_region(dev->base_addr, EWRK3_TOTAL_SIZE);
+
+       return err;
 }
 
 static int __init 
@@ -396,8 +397,8 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
        u_char eeprom_image[EEPROM_MAX], chksum, eisa_cr = 0;
 
        /*
-          ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
-          ** This also disables the EISA_ENABLE bit in the EISA Control Register.
+       ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
+       ** This also disables the EISA_ENABLE bit in the EISA Control Register.
         */
        if (iobase > 0x400)
                eisa_cr = inb(EISA_CR);
@@ -409,232 +410,210 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
        icr &= 0x70;
        outb(icr, EWRK3_ICR);   /* Disable all the IRQs */
 
-       if (nicsr == (CSR_TXD | CSR_RXD)) {
+       if (nicsr == (CSR_TXD | CSR_RXD))
+               return -ENXIO;
 
-               /* Check that the EEPROM is alive and well and not living on Pluto... */
-               for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
-                       union {
-                               short val;
-                               char c[2];
-                       } tmp;
 
-                       tmp.val = (short) Read_EEPROM(iobase, (i >> 1));
-                       eeprom_image[i] = tmp.c[0];
-                       eeprom_image[i + 1] = tmp.c[1];
-                       chksum += eeprom_image[i] + eeprom_image[i + 1];
-               }
+       /* Check that the EEPROM is alive and well and not living on Pluto... */
+       for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
+               union {
+                       short val;
+                       char c[2];
+               } tmp;
 
-               if (chksum != 0) {      /* Bad EEPROM Data! */
-                       printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
-                       status = -ENXIO;
-               } else {
-                       EthwrkSignature(name, eeprom_image);
-                       if (*name != '\0') {    /* found a EWRK3 device */
-                               dev->base_addr = iobase;
+               tmp.val = (short) Read_EEPROM(iobase, (i >> 1));
+               eeprom_image[i] = tmp.c[0];
+               eeprom_image[i + 1] = tmp.c[1];
+               chksum += eeprom_image[i] + eeprom_image[i + 1];
+       }
 
-                               if (iobase > 0x400) {
-                                       outb(eisa_cr, EISA_CR);         /* Rewrite the EISA CR */
-                               }
-                               lemac = eeprom_image[EEPROM_CHIPVER];
-                               cmr = inb(EWRK3_CMR);
-
-                               if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
-                               ((lemac == LeMAC2) && !(cmr & CMR_HS))) {
-                                       printk("%s: %s at %#4lx", dev->name, name, iobase);
-                                       hard_strapped = 1;
-                               } else if ((iobase & 0x0fff) == EWRK3_EISA_IO_PORTS) {
-                                       /* EISA slot address */
-                                       printk("%s: %s at %#4lx (EISA slot %ld)",
-                                              dev->name, name, iobase, ((iobase >> 12) & 0x0f));
-                               } else {        /* ISA port address */
-                                       printk("%s: %s at %#4lx", dev->name, name, iobase);
-                               }
+       if (chksum != 0) {      /* Bad EEPROM Data! */
+               printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
+               return -ENXIO;
+       }
+       
+       EthwrkSignature(name, eeprom_image);
+       if (*name == '\0') 
+               return -ENXIO;
+
+       dev->base_addr = iobase;
+                               
+       if (iobase > 0x400) {
+               outb(eisa_cr, EISA_CR);         /* Rewrite the EISA CR */
+       }
+       lemac = eeprom_image[EEPROM_CHIPVER];
+       cmr = inb(EWRK3_CMR);
+       
+       if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
+           ((lemac == LeMAC2) && !(cmr & CMR_HS))) {
+               printk("%s: %s at %#4lx", dev->name, name, iobase);
+               hard_strapped = 1;
+       } else if ((iobase & 0x0fff) == EWRK3_EISA_IO_PORTS) {
+               /* EISA slot address */
+               printk("%s: %s at %#4lx (EISA slot %ld)",
+                      dev->name, name, iobase, ((iobase >> 12) & 0x0f));
+       } else {        /* ISA port address */
+               printk("%s: %s at %#4lx", dev->name, name, iobase);
+       }
 
-                               if (!status) {
-                                       printk(", h/w address ");
-                                       if (lemac != LeMAC2)
-                                               DevicePresent(iobase);  /* need after EWRK3_INIT */
-                                       status = get_hw_addr(dev, eeprom_image, lemac);
-                                       for (i = 0; i < ETH_ALEN - 1; i++) {    /* get the ethernet addr. */
-                                               printk("%2.2x:", dev->dev_addr[i]);
-                                       }
-                                       printk("%2.2x,\n", dev->dev_addr[i]);
+       printk(", h/w address ");
+       if (lemac != LeMAC2)
+               DevicePresent(iobase);  /* need after EWRK3_INIT */
+       status = get_hw_addr(dev, eeprom_image, lemac);
+       for (i = 0; i < ETH_ALEN - 1; i++) {    /* get the ethernet addr. */
+               printk("%2.2x:", dev->dev_addr[i]);
+       }
+       printk("%2.2x,\n", dev->dev_addr[i]);
+       
+       if (status) {
+               printk("      which has an EEPROM CRC error.\n");
+               return -ENXIO;
+       }
 
-                                       if (status) {
-                                               printk("      which has an EEPROM CRC error.\n");
-                                               status = -ENXIO;
-                                       } else {
-                                               if (lemac == LeMAC2) {  /* Special LeMAC2 CMR things */
-                                                       cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
-                                                       if (eeprom_image[EEPROM_MISC0] & READ_AHEAD)
-                                                               cmr |= CMR_RA;
-                                                       if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND)
-                                                               cmr |= CMR_WB;
-                                                       if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL)
-                                                               cmr |= CMR_POLARITY;
-                                                       if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK)
-                                                               cmr |= CMR_LINK;
-                                                       if (eeprom_image[EEPROM_MISC0] & _0WS_ENA)
-                                                               cmr |= CMR_0WS;
-                                               }
-                                               if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
-                                                       cmr |= CMR_DRAM;
-                                               outb(cmr, EWRK3_CMR);
-
-                                               cr = inb(EWRK3_CR);     /* Set up the Control Register */
-                                               cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
-                                               if (cr & SETUP_APD)
-                                                       cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
-                                               cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
-                                               cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
-                                               outb(cr, EWRK3_CR);
+       if (lemac == LeMAC2) {  /* Special LeMAC2 CMR things */
+               cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
+               if (eeprom_image[EEPROM_MISC0] & READ_AHEAD)
+                       cmr |= CMR_RA;
+               if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND)
+                       cmr |= CMR_WB;
+               if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL)
+                       cmr |= CMR_POLARITY;
+               if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK)
+                       cmr |= CMR_LINK;
+               if (eeprom_image[EEPROM_MISC0] & _0WS_ENA)
+                       cmr |= CMR_0WS;
+       }
+       if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
+               cmr |= CMR_DRAM;
+       outb(cmr, EWRK3_CMR);
+       
+       cr = inb(EWRK3_CR);     /* Set up the Control Register */
+       cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
+       if (cr & SETUP_APD)
+               cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
+       cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
+       cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
+       outb(cr, EWRK3_CR);
 
-                                               /*
-                                                  ** Determine the base address and window length for the EWRK3
-                                                  ** RAM from the memory base register.
-                                                */
-                                               mem_start = inb(EWRK3_MBR);
-                                               shmem_length = 0;
-                                               if (mem_start != 0) {
-                                                       if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
-                                                               mem_start *= SHMEM_64K;
-                                                               shmem_length = SHMEM_64K;
-                                                       } else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
-                                                               mem_start *= SHMEM_32K;
-                                                               shmem_length = SHMEM_32K;
-                                                       } else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
-                                                               mem_start = mem_start * SHMEM_2K + 0x80000;
-                                                               shmem_length = SHMEM_2K;
-                                                       } else {
-                                                               status = -ENXIO;
-                                                       }
-                                               }
-                                               /*
-                                                  ** See the top of this source code for comments about
-                                                  ** uncommenting this line.
-                                                */
+       /*
+       ** Determine the base address and window length for the EWRK3
+       ** RAM from the memory base register.
+       */
+       mem_start = inb(EWRK3_MBR);
+       shmem_length = 0;
+       if (mem_start != 0) {
+               if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
+                       mem_start *= SHMEM_64K;
+                       shmem_length = SHMEM_64K;
+               } else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
+                       mem_start *= SHMEM_32K;
+                       shmem_length = SHMEM_32K;
+               } else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
+                       mem_start = mem_start * SHMEM_2K + 0x80000;
+                       shmem_length = SHMEM_2K;
+               } else {
+                       return -ENXIO;
+               }
+       }
+       /*
+       ** See the top of this source code for comments about
+       ** uncommenting this line.
+       */
 /*          FORCE_2K_MODE; */
+       
+       if (hard_strapped) {
+               printk("      is hard strapped.\n");
+       } else if (mem_start) {
+               printk("      has a %dk RAM window", (int) (shmem_length >> 10));
+               printk(" at 0x%.5lx", mem_start);
+       } else {
+               printk("      is in I/O only mode");
+       }
 
-                                               if (!status) {
-                                                       if (hard_strapped) {
-                                                               printk("      is hard strapped.\n");
-                                                       } else if (mem_start) {
-                                                               printk("      has a %dk RAM window", (int) (shmem_length >> 10));
-                                                               printk(" at 0x%.5lx", mem_start);
-                                                       } else {
-                                                               printk("      is in I/O only mode");
-                                                       }
-
-                                                       /* private area & initialise */
-                                                       dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private),
-                                                            GFP_KERNEL);
-                                                       if (dev->priv == NULL) {
-                                                               return -ENOMEM;
-                                                       }
-                                                       lp = (struct ewrk3_private *) dev->priv;
-                                                       memset(dev->priv, 0, sizeof(struct ewrk3_private));
-                                                       lp->shmem_base = mem_start;
-                                                       lp->shmem_length = shmem_length;
-                                                       lp->lemac = lemac;
-                                                       lp->hard_strapped = hard_strapped;
-                                                       lp->led_mask = CR_LED;
-                                                       spin_lock_init(&lp->hw_lock);
-
-                                                       lp->mPage = 64;
-                                                       if (cmr & CMR_DRAM)
-                                                               lp->mPage <<= 1;        /* 2 DRAMS on module */
-
-                                                       sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
-                                                       request_region(iobase, EWRK3_TOTAL_SIZE, lp->adapter_name);
-
-                                                       lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
-
-                                                       if (!hard_strapped) {
-                                                               /*
-                                                                  ** Enable EWRK3 board interrupts for autoprobing
-                                                                */
-                                                               icr |= ICR_IE;  /* Enable interrupts */
-                                                               outb(icr, EWRK3_ICR);
-
-                                                               /* The DMA channel may be passed in on this parameter. */
-                                                               dev->dma = 0;
-
-                                                               /* To auto-IRQ we enable the initialization-done and DMA err,
-                                                                  interrupts. For now we will always get a DMA error. */
-                                                               if (dev->irq < 2) {
+       lp = (struct ewrk3_private *) dev->priv;
+       lp->shmem_base = mem_start;
+       lp->shmem_length = shmem_length;
+       lp->lemac = lemac;
+       lp->hard_strapped = hard_strapped;
+       lp->led_mask = CR_LED;
+       spin_lock_init(&lp->hw_lock);
+       
+       lp->mPage = 64;
+       if (cmr & CMR_DRAM)
+               lp->mPage <<= 1;        /* 2 DRAMS on module */
+       
+       sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
+       
+       lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
+       
+       if (!hard_strapped) {
+               /*
+               ** Enable EWRK3 board interrupts for autoprobing
+               */
+               icr |= ICR_IE;  /* Enable interrupts */
+               outb(icr, EWRK3_ICR);
+               
+               /* The DMA channel may be passed in on this parameter. */
+               dev->dma = 0;
+               
+               /* To auto-IRQ we enable the initialization-done and DMA err,
+                  interrupts. For now we will always get a DMA error. */
+               if (dev->irq < 2) {
 #ifndef MODULE
-                                                                       u_char irqnum;
-                                                                       unsigned long irq_mask;
+                       u_char irqnum;
+                       unsigned long irq_mask;
                        
 
-                                                                       irq_mask = probe_irq_on();
-
-                                                                       /*
-                                                                          ** Trigger a TNE interrupt.
-                                                                        */
-                                                                       icr |= ICR_TNEM;
-                                                                       outb(1, EWRK3_TDQ);     /* Write to the TX done queue */
-                                                                       outb(icr, EWRK3_ICR);   /* Unmask the TXD interrupt */
-
-                                                                       irqnum = irq[((icr & IRQ_SEL) >> 4)];
-
-                                                                       mdelay(20);
-                                                                       dev->irq = probe_irq_off(irq_mask);
-                                                                       if ((dev->irq) && (irqnum == dev->irq)) {
-                                                                               printk(" and uses IRQ%d.\n", dev->irq);
-                                                                       } else {
-                                                                               if (!dev->irq) {
-                                                                                       printk(" and failed to detect IRQ line.\n");
-                                                                               } else if ((irqnum == 1) && (lemac == LeMAC2)) {
-                                                                                       printk(" and an illegal IRQ line detected.\n");
-                                                                               } else {
-                                                                                       printk(", but incorrect IRQ line detected.\n");
-                                                                               }
-                                                                               status = -ENXIO;
-                                                                       }
-
-                                                                       DISABLE_IRQs;   /* Mask all interrupts */
-
-#endif                         /* MODULE */
-                                                               } else {
-                                                                       printk(" and requires IRQ%d.\n", dev->irq);
-                                                               }
-                                                       }
-                                                       if (status)
-                                                               release_region(iobase, EWRK3_TOTAL_SIZE);
-                                               } else {
-                                                       status = -ENXIO;
-                                               }
-                                       }
-                               }
+                       irq_mask = probe_irq_on();
+                       
+                       /*
+                       ** Trigger a TNE interrupt.
+                       */
+                       icr |= ICR_TNEM;
+                       outb(1, EWRK3_TDQ);     /* Write to the TX done queue */
+                       outb(icr, EWRK3_ICR);   /* Unmask the TXD interrupt */
+                       
+                       irqnum = irq[((icr & IRQ_SEL) >> 4)];
+                       
+                       mdelay(20);
+                       dev->irq = probe_irq_off(irq_mask);
+                       if ((dev->irq) && (irqnum == dev->irq)) {
+                               printk(" and uses IRQ%d.\n", dev->irq);
                        } else {
-                               status = -ENXIO;
+                               if (!dev->irq) {
+                                       printk(" and failed to detect IRQ line.\n");
+                               } else if ((irqnum == 1) && (lemac == LeMAC2)) {
+                                       printk(" and an illegal IRQ line detected.\n");
+                               } else {
+                                       printk(", but incorrect IRQ line detected.\n");
+                               }
+                               return -ENXIO;
                        }
-               }
 
-               if (!status) {
-                       if (ewrk3_debug > 1) {
-                               printk(version);
-                       }
-                       /* The EWRK3-specific entries in the device structure. */
-                       dev->open = ewrk3_open;
-                       dev->hard_start_xmit = ewrk3_queue_pkt;
-                       dev->stop = ewrk3_close;
-                       dev->get_stats = ewrk3_get_stats;
-                       dev->set_multicast_list = set_multicast_list;
-                       dev->do_ioctl = ewrk3_ioctl;
-                       dev->tx_timeout = ewrk3_timeout;
-                       dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
-
-                       dev->mem_start = 0;
-
-                       /* Fill in the generic field of the device structure. */
-                       ether_setup(dev);
+                       DISABLE_IRQs;   /* Mask all interrupts */
+
+#endif                         /* MODULE */
+               } else {
+                       printk(" and requires IRQ%d.\n", dev->irq);
                }
-       } else {
-               status = -ENXIO;
        }
-       return status;
+
+       if (ewrk3_debug > 1) {
+               printk(version);
+       }
+       /* The EWRK3-specific entries in the device structure. */
+       dev->open = ewrk3_open;
+       dev->hard_start_xmit = ewrk3_queue_pkt;
+       dev->stop = ewrk3_close;
+       dev->get_stats = ewrk3_get_stats;
+       dev->set_multicast_list = set_multicast_list;
+       dev->do_ioctl = ewrk3_ioctl;
+       dev->tx_timeout = ewrk3_timeout;
+       dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
+       
+       dev->mem_start = 0;
+
+       return 0;
 }
 \f
 
@@ -1269,15 +1248,15 @@ static void SetMulticastFilter(struct net_device *dev)
 /*
    ** ISA bus I/O device probe
  */
-static void __init isa_probe(struct net_device *dev, u_long ioaddr)
+static int __init isa_probe(struct net_device *dev, u_long ioaddr)
 {
-       int i = num_ewrk3s, maxSlots;
+       int i = num_ewrks3s, maxSlots;
+       int ret = -ENODEV;
+
        u_long iobase;
 
-       if (!ioaddr && autoprobed)
-               return;         /* Been here before ! */
        if (ioaddr >= 0x400)
-               return;         /* Not ISA */
+               goto out;
 
        if (ioaddr == 0) {      /* Autoprobing */
                iobase = EWRK3_IO_BASE;         /* Get the first slot address */
@@ -1287,38 +1266,37 @@ static void __init isa_probe(struct net_device *dev, u_long ioaddr)
                maxSlots = i + 1;
        }
 
-       for (; (i < maxSlots) && (dev != NULL); iobase += EWRK3_IOP_INC, i++) {
-               if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
+       for (; (i < maxSlots) && (dev != NULL);
+            iobase += EWRK3_IOP_INC, i++)
+       {
+               if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name)) {
                        if (DevicePresent(iobase) == 0) {
-                               if ((dev = alloc_device(dev, iobase)) != NULL) {
-                                       if (ewrk3_hw_init(dev, iobase) == 0) {
-                                               num_ewrk3s++;
-                                       }
-                                       num_eth++;
-                               }
+                               int irq = dev->irq;
+                               ret = ewrk3_hw_init(dev, iobase);
+                               if (!ret)
+                                       break;
+                               dev->irq = irq;
                        }
-               } else if (autoprobed) {
-                       printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
+                       release_region(iobase, EWRK3_TOTAL_SIZE);
                }
        }
+ out:
 
-       return;
+       return ret;
 }
 
 /*
    ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
    ** the motherboard.
  */
-static void __init eisa_probe(struct net_device *dev, u_long ioaddr)
+static int __init eisa_probe(struct net_device *dev, u_long ioaddr)
 {
        int i, maxSlots;
        u_long iobase;
-       char name[EWRK3_STRLEN];
+       int ret = -ENODEV;
 
-       if (!ioaddr && autoprobed)
-               return;         /* Been here before ! */
        if (ioaddr < 0x1000)
-               return;         /* Not EISA */
+               goto out;
 
        if (ioaddr == 0) {      /* Autoprobing */
                iobase = EISA_SLOT_INC;         /* Get the first slot address */
@@ -1332,114 +1310,22 @@ static void __init eisa_probe(struct net_device *dev, u_long ioaddr)
 
        for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
                if (EISA_signature(name, EISA_ID) == 0) {
-                       if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
-                               if (DevicePresent(iobase) == 0) {
-                                       if ((dev = alloc_device(dev, iobase)) != NULL) {
-                                               if (ewrk3_hw_init(dev, iobase) == 0) {
-                                                       num_ewrk3s++;
-                                               }
-                                               num_eth++;
-                                       }
-                               }
-                       } else if (autoprobed) {
-                               printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
+                       if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name) &&
+                           DevicePresent(iobase) == 0) {
+                               int irq = dev->irq;
+                               ret = ewrk3_hw_init(dev, iobase);
+                               if (!ret)
+                                       break;
+                               dev->irq = irq;
                        }
+                       release_region(iobase, EWRK3_TOTAL_SIZE);
                }
        }
 
-       return;
+ out:
+       return ret;
 }
 
-/*
-   ** Search the entire 'eth' device list for a fixed probe. If a match isn't
-   ** found then check for an autoprobe or unused device location. If they
-   ** are not available then insert a new device structure at the end of
-   ** the current list.
- */
-static struct net_device * __init  alloc_device(struct net_device *dev, u_long iobase)
-{
-       struct net_device *adev = NULL;
-       int fixed = 0, new_dev = 0;
-
-       num_eth = ewrk3_dev_index(dev->name);
-       if (loading_module)
-               return dev;
-
-       while (1) {
-               if (((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0)) && !adev) {
-                       adev = dev;
-               } else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
-                       fixed = 1;
-               } else {
-                       if (dev->next == NULL) {
-                               new_dev = 1;
-                       } else if (strncmp(dev->next->name, "eth", 3) != 0) {
-                               new_dev = 1;
-                       }
-               }
-               if ((dev->next == NULL) || new_dev || fixed)
-                       break;
-               dev = dev->next;
-               num_eth++;
-       }
-       if (adev && !fixed) {
-               dev = adev;
-               num_eth = ewrk3_dev_index(dev->name);
-               new_dev = 0;
-       }
-       if (((dev->next == NULL) &&
-            ((dev->base_addr != EWRK3_NDA) && (dev->base_addr != 0)) && !fixed) ||
-           new_dev) {
-               num_eth++;      /* New device */
-               dev = insert_device(dev, iobase, ewrk3_probe);
-       }
-       return dev;
-}
-
-/*
-   ** If at end of eth device list and can't use current entry, malloc
-   ** one up. If memory could not be allocated, print an error message.
- */
-static struct net_device * __init
-insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *))
-{
-       struct net_device *new;
-
-       new = (struct net_device *) kmalloc(sizeof(struct net_device) + 8, GFP_KERNEL);
-       if (new == NULL) {
-               printk("eth%d: Device not initialised, insufficient memory\n", num_eth);
-               return NULL;
-       } else {
-               new->next = dev->next;
-               dev->next = new;
-               dev = dev->next;        /* point to the new device */
-               if (num_eth > 9999) {
-                       sprintf(dev->name, "eth????");  /* New device name */
-               } else {
-                       sprintf(dev->name, "eth%d", num_eth);   /* New device name */
-               }
-               dev->base_addr = iobase;        /* assign the io address */
-               dev->init = init;       /* initialisation routine */
-       }
-
-       return dev;
-}
-
-static int __init 
-ewrk3_dev_index(char *s)
-{
-       int i = 0, j = 0;
-
-       for (; *s; s++) {
-               if (isdigit(*s)) {
-                       j = 1;
-                       i = (i * 10) + (*s - '0');
-               } else if (j)
-                       break;
-       }
-
-       return i;
-}
 
 /*
    ** Read the EWRK3 EEPROM using this routine
@@ -2074,8 +1960,7 @@ static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 #ifdef MODULE
 static struct net_device *ewrk3_devs[MAX_NUM_EWRK3S];
 static int ndevs;
-static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, };       /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
-static int irq[MAX_NUM_EWRK3S+1] = { 5, 0, };          /* or use the insmod io= irq= options           */
+static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, };
 
 /* '21' below should really be 'MAX_NUM_EWRK3S' */
 MODULE_PARM(io, "0-21i");
@@ -2083,50 +1968,39 @@ MODULE_PARM(irq, "0-21i");
 MODULE_PARM_DESC(io, "EtherWORKS 3 I/O base address(es)");
 MODULE_PARM_DESC(irq, "EtherWORKS 3 IRQ number(s)");
 
-static void ewrk3_exit_module(void)
+static __exit void ewrk3_exit_module(void)
 {
        int i;
 
        for( i=0; i<ndevs; i++ ) {
                unregister_netdev(ewrk3_devs[i]);
-               if (ewrk3_devs[i]->priv) {
-                       kfree(ewrk3_devs[i]->priv);
-                       ewrk3_devs[i]->priv = NULL;
-               }
-               ewrk3_devs[i]->irq = 0;
-
                release_region(ewrk3_devs[i]->base_addr, EWRK3_TOTAL_SIZE);
                free_netdev(ewrk3_devs[i]);
                ewrk3_devs[i] = NULL;
        }
 }
 
-static int ewrk3_init_module(void)
+static __init int ewrk3_init_module(void)
 {
        int i=0;
 
        while( io[i] && irq[i] ) {
-               ewrk3_devs[ndevs] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-               if (!ewrk3_devs[ndevs])
-                       goto error; 
-               memset(ewrk3_devs[ndevs], 0, sizeof(struct net_device));
-               ewrk3_devs[ndevs]->base_addr = io[i];
-               ewrk3_devs[ndevs]->irq = irq[i];
-               ewrk3_devs[ndevs]->init = ewrk3_probe;
-
-               if (register_netdev(ewrk3_devs[ndevs]) == 0)
-                       ndevs++;
-               else
-                       kfree(ewrk3_devs[ndevs]);
+               struct net_device *dev
+                       = alloc_etherdev(sizeof(struct ewrk3_private));
+
+               if (!dev)
+                       break;
 
+               if (ewrk3_probe1(dev, io[i], irq[i]) != 0) {
+                       free_netdev(dev);
+                       break;
+               }
+
+               ewrk3_devs[ndevs++] = dev;
                i++;
        }
 
        return ndevs ? 0 : -EIO;
-
-error:
-       ewrk3_exit_module();
-       return -ENOMEM;
 }
 
 
index df3b9bd..11a346c 100644 (file)
@@ -259,6 +259,7 @@ static int __init iph5526_probe_pci(struct net_device *dev)
 
 static int __init fcdev_init(struct net_device *dev)
 {
+       SET_MODULE_OWNER(dev);
        dev->open = iph5526_open;
        dev->stop = iph5526_close;
        dev->hard_start_xmit = iph5526_send_packet;
@@ -2896,14 +2897,12 @@ static void update_EDB_indx(struct fc_info *fi)
 static int iph5526_open(struct net_device *dev)
 {
        netif_start_queue(dev);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
 static int iph5526_close(struct net_device *dev)
 {
        netif_stop_queue(dev);
-       MOD_DEC_USE_COUNT;
        return 0;
 }
 
index 32c8d9f..1cd4eb1 100644 (file)
@@ -25,7 +25,7 @@ int iph5526_queuecommand(Scsi_Cmnd *Cmnd, void (*done) (Scsi_Cmnd *));
 int iph5526_release(struct Scsi_Host *host);
 int iph5526_abort(Scsi_Cmnd *Cmnd);
 const char *iph5526_info(struct Scsi_Host *host);
-int iph5526_biosparam(Disk * disk, struct block_device *n, int ip[]);
+int iph5526_biosparam(struct Scsi_Disk * disk, struct block_device *n, int ip[]);
 
 #endif
 
index 5e67cf6..8bfb50f 100644 (file)
@@ -57,7 +57,7 @@ static const char version[] =
 #include <asm/io.h>
 #include <asm/dma.h>
 
-static int fmv18x_probe_list[] __initdata = {
+static unsigned fmv18x_probe_list[] __initdata = {
        0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
 };
 
@@ -109,8 +109,6 @@ struct net_local {
 
 /* Index to functions, as function prototypes. */
 
-extern int fmv18x_probe(struct net_device *dev);
-
 static int fmv18x_probe1(struct net_device *dev, short ioaddr);
 static int net_open(struct net_device *dev);
 static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
@@ -129,23 +127,50 @@ static void set_multicast_list(struct net_device *dev);
    (detachable devices only).
    */
 
-int __init fmv18x_probe(struct net_device *dev)
+static int io = 0x220;
+static int irq;
+
+struct net_device * __init fmv18x_probe(int unit)
 {
-       int i;
-       int base_addr = dev->base_addr;
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       unsigned *port;
+       int err = 0;
 
-       SET_MODULE_OWNER(dev);
+       if (!dev)
+               return ERR_PTR(-ENODEV);
 
-       if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return fmv18x_probe1(dev, base_addr);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+       }
 
-       for (i = 0; fmv18x_probe_list[i]; i++)
-               if (fmv18x_probe1(dev, fmv18x_probe_list[i]) == 0)
-                       return 0;
+       SET_MODULE_OWNER(dev);
 
-       return -ENODEV;
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = fmv18x_probe1(dev, io);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = fmv18x_probe_list; *port; port++)
+                       if (fmv18x_probe1(dev, *port) == 0)
+                               break;
+               if (!*port)
+                       err = -ENODEV;
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, FMV18X_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /* The Fujitsu datasheet suggests that the NIC be probed for by checking its
@@ -160,7 +185,7 @@ static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
 {
        char irqmap[4] = {3, 7, 10, 15};
        char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
-       unsigned int i, irq, retval;
+       unsigned int i, retval;
        struct net_local *lp;
 
        /* Resetting the chip doesn't reset the ISA interface, so don't bother.
@@ -170,6 +195,9 @@ static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
        if (!request_region(ioaddr, FMV18X_IO_EXTENT, dev->name))
                return -EBUSY;
 
+       dev->irq = irq;
+       dev->base_addr = ioaddr;
+
        /* Check I/O address configuration and Fujitsu vendor code */
        if (inb(ioaddr+FJ_MACADDR  ) != 0x00
        ||  inb(ioaddr+FJ_MACADDR+1) != 0x00
@@ -181,9 +209,8 @@ static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
        /* Check PnP mode for FMV-183/184/183A/184A. */
        /* This PnP routine is very poor. IO and IRQ should be known. */
        if (inb(ioaddr + FJ_STATUS1) & 0x20) {
-               irq = dev->irq;
                for (i = 0; i < 8; i++) {
-                       if (irq == irqmap_pnp[i])
+                       if (dev->irq == irqmap_pnp[i])
                                break;
                }
                if (i == 8) {
@@ -193,22 +220,19 @@ static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
        } else {
                if (fmv18x_probe_list[inb(ioaddr + FJ_CONFIG0) & 0x07] != ioaddr)
                        return -ENODEV;
-               irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
+               dev->irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
        }
 
        /* Snarf the interrupt vector now. */
-       retval = request_irq(irq, &net_interrupt, 0, dev->name, dev);
+       retval = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
        if (retval) {
                printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
-                               "IRQ %d.\n", ioaddr, irq);
+                               "IRQ %d.\n", ioaddr, dev->irq);
                goto out;
        }
 
        printk("%s: FMV-18x found at %#3x, IRQ %d, address ", dev->name,
-                  ioaddr, irq);
-
-       dev->base_addr = ioaddr;
-       dev->irq = irq;
+                  ioaddr, dev->irq);
 
        for(i = 0; i < 6; i++) {
                unsigned char val = inb(ioaddr + FJ_MACADDR + i);
@@ -279,14 +303,10 @@ static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
        dev->watchdog_timeo     = HZ/10;
        dev->get_stats          = net_get_stats;
        dev->set_multicast_list = set_multicast_list;
-
-       /* Fill in the fields of 'dev' with ethernet-generic values. */
-
-       ether_setup(dev);
        return 0;
 
 out_irq:
-       free_irq(irq, dev);
+       free_irq(dev->irq, dev);
 out:
        release_region(ioaddr, FMV18X_IO_EXTENT);
        return retval;
@@ -413,9 +433,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
                lp->tx_queue_len = 0;
                dev->trans_start = jiffies;
                lp->tx_started = 1;
-       } else if (lp->tx_queue_len < 4096 - 1502)
-               /* Yes, there is room for one more packet. */
-       else
+       } else if (lp->tx_queue_len >= 4096 - 1502) /* No room for a packet */
                netif_stop_queue(dev);
 
        dev_kfree_skb(skb);
@@ -628,9 +646,7 @@ static void set_multicast_list(struct net_device *dev)
 }
 
 #ifdef MODULE
-static struct net_device dev_fmv18x;
-static int io = 0x220;
-static int irq;
+static struct net_device *dev_fmv18x;
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -644,26 +660,19 @@ int init_module(void)
 {
        if (io == 0)
                printk("fmv18x: You should not use auto-probing with insmod!\n");
-       dev_fmv18x.base_addr    = io;
-       dev_fmv18x.irq          = irq;
-       dev_fmv18x.init         = fmv18x_probe;
-       if (register_netdev(&dev_fmv18x) != 0) {
-               printk("fmv18x: register_netdev() returned non-zero.\n");
-               return -EIO;
-       }
+       dev_fmv18x = fmv18x_probe(-1);
+       if (IS_ERR(dev_fmv18x))
+               return PTR_ERR(dev_fmv18x);
        return 0;
 }
 
 void
 cleanup_module(void)
 {
-       unregister_netdev(&dev_fmv18x);
-       kfree(dev_fmv18x.priv);
-       dev_fmv18x.priv = NULL;
-
-       /* If we don't do this, we can't re-insmod it later. */
-       free_irq(dev_fmv18x.irq, &dev_fmv18x);
-       release_region(dev_fmv18x.base_addr, FMV18X_IO_EXTENT);
+       unregister_netdev(dev_fmv18x);
+       free_irq(dev_fmv18x->irq, dev_fmv18x);
+       release_region(dev_fmv18x->base_addr, FMV18X_IO_EXTENT);
+       free_netdev(dev_fmv18x);
 }
 #endif /* MODULE */
 \f
index d4e3796..453f7e3 100644 (file)
  *                        addresses, really stop rx if already running
  *                        in start_rx, clean up a bit.
  *                             (C) Carl-Daniel Hailfinger
- *     0.20: 07 Dev 2003: alloc fixes
+ *     0.20: 07 Dec 2003: alloc fixes
+ *     0.21: 12 Jan 2004: additional alloc fix, nic polling fix.
+ *     0.22: 19 Jan 2004: reprogram timer to a sane rate, avoid lockup
+ *                        on close.
+ *                             (C) Carl-Daniel Hailfinger, Manfred Spraul
+ *     0.23: 26 Jan 2004: various small cleanups
  *
  * Known bugs:
- * The irq handling is wrong - no tx done interrupts are generated.
- * This means recovery from netif_stop_queue only happens in the hw timer
- * interrupt (1/2 second on nForce2, 1/100 second on nForce3), or if an
- * rx packet arrives by chance.
+ * We suspect that on some hardware no TX done interrupts are generated.
+ * This means recovery from netif_stop_queue only happens if the hw timer
+ * interrupt fires (100 times/second, configurable with NVREG_POLL_DEFAULT)
+ * and the timer is active in the IRQMask, or if a rx packet arrives by chance.
+ * If your hardware reliably generates tx done interrupts, then you can remove
+ * DEV_NEED_TIMERIRQ from the driver_data flags.
+ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
+ * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION              "0.19"
+#define FORCEDETH_VERSION              "0.23"
 
 #include <linux/module.h>
 #include <linux/types.h>
 #define DEV_NEED_LASTPACKET1   0x0001
 #define DEV_IRQMASK_1          0x0002
 #define DEV_IRQMASK_2          0x0004
+#define DEV_NEED_TIMERIRQ      0x0008
 
 enum {
        NvRegIrqStatus = 0x000,
@@ -124,7 +134,12 @@ enum {
        NvRegUnknownSetupReg6 = 0x008,
 #define NVREG_UNKSETUP6_VAL            3
 
+/*
+ * NVREG_POLL_DEFAULT is the interval length of the timer source on the nic
+ * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
+ */
        NvRegPollingInterval = 0x00c,
+#define NVREG_POLL_DEFAULT     970
        NvRegMisc1 = 0x080,
 #define NVREG_MISC1_HD         0x02
 #define NVREG_MISC1_FORCE      0x3b0f3c
@@ -286,7 +301,7 @@ struct ring_desc {
 #define NV_WAKEUPMASKENTRIES   4
 
 /* General driver defaults */
-#define NV_WATCHDOG_TIMEO      (2*HZ)
+#define NV_WATCHDOG_TIMEO      (5*HZ)
 #define DEFAULT_MTU            1500    /* also maximum supported, at least for now */
 
 #define RX_RING                128
@@ -520,12 +535,12 @@ static void txrx_reset(struct net_device *dev)
 }
 
 /*
- * get_stats: dev->get_stats function
+ * nv_get_stats: dev->get_stats function
  * Get latest stats value from the nic.
  * Called with read_lock(&dev_base_lock) held for read -
  * only synchronized against unregister_netdevice.
  */
-static struct net_device_stats *get_stats(struct net_device *dev)
+static struct net_device_stats *nv_get_stats(struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
 
@@ -536,14 +551,55 @@ static struct net_device_stats *get_stats(struct net_device *dev)
        return &np->stats;
 }
 
+static int nv_ethtool_ioctl (struct net_device *dev, void *useraddr)
+{
+       struct fe_priv *np = get_nvpriv(dev);
+       u32 ethcmd;
+
+       if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
+               return -EFAULT;
+
+       switch (ethcmd) {
+       case ETHTOOL_GDRVINFO:
+       {
+               struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+               strcpy(info.driver, "forcedeth");
+               strcpy(info.version, FORCEDETH_VERSION);
+               strcpy(info.bus_info, pci_name(np->pci_dev));
+               if (copy_to_user(useraddr, &info, sizeof (info)))
+                       return -EFAULT;
+               return 0;
+       }
+       case ETHTOOL_GLINK:
+       {
+               struct ethtool_value edata = { ETHTOOL_GLINK };
+
+               edata.data = !!netif_carrier_ok(dev);
+
+               if (copy_to_user(useraddr, &edata, sizeof(edata)))
+                       return -EFAULT;
+               return 0;
+       }
 
+       default:
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
 /*
- * nic_ioctl: dev->do_ioctl function
+ * nv_ioctl: dev->do_ioctl function
  * Called with rtnl_lock held.
  */
-static int nic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int nv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       return -EOPNOTSUPP;
+       switch(cmd) {
+       case SIOCETHTOOL:
+               return nv_ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 /*
@@ -661,10 +717,10 @@ static void drain_ring(struct net_device *dev)
 }
 
 /*
- * start_xmit: dev->hard_start_xmit function
+ * nv_start_xmit: dev->hard_start_xmit function
  * Called with dev->xmit_lock held.
  */
-static int start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
        int nr = np->next_tx % TX_RING;
@@ -679,7 +735,7 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
        spin_lock_irq(&np->lock);
        wmb();
        np->tx_ring[nr].Flags = np->tx_flags;
-       dprintk(KERN_DEBUG "%s: start_xmit: packet packet %d queued for transmission.\n",
+       dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
                                dev->name, np->next_tx);
        {
                int j;
@@ -698,6 +754,7 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
        spin_unlock_irq(&np->lock);
        writel(NVREG_TXRXCTL_KICK, get_hwbase(dev) + NvRegTxRxControl);
+       pci_push(get_hwbase(dev));
        return 0;
 }
 
@@ -743,10 +800,10 @@ static void tx_done(struct net_device *dev)
 }
 
 /*
- * tx_timeout: dev->tx_timeout function
+ * nv_tx_timeout: dev->tx_timeout function
  * Called with dev->xmit_lock held.
  */
-static void tx_timeout(struct net_device *dev)
+static void nv_tx_timeout(struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
        u8 *base = get_hwbase(dev);
@@ -797,13 +854,13 @@ static void rx_process(struct net_device *dev)
                        break;  /* still owned by hardware, */
 
                /*
-                * the packet is for us - immediately tear down the pci mapping, and
-                * prefetch the first cacheline of the packet.
+                * the packet is for us - immediately tear down the pci mapping.
+                * TODO: check if a prefetch of the first cacheline improves
+                * the performance.
                 */
                pci_unmap_single(np->pci_dev, np->rx_dma[i],
                                np->rx_skbuff[i]->len,
                                PCI_DMA_FROMDEVICE);
-               prefetch(np->rx_skbuff[i]->data);
 
                {
                        int j;
@@ -870,10 +927,10 @@ next_pkt:
 }
 
 /*
- * change_mtu: dev->change_mtu function
+ * nv_change_mtu: dev->change_mtu function
  * Called with dev_base_lock held for read.
  */
-static int change_mtu(struct net_device *dev, int new_mtu)
+static int nv_change_mtu(struct net_device *dev, int new_mtu)
 {
        if (new_mtu > DEFAULT_MTU)
                return -EINVAL;
@@ -882,10 +939,10 @@ static int change_mtu(struct net_device *dev, int new_mtu)
 }
 
 /*
- * change_mtu: dev->change_mtu function
+ * nv_set_multicast: dev->set_multicast function
  * Called with dev->xmit_lock held.
  */
-static void set_multicast(struct net_device *dev)
+static void nv_set_multicast(struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
        u8 *base = get_hwbase(dev);
@@ -1098,13 +1155,13 @@ static void do_nic_poll(unsigned long data)
        enable_irq(dev->irq);
 }
 
-static int open(struct net_device *dev)
+static int nv_open(struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
        u8 *base = get_hwbase(dev);
        int ret, oom, i;
 
-       dprintk(KERN_DEBUG "forcedeth: open\n");
+       dprintk(KERN_DEBUG "nv_open: begin\n");
 
        /* 1) erase previous misconfiguration */
        /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */
@@ -1152,17 +1209,23 @@ static int open(struct net_device *dev)
        for (i = 1; i < 32; i++) {
                int id1, id2;
 
+               spin_lock_irq(&np->lock);
                id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);
-               if (id1 < 0)
+               spin_unlock_irq(&np->lock);
+               if (id1 < 0 || id1 == 0xffff)
                        continue;
+               spin_lock_irq(&np->lock);
                id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);
-               if (id2 < 0)
+               spin_unlock_irq(&np->lock);
+               if (id2 < 0 || id2 == 0xffff)
                        continue;
                dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
                                dev->name, id1, id2, i);
                np->phyaddr = i;
 
+               spin_lock_irq(&np->lock);
                update_linkspeed(dev);
+               spin_unlock_irq(&np->lock);
 
                break;
        }
@@ -1185,6 +1248,7 @@ static int open(struct net_device *dev)
        writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed);
        writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
        writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
+       writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);
        writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
        writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID,
                        base + NvRegAdapterControl);
@@ -1198,9 +1262,9 @@ static int open(struct net_device *dev)
                        base + NvRegRingSizes);
 
        i = readl(base + NvRegPowerState);
-       if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) {
+       if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0)
                writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState);
-       }
+
        pci_push(base);
        udelay(10);
        writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState);
@@ -1232,7 +1296,9 @@ static int open(struct net_device *dev)
        netif_start_queue(dev);
        if (oom)
                mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-       if (!(mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ) & BMSR_ANEGCOMPLETE)) {
+       if (mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ) & BMSR_ANEGCOMPLETE) {
+               netif_carrier_on(dev);
+       } else {
                printk("%s: no link during initialization.\n", dev->name);
                netif_carrier_off(dev);
        }
@@ -1245,9 +1311,10 @@ out_drain:
        return ret;
 }
 
-static int close(struct net_device *dev)
+static int nv_close(struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
+       u8 *base;
 
        spin_lock_irq(&np->lock);
        np->in_shutdown = 1;
@@ -1261,6 +1328,13 @@ static int close(struct net_device *dev)
        spin_lock_irq(&np->lock);
        stop_tx(dev);
        stop_rx(dev);
+       base = get_hwbase(dev);
+
+       /* disable interrupts on the nic or we will lock up */
+       writel(0, base + NvRegIrqMask);
+       pci_push(base);
+       dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
+
        spin_unlock_irq(&np->lock);
 
        free_irq(dev->irq, dev);
@@ -1272,7 +1346,7 @@ static int close(struct net_device *dev)
        return 0;
 }
 
-static int __devinit probe_nic(struct pci_dev *pci_dev, const struct pci_device_id *id)
+static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 {
        struct net_device *dev;
        struct fe_priv *np;
@@ -1281,11 +1355,11 @@ static int __devinit probe_nic(struct pci_dev *pci_dev, const struct pci_device_
        int err, i;
 
        dev = alloc_etherdev(sizeof(struct fe_priv));
-       np = get_nvpriv(dev);
        err = -ENOMEM;
        if (!dev)
                goto out;
 
+       np = get_nvpriv(dev);
        np->pci_dev = pci_dev;
        spin_lock_init(&np->lock);
        SET_MODULE_OWNER(dev);
@@ -1333,7 +1407,7 @@ static int __devinit probe_nic(struct pci_dev *pci_dev, const struct pci_device_
        err = -ENOMEM;
        dev->base_addr = (unsigned long) ioremap(addr, NV_PCI_REGSZ);
        if (!dev->base_addr)
-               goto out_disable;
+               goto out_relreg;
        dev->irq = pci_dev->irq;
        np->rx_ring = pci_alloc_consistent(pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING),
                                                &np->ring_addr);
@@ -1341,19 +1415,18 @@ static int __devinit probe_nic(struct pci_dev *pci_dev, const struct pci_device_
                goto out_unmap;
        np->tx_ring = &np->rx_ring[RX_RING];
 
-       dev->open = open;
-       dev->stop = close;
-       dev->hard_start_xmit = start_xmit;
-       dev->get_stats = get_stats;
-       dev->change_mtu = change_mtu;
-       dev->set_multicast_list = set_multicast;
-       dev->do_ioctl = nic_ioctl;
-       dev->tx_timeout = tx_timeout;
+       dev->open = nv_open;
+       dev->stop = nv_close;
+       dev->hard_start_xmit = nv_start_xmit;
+       dev->get_stats = nv_get_stats;
+       dev->change_mtu = nv_change_mtu;
+       dev->set_multicast_list = nv_set_multicast;
+       dev->do_ioctl = nv_ioctl;
+       dev->tx_timeout = nv_tx_timeout;
        dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
 
        pci_set_drvdata(pci_dev, dev);
 
-
        /* read the mac address */
        base = get_hwbase(dev);
        np->orig_mac[0] = readl(base + NvRegMacAddrA);
@@ -1393,6 +1466,8 @@ static int __devinit probe_nic(struct pci_dev *pci_dev, const struct pci_device_
                np->irqmask = NVREG_IRQMASK_WANTED_1;
        if (id->driver_data & DEV_IRQMASK_2)
                np->irqmask = NVREG_IRQMASK_WANTED_2;
+       if (id->driver_data & DEV_NEED_TIMERIRQ)
+               np->irqmask |= NVREG_IRQ_TIMER;
 
        err = register_netdev(dev);
        if (err) {
@@ -1408,6 +1483,7 @@ static int __devinit probe_nic(struct pci_dev *pci_dev, const struct pci_device_
 out_freering:
        pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING),
                                np->rx_ring, np->ring_addr);
+       pci_set_drvdata(pci_dev, NULL);
 out_unmap:
        iounmap(get_hwbase(dev));
 out_relreg:
@@ -1416,12 +1492,11 @@ out_disable:
        pci_disable_device(pci_dev);
 out_free:
        free_netdev(dev);
-       pci_set_drvdata(pci_dev, NULL);
 out:
        return err;
 }
 
-static void __devexit remove_nic(struct pci_dev *pci_dev)
+static void __devexit nv_remove(struct pci_dev *pci_dev)
 {
        struct net_device *dev = pci_get_drvdata(pci_dev);
        struct fe_priv *np = get_nvpriv(dev);
@@ -1430,7 +1505,7 @@ static void __devexit remove_nic(struct pci_dev *pci_dev)
        unregister_netdev(dev);
 
        /* special op: write back the misordered MAC address - otherwise
-        * the next probe_nic would see a wrong address.
+        * the next nv_probe would see a wrong address.
         */
        writel(np->orig_mac[0], base + NvRegMacAddrA);
        writel(np->orig_mac[1], base + NvRegMacAddrB);
@@ -1450,21 +1525,21 @@ static struct pci_device_id pci_tbl[] = {
                .device = 0x1C3,
                .subvendor = PCI_ANY_ID,
                .subdevice = PCI_ANY_ID,
-               .driver_data = DEV_IRQMASK_1,
+               .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ,
        },
        {       /* nForce2 Ethernet Controller */
                .vendor = PCI_VENDOR_ID_NVIDIA,
                .device = 0x0066,
                .subvendor = PCI_ANY_ID,
                .subdevice = PCI_ANY_ID,
-               .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2,
+               .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
        },
        {       /* nForce3 Ethernet Controller */
                .vendor = PCI_VENDOR_ID_NVIDIA,
                .device = 0x00D6,
                .subvendor = PCI_ANY_ID,
                .subdevice = PCI_ANY_ID,
-               .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2,
+               .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
        },
        {0,},
 };
@@ -1472,8 +1547,8 @@ static struct pci_device_id pci_tbl[] = {
 static struct pci_driver driver = {
        .name = "forcedeth",
        .id_table = pci_tbl,
-       .probe = probe_nic,
-       .remove = __devexit_p(remove_nic),
+       .probe = nv_probe,
+       .remove = __devexit_p(nv_remove),
 };
 
 
index c25b9fd..49e27df 100644 (file)
@@ -729,10 +729,12 @@ gt96100_probe1(int port_num)
                return -EBUSY;
        }
 
-       dev = init_etherdev(0, sizeof(struct gt96100_private));
+       dev = alloc_etherdev(sizeof(struct gt96100_private));
+       if (!dev)
+               goto out;
        gtif->dev = dev;
        
-       /* private struct aligned and zeroed by init_etherdev */
+       /* private struct aligned and zeroed by alloc_etherdev */
        /* Fill in the 'dev' fields. */
        dev->base_addr = gtif->iobase;
        dev->irq = gtif->irq;
@@ -740,7 +742,7 @@ gt96100_probe1(int port_num)
        if ((retval = parse_mac_addr(dev, gtif->mac_str))) {
                err("%s: MAC address parse failed\n", __FUNCTION__);
                retval = -EINVAL;
-               goto free_region;
+               goto out1;
        }
 
        gp = dev->priv;
@@ -768,7 +770,7 @@ gt96100_probe1(int port_num)
                                       &gp->rx_ring_dma);
                if (gp->rx_ring == NULL) {
                        retval = -ENOMEM;
-                       goto free_region;
+                       goto out1;
                }
        
                gp->tx_ring = (gt96100_td_t *)(gp->rx_ring + RX_RING_SIZE);
@@ -781,11 +783,8 @@ gt96100_probe1(int port_num)
                gp->rx_buff = dmaalloc(PKT_BUF_SZ*RX_RING_SIZE,
                                       &gp->rx_buff_dma);
                if (gp->rx_buff == NULL) {
-                       dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
-                               + sizeof(gt96100_td_t) * TX_RING_SIZE,
-                               gp->rx_ring);
                        retval = -ENOMEM;
-                       goto free_region;
+                       goto out2;
                }
        }
     
@@ -797,12 +796,8 @@ gt96100_probe1(int port_num)
                gp->hash_table = (char*)dmaalloc(RX_HASH_TABLE_SIZE,
                                                 &gp->hash_table_dma);
                if (gp->hash_table == NULL) {
-                       dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
-                               + sizeof(gt96100_td_t) * TX_RING_SIZE,
-                               gp->rx_ring);
-                       dmafree(PKT_BUF_SZ*RX_RING_SIZE, gp->rx_buff);
                        retval = -ENOMEM;
-                       goto free_region;
+                       goto out3;
                }
        }
     
@@ -819,14 +814,23 @@ gt96100_probe1(int port_num)
        dev->tx_timeout = gt96100_tx_timeout;
        dev->watchdog_timeo = GT96100ETH_TX_TIMEOUT;
 
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
+       retval = register_netdev(dev);
+       if (retval)
+               goto out4;
        return 0;
 
- free_region:
-       release_region(gtif->iobase, GT96100_ETH_IO_SIZE);
-       unregister_netdev(dev);
+out4:
+       dmafree(RX_HASH_TABLE_SIZE, gp->hash_table_dma);
+out3:
+       dmafree(PKT_BUF_SZ*RX_RING_SIZE, gp->rx_buff);
+out2:
+       dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
+               + sizeof(gt96100_td_t) * TX_RING_SIZE,
+               gp->rx_ring);
+out1:
        free_netdev (dev);
+out:
+       release_region(gtif->iobase, GT96100_ETH_IO_SIZE);
        err("%s failed.  Returns %d\n", __FUNCTION__, retval);
        return retval;
 }
@@ -1573,9 +1577,14 @@ static void gt96100_cleanup_module(void)
                if (gtif->dev != NULL) {
                        struct gt96100_private *gp =
                                (struct gt96100_private *)gtif->dev->priv;
-                       release_region(gtif->iobase, gp->io_size);
                        unregister_netdev(gtif->dev);
-                       free_netdev (gtif->dev);
+                       dmafree(RX_HASH_TABLE_SIZE, gp->hash_table_dma);
+                       dmafree(PKT_BUF_SZ*RX_RING_SIZE, gp->rx_buff);
+                       dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
+                               + sizeof(gt96100_td_t) * TX_RING_SIZE,
+                               gp->rx_ring);
+                       free_netdev(gtif->dev);
+                       release_region(gtif->iobase, gp->io_size);
                }
        }
 }
index ea53fe7..91ceae8 100644 (file)
@@ -516,7 +516,6 @@ static int sixpack_receive_room(struct tty_struct *tty)
 static void sixpack_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
 {
        unsigned char buf[512];
-       unsigned long flags;
        int count1;
 
        struct sixpack *sp = (struct sixpack *) tty->disc_data;
@@ -525,10 +524,7 @@ static void sixpack_receive_buf(struct tty_struct *tty, const unsigned char *cp,
            !netif_running(sp->dev) || !count)
                return;
 
-       save_flags(flags);
-       cli();
        memcpy(buf, cp, count<sizeof(buf)? count:sizeof(buf));
-       restore_flags(flags);
 
        /* Read the characters out of the buffer */
 
index 7cbeb34..bc85d5d 100644 (file)
@@ -991,9 +991,7 @@ static int epp_open(struct net_device *dev)
        
        baycom_paranoia_check(dev, "epp_open", -ENXIO);
        bc = (struct baycom_state *)dev->priv;
-        pp = parport_enumerate();
-        while (pp && pp->base != dev->base_addr) 
-                pp = pp->next;
+        pp = parport_find_base(dev->base_addr);
         if (!pp) {
                 printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr);
                 return -ENXIO;
@@ -1001,17 +999,21 @@ static int epp_open(struct net_device *dev)
 #if 0
         if (pp->irq < 0) {
                 printk(KERN_ERR "%s: parport at 0x%lx has no irq\n", bc_drvname, pp->base);
+               parport_put_port(pp);
                 return -ENXIO;
         }
 #endif
        if ((~pp->modes) & (PARPORT_MODE_TRISTATE | PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {
                 printk(KERN_ERR "%s: parport at 0x%lx cannot be used\n",
                       bc_drvname, pp->base);
+               parport_put_port(pp);
                 return -EIO;
        }
        memset(&bc->modem, 0, sizeof(bc->modem));
-        if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup, 
-                                                 epp_interrupt, PARPORT_DEV_EXCL, dev))) {
+        bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup, 
+                                       epp_interrupt, PARPORT_DEV_EXCL, dev);
+       parport_put_port(pp);
+        if (!bc->pdev) {
                 printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);
                 return -ENXIO;
         }
@@ -1275,7 +1277,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  * If dev->base_addr == 2, allocate space for the device and return success
  * (detachable devices only).
  */
-static int baycom_probe(struct net_device *dev)
+static void baycom_probe(struct net_device *dev)
 {
        static char ax25_bcast[AX25_ADDR_LEN] = {
                'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1
@@ -1288,9 +1290,6 @@ static int baycom_probe(struct net_device *dev)
        };
        struct baycom_state *bc;
 
-       if (!dev)
-               return -ENXIO;
-       baycom_paranoia_check(dev, "baycom_probe", -ENXIO);
        /*
         * not a real probe! only initialize data structures
         */
@@ -1332,8 +1331,6 @@ static int baycom_probe(struct net_device *dev)
 
        /* New style flags */
        dev->flags = 0;
-
-       return 0;
 }
 
 /* --------------------------------------------------------------------- */
@@ -1368,7 +1365,7 @@ static void __init baycom_epp_dev_setup(struct net_device *dev)
        /*
         * initialize part of the device struct
         */
-       dev->init = baycom_probe;
+       baycom_probe(dev);
 }
 
 static int __init init_baycomepp(void)
@@ -1401,7 +1398,7 @@ static int __init init_baycomepp(void)
 
                if (register_netdev(dev)) {
                        printk(KERN_WARNING "%s: cannot register net device %s\n", bc_drvname, dev->name);
-                       kfree(dev);
+                       free_netdev(dev);
                        break;
                }
                if (set_hw && baycom_setmode(dev->priv, mode[i]))
index 40d96a5..fa910d9 100644 (file)
@@ -314,29 +314,32 @@ static void par96_wakeup(void *handle)
 static int par96_open(struct net_device *dev)
 {
        struct baycom_state *bc = (struct baycom_state *)dev->priv;
-       struct parport *pp = parport_enumerate();
+       struct parport *pp;
 
        if (!dev || !bc)
                return -ENXIO;
-       while (pp && pp->base != dev->base_addr) 
-               pp = pp->next;
+       pp = parport_find_base(dev->base_addr);
        if (!pp) {
                printk(KERN_ERR "baycom_par: parport at 0x%lx unknown\n", dev->base_addr);
                return -ENXIO;
        }
        if (pp->irq < 0) {
                printk(KERN_ERR "baycom_par: parport at 0x%lx has no irq\n", pp->base);
+               parport_put_port(pp);
                return -ENXIO;
        }
        if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {
                printk(KERN_ERR "baycom_par: parport at 0x%lx cannot be used\n", pp->base);
+               parport_put_port(pp);
                return -ENXIO;
        }
        memset(&bc->modem, 0, sizeof(bc->modem));
        bc->hdrv.par.bitrate = 9600;
-       if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup, 
-                                                par96_interrupt, PARPORT_DEV_EXCL, dev))) {
-               printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", pp->base);
+       bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup, 
+                                par96_interrupt, PARPORT_DEV_EXCL, dev);
+       parport_put_port(pp);
+       if (!bc->pdev) {
+               printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", dev->base_addr);
                return -ENXIO;
        }
        if (parport_claim(bc->pdev)) {
index b0bf84f..fda1872 100644 (file)
@@ -547,7 +547,7 @@ static int bpq_new_device(struct net_device *edev)
 
  error:
        dev_put(edev);
-       kfree(ndev);
+       free_netdev(ndev);
        return err;
        
 }
index 1c68cb0..e122203 100644 (file)
@@ -242,7 +242,7 @@ struct scc_priv {
 struct scc_info {
   int irq_used;
   int twin_serial_cfg;
-  struct net_device dev[2];
+  struct net_device *dev[2];
   struct scc_priv priv[2];
   struct scc_info *next;
   spinlock_t register_lock;    /* Per device register lock */
@@ -310,18 +310,19 @@ static void __exit dmascc_exit(void) {
     info = first;
 
     /* Unregister devices */
-    for (i = 0; i < 2; i++) {
-      if (info->dev[i].name)
-       unregister_netdev(&info->dev[i]);
-    }
+    for (i = 0; i < 2; i++)
+       unregister_netdev(info->dev[i]);
 
     /* Reset board */
     if (info->priv[0].type == TYPE_TWIN)
-      outb(0, info->dev[0].base_addr + TWIN_SERIAL_CFG);
+      outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
     write_scc(&info->priv[0], R9, FHWRES);
-    release_region(info->dev[0].base_addr,
+    release_region(info->dev[0]->base_addr,
                   hw[info->priv[0].type].io_size);
 
+    for (i = 0; i < 2; i++)
+       free_netdev(info->dev[i]);
+
     /* Free memory */
     first = info->next;
     kfree(info);
@@ -443,156 +444,193 @@ static int __init dmascc_init(void) {
 module_init(dmascc_init);
 module_exit(dmascc_exit);
 
+static void dev_setup(struct net_device *dev)
+{
+       dev->type = ARPHRD_AX25;
+       dev->hard_header_len = 73;
+       dev->mtu = 1500;
+       dev->addr_len = 7;
+       dev->tx_queue_len = 64;
+       memcpy(dev->broadcast, ax25_broadcast, 7);
+       memcpy(dev->dev_addr, ax25_test, 7);
+}
 
-int __init setup_adapter(int card_base, int type, int n) {
-  int i, irq, chip;
-  struct scc_info *info;
-  struct net_device *dev;
-  struct scc_priv *priv;
-  unsigned long time;
-  unsigned int irqs;
-  int tmr_base = card_base + hw[type].tmr_offset;
-  int scc_base = card_base + hw[type].scc_offset;
-  char *chipnames[] = CHIPNAMES;
-
-  /* Allocate memory */
-  info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
-  if (!info) {
-    printk(KERN_ERR "dmascc: could not allocate memory for %s at %#3x\n",
-          hw[type].name, card_base);
-    return -1;
-  }
+static int __init setup_adapter(int card_base, int type, int n)
+{
+       int i, irq, chip;
+       struct scc_info *info;
+       struct net_device *dev;
+       struct scc_priv *priv;
+       unsigned long time;
+       unsigned int irqs;
+       int tmr_base = card_base + hw[type].tmr_offset;
+       int scc_base = card_base + hw[type].scc_offset;
+       char *chipnames[] = CHIPNAMES;
+
+       /* Allocate memory */
+       info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
+       if (!info) {
+               printk(KERN_ERR "dmascc: "
+                       "could not allocate memory for %s at %#3x\n",
+                       hw[type].name, card_base);
+               goto out;
+       }
 
-  /* Initialize what is necessary for write_scc and write_scc_data */
-  memset(info, 0, sizeof(struct scc_info));
-  spin_lock_init(&info->register_lock);
-  
-  priv = &info->priv[0];
-  priv->type = type;
-  priv->card_base = card_base;
-  priv->scc_cmd = scc_base + SCCA_CMD;
-  priv->scc_data = scc_base + SCCA_DATA;
-  priv->register_lock = &info->register_lock;
-
-  /* Reset SCC */
-  write_scc(priv, R9, FHWRES | MIE | NV);
-
-  /* Determine type of chip by enabling SDLC/HDLC enhancements */
-  write_scc(priv, R15, SHDLCE);
-  if (!read_scc(priv, R15)) {
-    /* WR7' not present. This is an ordinary Z8530 SCC. */
-    chip = Z8530;
-  } else {
-    /* Put one character in TX FIFO */
-    write_scc_data(priv, 0, 0);
-    if (read_scc(priv, R0) & Tx_BUF_EMP) {
-      /* TX FIFO not full. This is a Z85230 ESCC with a 4-byte FIFO. */
-      chip = Z85230;
-    } else {
-      /* TX FIFO full. This is a Z85C30 SCC with a 1-byte FIFO. */
-      chip = Z85C30;
-    }
-  }
-  write_scc(priv, R15, 0);
+       /* Initialize what is necessary for write_scc and write_scc_data */
+       memset(info, 0, sizeof(struct scc_info));
 
-  /* Start IRQ auto-detection */
-  irqs = probe_irq_on();
+       info->dev[0] = alloc_netdev(0, "", dev_setup);
+       if (!info->dev[0]) {
+               printk(KERN_ERR "dmascc: "
+                       "could not allocate memory for %s at %#3x\n",
+                       hw[type].name, card_base);
+               goto out1;
+       }
 
-  /* Enable interrupts */
-  if (type == TYPE_TWIN) {
-    outb(0, card_base + TWIN_DMA_CFG);
-    inb(card_base + TWIN_CLR_TMR1);
-    inb(card_base + TWIN_CLR_TMR2);
-    outb((info->twin_serial_cfg = TWIN_EI), card_base + TWIN_SERIAL_CFG);
-  } else {
-    write_scc(priv, R15, CTSIE);
-    write_scc(priv, R0, RES_EXT_INT);
-    write_scc(priv, R1, EXT_INT_ENAB);
-  }
+       info->dev[1] = alloc_netdev(0, "", dev_setup);
+       if (!info->dev[1]) {
+               printk(KERN_ERR "dmascc: "
+                       "could not allocate memory for %s at %#3x\n",
+                       hw[type].name, card_base);
+               goto out2;
+       }
+       spin_lock_init(&info->register_lock);
+
+       priv = &info->priv[0];
+       priv->type = type;
+       priv->card_base = card_base;
+       priv->scc_cmd = scc_base + SCCA_CMD;
+       priv->scc_data = scc_base + SCCA_DATA;
+       priv->register_lock = &info->register_lock;
+
+       /* Reset SCC */
+       write_scc(priv, R9, FHWRES | MIE | NV);
+
+       /* Determine type of chip by enabling SDLC/HDLC enhancements */
+       write_scc(priv, R15, SHDLCE);
+       if (!read_scc(priv, R15)) {
+               /* WR7' not present. This is an ordinary Z8530 SCC. */
+               chip = Z8530;
+       } else {
+               /* Put one character in TX FIFO */
+               write_scc_data(priv, 0, 0);
+               if (read_scc(priv, R0) & Tx_BUF_EMP) {
+                       /* TX FIFO not full. This is a Z85230 ESCC with a 4-byte FIFO. */
+                       chip = Z85230;
+               } else {
+                       /* TX FIFO full. This is a Z85C30 SCC with a 1-byte FIFO. */
+                       chip = Z85C30;
+               }
+       }
+       write_scc(priv, R15, 0);
 
-  /* Start timer */
-  outb(1, tmr_base + TMR_CNT1);
-  outb(0, tmr_base + TMR_CNT1);
+       /* Start IRQ auto-detection */
+       irqs = probe_irq_on();
 
-  /* Wait and detect IRQ */
-  time = jiffies; while (jiffies - time < 2 + HZ / TMR_0_HZ);
-  irq = probe_irq_off(irqs);
+       /* Enable interrupts */
+       if (type == TYPE_TWIN) {
+               outb(0, card_base + TWIN_DMA_CFG);
+               inb(card_base + TWIN_CLR_TMR1);
+               inb(card_base + TWIN_CLR_TMR2);
+               info->twin_serial_cfg = TWIN_EI;
+               outb(info->twin_serial_cfg, card_base + TWIN_SERIAL_CFG);
+       } else {
+               write_scc(priv, R15, CTSIE);
+               write_scc(priv, R0, RES_EXT_INT);
+               write_scc(priv, R1, EXT_INT_ENAB);
+       }
 
-  /* Clear pending interrupt, disable interrupts */
-  if (type == TYPE_TWIN) {
-    inb(card_base + TWIN_CLR_TMR1);
-  } else {
-    write_scc(priv, R1, 0);
-    write_scc(priv, R15, 0);
-    write_scc(priv, R0, RES_EXT_INT);
-  }
+       /* Start timer */
+       outb(1, tmr_base + TMR_CNT1);
+       outb(0, tmr_base + TMR_CNT1);
 
-  if (irq <= 0) {
-    printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
-          hw[type].name, card_base, irq);
-    kfree(info);
-    return -1;
-  }
+       /* Wait and detect IRQ */
+       time = jiffies; while (jiffies - time < 2 + HZ / TMR_0_HZ);
+       irq = probe_irq_off(irqs);
 
-  /* Set up data structures */
-  for (i = 0; i < 2; i++) {
-    dev = &info->dev[i];
-    priv = &info->priv[i];
-    priv->type = type;
-    priv->chip = chip;
-    priv->dev = dev;
-    priv->info = info;
-    priv->channel = i;
-    spin_lock_init(&priv->ring_lock);
-    priv->register_lock = &info->register_lock;
-    priv->card_base = card_base;
-    priv->scc_cmd = scc_base + (i ? SCCB_CMD : SCCA_CMD);
-    priv->scc_data = scc_base + (i ? SCCB_DATA : SCCA_DATA);
-    priv->tmr_cnt = tmr_base + (i ? TMR_CNT2 : TMR_CNT1);
-    priv->tmr_ctrl = tmr_base + TMR_CTRL;
-    priv->tmr_mode = i ? 0xb0 : 0x70;
-    priv->param.pclk_hz = hw[type].pclk_hz;
-    priv->param.brg_tc = -1;
-    priv->param.clocks = TCTRxCP | RCRTxCP;
-    priv->param.persist = 256;
-    priv->param.dma = -1;
-    INIT_WORK(&priv->rx_work, rx_bh, priv);
-    dev->priv = priv;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-    if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name;
-#endif
-    sprintf(dev->name, "dmascc%i", 2*n+i);
-    SET_MODULE_OWNER(dev);
-    dev->base_addr = card_base;
-    dev->irq = irq;
-    dev->open = scc_open;
-    dev->stop = scc_close;
-    dev->do_ioctl = scc_ioctl;
-    dev->hard_start_xmit = scc_send_packet;
-    dev->get_stats = scc_get_stats;
-    dev->hard_header = ax25_encapsulate;
-    dev->rebuild_header = ax25_rebuild_header;
-    dev->set_mac_address = scc_set_mac_address;
-    dev->type = ARPHRD_AX25;
-    dev->hard_header_len = 73;
-    dev->mtu = 1500;
-    dev->addr_len = 7;
-    dev->tx_queue_len = 64;
-    memcpy(dev->broadcast, ax25_broadcast, 7);
-    memcpy(dev->dev_addr, ax25_test, 7);
-    rtnl_lock();
-    if (register_netdevice(dev)) {
-      printk(KERN_ERR "dmascc: could not register %s\n", dev->name);
-    }
-    rtnl_unlock();
-  }
+       /* Clear pending interrupt, disable interrupts */
+       if (type == TYPE_TWIN) {
+               inb(card_base + TWIN_CLR_TMR1);
+       } else {
+               write_scc(priv, R1, 0);
+               write_scc(priv, R15, 0);
+               write_scc(priv, R0, RES_EXT_INT);
+       }
 
+       if (irq <= 0) {
+               printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
+                       hw[type].name, card_base, irq);
+               goto out3;
+       }
 
-  info->next = first;
-  first = info;
-  printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
-        chipnames[chip], card_base, irq);
-  return 0;
+       /* Set up data structures */
+       for (i = 0; i < 2; i++) {
+               dev = info->dev[i];
+               priv = &info->priv[i];
+               priv->type = type;
+               priv->chip = chip;
+               priv->dev = dev;
+               priv->info = info;
+               priv->channel = i;
+               spin_lock_init(&priv->ring_lock);
+               priv->register_lock = &info->register_lock;
+               priv->card_base = card_base;
+               priv->scc_cmd = scc_base + (i ? SCCB_CMD : SCCA_CMD);
+               priv->scc_data = scc_base + (i ? SCCB_DATA : SCCA_DATA);
+               priv->tmr_cnt = tmr_base + (i ? TMR_CNT2 : TMR_CNT1);
+               priv->tmr_ctrl = tmr_base + TMR_CTRL;
+               priv->tmr_mode = i ? 0xb0 : 0x70;
+               priv->param.pclk_hz = hw[type].pclk_hz;
+               priv->param.brg_tc = -1;
+               priv->param.clocks = TCTRxCP | RCRTxCP;
+               priv->param.persist = 256;
+               priv->param.dma = -1;
+               INIT_WORK(&priv->rx_work, rx_bh, priv);
+               dev->priv = priv;
+               sprintf(dev->name, "dmascc%i", 2*n+i);
+               SET_MODULE_OWNER(dev);
+               dev->base_addr = card_base;
+               dev->irq = irq;
+               dev->open = scc_open;
+               dev->stop = scc_close;
+               dev->do_ioctl = scc_ioctl;
+               dev->hard_start_xmit = scc_send_packet;
+               dev->get_stats = scc_get_stats;
+               dev->hard_header = ax25_encapsulate;
+               dev->rebuild_header = ax25_rebuild_header;
+               dev->set_mac_address = scc_set_mac_address;
+       }
+       if (register_netdev(info->dev[0])) {
+               printk(KERN_ERR "dmascc: could not register %s\n",
+                               info->dev[0]->name);
+               goto out3;
+       }
+       if (register_netdev(info->dev[1])) {
+               printk(KERN_ERR "dmascc: could not register %s\n",
+                               info->dev[1]->name);
+               goto out4;
+       }
+
+
+       info->next = first;
+       first = info;
+       printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
+       chipnames[chip], card_base, irq);
+       return 0;
+
+out4:
+       unregister_netdev(info->dev[0]);
+out3:
+       if (info->priv[0].type == TYPE_TWIN)
+               outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
+       write_scc(&info->priv[0], R9, FHWRES);
+       free_netdev(info->dev[1]);
+out2:
+       free_netdev(info->dev[0]);
+out1:
+       kfree(info);
+out:
+       return -1;
 }
 
 
index ca306b5..787ca8f 100644 (file)
@@ -832,7 +832,7 @@ struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
        if (err < 0) {
                printk(KERN_WARNING "hdlcdrv: cannot register net "
                       "device %s\n", dev->name);
-               kfree(dev);
+               free_netdev(dev);
                dev = ERR_PTR(err);
        }
        return dev;
index c787326..4d29cf4 100644 (file)
@@ -24,6 +24,7 @@
  *                              called twice, causing a deadlock.
  *     Jeroen (PE1RXQ)         Removed old MKISS_MAGIC stuff and calls to
  *                             MOD_*_USE_COUNT
+ *                             Remove cli() and fix rtnl lock usage.
  */
 
 #include <linux/config.h>
@@ -167,17 +168,17 @@ static inline struct ax_disp *ax_alloc(void)
        /* If no channels are available, allocate one */
        if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) {
                axp = ax25_ctrls[i];
-               memset(axp, 0, sizeof(ax25_ctrl_t));
-
-               /* Initialize channel control data */
-               set_bit(AXF_INUSE, &axp->ctrl.flags);
-               sprintf(axp->dev.name, "ax%d", i++);
-               axp->ctrl.tty      = NULL;
-               axp->dev.base_addr = i;
-               axp->dev.priv      = (void *)&axp->ctrl;
-               axp->dev.next      = NULL;
-               axp->dev.init      = ax25_init;
        }
+       memset(axp, 0, sizeof(ax25_ctrl_t));
+
+       /* Initialize channel control data */
+       set_bit(AXF_INUSE, &axp->ctrl.flags);
+       sprintf(axp->dev.name, "ax%d", i++);
+       axp->ctrl.tty      = NULL;
+       axp->dev.base_addr = i;
+       axp->dev.priv      = (void *)&axp->ctrl;
+       axp->dev.next      = NULL;
+       axp->dev.init      = ax25_init;
 
        if (axp != NULL) {
                /*
@@ -220,7 +221,6 @@ static void ax_changedmtu(struct ax_disp *ax)
        struct net_device *dev = ax->dev;
        unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
        int len;
-       unsigned long flags;
 
        len = dev->mtu * 2;
 
@@ -246,8 +246,7 @@ static void ax_changedmtu(struct ax_disp *ax)
                return;
        }
 
-       save_flags(flags);
-       cli();
+       spin_lock_bh(&ax->buflock);
 
        oxbuff    = ax->xbuff;
        ax->xbuff = xbuff;
@@ -278,7 +277,7 @@ static void ax_changedmtu(struct ax_disp *ax)
        ax->mtu      = dev->mtu + 73;
        ax->buffsize = len;
 
-       restore_flags(flags);
+       spin_unlock_bh(&ax->buflock);
 
        if (oxbuff != NULL)
                kfree(oxbuff);
@@ -306,6 +305,7 @@ static void ax_bump(struct ax_disp *ax)
        struct sk_buff *skb;
        int count;
 
+       spin_lock_bh(&ax->buflock);
        if (ax->rbuff[0] > 0x0f) {
                if (ax->rbuff[0] & 0x20) {
                        ax->crcmode = CRC_MODE_FLEX;
@@ -322,6 +322,7 @@ static void ax_bump(struct ax_disp *ax)
                         *ax->rbuff &= ~0x20;
                }
        }
+       spin_unlock_bh(&ax->buflock);
 
        count = ax->rcount;
 
@@ -332,7 +333,9 @@ static void ax_bump(struct ax_disp *ax)
        }
 
        skb->dev      = ax->dev;
+       spin_lock_bh(&ax->buflock);
        memcpy(skb_put(skb,count), ax->rbuff, count);
+       spin_unlock_bh(&ax->buflock);
        skb->mac.raw  = skb->data;
        skb->protocol = htons(ETH_P_AX25);
        netif_rx(skb);
@@ -360,6 +363,7 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
 
        p = icp;
 
+       spin_lock_bh(&ax->buflock);
         switch (ax->crcmode) {
                 unsigned short crc;
 
@@ -373,6 +377,7 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
                 count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
                 break;
        }
+       
        ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
        actual = ax->tty->driver->write(ax->tty, 0, ax->xbuff, count);
        ax->tx_packets++;
@@ -380,6 +385,8 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
        ax->dev->trans_start = jiffies;
        ax->xleft = count - actual;
        ax->xhead = ax->xbuff + actual;
+
+       spin_unlock_bh(&ax->buflock);
 }
 
 /*
@@ -511,6 +518,8 @@ static int ax_open(struct net_device *dev)
 
        ax->flags   &= (1 << AXF_INUSE);      /* Clear ESCAPE & ERROR flags */
 
+       ax->buflock = SPIN_LOCK_UNLOCKED;
+
        netif_start_queue(dev);
        return 0;
 
@@ -750,15 +759,18 @@ static void kiss_unesc(struct ax_disp *ax, unsigned char s)
                        break;
        }
 
+       spin_lock_bh(&ax->buflock);
        if (!test_bit(AXF_ERROR, &ax->flags)) {
                if (ax->rcount < ax->buffsize) {
                        ax->rbuff[ax->rcount++] = s;
+                       spin_unlock_bh(&ax->buflock);
                        return;
                }
 
                ax->rx_over_errors++;
                set_bit(AXF_ERROR, &ax->flags);
        }
+       spin_unlock_bh(&ax->buflock);
 }
 
 
index fa62e76..4ab7004 100644 (file)
@@ -56,6 +56,7 @@ struct ax_disp {
 #define CRC_MODE_NONE   0
 #define CRC_MODE_FLEX   1
 #define CRC_MODE_SMACK  2
+       spinlock_t          buflock;    /* lock for rbuf and xbuf */
 };
 
 #define AX25_MAGIC             0x5316
index 7d4afa3..0e6844f 100644 (file)
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
 #include <linux/if_ether.h>
 #include <linux/if_arp.h>
 #include <linux/socket.h>
@@ -1520,8 +1521,10 @@ static int scc_net_alloc(const char *name, struct scc_channel *scc)
        dev->priv = scc;
        scc->dev = dev;
        spin_lock_init(&scc->lock);
+       init_timer(&scc->tx_t);
+       init_timer(&scc->tx_wdog);
 
-       err = register_netdev(dev);
+       err = register_netdevice(dev);
        if (err) {
                printk(KERN_ERR "%s: can't register network device (%d)\n", 
                       name, err);
@@ -1625,6 +1628,7 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb)
        }
                
        scc->dev_stat.rx_packets++;
+       scc->dev_stat.rx_bytes += skb->len;
 
        skb->dev      = scc->dev;
        skb->protocol = htons(ETH_P_AX25);
@@ -1651,6 +1655,7 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
        }
        
        scc->dev_stat.tx_packets++;
+       scc->dev_stat.tx_bytes += skb->len;
        scc->stat.txframes++;
        
        kisscmd = *skb->data & 0x1f;
@@ -2114,10 +2119,13 @@ static int __init scc_init_driver (void)
        
        sprintf(devname,"%s0", SCC_DriverName);
        
+       rtnl_lock();
        if (scc_net_alloc(devname, SCC_Info)) {
+               rtnl_unlock();
                printk(KERN_ERR "z8530drv: cannot initialize module\n");
                return -EIO;
        }
+       rtnl_unlock();
 
        proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops);
 
index 58c0a07..c516e71 100644 (file)
@@ -1192,7 +1192,7 @@ static void __exit yam_cleanup_driver(void)
                struct net_device *dev = yam_devs[i];
                if (dev) {
                        unregister_netdev(dev);
-                       kfree(dev);
+                       free_netdev(dev);
                }
        }
 
index ae1c260..614ee7e 100644 (file)
@@ -92,7 +92,6 @@ enum HP_Option {
        EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
        MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
 
-int hp_plus_probe(struct net_device *dev);
 static int hpp_probe1(struct net_device *dev, int ioaddr);
 
 static void hpp_reset_8390(struct net_device *dev);
@@ -115,10 +114,11 @@ static void hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hd
 /*     Probe a list of addresses for an HP LAN+ adaptor.
        This routine is almost boilerplate. */
 
-int __init hp_plus_probe(struct net_device *dev)
+static int __init do_hpp_probe(struct net_device *dev)
 {
        int i;
        int base_addr = dev->base_addr;
+       int irq = dev->irq;
 
        SET_MODULE_OWNER(dev);
 
@@ -127,13 +127,46 @@ int __init hp_plus_probe(struct net_device *dev)
        else if (base_addr != 0)        /* Don't probe at all. */
                return -ENXIO;
 
-       for (i = 0; hpplus_portlist[i]; i++)
+       for (i = 0; hpplus_portlist[i]; i++) {
                if (hpp_probe1(dev, hpplus_portlist[i]) == 0)
                        return 0;
+               dev->irq = irq;
+       }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       /* NB: hpp_close() handles free_irq */
+       release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
+}
+
+struct net_device * __init hp_plus_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_hpp_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 /* Do the interesting part of the probe at a single address. */
 static int __init hpp_probe1(struct net_device *dev, int ioaddr)
 {
@@ -179,13 +212,6 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
                printk(" ID %4.4x", inw(ioaddr + 12));
        }
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk ("hp-plus.c: unable to allocate memory for dev->priv.\n");
-               retval = -ENOMEM;
-               goto out;
-        }
-
        /* Read the IRQ line. */
        outw(HW_Page, ioaddr + HP_PAGING);
        {
@@ -400,7 +426,7 @@ hpp_mem_block_output(struct net_device *dev, int count,
 \f
 #ifdef MODULE
 #define MAX_HPP_CARDS  4       /* Max number of HPP cards per module */
-static struct net_device dev_hpp[MAX_HPP_CARDS];
+static struct net_device *dev_hpp[MAX_HPP_CARDS];
 static int io[MAX_HPP_CARDS];
 static int irq[MAX_HPP_CARDS];
 
@@ -416,27 +442,33 @@ ISA device autoprobes on a running machine are not recommended. */
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
-               struct net_device *dev = &dev_hpp[this_dev];
-               dev->irq = irq[this_dev];
-               dev->base_addr = io[this_dev];
-               dev->init = hp_plus_probe;
                if (io[this_dev] == 0)  {
                        if (this_dev != 0) break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               if (do_hpp_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_hpp[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -445,14 +477,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
-               struct net_device *dev = &dev_hpp[this_dev];
-               if (dev->priv != NULL) {
-                       int ioaddr = dev->base_addr - NIC_OFFSET;
-                       void *priv = dev->priv;
-                       /* NB: hpp_close() handles free_irq */
-                       release_region(ioaddr, HP_IO_EXTENT);
+               struct net_device *dev = dev_hpp[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index d1d2e56..bc50724 100644 (file)
@@ -55,7 +55,6 @@ static unsigned int hppclan_portlist[] __initdata =
 #define HP_8BSTOP_PG   0x80    /* Last page +1 of RX ring */
 #define HP_16BSTOP_PG  0xFF    /* Same, for 16 bit cards. */
 
-int hp_probe(struct net_device *dev);
 static int hp_probe1(struct net_device *dev, int ioaddr);
 
 static int hp_open(struct net_device *dev);
@@ -79,10 +78,11 @@ static char irqmap[16] __initdata= { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0}
        Also initialize the card and fill in STATION_ADDR with the station
        address. */
 
-int __init hp_probe(struct net_device *dev)
+static int __init do_hp_probe(struct net_device *dev)
 {
        int i;
        int base_addr = dev->base_addr;
+       int irq = dev->irq;
 
        SET_MODULE_OWNER(dev);
 
@@ -91,13 +91,46 @@ int __init hp_probe(struct net_device *dev)
        else if (base_addr != 0)        /* Don't probe at all. */
                return -ENXIO;
 
-       for (i = 0; hppclan_portlist[i]; i++)
+       for (i = 0; hppclan_portlist[i]; i++) {
                if (hp_probe1(dev, hppclan_portlist[i]) == 0)
                        return 0;
+               dev->irq = irq;
+       }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
+}
+
+struct net_device * __init hp_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_hp_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init hp_probe1(struct net_device *dev, int ioaddr)
 {
        int i, retval, board_id, wordmode;
@@ -131,13 +164,6 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
        if (ei_debug  &&  version_printed++ == 0)
                printk(version);
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (" unable to get memory for dev->priv.\n");
-               retval = -ENOMEM;
-               goto out;
-       }
-
        printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
 
        for(i = 0; i < ETHER_ADDR_LEN; i++)
@@ -166,14 +192,14 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
                if (*irqp == 0) {
                        printk(" no free IRQ lines.\n");
                        retval = -EBUSY;
-                       goto out1;
+                       goto out;
                }
        } else {
                if (dev->irq == 2)
                        dev->irq = 9;
                if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
                        printk (" unable to get IRQ %d.\n", dev->irq);
-                       goto out1;
+                       goto out;
                }
        }
 
@@ -195,9 +221,6 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
        hp_init_card(dev);
 
        return 0;
-out1:
-       kfree(dev->priv);
-       dev->priv = NULL;
 out:
        release_region(ioaddr, HP_IO_EXTENT);
        return retval;
@@ -372,7 +395,7 @@ hp_init_card(struct net_device *dev)
 
 #ifdef MODULE
 #define MAX_HP_CARDS   4       /* Max number of HP cards per module */
-static struct net_device dev_hp[MAX_HP_CARDS];
+static struct net_device *dev_hp[MAX_HP_CARDS];
 static int io[MAX_HP_CARDS];
 static int irq[MAX_HP_CARDS];
 
@@ -388,27 +411,33 @@ ISA device autoprobes on a running machine are not recommended. */
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
-               struct net_device *dev = &dev_hp[this_dev];
-               dev->irq = irq[this_dev];
-               dev->base_addr = io[this_dev];
-               dev->init = hp_probe;
                if (io[this_dev] == 0)  {
                        if (this_dev != 0) break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "hp.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               if (do_hp_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_hp[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -417,14 +446,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
-               struct net_device *dev = &dev_hp[this_dev];
-               if (dev->priv != NULL) {
-                       int ioaddr = dev->base_addr - NIC_OFFSET;
-                       void *priv = dev->priv;
-                       free_irq(dev->irq, dev);
-                       release_region(ioaddr, HP_IO_EXTENT);
+               struct net_device *dev = dev_hp[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index f92d5c9..e30346b 100644 (file)
 #include <asm/bitops.h>
 #include <asm/io.h>
 
-typedef struct net_device_stats hp100_stats_t;
-
 #include "hp100.h"
 
 /*
@@ -130,23 +128,8 @@ typedef struct net_device_stats hp100_stats_t;
 #define HP100_BUS_EISA    1
 #define HP100_BUS_PCI     2
 
-#ifndef PCI_DEVICE_ID_HP_J2585B
-#define PCI_DEVICE_ID_HP_J2585B 0x1031
-#endif
-#ifndef PCI_VENDOR_ID_COMPEX
-#define PCI_VENDOR_ID_COMPEX 0x11f6
-#endif
-#ifndef PCI_DEVICE_ID_COMPEX_ENET100VG4
-#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
-#endif
-#ifndef PCI_VENDOR_ID_COMPEX2
-#define PCI_VENDOR_ID_COMPEX2 0x101a
-#endif
-#ifndef PCI_DEVICE_ID_COMPEX2_100VG
-#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005
-#endif
-
 #define HP100_REGION_SIZE      0x20    /* for ioports */
+#define HP100_SIG_LEN          8       /* same as EISA_SIG_LEN */
 
 #define HP100_MAX_PACKET_SIZE  (1536+4)
 #define HP100_MIN_PACKET_SIZE  60
@@ -165,20 +148,9 @@ typedef struct net_device_stats hp100_stats_t;
  *  structures
  */
 
-struct hp100_eisa_id {
-       u_int id;
-       const char *name;
-       u_char bus;
-};
-
-struct hp100_pci_id {
-       u_short vendor;
-       u_short device;
-};
-
 struct hp100_private {
-       struct hp100_eisa_id *id;
        spinlock_t lock;
+       char id[HP100_SIG_LEN];
        u_short chip;
        u_short soft_model;
        u_int memory_size;
@@ -196,7 +168,7 @@ struct hp100_private {
        u_char mac1_mode;
        u_char mac2_mode;
        u_char hash_bytes[8];
-       hp100_stats_t stats;
+       struct net_device_stats stats;
 
        /* Rings for busmaster mode: */
        hp100_ring_t *rxrhead;  /* Head (oldest) index into rxring */
@@ -216,83 +188,36 @@ struct hp100_private {
 /*
  *  variables
  */
-
-static struct hp100_eisa_id hp100_eisa_ids[] = {
-
-       /* 10/100 EISA card with revision A Cascade chip */
-       {0x80F1F022, "HP J2577 rev A", HP100_BUS_EISA},
-
-       /* 10/100 ISA card with revision A Cascade chip */
-       {0x50F1F022, "HP J2573 rev A", HP100_BUS_ISA},
-
-       /* 10 only EISA card with Cascade chip */
-       {0x2019F022, "HP 27248B", HP100_BUS_EISA},
-
-       /* 10/100 EISA card with Cascade chip */
-       {0x4019F022, "HP J2577", HP100_BUS_EISA},
-
-       /* 10/100 ISA card with Cascade chip */
-       {0x5019F022, "HP J2573", HP100_BUS_ISA},
-
-       /* 10/100 EISA card with AT&T chip */
-       {0x9019f022, "HP J2577", HP100_BUS_EISA },
-
-       /* 10/100 PCI card - old J2585A */
-       {0x1030103c, "HP J2585A", HP100_BUS_PCI},
-
-       /* 10/100 PCI card - new J2585B - master capable */
-       {0x1041103c, "HP J2585B", HP100_BUS_PCI},
-
-       /* 10 Mbit Combo Adapter */
-       {0x1042103c, "HP J2970", HP100_BUS_PCI},
-
-       /* 10 Mbit 10baseT Adapter */
-       {0x1040103c, "HP J2973", HP100_BUS_PCI},
-
-       /* 10/100 EISA card from Compex */
-       {0x0103180e, "ReadyLink ENET100-VG4", HP100_BUS_EISA},
-
-       /* 10/100 EISA card from Compex - FreedomLine (sq5bpf) */
-       /* Note: plhbrod@mbox.vol.cz reported that same ID have ISA */
-       /*       version of adapter, too... */
-       {0x0104180e, "FreedomLine 100/VG", HP100_BUS_EISA},
-
-       /* 10/100 PCI card from Compex - FreedomLine
-        *
-        * I think this card doesn't like aic7178 scsi controller, but
-        * I haven't tested this much. It works fine on diskless machines.
-        *                            Jacek Lipkowski <sq5bpf@acid.ch.pw.edu.pl>
-        */
-       {0x021211f6, "FreedomLine 100/VG", HP100_BUS_PCI},
-
-       /* 10/100 PCI card from Compex (J2585A compatible) */
-       {0x011211f6, "ReadyLink ENET100-VG4", HP100_BUS_PCI},
-       
-       /* 10/100 PCI card from KTI */
-       {0x40008e2e, "KTI DP-200", HP100_BUS_PCI }
+static const char *hp100_isa_tbl[] = {
+       "HWPF150", /* HP J2573 rev A */
+       "HWP1950", /* HP J2573 */
 };
 
-#define HP100_EISA_IDS_SIZE    (sizeof(hp100_eisa_ids)/sizeof(struct hp100_eisa_id))
-
-#ifdef CONFIG_PCI
-static struct hp100_pci_id hp100_pci_ids[] = {
-       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A},
-       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B},
-       {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4},
-       {PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG}
+#ifdef CONFIG_EISA
+static struct eisa_device_id hp100_eisa_tbl[] = {
+       { "HWPF180" }, /* HP J2577 rev A */
+       { "HWP1920" }, /* HP 27248B */
+       { "HWP1940" }, /* HP J2577 */
+       { "HWP1990" }, /* HP J2577 */
+       { "CPX0301" }, /* ReadyLink ENET100-VG4 */
+       { "CPX0401" }, /* FreedomLine 100/VG */
 };
+MODULE_DEVICE_TABLE(eisa, hp100_eisa_tbl);
 #endif
 
-#define HP100_PCI_IDS_SIZE     (sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))
-
+#ifdef CONFIG_PCI
 static struct pci_device_id hp100_pci_tbl[] = {
        {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
        {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
+       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2970A, PCI_ANY_ID, PCI_ANY_ID,},
+       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2973A, PCI_ANY_ID, PCI_ANY_ID,},
        {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID,},
        {PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG, PCI_ANY_ID, PCI_ANY_ID,},
+/*     {PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_DP200, PCI_ANY_ID, PCI_ANY_ID }, */
        {}                      /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, hp100_pci_tbl);
+#endif
 
 static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
 static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
@@ -316,7 +241,7 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int hp100_start_xmit_bm(struct sk_buff *skb,
                               struct net_device *dev);
 static void hp100_rx(struct net_device *dev);
-static hp100_stats_t *hp100_get_stats(struct net_device *dev);
+static struct net_device_stats *hp100_get_stats(struct net_device *dev);
 static void hp100_misc_interrupt(struct net_device *dev);
 static void hp100_update_stats(struct net_device *dev);
 static void hp100_clear_stats(struct hp100_private *lp, int ioaddr);
@@ -370,196 +295,180 @@ static void wait(void)
  *  since this could cause problems when the card is not installed.
  */
 
-int __init hp100_probe(struct net_device *dev)
+/*
+ * Read board id and convert to string.
+ * Effectively same code as decode_eisa_sig
+ */
+static __init const char *hp100_read_id(int ioaddr)
 {
-       int base_addr = dev ? dev->base_addr : 0;
-       int ioaddr = 0;
-       int pci_start_index = 0;
+       int i;
+       static char str[HP100_SIG_LEN];
+       unsigned char sig[4], sum;
+        unsigned short rev;
 
-#ifdef HP100_DEBUG_B
-       hp100_outw(0x4200, TRACE);
-       printk("hp100: %s: probe\n", dev->name);
-#endif
+       hp100_page(ID_MAC_ADDR);
+       sum = 0;
+       for (i = 0; i < 4; i++) {
+               sig[i] = hp100_inb(BOARD_ID + i);
+               sum += sig[i];
+       }
 
-       if (base_addr > 0xff) { /* Check a single specified location. */
-               if (check_region(base_addr, HP100_REGION_SIZE))
-                       return -EINVAL;
-               if (base_addr < 0x400)
-                       return hp100_probe1(dev, base_addr, HP100_BUS_ISA,
-                                           NULL);
-               if (EISA_bus && base_addr >= 0x1c38 && ((base_addr - 0x1c38) & 0x3ff) == 0)
-                       return hp100_probe1(dev, base_addr, HP100_BUS_EISA, NULL);
-#ifdef CONFIG_PCI
-               printk("hp100: %s: You must specify card # in i/o address parameter for PCI bus...", dev->name);
-#else
-               return -ENODEV;
-#endif
-       } else
-#ifdef CONFIG_PCI
-               if (base_addr > 0 && base_addr < 8 + 1)
-                       pci_start_index = 0x100 | (base_addr - 1);
-         else
-#endif
-               if (base_addr != 0)
-                       return -ENXIO;
+       sum += hp100_inb(BOARD_ID + i);
+       if (sum != 0xff)
+               return NULL;    /* bad checksum */
 
-       /* First: scan PCI bus(es) */
+        str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+        str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+        str[2] = (sig[1] & 0x1f) + ('A' - 1);
+        rev = (sig[2] << 8) | sig[3];
+        sprintf(str + 3, "%04X", rev);
+
+       return str;
+}
+
+static __init int hp100_isa_probe1(struct net_device *dev, int addr)
+{
+       const char *sig;
+       int i;
+
+       if (!request_region(addr, HP100_REGION_SIZE, "hp100"))
+               goto err;
+
+       sig = hp100_read_id(addr);
+       release_region(addr, HP100_REGION_SIZE);
+
+       if (sig == NULL)
+               goto err;
+
+       for (i = 0; i < ARRAY_SIZE(hp100_isa_tbl); i++) {
+               if (!strcmp(hp100_isa_tbl[i], sig)) 
+                       break;
 
-#ifdef CONFIG_PCI
-       {
-               int pci_index;
-               struct pci_dev *pci_dev = NULL;
-               int pci_id_index;
-               u_short pci_command;
-
-#ifdef HP100_DEBUG_PCI
-               printk("hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name);
-#endif
-               pci_index = 0;
-               for (pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE;
-                    pci_id_index++) {
-                       while ((pci_dev = pci_find_device(hp100_pci_ids[pci_id_index].vendor,
-                                                         hp100_pci_ids[pci_id_index].device,
-                                                         pci_dev)) != NULL) {
-                               if (pci_index < (pci_start_index & 7)) {
-                                       pci_index++;
-                                       continue;
-                               }
-                               if (pci_enable_device(pci_dev))
-                                       continue;
-                               /* found... */
-                               ioaddr = pci_resource_start(pci_dev, 0);
-                               if (check_region(ioaddr, HP100_REGION_SIZE))
-                                       continue;
-                               pci_read_config_word(pci_dev, PCI_COMMAND, &pci_command);
-                               if (!(pci_command & PCI_COMMAND_IO)) {
-#ifdef HP100_DEBUG
-                                       printk("hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name);
-#endif
-                                       pci_command |= PCI_COMMAND_IO;
-                                       pci_write_config_word(pci_dev, PCI_COMMAND, pci_command);
-                               }
-                               if (!(pci_command & PCI_COMMAND_MASTER)) {
-#ifdef HP100_DEBUG
-                                       printk("hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name);
-#endif
-                                       pci_command |= PCI_COMMAND_MASTER;
-                                       pci_write_config_word(pci_dev, PCI_COMMAND, pci_command);
-                               }
-#ifdef HP100_DEBUG
-                               printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr);
-#endif
-                               if (hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pci_dev) == 0)
-                                       return 0;
-                       }
-               }
        }
-       if (pci_start_index > 0)
-               return -ENODEV;
-#endif /* CONFIG_PCI */
 
-       /* Second: Probe all EISA possible port regions (if EISA bus present) */
-       for (ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400) {
-               if (check_region(ioaddr, HP100_REGION_SIZE))
-                       continue;
-               if (hp100_probe1(dev, ioaddr, HP100_BUS_EISA, NULL) == 0)
-                       return 0;
+       if (i < ARRAY_SIZE(hp100_isa_tbl))
+               return hp100_probe1(dev, addr, HP100_BUS_ISA, NULL);
+ err:
+       return -ENODEV;
+
+}
+/*
+ * Probe for ISA board.
+ * EISA and PCI are handled by device infrastructure.
+ */
+
+static int  __init hp100_isa_probe(struct net_device *dev, int addr)
+{
+       int err = -ENODEV;
+
+       /* Probe for a specific ISA address */          
+       if (addr > 0xff && addr < 0x400)
+               err = hp100_isa_probe1(dev, addr);
+
+       else if (addr != 0) 
+               err = -ENXIO;
+
+       else {
+               /* Probe all ISA possible port regions */
+               for (addr = 0x100; addr < 0x400; addr += 0x20) {
+                       err = hp100_isa_probe1(dev, addr);
+                       if (!err)
+                               break;
+               }
        }
+       return err;
+}
 
-       /* Third: Probe all ISA possible port regions */
-       for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
-               if (check_region(ioaddr, HP100_REGION_SIZE))
-                       continue;
-               if (hp100_probe1(dev, ioaddr, HP100_BUS_ISA, NULL) == 0)
-                       return 0;
+
+struct net_device * __init hp100_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       SET_MODULE_OWNER(dev);
+
+#ifdef HP100_DEBUG_B
+       hp100_outw(0x4200, TRACE);
+       printk("hp100: %s: probe\n", dev->name);
+#endif
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
        }
 
-       return -ENODEV;
+       err = hp100_isa_probe(dev, dev->base_addr);
+       if (err)
+               goto out;
+
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+ out1:
+       release_region(dev->base_addr, HP100_REGION_SIZE);
+ out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                               u_char bus, struct pci_dev *pci_dev)
 {
        int i;
-
-       u_char uc, uc_1;
-       u_int eisa_id;
+       int err = -ENODEV;
+       const char *eid;
        u_int chip;
+       u_char uc;
        u_int memory_size = 0, virt_memory_size = 0;
        u_short local_mode, lsw;
        short mem_mapped;
        unsigned long mem_ptr_phys;
        void **mem_ptr_virt;
        struct hp100_private *lp;
-       struct hp100_eisa_id *eid;
 
 #ifdef HP100_DEBUG_B
        hp100_outw(0x4201, TRACE);
        printk("hp100: %s: probe1\n", dev->name);
 #endif
 
-       if (dev == NULL) {
-#ifdef HP100_DEBUG
-               printk("hp100_probe1: %s: dev == NULL ?\n", dev->name);
-#endif
-               return -EIO;
-       }
+       /* memory region for programmed i/o */
+       if (!request_region(ioaddr, HP100_REGION_SIZE, "hp100"))
+               goto out1;
 
-       if (hp100_inw(HW_ID) != HP100_HW_ID_CASCADE) {
-               return -ENODEV;
-       } else {
-               chip = hp100_inw(PAGING) & HP100_CHIPID_MASK;
+       if (hp100_inw(HW_ID) != HP100_HW_ID_CASCADE) 
+               goto out2;
+
+       chip = hp100_inw(PAGING) & HP100_CHIPID_MASK;
 #ifdef HP100_DEBUG
-               if (chip == HP100_CHIPID_SHASTA)
-                       printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name);
-               else if (chip == HP100_CHIPID_RAINIER)
-                       printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name);
-               else if (chip == HP100_CHIPID_LASSEN)
-                       printk("hp100: %s: Lassen Chip detected.\n", dev->name);
-               else
-                       printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n", dev->name, chip);
+       if (chip == HP100_CHIPID_SHASTA)
+               printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name);
+       else if (chip == HP100_CHIPID_RAINIER)
+               printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name);
+       else if (chip == HP100_CHIPID_LASSEN)
+               printk("hp100: %s: Lassen Chip detected.\n", dev->name);
+       else
+               printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n", dev->name, chip);
 #endif
-       }
 
        dev->base_addr = ioaddr;
 
-       hp100_page(ID_MAC_ADDR);
-       for (i = uc = eisa_id = 0; i < 4; i++) {
-               eisa_id >>= 8;
-               uc_1 = hp100_inb(BOARD_ID + i);
-               eisa_id |= uc_1 << 24;
-               uc += uc_1;
-       }
-       uc += hp100_inb(BOARD_ID + 4);
-
-       if (uc != 0xff) {       /* bad checksum? */
-               printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr);
-               return -ENODEV;
-       }
-
-       for (i = 0; i < HP100_EISA_IDS_SIZE; i++)
-               if (hp100_eisa_ids[i].id == eisa_id)
-                       break;
-       if (i >= HP100_EISA_IDS_SIZE) {
-               for (i = 0; i < HP100_EISA_IDS_SIZE; i++)
-                       if ((hp100_eisa_ids[i].id & 0xf0ffffff) == (eisa_id & 0xf0ffffff))
-                               break;
-               if (i >= HP100_EISA_IDS_SIZE) {
-                       printk ("hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev->name, ioaddr, eisa_id);
-                       return -ENODEV;
-               }
-       }
-       eid = &hp100_eisa_ids[i];
-       if ((eid->id & 0x0f000000) < (eisa_id & 0x0f000000)) {
-               printk("hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n", dev->name, eid->name, ioaddr);
-               return -ENODEV;
+       eid = hp100_read_id(ioaddr);
+       if (eid == NULL) {      /* bad checksum? */
+               printk(KERN_WARNING "hp100_probe: bad ID checksum at base port 0x%x\n", ioaddr);
+               goto out2;
        }
 
+       hp100_page(ID_MAC_ADDR);
        for (i = uc = 0; i < 7; i++)
                uc += hp100_inb(LAN_ADDR + i);
        if (uc != 0xff) {
-               printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n", dev->name, eid->name, ioaddr);
-               return -EIO;
+               printk(KERN_WARNING "hp100_probe: bad lan address checksum at port 0x%x)\n", ioaddr);
+               err = -EIO;
+               goto out2;
        }
 
        /* Make sure, that all registers are correctly updated... */
@@ -607,17 +516,17 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                hp100_outw(HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW);
                hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
                hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW);
-               printk("hp100: %s: IO mapped mode forced.\n", dev->name);
+               printk("hp100: IO mapped mode forced.\n");
        } else if (local_mode == 2) {
                hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW);
                hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
                hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW);
-               printk("hp100: %s: Shared memory mode requested.\n", dev->name);
+               printk("hp100: Shared memory mode requested.\n");
        } else if (local_mode == 4) {
                if (chip == HP100_CHIPID_LASSEN) {
                        hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_SET_HB, OPTION_LSW);
                        hp100_outw(HP100_IO_EN | HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW);
-                       printk("hp100: %s: Busmaster mode requested.\n", dev->name);
+                       printk("hp100: Busmaster mode requested.\n");
                }
                local_mode = 1;
        }
@@ -643,7 +552,7 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                                /* Gracefully fallback to shared memory */
                                goto busmasterfail;
                        }
-                       printk("hp100: %s: Busmaster mode enabled.\n", dev->name);
+                       printk("hp100: Busmaster mode enabled.\n");
                        hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW);
                } else {
                busmasterfail:
@@ -675,7 +584,7 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                mem_ptr_phys &= ~0x1fff;        /* 8k alignment */
 
                if (bus == HP100_BUS_ISA && (mem_ptr_phys & ~0xfffff) != 0) {
-                       printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name);
+                       printk("hp100: Can only use programmed i/o mode.\n");
                        mem_ptr_phys = 0;
                        mem_mapped = 0;
                        local_mode = 3; /* Use programmed i/o */
@@ -699,7 +608,7 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                        }
 
                        if (mem_ptr_virt == NULL) {     /* all ioremap tries failed */
-                               printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name);
+                               printk("hp100: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n");
                                local_mode = 3;
                                virt_memory_size = 0;
                        }
@@ -710,17 +619,14 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                mem_mapped = 0;
                mem_ptr_phys = 0;
                mem_ptr_virt = NULL;
-               printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name);
+               printk("hp100: Using (slow) programmed i/o mode.\n");
        }
 
        /* Initialise the "private" data structure for this card. */
-       if ((dev->priv = kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL)
-               return -ENOMEM;
-
        lp = (struct hp100_private *) dev->priv;
-       memset(lp, 0, sizeof(struct hp100_private));
+
        spin_lock_init(&lp->lock);
-       lp->id = eid;
+       strlcpy(lp->id, eid, HP100_SIG_LEN);
        lp->chip = chip;
        lp->mode = local_mode;
        lp->bus = bus;
@@ -741,9 +647,6 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
        lp->virt_memory_size = virt_memory_size;
        lp->rx_ratio = hp100_rx_ratio;  /* can be conf'd with insmod */
 
-       /* memory region for programmed i/o */
-       request_region(dev->base_addr, HP100_REGION_SIZE, eid->name);
-
        dev->open = hp100_open;
        dev->stop = hp100_close;
 
@@ -776,10 +679,6 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
        /* Reset statistics (counters) */
        hp100_clear_stats(lp, ioaddr);
 
-       SET_MODULE_OWNER(dev);
-       SET_NETDEV_DEV(dev, &pci_dev->dev);
-       ether_setup(dev);
-
        /* If busmaster mode is wanted, a dma-capable memory area is needed for
         * the rx and tx PDLs 
         * PCI cards can access the whole PC memory. Therefore GFP_DMA is not
@@ -795,8 +694,10 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                /* Conversion to new PCI API :
                 * Pages are always aligned and zeroed, no need to it ourself.
                 * Doc says should be OK for EISA bus as well - Jean II */
-               if ((lp->page_vaddr_algn = pci_alloc_consistent(lp->pci_dev, MAX_RINGSIZE, &page_baddr)) == NULL)
-                       return -ENOMEM;
+               if ((lp->page_vaddr_algn = pci_alloc_consistent(lp->pci_dev, MAX_RINGSIZE, &page_baddr)) == NULL) {
+                       err = -ENOMEM;
+                       goto out2;
+               }
                lp->whatever_offset = ((u_long) page_baddr) - ((u_long) lp->page_vaddr_algn);
 
 #ifdef HP100_DEBUG_BM
@@ -818,7 +719,7 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
        lp->lan_type = hp100_sense_lan(dev);
 
        /* Print out a message what about what we think we have probed. */
-       printk("hp100: %s: %s at 0x%x, IRQ %d, ", dev->name, lp->id->name, ioaddr, dev->irq);
+       printk("hp100: at 0x%x, IRQ %d, ", ioaddr, dev->irq);
        switch (bus) {
        case HP100_BUS_EISA:
                printk("EISA");
@@ -833,7 +734,7 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
        printk(" bus, %dk SRAM (rx/tx %d%%).\n", lp->memory_size >> 10, lp->rx_ratio);
 
        if (lp->mode == 2) {    /* memory mapped */
-               printk("hp100: %s: Memory area at 0x%lx-0x%lx", dev->name, mem_ptr_phys,
+               printk("hp100: Memory area at 0x%lx-0x%lx", mem_ptr_phys,
                                (mem_ptr_phys + (mem_ptr_phys > 0x100000 ? (u_long) lp->memory_size : 16 * 1024)) - 1);
                if (mem_ptr_virt)
                        printk(" (virtual base %p)", mem_ptr_virt);
@@ -843,7 +744,8 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
                dev->mem_start = mem_ptr_phys;
                dev->mem_end = mem_ptr_phys + lp->memory_size;
        }
-       printk("hp100: %s: ", dev->name);
+
+       printk("hp100: ");
        if (lp->lan_type != HP100_LAN_ERR)
                printk("Adapter is attached to ");
        switch (lp->lan_type) {
@@ -861,6 +763,10 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
        }
 
        return 0;
+out2:
+       release_region(ioaddr, HP100_REGION_SIZE);
+out1:
+       return -ENODEV;
 }
 
 /* This procedure puts the card into a stable init state */
@@ -950,6 +856,7 @@ static void hp100_hwinit(struct net_device *dev)
        /* Finally try to log in the Hub if there may be a VG connection. */
        if ((lp->lan_type == HP100_LAN_100) || (lp->lan_type == HP100_LAN_ERR))
                hp100_login_to_vg_hub(dev, 0);  /* relogin */
+
 }
 \f
 
@@ -1152,7 +1059,7 @@ static int hp100_open(struct net_device *dev)
        if (request_irq(dev->irq, hp100_interrupt,
                        lp->bus == HP100_BUS_PCI || lp->bus ==
                        HP100_BUS_EISA ? SA_SHIRQ : SA_INTERRUPT,
-                       lp->id->name, dev)) {
+                       "hp100", dev)) {
                printk("hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq);
                return -EAGAIN;
        }
@@ -2054,7 +1961,7 @@ static void hp100_rx_bm(struct net_device *dev)
 /*
  *  statistics
  */
-static hp100_stats_t *hp100_get_stats(struct net_device *dev)
+static struct net_device_stats *hp100_get_stats(struct net_device *dev)
 {
        unsigned long flags;
        int ioaddr = dev->base_addr;
@@ -2558,10 +2465,14 @@ static int hp100_sense_lan(struct net_device *dev)
                return HP100_LAN_COAX;
        }
 
-       if ((lp->id->id == 0x02019F022) ||
-           (lp->id->id == 0x01042103c) || (lp->id->id == 0x01040103c))
-               return HP100_LAN_ERR;   /* Those cards don't have a 100 Mbit connector */
-
+       /* Those cards don't have a 100 Mbit connector */
+       if ( !strcmp(lp->id, "HWP1920")  ||
+            (lp->pci_dev && 
+             lp->pci_dev->vendor == PCI_VENDOR_ID && 
+             (lp->pci_dev->device == PCI_DEVICE_ID_HP_J2970A ||
+              lp->pci_dev->device == PCI_DEVICE_ID_HP_J2973A)))
+               return HP100_LAN_ERR;
+       
        if (val_VG & HP100_LINK_CABLE_ST)       /* Can hear the HUBs tone. */
                return HP100_LAN_100;
        return HP100_LAN_ERR;
@@ -2915,122 +2826,248 @@ void hp100_RegisterDump(struct net_device *dev)
 #endif
 
 
+static void cleanup_dev(struct net_device *d)
+{
+       struct hp100_private *p = (struct hp100_private *) d->priv;
+
+       unregister_netdev(d);
+       release_region(d->base_addr, HP100_REGION_SIZE);
+
+       if (p->mode == 1)       /* busmaster */
+               pci_free_consistent(p->pci_dev, MAX_RINGSIZE + 0x0f, 
+                                   p->page_vaddr_algn, 
+                                   virt_to_whatever(d, p->page_vaddr_algn));
+       if (p->mem_ptr_virt)
+               iounmap(p->mem_ptr_virt);
+
+       free_netdev(d);
+}
+
+#ifdef CONFIG_EISA
+static int __init hp100_eisa_probe (struct device *gendev)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
+       struct eisa_device *edev = to_eisa_device(gendev);
+       int err;
+
+       if (!dev)
+               return -ENOMEM;
+
+       SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &edev->dev);
+
+       err = hp100_probe1(dev, edev->base_addr, HP100_BUS_EISA, NULL);
+       if (err)
+               goto out1;
+
+       err = register_netdev(dev);
+       if (err)
+               goto out2;
+       
+#ifdef HP100_DEBUG
+       printk("hp100: %s: EISA adapter found at 0x%x\n", dev->name, 
+              dev->base_addr);
+#endif
+       gendev->driver_data = dev;
+       return 0;
+ out2:
+       release_region(dev->base_addr, HP100_REGION_SIZE);
+ out1:
+       free_netdev(dev);
+       return err;
+}
+
+static int __devexit hp100_eisa_remove (struct device *gendev)
+{
+       struct net_device *dev = gendev->driver_data;
+       cleanup_dev(dev);
+       return 0;
+}
+
+static struct eisa_driver hp100_eisa_driver = {
+        .id_table = hp100_eisa_tbl,
+        .driver   = {
+                .name    = "hp100",
+                .probe   = hp100_eisa_probe,
+                .remove  = __devexit_p (hp100_eisa_remove),
+        }
+};
+#endif
+
+#ifdef CONFIG_PCI
+static int __devinit hp100_pci_probe (struct pci_dev *pdev,
+                                    const struct pci_device_id *ent)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
+       int ioaddr = pci_resource_start(pdev, 0);
+       u_short pci_command;
+       int err;
+       
+       if (!dev)
+               return -ENOMEM;
+
+       SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+       if (!(pci_command & PCI_COMMAND_IO)) {
+#ifdef HP100_DEBUG
+               printk("hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name);
+#endif
+               pci_command |= PCI_COMMAND_IO;
+               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+       }
+
+       if (!(pci_command & PCI_COMMAND_MASTER)) {
+#ifdef HP100_DEBUG
+               printk("hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name);
+#endif
+               pci_command |= PCI_COMMAND_MASTER;
+               pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+       }
+       
+
+       err = hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pdev);
+       if (err) 
+               goto out1;
+       err = register_netdev(dev);
+       if (err)
+               goto out2;
+       
+#ifdef HP100_DEBUG
+       printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr);
+#endif
+       pci_set_drvdata(pdev, dev);
+       return 0;
+ out2:
+       release_region(dev->base_addr, HP100_REGION_SIZE);
+ out1:
+       free_netdev(dev);
+       return err;
+}
+
+static void __devexit hp100_pci_remove (struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+
+       cleanup_dev(dev);
+}
+
+
+static struct pci_driver hp100_pci_driver = {
+       .name           = "hp100",
+       .id_table       = hp100_pci_tbl,
+       .probe          = hp100_pci_probe,
+       .remove         = __devexit_p(hp100_pci_remove),
+};
+#endif
+
 /*
  *  module section
  */
 
-#ifdef MODULE
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, "
               "Siegfried \"Frieder\" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>");
 MODULE_DESCRIPTION("HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters");
 
 /*
- * Note: if you have more than five 100vg cards in your pc, feel free to
- * increase this value 
- */
-
-#define HP100_DEVICES 5
-
-/*
- * Note: to register three eisa or pci devices, use:
+ * Note: to register three isa devices, use:
  * option hp100 hp100_port=0,0,0
  *        to register one card at io 0x280 as eth239, use:
- * option hp100 hp100_port=0x280 hp100_name=eth239
+ * option hp100 hp100_port=0x280
  */
-
+#if defined(MODULE) && defined(CONFIG_ISA)
+#define HP100_DEVICES 5
 /* Parameters set by insmod */
 static int hp100_port[HP100_DEVICES] = { 0, [1 ... (HP100_DEVICES-1)] = -1 };
 MODULE_PARM(hp100_port, "1-" __MODULE_STRING(HP100_DEVICES) "i");
 
-/* Allocate HP100_DEVICES strings of length IFNAMSIZ, one string for each device */
-static char hp100_name[HP100_DEVICES][IFNAMSIZ] = { "", "", "", "", "" };
-/* Allow insmod to write those HP100_DEVICES strings individually */
-MODULE_PARM(hp100_name, "1-" __MODULE_STRING(HP100_DEVICES) "c" __MODULE_STRING(IFNAMSIZ));
-
 /* List of devices */
 static struct net_device *hp100_devlist[HP100_DEVICES];
 
-static void release_dev(int i)
+static int __init hp100_isa_init(void)
 {
-       struct net_device *d = hp100_devlist[i];
-       struct hp100_private *p = (struct hp100_private *) d->priv;
+       struct net_device *dev;
+       int i, err, cards = 0;
 
-       unregister_netdev(d);
-       release_region(d->base_addr, HP100_REGION_SIZE);
+       /* Don't autoprobe ISA bus */
+       if (hp100_port[0] == 0)
+               return -ENODEV;
 
-       if (p->mode == 1)       /* busmaster */
-               pci_free_consistent(p->pci_dev, MAX_RINGSIZE + 0x0f, p->page_vaddr_algn, virt_to_whatever(d, p->page_vaddr_algn));
-       if (p->mem_ptr_virt)
-               iounmap(p->mem_ptr_virt);
-       kfree(d->priv);
-       d->priv = NULL;
-       free_netdev(d);
-       hp100_devlist[i] = NULL;
+       /* Loop on all possible base addresses */
+       for (i = 0; i < HP100_DEVICES && hp100_port[i] != -1; ++i) {
+               dev = alloc_etherdev(sizeof(struct hp100_private));
+               if (!dev) {
+                       printk(KERN_WARNING "hp100: no memory for network device\n");
+                       while (cards > 0)
+                               cleanup_dev(hp100_devlist[--cards]);
+
+                       return -ENOMEM;
+               }
+               SET_MODULE_OWNER(dev);
+
+               err = hp100_isa_probe(dev, hp100_port[i]);
+               if (!err) {
+                       err = register_netdev(dev);
+                       if (!err) 
+                               hp100_devlist[cards++] = dev;
+                       else
+                               release_region(dev->base_addr, HP100_REGION_SIZE);
+               }
+
+               if (err)
+                       free_netdev(dev);
+       }
+
+       return cards > 0 ? 0 : -ENODEV;
 }
 
-static int __init hp100_module_init(void)
+static void __exit hp100_isa_cleanup(void) 
 {
-       int i, cards;
+       int i;
 
-#ifndef CONFIG_PCI
-       if (hp100_port == 0 && !EISA_bus)
-               printk("hp100: You should not use auto-probing with insmod!\n");
+       for (i = 0; i < HP100_DEVICES; i++) {
+               struct net_device *dev = hp100_devlist[i];
+               if (dev)
+                       cleanup_dev(dev);
+       }
+}
+#else
+#define hp100_isa_init()       (0)
+#define hp100_isa_cleanup()    do { } while(0)
 #endif
 
-       /* Loop on all possible base addresses */
-       i = -1;
-       cards = 0;
-       while ((hp100_port[++i] != -1) && (i < HP100_DEVICES)) {
-               /* Create device and set basics args */
-               hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-               if (!hp100_devlist[i])
-                       goto fail;
-               memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
-#if LINUX_VERSION_CODE >= 0x020362     /* 2.3.99-pre7 */
-               memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ);        /* Copy name */
-#else
-               hp100_devlist[i]->name = hp100_name[i];
-#endif                         /* LINUX_VERSION_CODE >= 0x020362 */
-               hp100_devlist[i]->base_addr = hp100_port[i];
-               hp100_devlist[i]->init = &hp100_probe;
-
-               /* Try to create the device */
-               if (register_netdev(hp100_devlist[i]) != 0) {
-                       /* DeAllocate everything */
-                       /* Note: if dev->priv is mallocated, there is no way to fail */
-                       kfree(hp100_devlist[i]);
-                       hp100_devlist[i] = (struct net_device *) NULL;
-               } else
-                       cards++;
-       }                       /* Loop over all devices */
+static int __init hp100_module_init(void)
+{
+       int err;
 
-       return cards > 0 ? 0 : -ENODEV;
-      fail:
-       while (cards && --i)
-               if (hp100_devlist[i]) {
-                       release_dev(i);
-                       --cards;
-               }
-       return -ENOMEM;
+       err = hp100_isa_init();
+
+#ifdef CONFIG_EISA
+       err |= eisa_driver_register(&hp100_eisa_driver);
+#endif
+#ifdef CONFIG_PCI
+       err |= pci_module_init(&hp100_pci_driver);
+#endif
+       return err;
 }
 
+
 static void __exit hp100_module_exit(void)
 {
-       int i;
-
-       /* TODO: Check if all skb's are released/freed. */
-       for (i = 0; i < HP100_DEVICES; i++)
-               if (hp100_devlist[i] != (struct net_device *) NULL)
-                       release_dev(i);
+       hp100_isa_cleanup();
+#ifdef CONFIG_EISA
+       eisa_driver_unregister (&hp100_eisa_driver);
+#endif
+#ifdef CONFIG_PCI
+       pci_unregister_driver (&hp100_pci_driver);
+#endif
 }
 
 module_init(hp100_module_init)
 module_exit(hp100_module_exit)
 
-#endif                         /* MODULE */
-
 
 /*
  * Local variables:
index 98cb52f..cd0b733 100644 (file)
@@ -50,8 +50,7 @@ struct hplance_private {
  * plus board-specific init, open and close actions. 
  * Oh, and we need to tell the generic code how to read and write LANCE registers...
  */
-int hplance_probe(struct net_device *dev);
-static int hplance_init(struct net_device *dev, int scode);
+static void hplance_init(struct net_device *dev, int scode);
 static int hplance_open(struct net_device *dev);
 static int hplance_close(struct net_device *dev);
 static void hplance_writerap(void *priv, unsigned short value);
@@ -62,57 +61,61 @@ static unsigned short hplance_readrdp(void *priv);
 static struct hplance_private *root_hplance_dev;
 #endif
 
+static void cleanup_card(struct net_device *dev)
+{
+        struct hplance_private *lp = dev->priv;
+       dio_unconfig_board(lp->scode);
+}
+
 /* Find all the HP Lance boards and initialise them... */
-int __init hplance_probe(struct net_device *dev)
+struct net_device * __init hplance_probe(int unit)
 {
-        int cards = 0, called = 0;
+       struct net_device *dev;
+
+        if (!MACH_IS_HP300)
+                return ERR_PTR(-ENODEV);
+
+       dev = alloc_etherdev(sizeof(struct hplance_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
 
-        if (!MACH_IS_HP300 || called)
-                return(ENODEV);
-        called++;
+       SET_MODULE_OWNER(dev);
         
         /* Isn't DIO nice? */
         for(;;)
         {
-                int v, scode = dio_find(DIO_ID_LAN);
+                int scode = dio_find(DIO_ID_LAN);
                                 
                 if (!scode)
                         break;
                 
-                if(cards)
-                        dev = NULL;      /* don't trash previous device, make a new one */
-                cards++;
-                
-                v = hplance_init(dev, scode);
-                if (v)                            /* error, abort immediately */
-                        return v;
+               dio_config_board(scode);
+                hplance_init(dev, scode);
+               if (!register_netdev(dev)) {
+                       struct hplance_private *lp = dev->priv;
+                       lp->next_module = root_hplance_dev;
+                       root_hplance_dev = lp;
+                       return dev;
+               }
+               cleanup_card(dev);
         }
-        /* OK, return success, or ENODEV if we didn't find any cards */
-        if (!cards)
-                return -ENODEV;
-        return 0;
+       free_netdev(dev);
+       return ERR_PTR(-ENODEV);
 }
 
 /* Initialise a single lance board at the given select code */
-static int __init hplance_init(struct net_device *dev, int scode)
+static void __init hplance_init(struct net_device *dev, int scode)
 {
         const char *name = dio_scodetoname(scode);
         void *va = dio_scodetoviraddr(scode);
         struct hplance_private *lp;
         int i;
         
-#ifdef MODULE
-       dev = init_etherdev(0, sizeof(struct hplance_private));
-       if (!dev)
-               return -ENOMEM;
-#else
-       dev->priv = kmalloc(sizeof(struct hplance_private), GFP_KERNEL);
-       if (dev->priv == NULL)
-               return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct hplance_private));
-#endif
-       SET_MODULE_OWNER(dev);
-
         printk("%s: %s; select code %d, addr", dev->name, name, scode);
 
         /* reset the board */
@@ -154,17 +157,7 @@ static int __init hplance_init(struct net_device *dev, int scode)
         lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
         lp->scode = scode;
        lp->base = va;
-        ether_setup(dev);
        printk(", irq %d\n", lp->lance.irq);
-
-#ifdef MODULE
-        dev->ifindex = dev_new_index();
-        lp->next_module = root_hplance_dev;
-        root_hplance_dev = lp;
-#endif /* MODULE */
-
-        dio_config_board(scode);                  /* tell bus scanning code this one's taken */
-        return 0;
 }
 
 /* This is disgusting. We have to check the DIO status register for ack every
@@ -227,8 +220,10 @@ static int hplance_close(struct net_device *dev)
 MODULE_LICENSE("GPL");
 int init_module(void)
 {
-        root_lance_dev = NULL;
-        return hplance_probe(NULL);
+       int found = 0;
+       while (!IS_ERR(hplance_probe(-1)))
+               found++;
+       return found ? 0 : -ENODEV;
 }
 
 void cleanup_module(void)
@@ -237,8 +232,8 @@ void cleanup_module(void)
         struct hplance_private *lp;
         while (root_hplance_dev) {
                 lp = root_hplance_dev->next_module;
-                dio_unconfig_board(lp->scode);
                 unregister_netdev(root_lance_dev->dev);
+                cleanup_card(root_lance_dev->dev);
                 free_netdev(root_lance_dev->dev);
                 root_lance_dev = lp;
         }
index b183b11..3a2ec0a 100644 (file)
@@ -89,13 +89,14 @@ static int __init hydra_init(unsigned long board)
     const char name[] = "NE2000";
     int start_page, stop_page;
     int j;
+    int err;
 
     static u32 hydra_offsets[16] = {
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
        0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
     };
 
-    dev = init_etherdev(NULL, 0);
+    dev = alloc_ei_netdev();
     if (!dev)
        return -ENOMEM;
     SET_MODULE_OWNER(dev);
@@ -113,13 +114,9 @@ static int __init hydra_init(unsigned long board)
 
     /* Install the Interrupt handler */
     if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, "Hydra Ethernet",
-                   dev))
+                   dev)) {
+       free_netdev(dev);
        return -EAGAIN;
-
-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
-    if (ethdev_init(dev)) {
-       printk("Unable to get memory for dev->priv.\n");
-       return -ENOMEM;
     }
 
     printk("%s: hydra at 0x%08lx, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", dev->name, ZTWO_PADDR(board),
@@ -146,7 +143,13 @@ static int __init hydra_init(unsigned long board)
     root_hydra_dev = dev;
 #endif
     NS8390_init(dev, 0);
-    return 0;
+    err = register_netdev(dev);
+    if (!err)
+       return 0;
+
+    free_irq(IRQ_AMIGA_PORTS, dev);
+    free_netdev(dev);
+    return err;
 }
 
 static int hydra_open(struct net_device *dev)
index 934335c..9fb3c99 100644 (file)
@@ -906,7 +906,7 @@ static void ibmlana_set_multicast_list(struct net_device *dev)
 
 static int startslot;          /* counts through slots when probing multiple devices */
 
-int ibmlana_probe(struct net_device *dev)
+static int ibmlana_probe(struct net_device *dev)
 {
        int force_detect = 0;
        int slot, z;
@@ -924,34 +924,21 @@ int ibmlana_probe(struct net_device *dev)
        if (dev->mem_start == 1)
                force_detect = 1;
 
-       /* search through slots */
-       if (dev != NULL) {
-               base = dev->mem_start;
-               irq = dev->irq;
-       }
-       slot = mca_find_adapter(IBM_LANA_ID, startslot);
+       base = dev->mem_start;
+       irq = dev->irq;
 
-       while (slot != -1) {
+       for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) {
                /* deduce card addresses */
                getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
 
                /* slot already in use ? */
-               if (mca_is_adapter_used(slot)) {
-                       slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
+               if (mca_is_adapter_used(slot))
                        continue;
-               }
                /* were we looking for something different ? */
-               if (dev->irq != 0 || dev->mem_start != 0) {
-                       if (dev->irq != 0 && dev->irq != irq) {
-                               slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
-                               continue;
-                       }
-                       if (dev->mem_start != 0 && dev->mem_start != base) 
-                       {
-                               slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
-                               continue;
-                       }
-               }
+               if (dev->irq && dev->irq != irq)
+                       continue;
+               if (dev->mem_start && dev->mem_start != base)
+                       continue;
                /* found something that matches */
                break;
        }
@@ -977,16 +964,11 @@ int ibmlana_probe(struct net_device *dev)
        mca_mark_as_used(slot);
 
        /* allocate structure */
-       priv = dev->priv = (ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL);
-       if (!priv) {
-               release_region(iobase, IBM_LANA_IORANGE);
-               return -ENOMEM;
-       }
+       priv = dev->priv;
        priv->slot = slot;
        priv->realirq = irq;
        priv->medium = medium;
        spin_lock_init(&priv->lock);
-       memset(&priv->stat, 0, sizeof(struct net_device_stats));
 
        /* set base + irq for this device (irq not allocated so far) */
 
@@ -1006,10 +988,6 @@ int ibmlana_probe(struct net_device *dev)
        dev->set_multicast_list = ibmlana_set_multicast_list;
        dev->flags |= IFF_MULTICAST;
 
-       /* generic setup */
-
-       ether_setup(dev);
-
        /* copy out MAC address */
 
        for (z = 0; z < sizeof(dev->dev_addr); z++)
@@ -1044,7 +1022,7 @@ int ibmlana_probe(struct net_device *dev)
 
 #define DEVMAX 5
 
-static struct net_device moddevs[DEVMAX];
+static struct net_device *moddevs[DEVMAX];
 static int irq;
 static int io;
 
@@ -1056,41 +1034,47 @@ MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
-       int z, res;
+       int z;
 
        startslot = 0;
        for (z = 0; z < DEVMAX; z++) {
-               moddevs[z].init = ibmlana_probe;
-               moddevs[z].irq = irq;
-               moddevs[z].base_addr = io;
-               res = register_netdev(moddevs + z);
-               if (res != 0)
-                       return (z > 0) ? 0 : -EIO;
+               struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv));
+               if (!dev)
+                       break;
+               dev->irq = irq;
+               dev->base_addr = io;
+               if (ibmlana_probe(dev)) {
+                       free_netdev(dev);
+                       break;
+               }
+               if (register_netdev(dev)) {
+                       ibmlana_priv *priv = dev->priv;
+                       release_region(dev->base_addr, IBM_LANA_IORANGE);
+                       mca_mark_as_unused(priv->slot);
+                       mca_set_adapter_name(priv->slot, "");
+                       mca_set_adapter_procfn(priv->slot, NULL, NULL);
+                       free_netdev(dev);
+                       break;
+               }
+               moddevs[z] = dev;
        }
-       return 0;
+       return (z > 0) ? 0 : -EIO;
 }
 
 void cleanup_module(void)
 {
-       struct net_device *dev;
-       ibmlana_priv *priv;
        int z;
-
        for (z = 0; z < DEVMAX; z++) {
-               dev = moddevs + z;
-               if (dev->priv != NULL) {
-                       priv = (ibmlana_priv *) dev->priv;
+               struct net_device *dev = moddevs[z];
+               if (dev) {
+                       ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+                       unregister_netdev(dev);
                        /*DeinitBoard(dev); */
-                       if (dev->irq != 0)
-                               free_irq(dev->irq, dev);
-                       dev->irq = 0;
                        release_region(dev->base_addr, IBM_LANA_IORANGE);
-                       unregister_netdev(dev);
                        mca_mark_as_unused(priv->slot);
                        mca_set_adapter_name(priv->slot, "");
                        mca_set_adapter_procfn(priv->slot, NULL, NULL);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
+                       free_netdev(dev);
                }
        }
 }
index 17ce22e..1b535e8 100644 (file)
@@ -275,7 +275,4 @@ typedef struct {
 
 #endif                         /* _IBM_LANA_DRIVER_ */
 
-extern int ibmlana_probe(struct net_device *);
-
-
 #endif /* _IBM_LANA_INCLUDE_ */
index 58e9312..c4b7b2a 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/errno.h>
@@ -358,9 +359,13 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
 static int sa1100_irda_suspend(struct device *_dev, u32 state, u32 level)
 {
        struct net_device *dev = dev_get_drvdata(_dev);
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si;
+
+       if (!dev || level != SUSPEND_DISABLE)
+               return 0;
 
-       if (si && si->open && level == SUSPEND_DISABLE) {
+       si = dev->priv;
+       if (si->open) {
                /*
                 * Stop the transmit queue
                 */
@@ -379,9 +384,13 @@ static int sa1100_irda_suspend(struct device *_dev, u32 state, u32 level)
 static int sa1100_irda_resume(struct device *_dev, u32 level)
 {
        struct net_device *dev = dev_get_drvdata(_dev);
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si;
 
-       if (si && si->open && level == RESUME_ENABLE) {
+       if (!dev || level != RESUME_ENABLE)
+               return 0;
+
+       si = dev->priv;
+       if (si->open) {
                /*
                 * If we missed a speed change, initialise at the new speed
                 * directly.  It is debatable whether this is actually
@@ -833,8 +842,6 @@ static int sa1100_irda_start(struct net_device *dev)
        struct sa1100_irda *si = dev->priv;
        int err;
 
-       MOD_INC_USE_COUNT;
-
        si->speed = 9600;
 
        err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev);
@@ -890,7 +897,6 @@ err_tx_dma:
 err_rx_dma:
        free_irq(dev->irq, dev);
 err_irq:
-       MOD_DEC_USE_COUNT;
        return err;
 }
 
@@ -930,8 +936,6 @@ static int sa1100_irda_stop(struct net_device *dev)
 
        sa1100_set_power(si, 0);
 
-       MOD_DEC_USE_COUNT;
-
        return 0;
 }
 
@@ -947,56 +951,48 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size)
        return io->head ? 0 : -ENOMEM;
 }
 
-static struct device_driver sa1100ir_driver = {
-       .name           = "sa1100ir",
-       .bus            = &system_bus_type,
-       .suspend        = sa1100_irda_suspend,
-       .resume         = sa1100_irda_resume,
-};
-
-static struct sys_device sa1100ir_device = {
-       .name           = "sa1100ir",
-       .id             = 0,
-       .root           = NULL,
-       .dev            = {
-               .name   = "Intel Corporation SA11x0 [IrDA]",
-               .bus_id = "0",
-               .driver = &sa1100ir_driver,
-       },
-};
-
-static int sa1100_irda_net_init(struct net_device *dev)
+static int sa1100_irda_probe(struct device *_dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct platform_device *pdev = to_platform_device(_dev);
+       struct net_device *dev;
+       struct sa1100_irda *si;
        unsigned int baudrate_mask;
-       int err = -ENOMEM;
+       int err;
 
-       si = kmalloc(sizeof(struct sa1100_irda), GFP_KERNEL);
-       if (!si)
-               goto out;
+       err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY;
+       if (err)
+               goto err_mem_1;
+       err = request_mem_region(__PREG(Ser2HSCR0), 0x1c, "IrDA") ? 0 : -EBUSY;
+       if (err)
+               goto err_mem_2;
+       err = request_mem_region(__PREG(Ser2HSCR2), 0x04, "IrDA") ? 0 : -EBUSY;
+       if (err)
+               goto err_mem_3;
 
-       memset(si, 0, sizeof(*si));
+       dev = alloc_irdadev(sizeof(struct sa1100_irda));
+       if (!dev)
+               goto err_mem_4;
 
-       si->dev = &sa1100ir_device.dev;
+       si = dev->priv;
+       si->dev = &pdev->dev;
 
        /*
         * Initialise the HP-SIR buffers
         */
        err = sa1100_irda_init_iobuf(&si->rx_buff, 14384);
        if (err)
-               goto out;
+               goto err_mem_5;
        err = sa1100_irda_init_iobuf(&si->tx_buff, 4000);
        if (err)
-               goto out_free_rx;
+               goto err_mem_5;
 
-       dev->priv = si;
        dev->hard_start_xmit    = sa1100_irda_hard_xmit;
        dev->open               = sa1100_irda_start;
        dev->stop               = sa1100_irda_stop;
        dev->do_ioctl           = sa1100_irda_ioctl;
        dev->get_stats          = sa1100_irda_stats;
+       dev->irq                = IRQ_Ser2ICP;
 
-       irda_device_setup(dev);
        irda_init_max_qos_capabilies(&si->qos);
 
        /*
@@ -1030,42 +1026,62 @@ static int sa1100_irda_net_init(struct net_device *dev)
        Ser2UTCR4 = si->utcr4;
        Ser2HSCR0 = HSCR0_UART;
 
-       return 0;
-
-       kfree(si->tx_buff.head);
-out_free_rx:
-       kfree(si->rx_buff.head);
-out:
-       kfree(si);
+       err = register_netdev(dev);
+       if (err == 0)
+               dev_set_drvdata(&pdev->dev, si);
 
+       if (err) {
+ err_mem_5:
+               kfree(si->tx_buff.head);
+               kfree(si->rx_buff.head);
+               free_netdev(dev);
+ err_mem_4:
+               release_mem_region(__PREG(Ser2HSCR2), 0x04);
+ err_mem_3:
+               release_mem_region(__PREG(Ser2HSCR0), 0x1c);
+ err_mem_2:
+               release_mem_region(__PREG(Ser2UTCR0), 0x24);
+       }
+ err_mem_1:
        return err;
 }
 
-/*
- * Remove all traces of this driver module from the kernel, so we can't be
- * called.  Note that the device has already been stopped, so we don't have
- * to worry about interrupts or dma.
- */
-static void sa1100_irda_net_uninit(struct net_device *dev)
+static int sa1100_irda_remove(struct device *_dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct net_device *dev = dev_get_drvdata(_dev);
 
-       dev->hard_start_xmit    = NULL;
-       dev->open               = NULL;
-       dev->stop               = NULL;
-       dev->do_ioctl           = NULL;
-       dev->get_stats          = NULL;
-       dev->priv               = NULL;
+       if (dev) {
+               struct sa1100_irda *si = dev->priv;
+               unregister_netdev(dev);
+               kfree(si->tx_buff.head);
+               kfree(si->rx_buff.head);
+               free_netdev(dev);
+       }
 
-       kfree(si->tx_buff.head);
-       kfree(si->rx_buff.head);
-       kfree(si);
+       release_mem_region(__PREG(Ser2HSCR2), 0x04);
+       release_mem_region(__PREG(Ser2HSCR0), 0x1c);
+       release_mem_region(__PREG(Ser2UTCR0), 0x24);
+
+       return 0;
 }
 
+static struct device_driver sa1100ir_driver = {
+       .name           = "sa11x0-ir",
+       .bus            = &platform_bus_type,
+       .probe          = sa1100_irda_probe,
+       .remove         = sa1100_irda_remove,
+       .suspend        = sa1100_irda_suspend,
+       .resume         = sa1100_irda_resume,
+};
+
+static struct platform_device sa1100ir_device = {
+       .name           = "sa11x0-ir",
+       .id             = 0,
+};
+
 static int __init sa1100_irda_init(void)
 {
-       struct net_device *dev;
-       int err;
+       int ret;
 
        /*
         * Limit power level a sensible range.
@@ -1075,103 +1091,30 @@ static int __init sa1100_irda_init(void)
        if (power_level > 3)
                power_level = 3;
 
-       err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY;
-       if (err)
-               goto err_mem_1;
-       err = request_mem_region(__PREG(Ser2HSCR0), 0x1c, "IrDA") ? 0 : -EBUSY;
-       if (err)
-               goto err_mem_2;
-       err = request_mem_region(__PREG(Ser2HSCR2), 0x04, "IrDA") ? 0 : -EBUSY;
-       if (err)
-               goto err_mem_3;
-
-       driver_register(&sa1100ir_driver);
-       sys_device_register(&sa1100ir_device);
-
-       rtnl_lock();
-       dev = dev_alloc("irda%d", &err);
-       if (dev) {
-               dev->irq    = IRQ_Ser2ICP;
-               dev->init   = sa1100_irda_net_init;
-               dev->uninit = sa1100_irda_net_uninit;
-
-               err = register_netdevice(dev);
-
-               if (err)
-                       kfree(dev);
-               else
-                       dev_set_drvdata(&sa1100ir_device.dev, dev);
-       }
-       rtnl_unlock();
-
-       if (err) {
-               sys_device_unregister(&sa1100ir_device);
-               driver_unregister(&sa1100ir_driver);
-
-               release_mem_region(__PREG(Ser2HSCR2), 0x04);
-err_mem_3:
-               release_mem_region(__PREG(Ser2HSCR0), 0x1c);
-err_mem_2:
-               release_mem_region(__PREG(Ser2UTCR0), 0x24);
+       ret = driver_register(&sa1100ir_driver);
+       if (ret == 0) {
+               ret = platform_device_register(&sa1100ir_device);
+               if (ret)
+                       driver_unregister(&sa1100ir_driver);
        }
-err_mem_1:
-       return err;
+       return ret;
 }
 
 static void __exit sa1100_irda_exit(void)
 {
-       struct net_device *dev = dev_get_drvdata(&sa1100ir_device.dev);
-
-       if (dev)
-               unregister_netdev(dev);
-
-       sys_device_unregister(&sa1100ir_device);
        driver_unregister(&sa1100ir_driver);
-
-       release_mem_region(__PREG(Ser2HSCR2), 0x04);
-       release_mem_region(__PREG(Ser2HSCR0), 0x1c);
-       release_mem_region(__PREG(Ser2UTCR0), 0x24);
-
-       if(dev)
-               free_netdev(dev);
+       platform_device_unregister(&sa1100ir_device);
 }
 
-static int __init sa1100ir_setup(char *line)
-{
-       char *opt;
-
-       if (!line)
-               return 0;
-
-       while ((opt = strsep(&line, ",")) != NULL) {
-               if (!strncmp(opt, "max_rate:", 9)) {
-                       max_rate = simple_strtoul(opt + 9, NULL, 0);
-                       continue;
-               }
-               if (!strncmp(opt, "power_level:", 12)) {
-                       power_level = simple_strtoul(opt + 12, NULL, 0);
-                       continue;
-               }
-               if (!strncmp(opt, "tx_lpm:", 7)) {
-                       tx_lpm = simple_strtoul(opt + 7, NULL, 0);
-                       continue;
-               }
-       }
-
-       return 1;
-}
-
-__setup("sa1100ir=", sa1100ir_setup);
-
 module_init(sa1100_irda_init);
 module_exit(sa1100_irda_exit);
+module_param(power_level, int, 0);
+module_param(tx_lpm, int, 0);
+module_param(max_rate, int, 0);
 
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("StrongARM SA1100 IrDA driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(power_level, "i");
 MODULE_PARM_DESC(power_level, "IrDA power level, 1 (low) to 3 (high)");
-MODULE_PARM(tx_lpm, "i");
 MODULE_PARM_DESC(tx_lpm, "Enable transmitter low power (1.6us) mode");
-MODULE_PARM(max_rate, "i");
 MODULE_PARM_DESC(max_rate, "Maximum baud rate (4000000, 115200, 57600, 38400, 19200, 9600)");
index 7b72cf3..ab0f3af 100644 (file)
@@ -446,7 +446,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        iounmap(adapter->hw.hw_addr);
       err_ioremap:
        pci_release_regions(pdev);
-       kfree(netdev);
+       free_netdev(netdev);
       err_alloc_etherdev:
        return -ENOMEM;
 }
index c554db3..20f757c 100644 (file)
@@ -80,7 +80,6 @@ static unsigned short known_revisions[] =
 
 /* Index to functions, as function prototypes. */
 
-extern int sonic_probe(struct net_device *dev);
 static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
                         unsigned int irq);
 
@@ -89,29 +88,57 @@ static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
  * Probe for a SONIC ethernet controller on a Mips Jazz board.
  * Actually probing is superfluous but we're paranoid.
  */
-int __init sonic_probe(struct net_device *dev)
+struct net_device * __init sonic_probe(int unit)
 {
-       unsigned int base_addr = dev ? dev->base_addr : 0;
+       struct net_device *dev;
+       struct sonic_local *lp;
+       unsigned int base_addr;
+       int err = 0;
        int i;
 
        /*
         * Don't probe if we're not running on a Jazz board.
         */
        if (mips_machgroup != MACH_GROUP_JAZZ)
-               return -ENODEV;
-       if (base_addr >= KSEG0) /* Check a single specified location. */
-               return sonic_probe1(dev, base_addr, dev->irq);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
-
-       for (i = 0; sonic_portlist[i].port; i++) {
-               int base_addr = sonic_portlist[i].port;
-               if (check_region(base_addr, 0x100))
-                       continue;
-               if (sonic_probe1(dev, base_addr, sonic_portlist[i].irq) == 0)
-                       return 0;
+               return ERR_PTR(-ENODEV);
+
+       dev = alloc_etherdev(0);
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+       base_addr = dev->base_addr;
+
+       if (base_addr >= KSEG0) { /* Check a single specified location. */
+               err = sonic_probe1(dev, base_addr, dev->irq);
+       } else if (base_addr != 0) { /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (i = 0; sonic_portlist[i].port; i++) {
+                       int io = sonic_portlist[i].port;
+                       if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0)
+                               break;
+               }
+               if (!sonic_portlist[i].port)
+                       err = -ENODEV;
        }
-       return -ENODEV;
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       lp = dev->priv;
+       vdma_free(lp->rba_laddr);
+       kfree(lp->rba);
+       vdma_free(lp->cda_laddr);
+       kfree(lp);
+       release_region(dev->base_addr, 0x100);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
@@ -121,8 +148,11 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
        unsigned int silicon_revision;
        unsigned int val;
        struct sonic_local *lp;
+       int err = -ENODEV;
        int i;
 
+       if (!request_region(base_addr, 0x100, dev->name))
+               return -EBUSY;
        /*
         * get the Silicon Revision ID. If this is one of the known
         * one assume that we found a SONIC ethernet controller at
@@ -140,12 +170,9 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
        if (known_revisions[i] == 0xffff) {
                printk("SONIC ethernet controller not found (0x%4x)\n",
                       silicon_revision);
-               return -ENODEV;
+               goto out;
        }
     
-       if (!request_region(base_addr, 0x100, dev->name))
-               return -EBUSY;
-
        if (sonic_debug  &&  version_printed++ == 0)
                printk(version);
 
@@ -175,6 +202,8 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
        }
 
        printk(" IRQ %d\n", irq);
+
+       err = -ENOMEM;
     
        /* Initialize the device structure. */
        if (dev->priv == NULL) {
@@ -196,7 +225,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
                if (lp == NULL) {
                        printk("%s: couldn't allocate memory for descriptors\n",
                               dev->name);
-                       return -ENOMEM;
+                       goto out;
                }
 
                memset(lp, 0, sizeof(struct sonic_local));
@@ -206,7 +235,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
                if (lp->cda_laddr == ~0UL) {
                        printk("%s: couldn't get DMA page entry for "
                               "descriptors\n", dev->name);
-                       return -ENOMEM;
+                       goto out1;
                }
 
                lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda);
@@ -219,7 +248,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
                if (!lp->rba) {
                        printk("%s: couldn't allocate receive buffers\n",
                               dev->name);
-                       return -ENOMEM;
+                       goto out2;
                }
 
                /* get virtual dma address */
@@ -228,7 +257,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
                if (lp->rba_laddr == ~0UL) {
                        printk("%s: couldn't get DMA page entry for receive "
                               "buffers\n",dev->name);
-                       return -ENOMEM;
+                       goto out3;
                }
 
                /* now convert pointer to KSEG1 pointer */
@@ -252,9 +281,16 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
        SONIC_WRITE(SONIC_FAET,0xffff);
        SONIC_WRITE(SONIC_MPT,0xffff);
 
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
        return 0;
+out3:
+       kfree(lp->rba);
+out2:
+       vdma_free(lp->cda_laddr);
+out1:
+       kfree(lp);
+out:
+       release_region(base_addr, 0x100);
+       return err;
 }
 
 /*
index a6862d6..fc1f9e9 100644 (file)
@@ -59,8 +59,8 @@ static const char version[] = "lance.c:v1.15ac 1999/11/13 dplatt@3do.com, becker
 #include <asm/dma.h>
 
 static unsigned int lance_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0};
-int lance_probe(struct net_device *dev);
 static int lance_probe1(struct net_device *dev, int ioaddr, int irq, int options);
+static int __init do_lance_probe(struct net_device *dev);
 
 #ifdef LANCE_DEBUG
 static int lance_debug = LANCE_DEBUG;
@@ -274,7 +274,6 @@ enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, PCNET_
 static unsigned char lance_need_isa_bounce_buffers = 1;
 
 static int lance_open(struct net_device *dev);
-static int lance_open_fail(struct net_device *dev);
 static void lance_init_ring(struct net_device *dev, int mode);
 static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lance_rx(struct net_device *dev);
@@ -286,10 +285,21 @@ static void lance_tx_timeout (struct net_device *dev);
 
 \f
 
+static void cleanup_card(struct net_device *dev)
+{
+       struct lance_private *lp = dev->priv;
+       if (dev->dma != 4)
+               free_dma(dev->dma);
+       release_region(dev->base_addr, LANCE_TOTAL_SIZE);
+       kfree(lp->tx_bounce_buffs);
+       kfree((void*)lp->rx_buffs);
+       kfree(lp);
+}
+
 #ifdef MODULE
 #define MAX_CARDS              8       /* Max number of interfaces (cards) per module */
 
-static struct net_device dev_lance[MAX_CARDS];
+static struct net_device *dev_lance[MAX_CARDS];
 static int io[MAX_CARDS];
 static int dma[MAX_CARDS];
 static int irq[MAX_CARDS];
@@ -305,28 +315,35 @@ MODULE_PARM_DESC(lance_debug, "LANCE/PCnet debug level (0-7)");
 
 int init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
-               struct net_device *dev = &dev_lance[this_dev];
-               dev->irq = irq[this_dev];
-               dev->base_addr = io[this_dev];
-               dev->dma = dma[this_dev];
-               dev->init = lance_probe;
                if (io[this_dev] == 0)  {
-                       if (this_dev != 0) break; /* only complain once */
+                       if (this_dev != 0) /* only complain once */
+                               break;
                        printk(KERN_NOTICE "lance.c: Module autoprobing not allowed. Append \"io=0xNNN\" value(s).\n");
                        return -EPERM;
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "lance.c: No PCnet/LANCE card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) return 0;       /* Got at least one. */
-                       return -ENXIO;
+               dev = alloc_etherdev(0);
+               if (!dev)
+                       break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               dev->dma = dma[this_dev];
+               if (do_lance_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_lance[found++] = dev;
+                               continue;
+                       }
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               break;
        }
-
-       return 0;
+       if (found != 0)
+               return 0;
+       return -ENXIO;
 }
 
 void cleanup_module(void)
@@ -334,13 +351,11 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
-               struct net_device *dev = &dev_lance[this_dev];
-               if (dev->priv != NULL) {
+               struct net_device *dev = dev_lance[this_dev];
+               if (dev) {
                        unregister_netdev(dev); 
-                       free_dma(dev->dma);
-                       release_region(dev->base_addr, LANCE_TOTAL_SIZE);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
@@ -352,7 +367,7 @@ MODULE_LICENSE("GPL");
    board probes now that kmalloc() can allocate ISA DMA-able regions.
    This also allows the LANCE driver to be used as a module.
    */
-int __init lance_probe(struct net_device *dev)
+static int __init do_lance_probe(struct net_device *dev)
 {
        int *port, result;
 
@@ -387,6 +402,31 @@ int __init lance_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+struct net_device * __init lance_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(0);
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_lance_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
 {
        struct lance_private *lp;
@@ -398,6 +438,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        int hp_builtin = 0;                     /* HP on-board ethernet. */
        static int did_version;                 /* Already printed version info. */
        unsigned long flags;
+       int err = -ENOMEM;
 
        /* First we look for special cases.
           Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
@@ -432,7 +473,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        outw(88, ioaddr+LANCE_ADDR);
        if (inw(ioaddr+LANCE_ADDR) != 88) {
                lance_version = 0;
-       } else {                                                        /* Good, it's a newer chip. */
+       } else {                        /* Good, it's a newer chip. */
                int chip_version = inw(ioaddr+LANCE_DATA);
                outw(89, ioaddr+LANCE_ADDR);
                chip_version |= inw(ioaddr+LANCE_DATA) << 16;
@@ -447,13 +488,9 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                }
        }
 
-       /* We can't use init_etherdev() to allocate dev->priv because it must
+       /* We can't allocate dev->priv from alloc_etherdev() because it must
           a ISA DMA-able region. */
-       dev = init_etherdev(dev, 0);
-       if (!dev)
-               return -ENOMEM;
        SET_MODULE_OWNER(dev);
-       dev->open = lance_open_fail;
        chipname = chip_table[lance_version].name;
        printk("%s: %s at %#3x,", dev->name, chipname, ioaddr);
 
@@ -465,8 +502,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        dev->base_addr = ioaddr;
        /* Make certain the data structures used by the LANCE are aligned and DMAble. */
                
-       lp = (struct lance_private *)(((unsigned long)kmalloc(sizeof(*lp)+7,
-                                          GFP_DMA | GFP_KERNEL)+7) & ~7);
+       lp = kmalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL);
        if(lp==NULL)
                return -ENODEV;
        if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
@@ -486,7 +522,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                lp->tx_bounce_buffs = NULL;
 
        lp->chip_version = lance_version;
-       lp->devlock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&lp->devlock);
 
        lp->init_block.mode = 0x0003;           /* Disable Rx and Tx. */
        for (i = 0; i < 6; i++)
@@ -540,6 +576,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
                        (inb(DMA2_STAT_REG) & 0xf0);
        }
+       err = -ENODEV;
        if (dev->irq >= 2)
                printk(" assigned IRQ %d", dev->irq);
        else if (lance_version != 0)  { /* 7990 boards need DMA detection first. */
@@ -559,7 +596,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                        printk(", probed IRQ %d", dev->irq);
                else {
                        printk(", failed to detect IRQ line.\n");
-                       return -ENODEV;
+                       goto out_tx;
                }
 
                /* Check for the initialization done bit, 0x0100, which means
@@ -573,7 +610,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        } else if (dev->dma) {
                if (request_dma(dev->dma, chipname)) {
                        printk("DMA %d allocation failed.\n", dev->dma);
-                       return -ENODEV;
+                       goto out_tx;
                } else
                        printk(", assigned DMA %d.\n", dev->dma);
        } else {                        /* OK, we have to auto-DMA. */
@@ -613,7 +650,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                }
                if (i == 4) {                   /* Failure: bail. */
                        printk("DMA detection failed.\n");
-                       return -ENODEV;
+                       goto out_tx;
                }
        }
 
@@ -629,7 +666,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                dev->irq = probe_irq_off(irq_mask);
                if (dev->irq == 0) {
                        printk("  Failed to detect the 7990 IRQ line.\n");
-                       return -ENODEV;
+                       goto out_dma;
                }
                printk("  Auto-IRQ detected IRQ%d.\n", dev->irq);
        }
@@ -655,18 +692,18 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        dev->watchdog_timeo = TX_TIMEOUT;
 
        return 0;
-out_rx:        kfree((void*)lp->rx_buffs);
-out_lp:        kfree(lp);
-       return -ENOMEM;
-}
-
-static int
-lance_open_fail(struct net_device *dev)
-{
-       return -ENODEV;
+out_dma:
+       if (dev->dma != 4)
+               free_dma(dev->dma);
+out_tx:
+       kfree(lp->tx_bounce_buffs);
+out_rx:
+       kfree((void*)lp->rx_buffs);
+out_lp:
+       kfree(lp);
+       return err;
 }
 
-
 \f
 static int
 lance_open(struct net_device *dev)
index 6f8c223..b2cbf97 100644 (file)
@@ -1149,12 +1149,11 @@ static void print_eth(unsigned char *add, char *str)
 
 #define LAN_PROM_ADDR  0xF0810000
 
-static int __devinit i82596_probe(struct net_device *dev)
+static int __devinit i82596_probe(struct net_device *dev,
+                                 struct device *gen_dev)
 {
        int i;
        struct i596_private *lp;
-       /* we're going to overwrite dev->priv, so pull the device out */
-       struct device *gen_dev = dev->priv;
        char eth_addr[6];
        dma_addr_t dma_addr;
 
@@ -1204,7 +1203,6 @@ static int __devinit i82596_probe(struct net_device *dev)
                return -ENOMEM;
        }
 
-       ether_setup(dev);
        DEB(DEB_PROBE,printk("%s: 82596 at %#3lx,", dev->name, dev->base_addr));
 
        for (i = 0; i < 6; i++)
@@ -1537,12 +1535,19 @@ lan_init_chip(struct parisc_device *dev)
 
        netdevice->base_addr = dev->hpa;
        netdevice->irq = dev->irq;
-       netdevice->init = i82596_probe;
-       netdevice->priv = &dev->dev;
+
+       retval = i82596_probe(netdevice, &dev->dev);
+       if (retval) {
+               free_netdev(netdevice);
+               return -ENODEV;
+       }
 
        retval = register_netdev(netdevice);
        if (retval) {
+               struct i596_private *lp = netdevice->priv;
                printk(KERN_WARNING __FILE__ ": register_netdevice ret'd %d\n", retval);
+               dma_free_noncoherent(lp->dev, sizeof(struct i596_private), 
+                                   (void *)netdevice->mem_start, lp->dma_addr);
                free_netdev(netdevice);
                return -ENODEV;
        };
index 16e41a1..d6dfa79 100644 (file)
@@ -49,7 +49,6 @@ static const char *version =
 
 #include "8390.h"
 
-int lne390_probe(struct net_device *dev);
 static int lne390_probe1(struct net_device *dev, int ioaddr);
 
 static int lne390_open(struct net_device *dev);
@@ -103,9 +102,11 @@ static unsigned int shmem_mapB[] __initdata = {0xff, 0xfe, 0x0e, 0xfff, 0xffe, 0
  *     PROM for a match against the value assigned to Mylex.
  */
 
-int __init lne390_probe(struct net_device *dev)
+static int __init do_lne390_probe(struct net_device *dev)
 {
        unsigned short ioaddr = dev->base_addr;
+       int irq = dev->irq;
+       int mem_start = dev->mem_start;
        int ret;
 
        SET_MODULE_OWNER(dev);
@@ -135,11 +136,46 @@ int __init lne390_probe(struct net_device *dev)
                if (lne390_probe1(dev, ioaddr) == 0)
                        return 0;
                release_region(ioaddr, LNE390_IO_EXTENT);
+               dev->irq = irq;
+               dev->mem_start = mem_start;
        }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, LNE390_IO_EXTENT);
+       if (ei_status.reg0)
+               iounmap((void *)dev->mem_start);
+}
+
+struct net_device * __init lne390_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_lne390_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init lne390_probe1(struct net_device *dev, int ioaddr)
 {
        int i, revision, ret;
@@ -174,11 +210,6 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
                return -ENODEV;
        }
 #endif
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk ("lne390.c: unable to allocate memory for dev->priv!\n");
-               return -ENOMEM;
-       }
 
        printk("lne390.c: LNE390%X in EISA slot %d, address", 0xa+revision, ioaddr/0x1000);
        for(i = 0; i < ETHER_ADDR_LEN; i++)
@@ -199,8 +230,6 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
 
        if ((ret = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
                printk (" unable to get IRQ %d.\n", dev->irq);
-               kfree(dev->priv);
-               dev->priv = NULL;
                return ret;
        }
 
@@ -274,8 +303,6 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
        return 0;
 cleanup:
        free_irq(dev->irq, dev);
-       kfree(dev->priv);
-       dev->priv = NULL;
        return ret;
 }
 
@@ -373,7 +400,7 @@ static int lne390_close(struct net_device *dev)
 
 #ifdef MODULE
 #define MAX_LNE_CARDS  4       /* Max number of LNE390 cards per module */
-static struct net_device dev_lne[MAX_LNE_CARDS];
+static struct net_device *dev_lne[MAX_LNE_CARDS];
 static int io[MAX_LNE_CARDS];
 static int irq[MAX_LNE_CARDS];
 static int mem[MAX_LNE_CARDS];
@@ -389,26 +416,32 @@ MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_lne[this_dev];
+               if (io[this_dev] == 0 && this_dev != 0)
+                       break;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = mem[this_dev];
-               dev->init = lne390_probe;
-               /* Default is to only install one card. */
-               if (io[this_dev] == 0 && this_dev != 0) break;
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               if (do_lne390_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_lne[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void cleanup_module(void)
@@ -416,15 +449,11 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_lne[this_dev];
-               if (dev->priv != NULL) {
-                       void *priv = dev->priv;
-                       free_irq(dev->irq, dev);
-                       release_region(dev->base_addr, LNE390_IO_EXTENT);
-                       if (ei_status.reg0)
-                               iounmap((void *)dev->mem_start);
+               struct net_device *dev = dev_lne[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index 3e687d9..7dda5dd 100644 (file)
@@ -1314,18 +1314,23 @@ static int io = IOADDR;
 static int irq = IRQ;
 
 static int __init lp486e_init_module(void) {
-       struct net_device *dev;
-
-       dev = alloc_etherdev(sizeof(struct i596_private));
+       int err;
+       struct net_device *dev = alloc_etherdev(sizeof(struct i596_private));
        if (!dev)
                return -ENOMEM;
 
        dev->irq = irq;
        dev->base_addr = io;
-       dev->init = lp486e_probe;
-       if (register_netdev(dev) != 0) {
+       err = lp486e_probe(dev);
+       if (err) {
+               free_netdev(dev);
+               return err;
+       }
+       err = register_netdev(dev);
+       if (err) {
+               release_region(dev->base_addr, LP486E_TOTAL_SIZE);
                free_netdev(dev);
-               return -EIO;
+               return err;
        }
        dev_lp486e = dev;
        full_duplex = 0;
index 4b2b653..36bbd4f 100644 (file)
@@ -124,11 +124,10 @@ static int useresources[] = {
 static char version[] __initdata =
        "mac8390.c: v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n";
                
-extern int mac8390_probe(struct net_device * dev);
 extern enum mac8390_type mac8390_ident(struct nubus_dev * dev);
 extern int mac8390_memsize(unsigned long membase);
 extern int mac8390_memtest(struct net_device * dev);
-extern int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
+static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
                           enum mac8390_type type);
 
 static int mac8390_open(struct net_device * dev);
@@ -223,43 +222,43 @@ int __init mac8390_memsize(unsigned long membase)
        return i * 0x1000;
 }
 
-static int probed __initdata = 0;
-
-int __init mac8390_probe(struct net_device * dev)
+struct net_device * __init mac8390_probe(int unit)
 {
+       struct net_device *dev;
        volatile unsigned short *i;
-       int boards_found = 0;
        int version_disp = 0;
        struct nubus_dev * ndev = NULL;
+       int err = -ENODEV;
        
        struct nubus_dir dir;
        struct nubus_dirent ent;
        int offset;
+       static unsigned int slots;
 
        enum mac8390_type cardtype;
 
-       if (probed)
-               return -ENODEV;
-       probed++;
-
        /* probably should check for Nubus instead */
 
        if (!MACH_IS_MAC)
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
+
+       dev = alloc_ei_netdev();
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0)
+               sprintf(dev->name, "eth%d", unit);
+
+       SET_MODULE_OWNER(dev);
 
        while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) {
-               
-               dev = NULL;
-               
-               if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
+               /* Have we seen it already? */
+               if (slots & (1<<ndev->board->slot))
                        continue;
+               slots |= 1<<ndev->board->slot;
 
-               dev = init_etherdev(dev, 0);
-               if (dev == NULL) {
-                       printk(KERN_ERR "Unable to allocate etherdev"
-                                       "structure!\n");
-                       return -ENOMEM;
-               }
+               if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
+                       continue;
 
                if (version_disp == 0) {
                        version_disp = 1;
@@ -358,21 +357,25 @@ int __init mac8390_probe(struct net_device * dev)
                                        printk(KERN_ERR "Card type %s is"
                                                        " unsupported, sorry\n",
                                               cardname[cardtype]);
-                                       return -ENODEV;
+                                       continue;
                        }
                }
 
                /* Do the nasty 8390 stuff */
-               if (mac8390_initdev(dev, ndev, cardtype))
-                       continue;
-               boards_found++;
+               if (!mac8390_initdev(dev, ndev, cardtype))
+                       break;
        }
 
-       /* We're outta here */
-       if (boards_found > 0)
-               return 0;
-       else
-               return -ENODEV;
+       if (!ndev)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out;
+       return dev;
+
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 #ifdef MODULE
@@ -380,26 +383,39 @@ MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others");
 MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver");
 MODULE_LICENSE("GPL");
 
+/* overkill, of course */
+static struct net_device *dev_mac8390[15];
 int init_module(void)
 {
-       if (mac8390_probe(NULL)) {
+       int i;
+       for (i = 0; i < 15; i++) {
+               struct net_device *dev = mac8390_probe(-1);
+               if (IS_ERR(dev))
+                       break;
+               dev_mac890[i] = dev;
+       }
+       if (!i) {
                printk(KERN_NOTICE "mac8390.c: No useable cards found, driver NOT installed.\n");
                return -ENODEV;
        }
-       lock_8390_module();
        return 0;
 }
 
 void cleanup_module(void)
 {
-       /* FIXME: should probably keep track of net_device structs
-           somewhere and unregister them here? */
-       unlock_8390_module();
+       int i;
+       for (i = 0; i < 15; i++) {
+               struct net_device *dev = dev_mac890[i];
+               if (dev) {
+                       unregister_netdev(dev);
+                       free_netdev(dev);
+               }
+       }
 }
 
 #endif /* MODULE */
 
-int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
+static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
                            enum mac8390_type type)
 {
        static u32 fwrd4_offsets[16]={
@@ -423,12 +439,6 @@ int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
 
        int access_bitmode;
        
-       /* 8390 specific init for dev - allocates dev->priv */
-       if (ethdev_init(dev)) {
-               printk(KERN_ERR "%s: Unable to allocate memory for dev->priv!\n", dev->name);
-               return -ENOMEM;
-       }
-
        /* Now fill in our stuff */
        dev->open = &mac8390_open;
        dev->stop = &mac8390_close;
@@ -529,7 +539,6 @@ static int mac8390_open(struct net_device *dev)
                printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
                return -EAGAIN;
        }       
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -537,7 +546,6 @@ static int mac8390_close(struct net_device *dev)
 {
        free_irq(dev->irq, dev);
        ei_close(dev);
-       MOD_DEC_USE_COUNT;
        return 0;
 }
 
index 67e1489..98503c7 100644 (file)
@@ -123,7 +123,6 @@ struct net_local {
 
 /* Index to functions, as function prototypes. */
 
-extern int mac89x0_probe(struct net_device *dev);
 #if 0
 extern void reset_chip(struct net_device *dev);
 #endif
@@ -170,8 +169,9 @@ writereg(struct net_device *dev, int portno, int value)
 
 /* Probe for the CS8900 card in slot E.  We won't bother looking
    anywhere else until we have a really good reason to do so. */
-int __init mac89x0_probe(struct net_device *dev)
+struct net_device * __init mac89x0_probe(int unit)
 {
+       struct net_device *dev;
        static int once_is_enough;
        struct net_local *lp;
        static unsigned version_printed;
@@ -179,18 +179,28 @@ int __init mac89x0_probe(struct net_device *dev)
        unsigned rev_type = 0;
        unsigned long ioaddr;
        unsigned short sig;
+       int err = -ENODEV;
+
+       dev = alloc_etherdev(sizeof(struct net_local));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
 
        SET_MODULE_OWNER(dev);
 
        if (once_is_enough)
-               return -ENODEV;
+               goto out;
        once_is_enough = 1;
 
        /* We might have to parameterize this later */
        slot = 0xE;
        /* Get out now if there's a real NuBus card in slot E */
        if (nubus_find_slot(slot, NULL) != NULL)
-               return -ENODEV; 
+               goto out;
 
        /* The pseudo-ISA bits always live at offset 0x300 (gee,
            wonder why...) */
@@ -206,21 +216,15 @@ int __init mac89x0_probe(struct net_device *dev)
                local_irq_restore(flags);
 
                if (!card_present)
-                       return -ENODEV;
+                       goto out;
        }
 
        nubus_writew(0, ioaddr + ADD_PORT);
        sig = nubus_readw(ioaddr + DATA_PORT);
        if (sig != swab16(CHIP_EISA_ID_SIG))
-               return -ENODEV;
+               goto out;
 
        /* Initialize the net_device structure. */
-       if (dev->priv == NULL) {
-               dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-               if (!dev->priv)
-                       return -ENOMEM;
-                memset(dev->priv, 0, sizeof(struct net_local));
-        }
        lp = (struct net_local *)dev->priv;
 
        /* Fill in the 'dev' fields. */
@@ -258,9 +262,7 @@ int __init mac89x0_probe(struct net_device *dev)
        /* Try to read the MAC address */
        if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
                printk("\nmac89x0: No EEPROM, giving up now.\n");
-               kfree(dev->priv);
-               dev->priv = NULL;
-               return -ENODEV;
+               goto out1;
         } else {
                 for (i = 0; i < ETH_ALEN; i += 2) {
                        /* Big-endian (why??!) */
@@ -277,6 +279,7 @@ int __init mac89x0_probe(struct net_device *dev)
        for (i = 0; i < ETH_ALEN; i++)
                printk("%2.2x%s", dev->dev_addr[i],
                       ((i < ETH_ALEN-1) ? ":" : ""));
+       printk("\n");
 
        dev->open               = net_open;
        dev->stop               = net_close;
@@ -285,11 +288,15 @@ int __init mac89x0_probe(struct net_device *dev)
        dev->set_multicast_list = &set_multicast_list;
        dev->set_mac_address = &set_mac_address;
 
-       /* Fill in the fields of the net_device structure with ethernet values. */
-       ether_setup(dev);
-
-       printk("\n");
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
        return 0;
+out1:
+       nubus_writew(0, dev->base_addr + ADD_PORT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 #if 0
@@ -619,7 +626,7 @@ static int set_mac_address(struct net_device *dev, void *addr)
 
 #ifdef MODULE
 
-static struct net_device dev_cs89x0;
+static struct net_device *dev_cs89x0;
 static int debug;
 
 MODULE_PARM(debug, "i");
@@ -630,36 +637,20 @@ int
 init_module(void)
 {
        net_debug = debug;
-        dev_cs89x0.init = mac89x0_probe;
-        dev_cs89x0.priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (!dev_cs89x0.priv)
-               return -ENOMEM;
-       memset(dev_cs89x0.priv, 0, sizeof(struct net_local));
-
-        if (register_netdev(&dev_cs89x0) != 0) {
+        dev_cs89x0 = mac89x0_probe(-1);
+       if (IS_ERR(dev_cs89x0)) {
                 printk(KERN_WARNING "mac89x0.c: No card found\n");
-               kfree(dev_cs89x0.priv);
-                return -ENXIO;
-        }
+               return PTR_ERR(dev_cs89x0);
+       }
        return 0;
 }
 
 void
 cleanup_module(void)
 {
-
-#endif
-#ifdef MODULE
-       nubus_writew(0, dev_cs89x0.base_addr + ADD_PORT);
-#endif
-#ifdef MODULE
-
-        if (dev_cs89x0.priv != NULL) {
-                /* Free up the private structure, or leak memory :-)  */
-                unregister_netdev(&dev_cs89x0);
-                kfree(dev_cs89x0.priv);
-                dev_cs89x0.priv = NULL;        /* gets re-allocated by cs89x0_probe1 */
-        }
+       unregister_netdev(dev_cs89x0);
+       nubus_writew(0, dev_cs89x0->base_addr + ADD_PORT);
+       free_netdev(dev_cs89x0);
 }
 #endif /* MODULE */
 \f
index e06740d..79a6fc1 100644 (file)
@@ -180,7 +180,7 @@ static void mace_dma_off(struct net_device *dev)
  * model of Macintrash has a MACE (AV macintoshes)
  */
  
-int mace_probe(struct net_device *unused)
+struct net_device *mace_probe(int unit)
 {
        int j;
        struct mace_data *mp;
@@ -188,13 +188,19 @@ int mace_probe(struct net_device *unused)
        struct net_device *dev;
        unsigned char checksum = 0;
        static int found = 0;
+       int err;
        
-       if (found || macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
+       if (found || macintosh_config->ether_type != MAC_ETHER_MACE)
+               return ERR_PTR(-ENODEV);
 
        found = 1;      /* prevent 'finding' one on every device probe */
 
-       dev = init_etherdev(0, PRIV_BYTES);
-       if (!dev) return -ENOMEM;
+       dev = alloc_etherdev(PRIV_BYTES);
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0)
+               sprintf(dev->name, "eth%d", unit);
 
        mp = (struct mace_data *) dev->priv;
        dev->base_addr = (u32)MACE_BASE;
@@ -221,7 +227,10 @@ int mace_probe(struct net_device *unused)
                checksum ^= bitrev(addr[j<<4]);
        }
        
-       if (checksum != 0xFF) return -ENODEV;
+       if (checksum != 0xFF) {
+               free_netdev(dev);
+               return ERR_PTR(-ENODEV);
+       }
 
        memset(&mp->stats, 0, sizeof(mp->stats));
 
@@ -234,13 +243,16 @@ int mace_probe(struct net_device *unused)
        dev->set_multicast_list = mace_set_multicast;
        dev->set_mac_address    = mace_set_address;
 
-       ether_setup(dev);
-
        printk(KERN_INFO "%s: 68K MACE, hardware address %.2X", dev->name, dev->dev_addr[0]);
        for (j = 1 ; j < 6 ; j++) printk(":%.2X", dev->dev_addr[j]);
        printk("\n");
 
-       return 0;
+       err = register_netdev(dev);
+       if (!err)
+               return dev;
+
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /*
index c2d9070..73b1bbe 100644 (file)
@@ -74,7 +74,6 @@ static int sonic_version_printed;
 
 static int reg_offset;
 
-extern int macsonic_probe(struct net_device* dev);
 extern int mac_onboard_sonic_probe(struct net_device* dev);
 extern int mac_nubus_sonic_probe(struct net_device* dev);
 
@@ -110,14 +109,38 @@ enum macsonic_type {
 
 #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr)
 
-int __init macsonic_probe(struct net_device* dev)
+struct net_device * __init macsonic_probe(int unit)
 {
-       int rv;
+       struct net_device *dev = alloc_etherdev(0);
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0)
+               sprintf(dev->name, "eth%d", unit);
+
+       SET_MODULE_OWNER(dev);
 
        /* This will catch fatal stuff like -ENOMEM as well as success */
-       if ((rv = mac_onboard_sonic_probe(dev)) != -ENODEV)
-               return rv;
-       return mac_nubus_sonic_probe(dev);
+       err = mac_onboard_sonic_probe(dev);
+       if (err == 0)
+               goto found;
+       if (err != -ENODEV)
+               goto out;
+       err = mac_nubus_sonic_probe(dev);
+       if (err)
+               goto out;
+found:
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       kfree(dev->priv);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /*
@@ -195,6 +218,7 @@ int __init macsonic_init(struct net_device* dev)
        if ((lp->rba = (char *)
             kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
                printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
+               dev->priv = NULL;
                kfree(lp);
                return -ENOMEM;
        }
@@ -229,8 +253,6 @@ int __init macsonic_init(struct net_device* dev)
        sonic_write(dev, SONIC_FAET, 0xffff);
        sonic_write(dev, SONIC_MPT, 0xffff);
 
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
        return 0;
 }
 
@@ -344,30 +366,6 @@ int __init mac_onboard_sonic_probe(struct net_device* dev)
 
        printk("yes\n");        
 
-       if (dev) {
-               dev = init_etherdev(dev, sizeof(struct sonic_local));
-               if (!dev)
-                       return -ENOMEM;
-               /* methinks this will always be true but better safe than sorry */
-               if (dev->priv == NULL) {
-                       dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
-                       if (!dev->priv)
-                               return -ENOMEM;
-               }
-       } else {
-               dev = init_etherdev(NULL, sizeof(struct sonic_local));
-       }
-
-       if (dev == NULL)
-               return -ENOMEM;
-
-       if(dev->priv) {
-               printk("%s: warning! sonic entering with priv already allocated!\n",
-                      dev->name);
-               printk("%s: discarding, will attempt to reallocate\n", dev->name);
-               dev->priv = NULL;
-       }
-
        /* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
 
@@ -497,7 +495,6 @@ int __init mac_nubus_sonic_probe(struct net_device* dev)
 {
        static int slots;
        struct nubus_dev* ndev = NULL;
-       struct sonic_local* lp;
        unsigned long base_addr, prom_addr;
        u16 sonic_dcr;
        int id;
@@ -567,25 +564,6 @@ int __init mac_nubus_sonic_probe(struct net_device* dev)
                return -ENODEV;
        }
 
-       if (dev) {
-               dev = init_etherdev(dev, sizeof(struct sonic_local));
-               if (!dev)
-                       return -ENOMEM;
-               /* methinks this will always be true but better safe than sorry */
-               if (dev->priv == NULL) {
-                       dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
-                       if (!dev->priv) /* FIXME: kfree dev if necessary */
-                               return -ENOMEM;
-               }
-       } else {
-               dev = init_etherdev(NULL, sizeof(struct sonic_local));
-       }
-
-       if (dev == NULL)
-               return -ENOMEM;
-
-       lp = (struct sonic_local*) dev->priv;
-       memset(lp, 0, sizeof(struct sonic_local));
        /* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
        dev->base_addr = base_addr;
@@ -631,8 +609,7 @@ int __init mac_nubus_sonic_probe(struct net_device* dev)
 }
 
 #ifdef MODULE
-static char namespace[16] = "";
-static struct net_device dev_macsonic;
+static struct net_device *dev_macsonic;
 
 MODULE_PARM(sonic_debug, "i");
 MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
@@ -641,24 +618,20 @@ MODULE_LICENSE("GPL");
 int
 init_module(void)
 {
-        dev_macsonic.name = namespace;
-        dev_macsonic.init = macsonic_probe;
-
-        if (register_netdev(&dev_macsonic) != 0) {
+        dev_macsonic = macsonic_probe(-1);
+       if (IS_ERR(dev_macsonic)) {
                 printk(KERN_WARNING "macsonic.c: No card found\n");
-                return -ENXIO;
-        }
+               return PTR_ERR(dev_macsonic);
+       }
        return 0;
 }
 
 void
 cleanup_module(void)
 {
-        if (dev_macsonic.priv != NULL) {
-                unregister_netdev(&dev_macsonic);
-                kfree(dev_macsonic.priv);
-                dev_macsonic.priv = NULL;
-        }
+       unregister_netdev(dev_macsonic);
+       kfree(dev_macsonic->priv);
+       free_netdev(dev_macsonic);
 }
 #endif /* MODULE */
 
index 3a253f1..17524d2 100644 (file)
@@ -95,7 +95,6 @@ typedef struct meth_private {
     spinlock_t meth_lock;
 } meth_private;
 
-extern struct net_device meth_devs[];
 void meth_tx_timeout (struct net_device *dev);
 void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs);
         
@@ -762,17 +761,16 @@ struct net_device_stats *meth_stats(struct net_device *dev)
 
 /*
  * The init function (sometimes called probe).
- * It is invoked by register_netdev()
  */
-int meth_init(struct net_device *dev)
+static struct net_device *meth_init(struct net_device *dev)
 {
+       struct net_device *dev;
        meth_private *priv;
        int ret;
-       /* 
-        * Then, assign other fields in dev, using ether_setup() and some
-        * hand assignments
-        */
-       ether_setup(dev); /* assign some of the fields */
+
+       dev = alloc_etherdev(sizeof(struct meth_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
        dev->open            = meth_open;
        dev->stop            = meth_release;
@@ -787,16 +785,8 @@ int meth_init(struct net_device *dev)
        dev->irq                 = MACE_ETHERNET_IRQ;
        SET_MODULE_OWNER(dev);
 
-       /*
-        * Then, allocate the priv field. This encloses the statistics
-        * and a few private fields.
-        */
-       priv = kmalloc(sizeof(struct meth_private), GFP_KERNEL);
-       if (priv == NULL)
-               return -ENOMEM;
-       dev->priv=priv;
-       memset(priv, 0, sizeof(struct meth_private));
-       spin_lock_init(&((struct meth_private *) dev->priv)->meth_lock);
+       priv = dev->priv;
+       spin_lock_init(&priv->meth_lock);
        /*
         * Make the usual checks: check_region(), probe irq, ...  -ENODEV
         * should be returned if no device found.  No resource should be
@@ -807,28 +797,41 @@ int meth_init(struct net_device *dev)
        priv->phy_addr = -1; /* No phy is known yet... */
 
        /* Initialize the hardware */
-       if((ret=meth_reset(dev)) < 0)
-               return ret;
+       ret = meth_reset(dev);
+       if (ret < 0)
+               goto out;
 
        /* Allocate the ring buffers */
-       if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){
-               meth_free_tx_ring(priv);
-               meth_free_rx_ring(priv);
-               return ret;
-       }
+       ret = meth_init_tx_ring(priv);
+       if (ret < 0)
+               goto out;
+
+       ret = meth_init_rx_ring(priv);
+       if (ret < 0)
+               goto out1;
+
+       ret = register_netdev(dev);
+       if (ret)
+               goto out2;
 
        printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29);
 
-    return 0;
+       return ret;
+
+out2:
+       meth_free_rx_ring(priv);
+out1:
+       meth_free_tx_ring(priv);
+out:
+       free_netdev(dev);
+       return ERR_PTR(ret);
 }
 
 /*
  * The devices
  */
 
-struct net_device meth_devs[1] = {
-    { init: meth_init, }  /* init, nothing more */
-};
+struct net_device *meth_dev;
 
 /*
  * Finally, the module stuff
@@ -836,23 +839,19 @@ struct net_device meth_devs[1] = {
 
 int meth_init_module(void)
 {
-       int result, device_present = 0;
-
-       strcpy(meth_devs[0].name, "eth%d");
-
-       if ( (result = register_netdev(meth_devs)) )
-               printk("meth: error %i registering device \"%s\"\n",
-                      result, meth_devs->name);
-       else device_present++;
-       
-       return device_present ? 0 : -ENODEV;
+       meth_dev = meth_init();
+       if (IS_ERR(meth_dev))
+               return PTR_ERR(meth_dev);
+       return 0;
 }
 
 void meth_cleanup(void)
 {
-    kfree(meth_devs->priv);
-    unregister_netdev(meth_devs);
-    return;
+       meth_private *priv = meth_dev->priv;
+       unregister_netdev(meth_dev);
+       meth_free_rx_ring(priv);
+       meth_free_tx_ring(priv);
+       free_netdev(meth_dev);
 }
 
 module_init(meth_init_module);
index 00d3c94..5995658 100644 (file)
@@ -41,7 +41,7 @@
 struct m147lance_private {
        struct lance_private lance;
        void *base;
-       void *ram;
+       unsigned long ram;
 };
 
 /* function prototypes... This is easy because all the grot is in the
@@ -49,7 +49,6 @@ struct m147lance_private {
  * plus board-specific init, open and close actions.
  * Oh, and we need to tell the generic code how to read and write LANCE registers...
  */
-int mvme147lance_probe(struct net_device *dev);
 static int m147lance_open(struct net_device *dev);
 static int m147lance_close(struct net_device *dev);
 static void m147lance_writerap(struct m147lance_private *lp, unsigned short value);
@@ -60,29 +59,29 @@ typedef void (*writerap_t)(void *, unsigned short);
 typedef void (*writerdp_t)(void *, unsigned short);
 typedef unsigned short (*readrdp_t)(void *);
 
-#ifdef MODULE
-static struct m147lance_private *root_m147lance_dev;
-#endif
-
 /* Initialise the one and only on-board 7990 */
-int __init mvme147lance_probe(struct net_device *dev)
+struct net_device * __init mvme147lance_probe(int unit)
 {
+       struct net_device *dev;
        static int called;
        static const char name[] = "MVME147 LANCE";
        struct m147lance_private *lp;
        u_long *addr;
        u_long address;
+       int err;
 
        if (!MACH_IS_MVME147 || called)
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
        called++;
 
-       SET_MODULE_OWNER(dev);
+       dev = alloc_etherdev(sizeof(struct m147lance_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-       dev->priv = kmalloc(sizeof(struct m147lance_private), GFP_KERNEL);
-       if (dev->priv == NULL)
-               return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct m147lance_private));
+       if (unit >= 0)
+               sprintf(dev->name, "eth%d", unit);
+
+       SET_MODULE_OWNER(dev);
 
        /* Fill the dev fields */
        dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
@@ -114,11 +113,12 @@ int __init mvme147lance_probe(struct net_device *dev)
                dev->dev_addr[5]);
 
        lp = (struct m147lance_private *)dev->priv;
-       lp->ram = (void *)__get_dma_pages(GFP_ATOMIC, 3);       /* 16K */
+       lp->ram = __get_dma_pages(GFP_ATOMIC, 3);       /* 16K */
        if (!lp->ram)
        {
                printk("%s: No memory for LANCE buffers\n", dev->name);
-               return -ENODEV;
+               free_netdev(dev);
+               return ERR_PTR(-ENOMEM);
        }
 
        lp->lance.name = (char*)name;                   /* discards const, shut up gcc */
@@ -134,15 +134,15 @@ int __init mvme147lance_probe(struct net_device *dev)
        lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
        lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
        lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
-       ether_setup(dev);
 
-#ifdef MODULE
-       dev->ifindex = dev_new_index();
-       lp->next_module = root_m147lance_dev;
-       root_m147lance_dev = lp;
-#endif /* MODULE */
+       err = register_netdev(dev);
+       if (err) {
+               free_pages(lp->ram, 3);
+               free_netdev(dev);
+               return ERR_PTR(err);
+       }
 
-       return 0;
+       return dev;
 }
 
 static void m147lance_writerap(struct m147lance_private *lp, unsigned short value)
@@ -185,23 +185,21 @@ static int m147lance_close(struct net_device *dev)
 #ifdef MODULE
 MODULE_LICENSE("GPL");
 
+static struct net_device *dev_mvme147_lance;
 int init_module(void)
 {
-       root_lance_dev = NULL;
-       return mvme147lance_probe(NULL);
+       dev_mvme147_lance = mvme147lance_probe(-1);
+       if (IS_ERR(dev_mvme147_lance))
+               return PTR_ERR(dev_mvme147_lance);
+       return 0;
 }
 
 void cleanup_module(void)
 {
-       /* Walk the chain of devices, unregistering them */
-       struct m147lance_private *lp;
-       while (root_m147lance_dev) {
-               lp = root_m147lance_dev->next_module;
-               unregister_netdev(root_lance_dev->dev);
-               free_pages(lp->ram, 3);
-               free_netdev(root_lance_dev->dev);
-               root_lance_dev = lp;
-       }
+       struct m147lance_private *lp = dev_mvme147_lance->priv;
+       unregister_netdev(dev_mvme147_lance);
+       free_pages(lp->ram, 3);
+       free_netdev(dev_mvme147_lance);
 }
 
 #endif /* MODULE */
index db5ed07..e9edd56 100644 (file)
@@ -126,7 +126,6 @@ bad_clone_list[] __initdata = {
 #define NESM_START_PG  0x40    /* First page of TX buffer */
 #define NESM_STOP_PG   0x80    /* Last page +1 of RX ring */
 
-int ne_probe(struct net_device *dev);
 static int ne_probe1(struct net_device *dev, int ioaddr);
 static int ne_probe_isapnp(struct net_device *dev);
 
@@ -163,9 +162,10 @@ static void ne_block_output(struct net_device *dev, const int count,
        E2010    starts at 0x100 and ends at 0x4000.
        E2010-x starts at 0x100 and ends at 0xffff.  */
 
-int __init ne_probe(struct net_device *dev)
+static int __init do_ne_probe(struct net_device *dev)
 {
        unsigned int base_addr = dev->base_addr;
+       int irq = dev->irq;
 
        SET_MODULE_OWNER(dev);
 
@@ -183,6 +183,7 @@ int __init ne_probe(struct net_device *dev)
        /* Last resort. The semi-risky ISA auto-probe. */
        for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) {
                int ioaddr = netcard_portlist[base_addr];
+               dev->irq = irq;
                if (ne_probe1(dev, ioaddr) == 0)
                        return 0;
        }
@@ -191,6 +192,40 @@ int __init ne_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+       if (idev)
+               pnp_device_detach(idev);
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, NE_IO_EXTENT);
+}
+
+struct net_device * __init ne_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_ne_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init ne_probe_isapnp(struct net_device *dev)
 {
        int i;
@@ -425,20 +460,12 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                goto err_out;
        }
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev))
-       {
-               printk (" unable to get memory for dev->priv.\n");
-               ret = -ENOMEM;
-               goto err_out;
-       }
-
        /* Snarf the interrupt now.  There's no point in waiting since we cannot
           share and the board will usually be enabled. */
        ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
        if (ret) {
                printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
-               goto err_out_kfree;
+               goto err_out;
        }
 
        dev->base_addr = ioaddr;
@@ -472,9 +499,6 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        NS8390_init(dev, 0);
        return 0;
 
-err_out_kfree:
-       kfree(dev->priv);
-       dev->priv = NULL;
 err_out:
        release_region(ioaddr, NE_IO_EXTENT);
        return ret;
@@ -734,7 +758,7 @@ retry:
 \f
 #ifdef MODULE
 #define MAX_NE_CARDS   4       /* Max number of NE cards per module */
-static struct net_device dev_ne[MAX_NE_CARDS];
+static struct net_device *dev_ne[MAX_NE_CARDS];
 static int io[MAX_NE_CARDS];
 static int irq[MAX_NE_CARDS];
 static int bad[MAX_NE_CARDS];  /* 0xbad = bad sig or no reset ack */
@@ -758,25 +782,31 @@ int init_module(void)
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ne[this_dev];
+               struct net_device *dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
                dev->irq = irq[this_dev];
                dev->mem_end = bad[this_dev];
                dev->base_addr = io[this_dev];
-               dev->init = ne_probe;
-               if (register_netdev(dev) == 0) {
-                       found++;
-                       continue;
-               }
-               if (found != 0) {       /* Got at least one. */
-                       return 0;
+               if (do_ne_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_ne[found++] = dev;
+                               continue;
+                       }
+                       cleanup_card(dev);
                }
+               free_netdev(dev);
+               if (found)
+                       break;
                if (io[this_dev] != 0)
                        printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
                else
                        printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
                return -ENXIO;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENODEV;
 }
 
 void cleanup_module(void)
@@ -784,16 +814,11 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ne[this_dev];
-               if (dev->priv != NULL) {
-                       void *priv = dev->priv;
-                       struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
-                       if (idev)
-                               pnp_device_detach(idev);
-                       free_irq(dev->irq, dev);
-                       release_region(dev->base_addr, NE_IO_EXTENT);
+               struct net_device *dev = dev_ne[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index adb09ff..549741a 100644 (file)
@@ -242,7 +242,7 @@ static unsigned int __init dlink_get_eeprom(unsigned int eeaddr, unsigned int ad
  * Note that at boot, this probe only picks up one card at a time.
  */
 
-int __init ne2_probe(struct net_device *dev)
+static int __init do_ne2_probe(struct net_device *dev)
 {
        static int current_mca_slot = -1;
        int i;
@@ -262,16 +262,52 @@ int __init ne2_probe(struct net_device *dev)
                        mca_find_unused_adapter(ne2_adapters[i].id, 0);
 
                if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) {
+                       int res;
                        mca_set_adapter_name(current_mca_slot, 
                                        ne2_adapters[i].name);
                        mca_mark_as_used(current_mca_slot);
                        
-                       return ne2_probe1(dev, current_mca_slot);
+                       res = ne2_probe1(dev, current_mca_slot);
+                       if (res)
+                               mca_mark_as_unused(current_mca_slot);
+                       return res;
                }
        }
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       mca_mark_as_unused(ei_status.priv);
+       mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, NE_IO_EXTENT);
+}
+
+struct net_device * __init ne2_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_ne2_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
 
 static int ne2_procinfo(char *buf, int slot, struct net_device *dev)
 {
@@ -443,14 +479,6 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
 
        dev->base_addr = base_addr;
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (" unable to get memory for dev->priv.\n");
-               free_irq(dev->irq, dev);
-               retval = -ENOMEM;
-               goto out;
-       }
-
        for(i = 0; i < ETHER_ADDR_LEN; i++) {
                printk(" %2.2x", SA_prom[i]);
                dev->dev_addr[i] = SA_prom[i];
@@ -735,7 +763,7 @@ retry:
 
 #ifdef MODULE
 #define MAX_NE_CARDS   4       /* Max number of NE cards per module */
-static struct net_device dev_ne[MAX_NE_CARDS];
+static struct net_device *dev_ne[MAX_NE_CARDS];
 static int io[MAX_NE_CARDS];
 static int irq[MAX_NE_CARDS];
 static int bad[MAX_NE_CARDS];  /* 0xbad = bad sig or no reset ack */
@@ -754,23 +782,30 @@ MODULE_PARM_DESC(bad, "(ignored)");
 
 int init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ne[this_dev];
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
                dev->irq = irq[this_dev];
                dev->mem_end = bad[this_dev];
                dev->base_addr = io[this_dev];
-               dev->init = ne2_probe;
-               if (register_netdev(dev) != 0) {
-                       if (found != 0) return 0;   /* Got at least one. */
-
-                       printk(KERN_WARNING "ne2.c: No NE/2 card found.\n");
-                       return -ENXIO;
+               if (do_ne2_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_ne[found++] = dev;
+                               continue;
+                       }
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       printk(KERN_WARNING "ne2.c: No NE/2 card found\n");
+       return -ENXIO;
 }
 
 void cleanup_module(void)
@@ -778,14 +813,11 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ne[this_dev];
-               if (dev->priv != NULL) {
-                       mca_mark_as_unused(ei_status.priv);
-                       mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
-                       kfree(dev->priv);
-                       free_irq(dev->irq, dev);
-                       release_region(dev->base_addr, NE_IO_EXTENT);
+               struct net_device *dev = dev_ne[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index 67947a6..d0f3ca5 100644 (file)
@@ -78,7 +78,6 @@ bad_clone_list[] __initdata = {
 
 #include "ne2k_cbus.h"
 
-int ne_probe(struct net_device *dev);
 static int ne_probe1(struct net_device *dev, int ioaddr);
 static int ne_open(struct net_device *dev);
 static int ne_close(struct net_device *dev);
@@ -113,9 +112,10 @@ static void ne_block_output(struct net_device *dev, const int count,
        E2010    starts at 0x100 and ends at 0x4000.
        E2010-x starts at 0x100 and ends at 0xffff.  */
 
-int __init ne_probe(struct net_device *dev)
+static int __init do_ne_probe(struct net_device *dev)
 {
        unsigned int base_addr = dev->base_addr;
+       int irq = dev->irq;
 
        SET_MODULE_OWNER(dev);
 
@@ -135,7 +135,7 @@ int __init ne_probe(struct net_device *dev)
                if (ei_debug > 2)
                        printk(KERN_DEBUG "ne_probe(): call ne_probe_cbus(base_addr=0x%x)\n", base_addr);
 
-               result = ne_probe_cbus(dev, hw, base_addr);
+               result = ne_probe_cbus(dev, hw, base_addr, irq);
                if (result != 0)
                        ne2k_cbus_destroy(dev);
 
@@ -156,13 +156,13 @@ int __init ne_probe(struct net_device *dev)
                if (hw && hw->hwtype) {
                        const unsigned short *plist;
                        for (plist = hw->portlist; *plist; plist++)
-                               if (ne_probe_cbus(dev, hw, *plist) == 0)
+                               if (ne_probe_cbus(dev, hw, *plist, irq) == 0)
                                        return 0;
                } else {
                        for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
                                const unsigned short *plist;
                                for (plist = hw->portlist; *plist; plist++)
-                                       if (ne_probe_cbus(dev, hw, *plist) == 0)
+                                       if (ne_probe_cbus(dev, hw, *plist, irq) == 0)
                                                return 0;
                        }
                }
@@ -174,7 +174,45 @@ int __init ne_probe(struct net_device *dev)
        return -ENODEV;
 }
 
-static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr)
+static void cleanup_card(struct net_device *dev)
+{
+       const struct ne2k_cbus_region *rlist;
+       const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
+
+       free_irq(dev->irq, dev);
+       for (rlist = hw->regionlist; rlist->range; rlist++) {
+               release_region(dev->base_addr + rlist->start,
+                               rlist->range);
+       }
+       ne2k_cbus_destroy(dev);
+}
+
+struct net_device * __init ne_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_ne_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
+static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr, int irq)
 {
        if (ei_debug > 2)
                printk(KERN_DEBUG "ne_probe_cbus(): entered. (called from %p)\n",
@@ -182,6 +220,7 @@ static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_h
 
        if (hw && hw->hwtype) {
                ne2k_cbus_set_hwtype(dev, hw, ioaddr);
+               dev->irq = irq;
                return ne_probe1(dev, ioaddr);
        } else {
                /* auto detect */
@@ -189,6 +228,7 @@ static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_h
                printk(KERN_DEBUG "ne_probe_cbus(): try to determine hardware types.\n");
                for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
                        ne2k_cbus_set_hwtype(dev, hw, ioaddr);
+                       dev->irq = irq;
                        if (ne_probe1(dev, ioaddr) == 0)
                                return 0;
                }
@@ -301,11 +341,12 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                if (ei_debug > 2)
                        printk(" [CNET98EL-specific initialize...");
                outb_p(E8390_NODMA | E8390_STOP, ioaddr + E8390_CMD); /* 0x20|0x1 */
+               ret = -ENODEV;
                i = inb(ioaddr);
                if ((i & ~0x2) != (0x20 | 0x01))
-                       return -ENODEV;
+                       goto err_out;
                if ((inb(ioaddr + 0x7) & 0x80) != 0x80)
-                       return -ENODEV;
+                       goto err_out;
                outb_p(E8390_RXOFF, ioaddr + EN0_RXCR); /* out(ioaddr+0xc, 0x20) */
                /* outb_p(ENDCFG_WTS|ENDCFG_FT1|ENDCFG_LS, ioaddr+EN0_DCFG); */
                outb_p(ENDCFG_WTS | 0x48, ioaddr + EN0_DCFG); /* 0x49 */
@@ -330,7 +371,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                        if (ei_debug > 2)
                                printk("] ");
                        printk("memory failure at %x\n", i);
-                       return -ENODEV;
+                       goto err_out;
                }
                if (ei_debug > 2)
                        printk(" good...");
@@ -338,7 +379,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                        if (ei_debug > 2)
                                printk("] ");
                        printk("IRQ must be specified for C-NET(98)E/L. probe failed.\n");
-                       return -ENODEV;
+                       goto err_out;
                }
                outb((dev->irq > 5) ? (dev->irq & 4):(dev->irq >> 1), ioaddr + (0x2 | 0x400));
                outb(0x7e, ioaddr + (0x4 | 0x400));
@@ -457,14 +498,6 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                goto err_out;
        }
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev))
-       {
-               printk (" unable to get memory for dev->priv.\n");
-               ret = -ENOMEM;
-               goto err_out;
-       }
-
        /* Snarf the interrupt now.  There's no point in waiting since we cannot
           share and the board will usually be enabled. */
        ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
@@ -779,7 +812,7 @@ retry:
 \f
 #ifdef MODULE
 #define MAX_NE_CARDS   4       /* Max number of NE cards per module */
-static struct net_device dev_ne[MAX_NE_CARDS];
+static struct net_device *dev_ne[MAX_NE_CARDS];
 static int io[MAX_NE_CARDS];
 static int irq[MAX_NE_CARDS];
 static int bad[MAX_NE_CARDS];  /* 0xbad = bad sig or no reset ack */
@@ -806,26 +839,32 @@ int init_module(void)
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ne[this_dev];
+               struct net_device *dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
                dev->irq = irq[this_dev];
                dev->mem_end = bad[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = hwtype[this_dev];
-               dev->init = ne_probe;
-               if (register_netdev(dev) == 0) {
-                       found++;
-                       continue;
-               }
-               if (found != 0) {       /* Got at least one. */
-                       return 0;
+               if (do_ne_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_ne[found++] = dev;
+                               continue;
+                       }
+                       cleanup_card(dev);
                }
+               free_netdev(dev);
+               if (found)
+                       break;
                if (io[this_dev] != 0)
                        printk(KERN_WARNING "ne2k_cbus: No NE*000 card found at i/o = %#x\n", io[this_dev]);
                else
-                       printk(KERN_NOTICE "ne2k_cbus: You must supply \"io=0xNNN\" value(s) for C-Bus cards.\n");
+                       printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
                return -ENXIO;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENODEV;
 }
 
 void cleanup_module(void)
@@ -833,18 +872,11 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ne[this_dev];
-               if (dev->priv != NULL) {
-                       const struct ne2k_cbus_region *rlist;
-                       const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
-
-                       free_irq(dev->irq, dev);
-                       for (rlist = hw->regionlist; rlist->range; rlist++) {
-                               release_region(dev->base_addr + rlist->start,
-                                               rlist->range);
-                       }
+               struct net_device *dev = dev_ne[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       ne2k_cbus_destroy(dev);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index e561ef7..adf2cbc 100644 (file)
@@ -477,5 +477,5 @@ static void __init ne2k_cbus_writemem(struct net_device *dev, int ioaddr, unsign
 }
 #endif
 
-static int ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr);
+static int ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr, int irq);
 /* End of ne2k_cbus.h */
index 52f67cb..5d3aea7 100644 (file)
@@ -111,12 +111,6 @@ static int __init ne3210_eisa_probe (struct device *device)
        device->driver_data = dev;
        ioaddr = edev->base_addr;
 
-       if (ethdev_init (dev)) {
-               printk ("ne3210.c: unable to allocate memory for dev->priv!\n");
-               retval = -ENOMEM;
-               goto out;
-       }
-
        if (!request_region(ioaddr, NE3210_IO_EXTENT, dev->name)) {
                retval = -EBUSY;
                goto out;
@@ -357,24 +351,6 @@ static struct eisa_driver ne3210_eisa_driver = {
        },
 };
 
-#ifdef MODULE
-#if 0
-#define MAX_NE3210_CARDS       4       /* Max number of NE3210 cards per module */
-static struct net_device dev_ne3210[MAX_NE3210_CARDS];
-static int io[MAX_NE3210_CARDS];
-static int irq[MAX_NE3210_CARDS];
-static int mem[MAX_NE3210_CARDS];
-
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s)");
-MODULE_PARM_DESC(mem, "memory base address(es)");
-#endif
-#endif /* MODULE */
-
-
 MODULE_DESCRIPTION("NE3210 EISA Ethernet driver");
 MODULE_LICENSE("GPL");
 
index a61eac6..72bb389 100644 (file)
 struct net_device *alloc_netdev(int sizeof_priv, const char *mask,
                                       void (*setup)(struct net_device *))
 {
+       void *p;
        struct net_device *dev;
        int alloc_size;
 
-       /* ensure 32-byte alignment of the private area */
-       alloc_size = sizeof (*dev) + sizeof_priv + 31;
+       /* ensure 32-byte alignment of both the device and private area */
 
-       dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
-       if (dev == NULL)
-       {
-               printk(KERN_ERR "alloc_dev: Unable to allocate device memory.\n");
+       alloc_size = (sizeof(struct net_device) + 31) & ~31;
+       alloc_size += sizeof_priv + 31;
+
+       p = kmalloc (alloc_size, GFP_KERNEL);
+       if (!p) {
+               printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
                return NULL;
        }
 
-       memset(dev, 0, alloc_size);
+       memset(p, 0, alloc_size);
+
+       dev = (struct net_device *)(((long)p + 31) & ~31);
+       dev->padded = (char *)dev - (char *)p;
 
        if (sizeof_priv)
-               dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
+               dev->priv = netdev_priv(dev);
 
        setup(dev);
        strcpy(dev->name, mask);
index 19dedf1..509f90e 100644 (file)
@@ -82,7 +82,7 @@ static unsigned int bufsize_rcv;
 
 #ifndef FULL_IODETECT
 /* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int ni5010_portlist[] __initdata =
+static unsigned int ports[] __initdata =
        { 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
 #endif
 
@@ -95,13 +95,11 @@ static unsigned int ni5010_portlist[] __initdata =
 struct ni5010_local {
        struct net_device_stats stats;
        int o_pkt_size;
-       int i_pkt_size;
        spinlock_t lock;
 };
 
 /* Index to functions, as function prototypes. */
 
-extern int     ni5010_probe(struct net_device *dev);
 static int     ni5010_probe1(struct net_device *dev, int ioaddr);
 static int     ni5010_open(struct net_device *dev);
 static int     ni5010_send_packet(struct sk_buff *skb, struct net_device *dev);
@@ -120,38 +118,58 @@ static void       chipset_init(struct net_device *dev, int startp);
 static void    dump_packet(void *buf, int len);
 static void    ni5010_show_registers(struct net_device *dev);
 
+static int io;
+static int irq;
 
-int __init ni5010_probe(struct net_device *dev)
+struct net_device * __init ni5010_probe(int unit)
 {
+       struct net_device *dev = alloc_etherdev(sizeof(struct ni5010_local));
        int *port;
-       int base_addr = dev->base_addr;
+       int err = 0;
 
-        PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-       SET_MODULE_OWNER(dev);
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+       }
 
-       if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return ni5010_probe1(dev, base_addr);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
+       PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name));
 
+       SET_MODULE_OWNER(dev);
+
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = ni5010_probe1(dev, io);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
 #ifdef FULL_IODETECT
-               for (int ioaddr=0x200; ioaddr<0x400; ioaddr+=0x20) {
-                       if (check_region(ioaddr, NI5010_IO_EXTENT))
-                               continue;
-                       if (ni5010_probe1(dev, ioaddr) == 0)
-                               return 0;
-               }
+               for (io=0x200; io<0x400 && ni5010_probe1(dev, io) ; io+=0x20)
+                       ;
+               if (io == 0x400)
+                       err = -ENODEV;
+
 #else
-               for (port = ni5010_portlist; *port; port++) {
-                       int ioaddr = *port;
-                       if (check_region(ioaddr, NI5010_IO_EXTENT))
-                               continue;
-                       if (ni5010_probe1(dev, ioaddr) == 0)
-                               return 0;
-               }
+               for (port = ports; *port && ni5010_probe1(dev, *port); port++)
+                       ;
+               if (!*port)
+                       err = -ENODEV;
 #endif /* FULL_IODETECT */
-       return -ENODEV;
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, NI5010_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static inline int rd_port(int ioaddr)
@@ -188,9 +206,17 @@ static void __init trigger_irq(int ioaddr)
 static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
 {
        static unsigned version_printed;
+       struct ni5010_local *lp;
        int i;
        unsigned int data = 0;
        int boguscount = 40;
+       int err = -ENODEV;
+
+       dev->base_addr = ioaddr;
+       dev->irq = irq;
+
+       if (!request_region(ioaddr, NI5010_IO_EXTENT, boardname))
+               return -EBUSY;
 
        /*
         * This is no "official" probe method, I've rather tested which
@@ -205,36 +231,40 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
         *
         *   - Andreas
         */
-       
+
        PRINTK2((KERN_DEBUG "%s: entering ni5010_probe1(%#3x)\n", 
                dev->name, ioaddr));
 
-       if (inb(ioaddr+0) == 0xff) return -ENODEV;
+       if (inb(ioaddr+0) == 0xff)
+               goto out;
 
        while ( (rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr) &
                 rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr)) != 0xff)
        {
-               if (boguscount-- == 0) return -ENODEV;
+               if (boguscount-- == 0)
+                       goto out;
        }
 
        PRINTK2((KERN_DEBUG "%s: I/O #1 passed!\n", dev->name));
 
        for (i=0; i<32; i++)
                if ( (data = rd_port(ioaddr)) != 0xff) break;
-       if (data==0xff) return -ENODEV;
+       if (data==0xff)
+               goto out;
 
        PRINTK2((KERN_DEBUG "%s: I/O #2 passed!\n", dev->name));
 
-       if (            (data == SA_ADDR0) &&
-            (rd_port(ioaddr) == SA_ADDR1) &&
-            (rd_port(ioaddr) == SA_ADDR2) ) {
-               for (i=0; i<4; i++) rd_port(ioaddr);
-               if ( (rd_port(ioaddr) != NI5010_MAGICVAL1) ||
-                    (rd_port(ioaddr) != NI5010_MAGICVAL2) ) {
-                       return -ENODEV;
-               }
-       } else return -ENODEV;
-       
+       if ((data != SA_ADDR0) || (rd_port(ioaddr) != SA_ADDR1) ||
+           (rd_port(ioaddr) != SA_ADDR2))
+               goto out;
+
+       for (i=0; i<4; i++)
+               rd_port(ioaddr);
+
+       if ( (rd_port(ioaddr) != NI5010_MAGICVAL1) ||
+            (rd_port(ioaddr) != NI5010_MAGICVAL2) )
+               goto out;
+
        PRINTK2((KERN_DEBUG "%s: I/O #3 passed!\n", dev->name));
 
        if (NI5010_DEBUG && version_printed++ == 0)
@@ -267,8 +297,9 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
                PRINTK2((KERN_DEBUG "%s: I/O #6 passed!\n", dev->name));
 
                if (dev->irq == 0) {
+                       err = -EAGAIN;
                        printk(KERN_WARNING "%s: no IRQ found!\n", dev->name);
-                       return -EAGAIN;
+                       goto out;
                }
                PRINTK2((KERN_DEBUG "%s: I/O #7 passed!\n", dev->name));
        } else if (dev->irq == 2) {
@@ -278,19 +309,9 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
        PRINTK2((KERN_DEBUG "%s: I/O #9 passed!\n", dev->name));
 
        /* DMA is not supported (yet?), so no use detecting it */
+       lp = (struct ni5010_local*)dev->priv;
 
-       if (dev->priv == NULL) {
-               struct ni5010_local* lp;
-
-               dev->priv = kmalloc(sizeof(struct ni5010_local), GFP_KERNEL|GFP_DMA);
-               if (dev->priv == NULL) {
-                       printk(KERN_WARNING "%s: Failed to allocate private memory\n", dev->name);
-                       return -ENOMEM;
-               }
-
-               lp = (struct ni5010_local*)dev->priv;
-               spin_lock_init(&lp->lock);
-       }
+       spin_lock_init(&lp->lock);
 
        PRINTK2((KERN_DEBUG "%s: I/O #10 passed!\n", dev->name));
 
@@ -315,9 +336,6 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
        }
         printk("// bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
        memset(dev->priv, 0, sizeof(struct ni5010_local));
-
-       /* Grab the region so we can find another board if autoIRQ fails. */
-       request_region(ioaddr, NI5010_IO_EXTENT, boardname);
        
        dev->open               = ni5010_open;
        dev->stop               = ni5010_close;
@@ -327,9 +345,6 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
        dev->tx_timeout         = ni5010_timeout;
        dev->watchdog_timeo     = HZ/20;
 
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-       
        dev->flags &= ~IFF_MULTICAST;   /* Multicast doesn't work */
 
        /* Shut up the ni5010 */
@@ -345,6 +360,9 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
        printk(KERN_INFO "Join the NI5010 driver development team!\n");
        printk(KERN_INFO "Mail to a.mohr@mailto.de or jvbest@wi.leidenuniv.nl\n");
        return 0;
+out:
+       release_region(dev->base_addr, NI5010_IO_EXTENT);
+       return err;
 }
 
 /* 
@@ -513,6 +531,7 @@ static void ni5010_rx(struct net_device *dev)
        int ioaddr = dev->base_addr;
        unsigned char rcv_stat;
        struct sk_buff *skb;
+       int i_pkt_size;
        
        PRINTK2((KERN_DEBUG "%s: entering ni5010_rx()\n", dev->name)); 
        
@@ -532,17 +551,17 @@ static void ni5010_rx(struct net_device *dev)
        
         outb(0xff, EDLC_RCLR);  /* Clear the interrupt */
 
-       lp->i_pkt_size = inw(IE_RCNT);
-       if (lp->i_pkt_size > ETH_FRAME_LEN || lp->i_pkt_size < 10 ) {
+       i_pkt_size = inw(IE_RCNT);
+       if (i_pkt_size > ETH_FRAME_LEN || i_pkt_size < 10 ) {
                PRINTK((KERN_DEBUG "%s: Packet size error, packet size = %#4.4x\n", 
-                       dev->name, lp->i_pkt_size));
+                       dev->name, i_pkt_size));
                lp->stats.rx_errors++;
                lp->stats.rx_length_errors++;
                return;
        }
 
        /* Malloc up new buffer. */
-       skb = dev_alloc_skb(lp->i_pkt_size + 3);
+       skb = dev_alloc_skb(i_pkt_size + 3);
        if (skb == NULL) {
                printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
                lp->stats.rx_dropped++;
@@ -555,7 +574,7 @@ static void ni5010_rx(struct net_device *dev)
        /* Read packet into buffer */
         outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
        outw(0, IE_GP); /* Seek to beginning of packet */
-       insb(IE_RBUF, skb_put(skb, lp->i_pkt_size), lp->i_pkt_size); 
+       insb(IE_RBUF, skb_put(skb, i_pkt_size), i_pkt_size); 
        
        if (NI5010_DEBUG >= 4) 
                dump_packet(skb->data, skb->len); 
@@ -564,10 +583,10 @@ static void ni5010_rx(struct net_device *dev)
        netif_rx(skb);
        dev->last_rx = jiffies;
        lp->stats.rx_packets++;
-       lp->stats.rx_bytes += lp->i_pkt_size;
+       lp->stats.rx_bytes += i_pkt_size;
 
        PRINTK2((KERN_DEBUG "%s: Received packet, size=%#4.4x\n", 
-               dev->name, lp->i_pkt_size));
+               dev->name, i_pkt_size));
        
 }
 
@@ -697,10 +716,10 @@ static void hardware_send_packet(struct net_device *dev, char *buf, int length,
        
        if (NI5010_DEBUG > 3) dump_packet(buf, length);
 
-        buf_offs = NI5010_BUFSIZE - length - pad;
-        lp->o_pkt_size = length + pad;
+       buf_offs = NI5010_BUFSIZE - length - pad;
 
        spin_lock_irqsave(&lp->lock, flags);
+       lp->o_pkt_size = length + pad;
 
        outb(0, EDLC_RMASK);    /* Mask all receive interrupts */
        outb(0, IE_MMODE);      /* Put Xmit buffer on system bus */
@@ -745,9 +764,7 @@ static void ni5010_show_registers(struct net_device *dev)
 }
 
 #ifdef MODULE
-static struct net_device dev_ni5010;
-static int io;
-static int irq;
+static struct net_device *dev_ni5010;
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -756,8 +773,6 @@ MODULE_PARM_DESC(irq, "ni5010 IRQ number");
 
 int init_module(void)
 {
-       int result;
-       
        PRINTK2((KERN_DEBUG "%s: entering init_module\n", boardname));
        /*
        if(io <= 0 || irq == 0){
@@ -771,29 +786,18 @@ int init_module(void)
        }
 
        PRINTK2((KERN_DEBUG "%s: init_module irq=%#2x, io=%#3x\n", boardname, irq, io));
-        dev_ni5010.irq=irq;
-        dev_ni5010.base_addr=io;
-       dev_ni5010.init=ni5010_probe;
-        if ((result = register_netdev(&dev_ni5010)) != 0) {
-               PRINTK((KERN_WARNING "%s: register_netdev returned %d.\n", 
-                       boardname, result));
-                return -EIO;
-        }
+       dev_ni5010 = ni5010_probe(-1);
+       if (IS_ERR(dev_ni5010))
+               return PTR_ERR(dev_ni5010);
         return 0;
 }
 
-void
-cleanup_module(void)
+void cleanup_module(void)
 {
        PRINTK2((KERN_DEBUG "%s: entering cleanup_module\n", boardname));
-
-        unregister_netdev(&dev_ni5010);
-
-       release_region(dev_ni5010.base_addr, NI5010_IO_EXTENT);
-       if (dev_ni5010.priv != NULL){
-               kfree(dev_ni5010.priv);
-               dev_ni5010.priv = NULL;
-       }
+       unregister_netdev(dev_ni5010);
+       release_region(dev_ni5010->base_addr, NI5010_IO_EXTENT);
+       free_netdev(dev_ni5010);
 }
 #endif /* MODULE */
 MODULE_LICENSE("GPL");
index f5d04d4..714d970 100644 (file)
@@ -354,50 +354,76 @@ static void alloc586(struct net_device *dev)
        memset((char *)p->scb,0,sizeof(struct scb_struct));
 }
 
+/* set: io,irq,memstart,memend or set it when calling insmod */
+static int irq=9;
+static int io=0x300;
+static long memstart;  /* e.g 0xd0000 */
+static long memend;    /* e.g 0xd4000 */
+
 /**********************************************
  * probe the ni5210-card
  */
-int __init ni52_probe(struct net_device *dev)
+struct net_device * __init ni52_probe(int unit)
 {
-#ifndef MODULE
-       int *port;
+       struct net_device *dev = alloc_etherdev(sizeof(struct priv));
        static int ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0};
-#endif
-       int base_addr = dev->base_addr;
+       int *port;
+       int err = 0;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+               memstart = dev->mem_start;
+               memend = dev->mem_end;
+       }
 
        SET_MODULE_OWNER(dev);
 
-       if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return ni52_probe1(dev, base_addr);
-       else if (base_addr > 0)         /* Don't probe at all. */
-               return -ENXIO;
-
-#ifdef MODULE
-       printk("%s: no autoprobing allowed for modules.\n",dev->name);
-#else
-       for (port = ports; *port; port++) {
-               int ioaddr = *port;
-               dev->base_addr = ioaddr;
-               if (ni52_probe1(dev, ioaddr) == 0)
-                       return 0;
-       }
-
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = ni52_probe1(dev, io);
+       } else if (io > 0) {            /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = ports; *port && ni52_probe1(dev, *port) ; port++)
+                       ;
+               if (*port)
+                       goto got_it;
 #ifdef FULL_IO_PROBE
-       for(dev->base_addr=0x200; dev->base_addr<0x400; dev->base_addr+=8)
-               if (ni52_probe1(dev, dev->base_addr) == 0)
-                       return 0;
-#endif
-
+               for (io = 0x200; io < 0x400 && ni52_probe1(dev, io); io += 8)
+                       ;
+               if (io < 0x400)
+                       goto got_it;
 #endif
-
-       dev->base_addr = base_addr;
-       return -ENODEV;
+               err = -ENODEV;
+       }
+       if (err)
+               goto out;
+got_it:
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, NI52_TOTAL_SIZE);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init ni52_probe1(struct net_device *dev,int ioaddr)
 {
        int i, size, retval;
 
+       dev->base_addr = ioaddr;
+       dev->irq = irq;
+       dev->mem_start = memstart;
+       dev->mem_end = memend;
+
        if (!request_region(ioaddr, NI52_TOTAL_SIZE, dev->name))
                return -EBUSY;
 
@@ -416,7 +442,7 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
                goto out;
        }
 
-       printk("%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr);
+       printk(KERN_INFO "%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr);
 
        /*
         * check (or search) IO-Memory, 8K and 16K
@@ -469,13 +495,6 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
        dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
 #endif
 
-       dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
-       if(dev->priv == NULL) {
-               printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
-               retval = -ENOMEM;
-               goto out;
-       }
-                                                                                                                                       /* warning: we don't free it on errors */
        memset((char *) dev->priv,0,sizeof(struct priv));
 
        ((struct priv *) (dev->priv))->memtop = isa_bus_to_virt(dev->mem_start) + size;
@@ -503,8 +522,6 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
                if(!dev->irq)
                {
                        printk("?autoirq, Failed to detect IRQ line!\n");
-                       kfree(dev->priv);
-                       dev->priv = NULL;
                        retval = -EAGAIN;
                        goto out;
                }
@@ -526,8 +543,6 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
 
        dev->if_port            = 0;
 
-       ether_setup(dev);
-
        return 0;
 out:
        release_region(ioaddr, NI52_TOTAL_SIZE);
@@ -1295,13 +1310,7 @@ static void set_multicast_list(struct net_device *dev)
 }
 
 #ifdef MODULE
-static struct net_device dev_ni52;
-
-/* set: io,irq,memstart,memend or set it when calling insmod */
-static int irq=9;
-static int io=0x300;
-static long memstart;  /* e.g 0xd0000 */
-static long memend;    /* e.g 0xd4000 */
+static struct net_device *dev_ni52;
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -1318,22 +1327,17 @@ int init_module(void)
                printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");
                return -ENODEV;
        }
-       dev_ni52.init = ni52_probe;
-       dev_ni52.irq = irq;
-       dev_ni52.base_addr = io;
-       dev_ni52.mem_end = memend;
-       dev_ni52.mem_start = memstart;
-       if (register_netdev(&dev_ni52) != 0)
-               return -EIO;
+       dev_ni52 = ni52_probe(-1);
+       if (IS_ERR(dev_ni52))
+               return PTR_ERR(dev_ni52);
        return 0;
 }
 
 void cleanup_module(void)
 {
-       release_region(dev_ni52.base_addr, NI52_TOTAL_SIZE);
-       unregister_netdev(&dev_ni52);
-       kfree(dev_ni52.priv);
-       dev_ni52.priv = NULL;
+       unregister_netdev(dev_ni52);
+       release_region(dev_ni52->base_addr, NI52_TOTAL_SIZE);
+       free_netdev(dev_ni52);
 }
 #endif /* MODULE */
 
index cd9aebb..c43c4cf 100644 (file)
@@ -343,29 +343,64 @@ static int ni65_close(struct net_device *dev)
        return 0;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       struct priv *p = (struct priv *) dev->priv;
+       disable_dma(dev->dma);
+       free_dma(dev->dma);
+       release_region(dev->base_addr, cards[p->cardno].total_size);
+       ni65_free_buffer(p);
+}
+
+/* set: io,irq,dma or set it when calling insmod */
+static int irq;
+static int io;
+static int dma;
+
 /*
  * Probe The Card (not the lance-chip)
  */
-#ifdef MODULE
-static
-#endif
-int __init ni65_probe(struct net_device *dev)
+struct net_device * __init ni65_probe(int unit)
 {
-       int *port;
+       struct net_device *dev = alloc_etherdev(0);
        static int ports[] = {0x360,0x300,0x320,0x340, 0};
-
-       if (dev->base_addr > 0x1ff)          /* Check a single specified location. */
-                return ni65_probe1(dev, dev->base_addr);
-       else if (dev->base_addr > 0)         /* Don't probe at all. */
-                return -ENXIO;
-
-       for (port = ports; *port; port++)
-       {
-               if (ni65_probe1(dev, *port) == 0)
-                        return 0;
+       int *port;
+       int err = 0;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               irq = dev->irq;
+               dma = dev->dma;
+       } else {
+               dev->base_addr = io;
        }
 
-       return -ENODEV;
+       if (dev->base_addr > 0x1ff) { /* Check a single specified location. */
+               err = ni65_probe1(dev, dev->base_addr);
+       } else if (dev->base_addr > 0) { /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = ports; *port && ni65_probe1(dev, *port); port++)
+                       ;
+               if (!*port)
+                       err = -ENODEV;
+       }
+       if (err)
+               goto out;
+
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /*
@@ -377,6 +412,9 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
        struct priv *p;
        unsigned long flags;
 
+       dev->irq = irq;
+       dev->dma = dma;
+
        for(i=0;i<NUM_CARDS;i++) {
                if(!request_region(ioaddr, cards[i].total_size, cards[i].cardname))
                        continue;
@@ -521,9 +559,6 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
        dev->watchdog_timeo     = HZ/2;
        dev->get_stats          = ni65_get_stats;
        dev->set_multicast_list = set_multicast_list;
-
-       ether_setup(dev);
-
        return 0; /* everything is OK */
 }
 
@@ -1213,12 +1248,7 @@ static void set_multicast_list(struct net_device *dev)
 }
 
 #ifdef MODULE
-static struct net_device dev_ni65 = { .base_addr = 0x360, .irq = 9, .init = ni65_probe };
-
-/* set: io,irq,dma or set it when calling insmod */
-static int irq;
-static int io;
-static int dma;
+static struct net_device *dev_ni65;
 
 MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
@@ -1229,26 +1259,15 @@ MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)");
 
 int init_module(void)
 {
-       dev_ni65.irq = irq;
-       dev_ni65.dma = dma;
-       dev_ni65.base_addr = io;
-       if (register_netdev(&dev_ni65) != 0)
-               return -EIO;
-       return 0;
+       dev_ni65 = ni65_probe(-1);
+       return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0;
 }
 
 void cleanup_module(void)
 {
-       struct priv *p;
-       p = (struct priv *) dev_ni65.priv;
-       if(!p)
-               BUG();
-       disable_dma(dev_ni65.dma);
-       free_dma(dev_ni65.dma);
-       unregister_netdev(&dev_ni65);
-       release_region(dev_ni65.base_addr,cards[p->cardno].total_size);
-       ni65_free_buffer(p);
-       dev_ni65.priv = NULL;
+       unregister_netdev(dev_ni65);
+       cleanup_card(dev_ni65);
+       free_netdev(dev_ni65);
 }
 #endif /* MODULE */
 
index 67d71fc..a525174 100644 (file)
@@ -374,19 +374,6 @@ static int lnksts = 0;             /* CFG_LNKSTS bit polarity */
 #define LINK_DOWN              0x02
 #define LINK_UP                        0x04
 
-#define __kick_rx(dev) writel(CR_RXE, dev->base + CR)
-
-#define kick_rx(dev) do { \
-       dprintk("kick_rx: maybe kicking\n"); \
-       if (test_and_clear_bit(0, &dev->rx_info.idle)) { \
-               dprintk("actually kicking\n"); \
-               writel(dev->rx_info.phy_descs + (4 * DESC_SIZE * dev->rx_info.next_rx), dev->base + RXDP); \
-               if (dev->rx_info.next_rx == dev->rx_info.next_empty) \
-                       printk(KERN_DEBUG "%s: uh-oh: next_rx == next_empty???\n", dev->net_dev.name);\
-               __kick_rx(dev); \
-       } \
-} while(0)
-
 #ifdef USE_64BIT_ADDR
 #define HW_ADDR_LEN    8
 #define desc_addr_set(desc, addr)                              \
@@ -438,7 +425,6 @@ struct rx_info {
 
 
 struct ns83820 {
-       struct net_device       net_dev;        /* must be first */
        struct net_device_stats stats;
        u8                      *base;
 
@@ -478,6 +464,29 @@ struct ns83820 {
        struct timer_list       tx_watchdog;
 };
 
+static inline struct ns83820 *PRIV(struct net_device *dev)
+{
+       return netdev_priv(dev);
+}
+
+#define __kick_rx(dev) writel(CR_RXE, dev->base + CR)
+
+static inline void kick_rx(struct net_device *ndev)
+{
+       struct ns83820 *dev = PRIV(ndev);
+       dprintk("kick_rx: maybe kicking\n");
+       if (test_and_clear_bit(0, &dev->rx_info.idle)) {
+               dprintk("actually kicking\n");
+               writel(dev->rx_info.phy_descs +
+                       (4 * DESC_SIZE * dev->rx_info.next_rx),
+                      dev->base + RXDP);
+               if (dev->rx_info.next_rx == dev->rx_info.next_empty)
+                       printk(KERN_DEBUG "%s: uh-oh: next_rx == next_empty???\n",
+                               ndev->name);
+               __kick_rx(dev);
+       }
+}
+
 //free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC
 #define start_tx_okay(dev)     \
        (((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE)
@@ -546,15 +555,16 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
        return 0;
 }
 
-static inline int rx_refill(struct ns83820 *dev, int gfp)
+static inline int rx_refill(struct net_device *ndev, int gfp)
 {
+       struct ns83820 *dev = PRIV(ndev);
        unsigned i;
        unsigned long flags = 0;
 
        if (unlikely(nr_rx_empty(dev) <= 2))
                return 0;
 
-       dprintk("rx_refill(%p)\n", dev);
+       dprintk("rx_refill(%p)\n", ndev);
        if (gfp == GFP_ATOMIC)
                spin_lock_irqsave(&dev->rx_info.lock, flags);
        for (i=0; i<NR_RX_DESC; i++) {
@@ -570,7 +580,7 @@ static inline int rx_refill(struct ns83820 *dev, int gfp)
                res &= 0xf;
                skb_reserve(skb, res);
 
-               skb->dev = &dev->net_dev;
+               skb->dev = ndev;
                if (gfp != GFP_ATOMIC)
                        spin_lock_irqsave(&dev->rx_info.lock, flags);
                res = ns83820_add_rx_skb(dev, skb);
@@ -587,20 +597,21 @@ static inline int rx_refill(struct ns83820 *dev, int gfp)
        return i ? 0 : -ENOMEM;
 }
 
-static void FASTCALL(rx_refill_atomic(struct ns83820 *dev));
-static void rx_refill_atomic(struct ns83820 *dev)
+static void FASTCALL(rx_refill_atomic(struct net_device *ndev));
+static void rx_refill_atomic(struct net_device *ndev)
 {
-       rx_refill(dev, GFP_ATOMIC);
+       rx_refill(ndev, GFP_ATOMIC);
 }
 
 /* REFILL */
 static inline void queue_refill(void *_dev)
 {
-       struct ns83820 *dev = _dev;
+       struct net_device *ndev = _dev;
+       struct ns83820 *dev = PRIV(ndev);
 
-       rx_refill(dev, GFP_KERNEL);
+       rx_refill(ndev, GFP_KERNEL);
        if (dev->rx_info.up)
-               kick_rx(dev);
+               kick_rx(ndev);
 }
 
 static inline void clear_rx_desc(struct ns83820 *dev, unsigned i)
@@ -608,9 +619,10 @@ static inline void clear_rx_desc(struct ns83820 *dev, unsigned i)
        build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
 }
 
-static void FASTCALL(phy_intr(struct ns83820 *dev));
-static void phy_intr(struct ns83820 *dev)
+static void FASTCALL(phy_intr(struct net_device *ndev));
+static void phy_intr(struct net_device *ndev)
 {
+       struct ns83820 *dev = PRIV(ndev);
        static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
        u32 cfg, new_cfg;
        u32 tbisr, tanar, tanlpar;
@@ -688,27 +700,28 @@ static void phy_intr(struct ns83820 *dev)
 
        if (newlinkstate & LINK_UP
            && dev->linkstate != newlinkstate) {
-               netif_start_queue(&dev->net_dev);
-               netif_wake_queue(&dev->net_dev);
+               netif_start_queue(ndev);
+               netif_wake_queue(ndev);
                printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
-                       dev->net_dev.name,
+                       ndev->name,
                        speeds[speed],
                        fullduplex ? "full" : "half");
        } else if (newlinkstate & LINK_DOWN
                   && dev->linkstate != newlinkstate) {
-               netif_stop_queue(&dev->net_dev);
-               printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name);
+               netif_stop_queue(ndev);
+               printk(KERN_INFO "%s: link now down.\n", ndev->name);
        }
 
        dev->linkstate = newlinkstate;
 }
 
-static int ns83820_setup_rx(struct ns83820 *dev)
+static int ns83820_setup_rx(struct net_device *ndev)
 {
+       struct ns83820 *dev = PRIV(ndev);
        unsigned i;
        int ret;
 
-       dprintk("ns83820_setup_rx(%p)\n", dev);
+       dprintk("ns83820_setup_rx(%p)\n", ndev);
 
        dev->rx_info.idle = 1;
        dev->rx_info.next_rx = 0;
@@ -721,7 +734,7 @@ static int ns83820_setup_rx(struct ns83820 *dev)
        writel(0, dev->base + RXDP_HI);
        writel(dev->rx_info.phy_descs, dev->base + RXDP);
 
-       ret = rx_refill(dev, GFP_KERNEL);
+       ret = rx_refill(ndev, GFP_KERNEL);
        if (!ret) {
                dprintk("starting receiver\n");
                /* prevent the interrupt handler from stomping on us */
@@ -734,7 +747,7 @@ static int ns83820_setup_rx(struct ns83820 *dev)
 
                dev->rx_info.up = 1;
 
-               phy_intr(dev);
+               phy_intr(ndev);
 
                /* Okay, let it rip */
                spin_lock_irq(&dev->misc_lock);
@@ -753,7 +766,7 @@ static int ns83820_setup_rx(struct ns83820 *dev)
                writel(1, dev->base + IER);
                spin_unlock_irq(&dev->misc_lock);
 
-               kick_rx(dev);
+               kick_rx(ndev);
 
                spin_unlock_irq(&dev->rx_info.lock);
        }
@@ -793,37 +806,39 @@ static void ns83820_cleanup_rx(struct ns83820 *dev)
        }
 }
 
-static void FASTCALL(ns83820_rx_kick(struct ns83820 *dev));
-static void ns83820_rx_kick(struct ns83820 *dev)
+static void FASTCALL(ns83820_rx_kick(struct net_device *ndev));
+static void ns83820_rx_kick(struct net_device *ndev)
 {
+       struct ns83820 *dev = PRIV(ndev);
        /*if (nr_rx_empty(dev) >= NR_RX_DESC/4)*/ {
                if (dev->rx_info.up) {
-                       rx_refill_atomic(dev);
-                       kick_rx(dev);
+                       rx_refill_atomic(ndev);
+                       kick_rx(ndev);
                }
        }
 
        if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4)
                schedule_work(&dev->tq_refill);
        else
-               kick_rx(dev);
+               kick_rx(ndev);
        if (dev->rx_info.idle)
-               printk(KERN_DEBUG "%s: BAD\n", dev->net_dev.name);
+               printk(KERN_DEBUG "%s: BAD\n", ndev->name);
 }
 
 /* rx_irq
  *     
  */
-static void FASTCALL(rx_irq(struct ns83820 *dev));
-static void rx_irq(struct ns83820 *dev)
+static void FASTCALL(rx_irq(struct net_device *ndev));
+static void rx_irq(struct net_device *ndev)
 {
+       struct ns83820 *dev = PRIV(ndev);
        struct rx_info *info = &dev->rx_info;
        unsigned next_rx;
        u32 cmdsts, *desc;
        unsigned long flags;
        int nr = 0;
 
-       dprintk("rx_irq(%p)\n", dev);
+       dprintk("rx_irq(%p)\n", ndev);
        dprintk("rxdp: %08x, descs: %08lx next_rx[%d]: %p next_empty[%d]: %p\n",
                readl(dev->base + RXDP),
                (long)(dev->rx_info.phy_descs),
@@ -873,7 +888,7 @@ static void rx_irq(struct ns83820 *dev)
                        } else {
                                skb->ip_summed = CHECKSUM_NONE;
                        }
-                       skb->protocol = eth_type_trans(skb, &dev->net_dev);
+                       skb->protocol = eth_type_trans(skb, ndev);
                        if (NET_RX_DROP == netif_rx(skb)) {
 netdev_mangle_me_harder_failed:
                                dev->stats.rx_dropped ++;
@@ -899,8 +914,9 @@ out:
 
 static void rx_action(unsigned long _dev)
 {
-       struct ns83820 *dev = (void *)_dev;
-       rx_irq(dev);
+       struct net_device *ndev = (void *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
+       rx_irq(ndev);
        writel(ihr, dev->base + IHR);
 
        spin_lock_irq(&dev->misc_lock);
@@ -908,8 +924,8 @@ static void rx_action(unsigned long _dev)
        writel(dev->IMR_cache, dev->base + IMR);
        spin_unlock_irq(&dev->misc_lock);
 
-       rx_irq(dev);
-       ns83820_rx_kick(dev);
+       rx_irq(ndev);
+       ns83820_rx_kick(ndev);
 }
 
 /* Packet Transmit code
@@ -924,13 +940,14 @@ static inline void kick_tx(struct ns83820 *dev)
 /* No spinlock needed on the transmit irq path as the interrupt handler is
  * serialized.
  */
-static void do_tx_done(struct ns83820 *dev)
+static void do_tx_done(struct net_device *ndev)
 {
+       struct ns83820 *dev = PRIV(ndev);
        u32 cmdsts, tx_done_idx, *desc;
 
        spin_lock_irq(&dev->tx_lock);
 
-       dprintk("do_tx_done(%p)\n", dev);
+       dprintk("do_tx_done(%p)\n", ndev);
        tx_done_idx = dev->tx_done_idx;
        desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
 
@@ -980,10 +997,10 @@ static void do_tx_done(struct ns83820 *dev)
        /* Allow network stack to resume queueing packets after we've
         * finished transmitting at least 1/4 of the packets in the queue.
         */
-       if (netif_queue_stopped(&dev->net_dev) && start_tx_okay(dev)) {
-               dprintk("start_queue(%p)\n", dev);
-               netif_start_queue(&dev->net_dev);
-               netif_wake_queue(&dev->net_dev);
+       if (netif_queue_stopped(ndev) && start_tx_okay(dev)) {
+               dprintk("start_queue(%p)\n", ndev);
+               netif_start_queue(ndev);
+               netif_wake_queue(ndev);
        }
        spin_unlock_irq(&dev->tx_lock);
 }
@@ -1015,9 +1032,9 @@ static void ns83820_cleanup_tx(struct ns83820 *dev)
  * while trying to track down a bug in either the zero copy code or
  * the tx fifo (hence the MAX_FRAG_LEN).
  */
-static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
+static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
-       struct ns83820 *dev = (struct ns83820 *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
        u32 free_idx, cmdsts, extsts;
        int nr_free, nr_frags;
        unsigned tx_done_idx, last_idx;
@@ -1033,10 +1050,10 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
        nr_frags =  skb_shinfo(skb)->nr_frags;
 again:
        if (unlikely(dev->CFG_cache & CFG_LNKSTS)) {
-               netif_stop_queue(&dev->net_dev);
+               netif_stop_queue(ndev);
                if (unlikely(dev->CFG_cache & CFG_LNKSTS))
                        return 1;
-               netif_start_queue(&dev->net_dev);
+               netif_start_queue(ndev);
        }
 
        last_idx = free_idx = dev->tx_free_idx;
@@ -1044,13 +1061,13 @@ again:
        nr_free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC;
        nr_free -= 1;
        if (nr_free <= nr_frags) {
-               dprintk("stop_queue - not enough(%p)\n", dev);
-               netif_stop_queue(&dev->net_dev);
+               dprintk("stop_queue - not enough(%p)\n", ndev);
+               netif_stop_queue(ndev);
 
                /* Check again: we may have raced with a tx done irq */
                if (dev->tx_done_idx != tx_done_idx) {
-                       dprintk("restart queue(%p)\n", dev);
-                       netif_start_queue(&dev->net_dev);
+                       dprintk("restart queue(%p)\n", ndev);
+                       netif_start_queue(ndev);
                        goto again;
                }
                return 1;
@@ -1063,8 +1080,8 @@ again:
 
        nr_free -= nr_frags;
        if (nr_free < MIN_TX_DESC_FREE) {
-               dprintk("stop_queue - last entry(%p)\n", dev);
-               netif_stop_queue(&dev->net_dev);
+               dprintk("stop_queue - last entry(%p)\n", ndev);
+               netif_stop_queue(ndev);
                stopped = 1;
        }
 
@@ -1136,10 +1153,10 @@ again:
 
        /* Check again: we may have raced with a tx done irq */
        if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev))
-               netif_start_queue(&dev->net_dev);
+               netif_start_queue(ndev);
 
        /* set the transmit start time to catch transmit timeouts */
-       dev->net_dev.trans_start = jiffies;
+       ndev->trans_start = jiffies;
        return 0;
 }
 
@@ -1161,9 +1178,9 @@ static void ns83820_update_stats(struct ns83820 *dev)
        dev->stats.tx_carrier_errors    += readl(base + 0x88) & 0xff;
 }
 
-static struct net_device_stats *ns83820_get_stats(struct net_device *_dev)
+static struct net_device_stats *ns83820_get_stats(struct net_device *ndev)
 {
-       struct ns83820 *dev = (void *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
 
        /* somewhat overkill */
        spin_lock_irq(&dev->misc_lock);
@@ -1213,9 +1230,9 @@ static int ns83820_ethtool_ioctl (struct ns83820 *dev, void *useraddr)
        return -EOPNOTSUPP;
 }
 
-static int ns83820_ioctl(struct net_device *_dev, struct ifreq *rq, int cmd)
+static int ns83820_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
-       struct ns83820 *dev = (struct ns83820 *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
 
        switch(cmd) {
        case SIOCETHTOOL:
@@ -1233,23 +1250,25 @@ static void ns83820_mib_isr(struct ns83820 *dev)
        spin_unlock(&dev->misc_lock);
 }
 
-static void ns83820_do_isr(struct ns83820 *dev, u32 isr);
+static void ns83820_do_isr(struct net_device *ndev, u32 isr);
 static irqreturn_t ns83820_irq(int foo, void *data, struct pt_regs *regs)
 {
-       struct ns83820 *dev = data;
+       struct net_device *ndev = data;
+       struct ns83820 *dev = PRIV(ndev);
        u32 isr;
-       dprintk("ns83820_irq(%p)\n", dev);
+       dprintk("ns83820_irq(%p)\n", ndev);
 
        dev->ihr = 0;
 
        isr = readl(dev->base + ISR);
        dprintk("irq: %08x\n", isr);
-       ns83820_do_isr(dev, isr);
+       ns83820_do_isr(ndev, isr);
        return IRQ_HANDLED;
 }
 
-static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
+static void ns83820_do_isr(struct net_device *ndev, u32 isr)
 {
+       struct ns83820 *dev = PRIV(ndev);
 #ifdef DEBUG
        if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC))
                Dprintk("odd isr? 0x%08x\n", isr);
@@ -1258,7 +1277,7 @@ static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
        if (ISR_RXIDLE & isr) {
                dev->rx_info.idle = 1;
                Dprintk("oh dear, we are idle\n");
-               ns83820_rx_kick(dev);
+               ns83820_rx_kick(ndev);
        }
 
        if ((ISR_RXDESC | ISR_RXOK) & isr) {
@@ -1270,12 +1289,12 @@ static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
                spin_unlock_irq(&dev->misc_lock);
 
                tasklet_schedule(&dev->rx_tasklet);
-               //rx_irq(dev);
+               //rx_irq(ndev);
                //writel(4, dev->base + IHR);
        }
 
        if ((ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr)
-               ns83820_rx_kick(dev);
+               ns83820_rx_kick(ndev);
 
        if (unlikely(ISR_RXSOVR & isr)) {
                //printk("overrun: rxsovr\n");
@@ -1297,7 +1316,7 @@ static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
                txdp -= dev->tx_phy_descs;
                dev->tx_idx = txdp / (DESC_SIZE * 4);
                if (dev->tx_idx >= NR_TX_DESC) {
-                       printk(KERN_ALERT "%s: BUG -- txdp out of range\n", dev->net_dev.name);
+                       printk(KERN_ALERT "%s: BUG -- txdp out of range\n", ndev->name);
                        dev->tx_idx = 0;
                }
                /* The may have been a race between a pci originated read
@@ -1313,7 +1332,7 @@ static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
         * work has accumulated
         */
        if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) {
-               do_tx_done(dev);
+               do_tx_done(ndev);
 
                /* Disable TxOk if there are no outstanding tx packets.
                 */
@@ -1345,7 +1364,7 @@ static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
 
        /* PHY: Link up/down/negotiation state change */
        if (unlikely(ISR_PHY & isr))
-               phy_intr(dev);
+               phy_intr(ndev);
 
 #if 0  /* Still working on the interrupt mitigation strategy */
        if (dev->ihr)
@@ -1363,9 +1382,9 @@ static void ns83820_do_reset(struct ns83820 *dev, u32 which)
        Dprintk("okay!\n");
 }
 
-static int ns83820_stop(struct net_device *_dev)
+static int ns83820_stop(struct net_device *ndev)
 {
-       struct ns83820 *dev = (struct ns83820 *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
 
        /* FIXME: protect against interrupt handler? */
        del_timer_sync(&dev->tx_watchdog);
@@ -1392,10 +1411,9 @@ static int ns83820_stop(struct net_device *_dev)
        return 0;
 }
 
-static void ns83820_do_isr(struct ns83820 *dev, u32 isr);
-static void ns83820_tx_timeout(struct net_device *_dev)
+static void ns83820_tx_timeout(struct net_device *ndev)
 {
-       struct ns83820 *dev = (struct ns83820 *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
         u32 tx_done_idx, *desc;
        unsigned long flags;
 
@@ -1405,7 +1423,7 @@ static void ns83820_tx_timeout(struct net_device *_dev)
        desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
 
        printk(KERN_INFO "%s: tx_timeout: tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
-               dev->net_dev.name,
+               ndev->name,
                tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS]));
 
 #if defined(DEBUG)
@@ -1413,17 +1431,17 @@ static void ns83820_tx_timeout(struct net_device *_dev)
                u32 isr;
                isr = readl(dev->base + ISR);
                printk("irq: %08x imr: %08x\n", isr, dev->IMR_cache);
-               ns83820_do_isr(dev, isr);
+               ns83820_do_isr(ndev, isr);
        }
 #endif
 
-       do_tx_done(dev);
+       do_tx_done(ndev);
 
        tx_done_idx = dev->tx_done_idx;
        desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
 
        printk(KERN_INFO "%s: after: tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
-               dev->net_dev.name,
+               ndev->name,
                tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS]));
 
        local_irq_restore(flags);
@@ -1431,7 +1449,8 @@ static void ns83820_tx_timeout(struct net_device *_dev)
 
 static void ns83820_tx_watch(unsigned long data)
 {
-       struct ns83820 *dev = (void *)data;
+       struct net_device *ndev = (void *)data;
+       struct ns83820 *dev = PRIV(ndev);
 
 #if defined(DEBUG)
        printk("ns83820_tx_watch: %u %u %d\n",
@@ -1439,21 +1458,21 @@ static void ns83820_tx_watch(unsigned long data)
                );
 #endif
 
-       if (time_after(jiffies, dev->net_dev.trans_start + 1*HZ) &&
+       if (time_after(jiffies, ndev->trans_start + 1*HZ) &&
            dev->tx_done_idx != dev->tx_free_idx) {
                printk(KERN_DEBUG "%s: ns83820_tx_watch: %u %u %d\n",
-                       dev->net_dev.name,
+                       ndev->name,
                        dev->tx_done_idx, dev->tx_free_idx,
                        atomic_read(&dev->nr_tx_skbs));
-               ns83820_tx_timeout(&dev->net_dev);
+               ns83820_tx_timeout(ndev);
        }
 
        mod_timer(&dev->tx_watchdog, jiffies + 2*HZ);
 }
 
-static int ns83820_open(struct net_device *_dev)
+static int ns83820_open(struct net_device *ndev)
 {
-       struct ns83820 *dev = (struct ns83820 *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
        unsigned i;
        u32 desc;
        int ret;
@@ -1462,7 +1481,7 @@ static int ns83820_open(struct net_device *_dev)
 
        writel(0, dev->base + PQCR);
 
-       ret = ns83820_setup_rx(dev);
+       ret = ns83820_setup_rx(ndev);
        if (ret)
                goto failed;
 
@@ -1481,16 +1500,16 @@ static int ns83820_open(struct net_device *_dev)
        writel(desc, dev->base + TXDP);
 
        init_timer(&dev->tx_watchdog);
-       dev->tx_watchdog.data = (unsigned long)dev;
+       dev->tx_watchdog.data = (unsigned long)ndev;
        dev->tx_watchdog.function = ns83820_tx_watch;
        mod_timer(&dev->tx_watchdog, jiffies + 2*HZ);
 
-       netif_start_queue(&dev->net_dev);       /* FIXME: wait for phy to come up */
+       netif_start_queue(ndev);        /* FIXME: wait for phy to come up */
 
        return 0;
 
 failed:
-       ns83820_stop(_dev);
+       ns83820_stop(ndev);
        return ret;
 }
 
@@ -1513,28 +1532,28 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
        }
 }
 
-static int ns83820_change_mtu(struct net_device *_dev, int new_mtu)
+static int ns83820_change_mtu(struct net_device *ndev, int new_mtu)
 {
        if (new_mtu > RX_BUF_SIZE)
                return -EINVAL;
-       _dev->mtu = new_mtu;
+       ndev->mtu = new_mtu;
        return 0;
 }
 
-static void ns83820_set_multicast(struct net_device *_dev)
+static void ns83820_set_multicast(struct net_device *ndev)
 {
-       struct ns83820 *dev = (void *)_dev;
+       struct ns83820 *dev = PRIV(ndev);
        u8 *rfcr = dev->base + RFCR;
        u32 and_mask = 0xffffffff;
        u32 or_mask = 0;
        u32 val;
 
-       if (dev->net_dev.flags & IFF_PROMISC)
+       if (ndev->flags & IFF_PROMISC)
                or_mask |= RFCR_AAU | RFCR_AAM;
        else
                and_mask &= ~(RFCR_AAU | RFCR_AAM);
 
-       if (dev->net_dev.flags & IFF_ALLMULTI)
+       if (ndev->flags & IFF_ALLMULTI)
                or_mask |= RFCR_AAM;
        else
                and_mask &= ~RFCR_AAM;
@@ -1547,14 +1566,15 @@ static void ns83820_set_multicast(struct net_device *_dev)
        spin_unlock_irq(&dev->misc_lock);
 }
 
-static void ns83820_run_bist(struct ns83820 *dev, const char *name, u32 enable, u32 done, u32 fail)
+static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enable, u32 done, u32 fail)
 {
+       struct ns83820 *dev = PRIV(ndev);
        int timed_out = 0;
        long start;
        u32 status;
        int loops = 0;
 
-       dprintk("%s: start %s\n", dev->net_dev.name, name);
+       dprintk("%s: start %s\n", ndev->name, name);
 
        start = jiffies;
 
@@ -1578,12 +1598,12 @@ static void ns83820_run_bist(struct ns83820 *dev, const char *name, u32 enable,
 
        if (status & fail)
                printk(KERN_INFO "%s: %s failed! (0x%08x & 0x%08x)\n",
-                       dev->net_dev.name, name, status, fail);
+                       ndev->name, name, status, fail);
        else if (timed_out)
                printk(KERN_INFO "%s: run_bist %s timed out! (%08x)\n",
-                       dev->net_dev.name, name, status);
+                       ndev->name, name, status);
 
-       dprintk("%s: done %s in %d loops\n", dev->net_dev.name, name, loops);
+       dprintk("%s: done %s in %d loops\n", ndev->name, name, loops);
 }
 
 #ifdef PHY_CODE_IS_FINISHED
@@ -1706,8 +1726,9 @@ static unsigned ns83820_mii_write_reg(struct ns83820 *dev, unsigned phy, unsigne
        return data;
 }
 
-static void ns83820_probe_phy(struct ns83820 *dev)
+static void ns83820_probe_phy(struct net_device *ndev)
 {
+       struct ns83820 *dev = PRIV(ndev);
        static int first;
        int i;
 #define MII_PHYIDR1    0x02
@@ -1734,11 +1755,11 @@ static void ns83820_probe_phy(struct ns83820 *dev)
                b = ns83820_mii_read_reg(dev, i, MII_PHYIDR2);
 
                //printk("%s: phy %d: 0x%04x 0x%04x\n",
-               //      dev->net_dev.name, i, a, b);
+               //      ndev->name, i, a, b);
 
                for (j=0; j<0x16; j+=4) {
                        dprintk("%s: [0x%02x] %04x %04x %04x %04x\n",
-                               dev->net_dev.name, j,
+                               ndev->name, j,
                                ns83820_mii_read_reg(dev, i, 0 + j),
                                ns83820_mii_read_reg(dev, i, 1 + j),
                                ns83820_mii_read_reg(dev, i, 2 + j),
@@ -1763,6 +1784,7 @@ static void ns83820_probe_phy(struct ns83820 *dev)
 
 static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_device_id *id)
 {
+       struct net_device *ndev;
        struct ns83820 *dev;
        long addr;
        int err;
@@ -1778,7 +1800,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
                return -ENODEV;
        }
 
-       dev = (struct ns83820 *)alloc_etherdev((sizeof *dev) - (sizeof dev->net_dev));
+       ndev = alloc_etherdev(sizeof(struct ns83820));
+       dev = PRIV(ndev);
        err = -ENOMEM;
        if (!dev)
                goto out;
@@ -1790,12 +1813,11 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
 
        dev->ee.cache = &dev->MEAR_cache;
        dev->ee.lock = &dev->misc_lock;
-       SET_MODULE_OWNER(dev->net_dev);
-       SET_NETDEV_DEV(&dev->net_dev, &pci_dev->dev);
-       dev->net_dev.priv = dev;
+       SET_MODULE_OWNER(ndev);
+       SET_NETDEV_DEV(ndev, &pci_dev->dev);
 
-       INIT_WORK(&dev->tq_refill, queue_refill, dev);
-       tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)dev);
+       INIT_WORK(&dev->tq_refill, queue_refill, ndev);
+       tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)ndev);
 
        err = pci_enable_device(pci_dev);
        if (err) {
@@ -1829,55 +1851,63 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
                0);
 
        err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
-                         dev->net_dev.name, dev);
+                         ndev->name, ndev);
        if (err) {
                printk(KERN_INFO "ns83820: unable to register irq %d\n",
                        pci_dev->irq);
                goto out_disable;
        }
 
-       err = register_netdev(&dev->net_dev);
-       if (err) {
-               printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err);
+       /*
+        * FIXME: we are holding rtnl_lock() over obscenely long area only
+        * because some of the setup code uses dev->name.  It's Wrong(tm) -
+        * we should be using driver-specific names for all that stuff.
+        * For now that will do, but we really need to come back and kill
+        * most of the dev_alloc_name() users later.
+        */
+       rtnl_lock();
+       err = dev_alloc_name(ndev, ndev->name);
+       if (err < 0) {
+               printk(KERN_INFO "ns83820: unable to get netdev name: %d\n", err);
                goto out_free_irq;
        }
 
        printk("%s: ns83820.c: 0x22c: %08x, subsystem: %04x:%04x\n",
-               dev->net_dev.name, le32_to_cpu(readl(dev->base + 0x22c)),
+               ndev->name, le32_to_cpu(readl(dev->base + 0x22c)),
                pci_dev->subsystem_vendor, pci_dev->subsystem_device);
 
-       dev->net_dev.open = ns83820_open;
-       dev->net_dev.stop = ns83820_stop;
-       dev->net_dev.hard_start_xmit = ns83820_hard_start_xmit;
-       dev->net_dev.get_stats = ns83820_get_stats;
-       dev->net_dev.change_mtu = ns83820_change_mtu;
-       dev->net_dev.set_multicast_list = ns83820_set_multicast;
-       dev->net_dev.do_ioctl = ns83820_ioctl;
-       dev->net_dev.tx_timeout = ns83820_tx_timeout;
-       dev->net_dev.watchdog_timeo = 5 * HZ;
+       ndev->open = ns83820_open;
+       ndev->stop = ns83820_stop;
+       ndev->hard_start_xmit = ns83820_hard_start_xmit;
+       ndev->get_stats = ns83820_get_stats;
+       ndev->change_mtu = ns83820_change_mtu;
+       ndev->set_multicast_list = ns83820_set_multicast;
+       ndev->do_ioctl = ns83820_ioctl;
+       ndev->tx_timeout = ns83820_tx_timeout;
+       ndev->watchdog_timeo = 5 * HZ;
 
-       pci_set_drvdata(pci_dev, dev);
+       pci_set_drvdata(pci_dev, ndev);
 
        ns83820_do_reset(dev, CR_RST);
 
        /* Must reset the ram bist before running it */
        writel(PTSCR_RBIST_RST, dev->base + PTSCR);
-       ns83820_run_bist(dev, "sram bist",   PTSCR_RBIST_EN,
+       ns83820_run_bist(ndev, "sram bist",   PTSCR_RBIST_EN,
                         PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL);
-       ns83820_run_bist(dev, "eeprom bist", PTSCR_EEBIST_EN, 0,
+       ns83820_run_bist(ndev, "eeprom bist", PTSCR_EEBIST_EN, 0,
                         PTSCR_EEBIST_FAIL);
-       ns83820_run_bist(dev, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
+       ns83820_run_bist(ndev, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
 
        /* I love config registers */
        dev->CFG_cache = readl(dev->base + CFG);
 
        if ((dev->CFG_cache & CFG_PCI64_DET)) {
                printk(KERN_INFO "%s: detected 64 bit PCI data bus.\n",
-                       dev->net_dev.name);
+                       ndev->name);
                /*dev->CFG_cache |= CFG_DATA64_EN;*/
                if (!(dev->CFG_cache & CFG_DATA64_EN))
                        printk(KERN_INFO "%s: EEPROM did not enable 64 bit bus.  Disabled.\n",
-                               dev->net_dev.name);
+                               ndev->name);
        } else
                dev->CFG_cache &= ~(CFG_DATA64_EN);
 
@@ -1905,7 +1935,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        /* setup optical transceiver if we have one */
        if (dev->CFG_cache & CFG_TBI_EN) {
                printk(KERN_INFO "%s: enabling optical transceiver\n",
-                       dev->net_dev.name);
+                       ndev->name);
                writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR);
 
                /* setup auto negotiation feature advertisement */
@@ -1926,7 +1956,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        dprintk("CFG: %08x\n", dev->CFG_cache);
 
        if (reset_phy) {
-               printk(KERN_INFO "%s: resetting phy\n", dev->net_dev.name);
+               printk(KERN_INFO "%s: resetting phy\n", ndev->name);
                writel(dev->CFG_cache | CFG_PHY_RST, dev->base + CFG);
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout((HZ+99)/100);
@@ -1996,37 +2026,49 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        /* Disable Wake On Lan */
        writel(0, dev->base + WCSR);
 
-       ns83820_getmac(dev, dev->net_dev.dev_addr);
+       ns83820_getmac(dev, ndev->dev_addr);
 
        /* Yes, we support dumb IP checksum on transmit */
-       dev->net_dev.features |= NETIF_F_SG;
-       dev->net_dev.features |= NETIF_F_IP_CSUM;
+       ndev->features |= NETIF_F_SG;
+       ndev->features |= NETIF_F_IP_CSUM;
 
        if (using_dac) {
                printk(KERN_INFO "%s: using 64 bit addressing.\n",
-                       dev->net_dev.name);
-               dev->net_dev.features |= NETIF_F_HIGHDMA;
+                       ndev->name);
+               ndev->features |= NETIF_F_HIGHDMA;
        }
 
        printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %02x:%02x:%02x:%02x:%02x:%02x io=0x%08lx irq=%d f=%s\n",
-               dev->net_dev.name,
+               ndev->name,
                (unsigned)readl(dev->base + SRR) >> 8,
                (unsigned)readl(dev->base + SRR) & 0xff,
-               dev->net_dev.dev_addr[0], dev->net_dev.dev_addr[1],
-               dev->net_dev.dev_addr[2], dev->net_dev.dev_addr[3],
-               dev->net_dev.dev_addr[4], dev->net_dev.dev_addr[5],
+               ndev->dev_addr[0], ndev->dev_addr[1],
+               ndev->dev_addr[2], ndev->dev_addr[3],
+               ndev->dev_addr[4], ndev->dev_addr[5],
                addr, pci_dev->irq,
-               (dev->net_dev.features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
+               (ndev->features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
                );
 
 #ifdef PHY_CODE_IS_FINISHED
-       ns83820_probe_phy(dev);
+       ns83820_probe_phy(ndev);
 #endif
 
+       err = register_netdevice(ndev);
+       if (err) {
+               printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err);
+               goto out_cleanup;
+       }
+       rtnl_unlock();
+
        return 0;
 
+out_cleanup:
+       writel(0, dev->base + IMR);     /* paranoia */
+       writel(0, dev->base + IER);
+       readl(dev->base + IER);
 out_free_irq:
-       free_irq(pci_dev->irq, dev);
+       rtnl_unlock();
+       free_irq(pci_dev->irq, ndev);
 out_disable:
        if (dev->base)
                iounmap(dev->base);
@@ -2034,7 +2076,7 @@ out_disable:
        pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_RX_DESC, dev->rx_info.descs, dev->rx_info.phy_descs);
        pci_disable_device(pci_dev);
 out_free:
-       kfree(dev);
+       free_netdev(ndev);
        pci_set_drvdata(pci_dev, NULL);
 out:
        return err;
@@ -2042,24 +2084,25 @@ out:
 
 static void __devexit ns83820_remove_one(struct pci_dev *pci_dev)
 {
-       struct ns83820  *dev = pci_get_drvdata(pci_dev);
+       struct net_device *ndev = pci_get_drvdata(pci_dev);
+       struct ns83820 *dev = PRIV(ndev); /* ok even if NULL */
 
-       if (!dev)                       /* paranoia */
+       if (!ndev)                      /* paranoia */
                return;
 
        writel(0, dev->base + IMR);     /* paranoia */
        writel(0, dev->base + IER);
        readl(dev->base + IER);
 
-       unregister_netdev(&dev->net_dev);
-       free_irq(dev->pci_dev->irq, dev);
+       unregister_netdev(ndev);
+       free_irq(dev->pci_dev->irq, ndev);
        iounmap(dev->base);
        pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC,
                        dev->tx_descs, dev->tx_phy_descs);
        pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC,
                        dev->rx_info.descs, dev->rx_info.phy_descs);
        pci_disable_device(dev->pci_dev);
-       free_netdev(&dev->net_dev);
+       free_netdev(ndev);
        pci_set_drvdata(pci_dev, NULL);
 }
 
index 08124c5..afb0d29 100644 (file)
@@ -94,8 +94,8 @@ static int __init oaknet_init(void)
 {
        register int i;
        int reg0, regd;
-       int ret;
-       struct net_device tmp, *dev = NULL;
+       int ret = -ENOMEM;
+       struct net_device *dev;
 #if 0
        unsigned long ioaddr = OAKNET_IO_BASE; 
 #else
@@ -105,17 +105,14 @@ static int __init oaknet_init(void)
 
        if (!ioaddr)
                return -ENOMEM;
-       /*
-        * This MUST happen here because of the nic_* macros
-        * which have an implicit dependency on dev->base_addr.
-        */
 
-       tmp.base_addr = ioaddr;
-       dev = &tmp;
+       dev = alloc_ei_netdev();
+       if (!dev)
+               goto out_unmap;
 
        ret = -EBUSY;
        if (!request_region(OAKNET_IO_BASE, OAKNET_IO_SIZE, name))
-               goto out_unmap;
+               goto out_dev;
 
        /* Quick register check to see if the device is really there. */
 
@@ -144,17 +141,7 @@ static int __init oaknet_init(void)
                goto out_region;
        }
 
-       /*
-        * We're not using the old-style probing API, so we have to allocate
-        * our own device structure.
-        */
-
-       dev = init_etherdev(NULL, 0);
-       ret = -ENOMEM;
-       if (!dev)
-               goto out_region;
        SET_MODULE_OWNER(dev);
-       oaknet_devs = dev;
 
        /*
         * This controller is on an embedded board, so the base address
@@ -164,14 +151,6 @@ static int __init oaknet_init(void)
        dev->base_addr = ioaddr;
        dev->irq = OAKNET_INT;
 
-       /* Allocate 8390-specific device-private area and fields. */
-
-       ret = -ENOMEM;
-       if (ethdev_init(dev)) {
-               printk(" unable to get memory for dev->priv.\n");
-               goto out_dev;
-       }
-
        /*
         * Disable all chip interrupts for now and ACK all pending
         * interrupts.
@@ -186,7 +165,7 @@ static int __init oaknet_init(void)
        if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) {
                printk("%s: unable to request interrupt %d.\n",
                       dev->name, dev->irq);
-               goto out_priv;
+               goto out_region;
        }
 
        /* Tell the world about what and where we've found. */
@@ -215,15 +194,19 @@ static int __init oaknet_init(void)
        dev->stop = oaknet_close;
 
        NS8390_init(dev, FALSE);
+       ret = register_netdev(dev);
+       if (ret)
+               goto out_irq;
+       
+       oaknet_devs = dev;
+       return 0;
 
-       return (0);
-out_priv:
-       kfree(dev->priv);
-out_dev:
-       unregister_netdev(dev);
-       kfree(dev);
+out_irq;
+       free_irq(dev->irq, dev);
 out_region:
        release_region(OAKNET_IO_BASE, OAKNET_IO_SIZE);
+out_dev:
+       free_netdev(dev);
 out_unmap:
        iounmap(ioaddr);
        return ret;
@@ -662,38 +645,18 @@ oaknet_dma_error(struct net_device *dev, const char *name)
 }
 
 /*
- * Oak Ethernet module load interface.
- */
-static int __init oaknet_init_module (void)
-{
-       if (oaknet_devs != NULL)
-               return (-EBUSY);
-
-       return (oaknet_init());
-}
-
-/*
  * Oak Ethernet module unload interface.
  */
 static void __exit oaknet_cleanup_module (void)
 {
-       if (oaknet_devs == NULL)
-               return;
-
-       if (oaknet_devs->priv != NULL) {
-               int ioaddr = oaknet_devs->base_addr;
-               void *priv = oaknet_devs->priv;
-               free_irq(oaknet_devs->irq, oaknet_devs);
-               release_region(ioaddr, OAKNET_IO_SIZE);
-               iounmap(ioaddr);
-               unregister_netdev(oaknet_dev);
-               free_netdev(priv);
-       }
-
        /* Convert to loop once driver supports multiple devices. */
-       kfree(oaknet_devs);
+       unregister_netdev(oaknet_dev);
+       free_irq(oaknet_devs->irq, oaknet_devs);
+       release_region(oaknet_devs->base_addr, OAKNET_IO_SIZE);
+       iounmap(ioaddr);
+       free_netdev(oaknet_devs);
 }
 
-module_init(oaknet_init_module);
+module_init(oaknet_init);
 module_exit(oaknet_cleanup_module);
 MODULE_LICENSE("GPL");
index b671d8c..28d8b53 100644 (file)
@@ -730,7 +730,7 @@ err_out_free_res:
 #endif
        pci_release_regions (pdev);
 err_out:
-       kfree (dev);
+       free_netdev (dev);
        DPRINTK ("EXIT, returning %d\n", rc);
        return rc;
 }
index 560d2ef..d7adba4 100644 (file)
@@ -362,23 +362,17 @@ static void tc574_detach(dev_link_t *link)
        if (*linkp == NULL)
        return;
 
-       if (link->state & DEV_CONFIG) {
+       if (link->state & DEV_CONFIG)
                tc574_release(link);
-               if (link->state & DEV_STALE_CONFIG)
-                       return;
-       }
 
        if (link->handle)
                pcmcia_deregister_client(link->handle);
 
        /* Unlink device structure, free bits */
        *linkp = link->next;
-       if (link->dev) {
+       if (link->dev)
                unregister_netdev(dev);
-               free_netdev(dev);
-       } else 
-               kfree(dev);
-
+       free_netdev(dev);
 } /* tc574_detach */
 
 /*
@@ -557,21 +551,11 @@ static void tc574_release(dev_link_t *link)
 {
        DEBUG(0, "3c574_release(0x%p)\n", link);
 
-       if (link->open) {
-               DEBUG(1, "3c574_cs: release postponed, '%s' still open\n",
-                         link->dev->dev_name);
-               link->state |= DEV_STALE_CONFIG;
-               return;
-       }
-
        pcmcia_release_configuration(link->handle);
        pcmcia_release_io(link->handle, &link->io);
        pcmcia_release_irq(link->handle, &link->irq);
 
        link->state &= ~DEV_CONFIG;
-
-       if (link->state & DEV_STALE_CONFIG)
-               tc574_detach(link);
 }
 
 /*
@@ -1300,8 +1284,7 @@ static int el3_close(struct net_device *dev)
        link->open--;
        netif_stop_queue(dev);
        del_timer_sync(&lp->media);
-       if (link->state & DEV_STALE_CONFIG)
-               tc574_release(link);
+
        return 0;
 }
 
index 5183bda..5b38165 100644 (file)
@@ -276,23 +276,17 @@ static void tc589_detach(dev_link_t *link)
     if (*linkp == NULL)
        return;
 
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
        tc589_release(link);
-       if (link->state & DEV_STALE_CONFIG)
-           return;
-    }
     
     if (link->handle)
        pcmcia_deregister_client(link->handle);
     
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    if (link->dev) {
+    if (link->dev)
        unregister_netdev(dev);
-       free_netdev(dev);
-    } else
-        kfree(dev);
-    
+    free_netdev(dev);
 } /* tc589_detach */
 
 /*======================================================================
@@ -433,21 +427,11 @@ static void tc589_release(dev_link_t *link)
 {
     DEBUG(0, "3c589_release(0x%p)\n", link);
     
-    if (link->open) {
-       DEBUG(1, "3c589_cs: release postponed, '%s' still open\n",
-             link->dev->dev_name);
-       link->state |= DEV_STALE_CONFIG;
-       return;
-    }
-    
     pcmcia_release_configuration(link->handle);
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
     
     link->state &= ~DEV_CONFIG;
-
-    if (link->state & DEV_STALE_CONFIG)
-           tc589_detach(link);
 }
 
 /*======================================================================
@@ -1076,8 +1060,6 @@ static int el3_close(struct net_device *dev)
     link->open--;
     netif_stop_queue(dev);
     del_timer_sync(&lp->media);
-    if (link->state & DEV_STALE_CONFIG)
-            tc589_release(link);
     
     return 0;
 }
index 4c99ae6..8ef57bd 100644 (file)
@@ -119,7 +119,7 @@ static void axnet_detach(dev_link_t *);
 static dev_info_t dev_info = "axnet_cs";
 static dev_link_t *dev_list;
 
-static int axdev_init(struct net_device *dev);
+static void axdev_setup(struct net_device *dev);
 static void AX88190_init(struct net_device *dev, int startp);
 static int ax_open(struct net_device *dev);
 static int ax_close(struct net_device *dev);
@@ -128,7 +128,6 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 /*====================================================================*/
 
 typedef struct axnet_dev_t {
-    struct net_device  dev;    /* so &dev == &axnet_dev_t */
     dev_link_t         link;
     dev_node_t         node;
     caddr_t            base;
@@ -140,16 +139,10 @@ typedef struct axnet_dev_t {
     int                        flags;
 } axnet_dev_t;
 
-/*======================================================================
-
-    We never need to do anything when a axnet device is "initialized"
-    by the net software, because we only register already-found cards.
-
-======================================================================*/
-
-static int axnet_init(struct net_device *dev)
+static inline axnet_dev_t *PRIV(struct net_device *dev)
 {
-    return 0;
+       void *p = (char *)netdev_priv(dev) + sizeof(struct ei_device);
+       return p;
 }
 
 /*======================================================================
@@ -170,12 +163,15 @@ static dev_link_t *axnet_attach(void)
 
     DEBUG(0, "axnet_attach()\n");
 
-    /* Create new ethernet device */
-    info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
-    memset(info, 0, sizeof(*info));
-    link = &info->link; dev = &info->dev;
-    link->priv = info;
+    dev = alloc_netdev(sizeof(struct ei_device) + sizeof(axnet_dev_t),
+                       "eth%d", axdev_setup);
+
+    if (!dev)
+       return NULL;
+
+    info = PRIV(dev);
+    link = &info->link;
+    link->priv = dev;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
     if (irq_list[0] == -1)
@@ -186,8 +182,6 @@ static dev_link_t *axnet_attach(void)
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    axdev_init(dev);
-    dev->init = &axnet_init;
     dev->open = &axnet_open;
     dev->stop = &axnet_close;
     dev->do_ioctl = &axnet_ioctl;
@@ -226,7 +220,7 @@ static dev_link_t *axnet_attach(void)
 
 static void axnet_detach(dev_link_t *link)
 {
-    axnet_dev_t *info = link->priv;
+    struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
     DEBUG(0, "axnet_detach(0x%p)\n", link);
@@ -237,23 +231,17 @@ static void axnet_detach(dev_link_t *link)
     if (*linkp == NULL)
        return;
 
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
        axnet_release(link);
-       if (link->state & DEV_STALE_CONFIG)
-           return;
-    }
 
     if (link->handle)
        pcmcia_deregister_client(link->handle);
 
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    if (link->dev) {
-       unregister_netdev(&info->dev);
-       free_netdev(&info->dev);
-    } else
-       kfree(info);
-
+    if (link->dev)
+       unregister_netdev(dev);
+    free_netdev(dev);
 } /* axnet_detach */
 
 /*======================================================================
@@ -349,8 +337,8 @@ static int try_io_port(dev_link_t *link)
 static void axnet_config(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
-    axnet_dev_t *info = link->priv;
-    struct net_device *dev = &info->dev;
+    struct net_device *dev = link->priv;
+    axnet_dev_t *info = PRIV(dev);
     tuple_t tuple;
     cisparse_t parse;
     int i, j, last_ret, last_fn;
@@ -425,15 +413,10 @@ static void axnet_config(dev_link_t *link)
     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
-    if (register_netdev(dev) != 0) {
-       printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
-       goto failed;
-    }
 
     if (!get_prom(link)) {
        printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
        printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n");
-       unregister_netdev(dev);
        goto failed;
     }
 
@@ -448,7 +431,6 @@ static void axnet_config(dev_link_t *link)
     ei_status.block_output = &block_output;
 
     strcpy(info->node.dev_name, dev->name);
-    link->dev = &info->node;
 
     if (inb(dev->base_addr + AXNET_TEST) != 0)
        info->flags |= IS_AX88790;
@@ -487,6 +469,12 @@ static void axnet_config(dev_link_t *link)
        printk(KERN_NOTICE "  No MII transceivers found!\n");
     }
 
+    if (register_netdev(dev) != 0) {
+       printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
+       goto failed;
+    }
+
+    link->dev = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
     return;
 
@@ -510,21 +498,11 @@ static void axnet_release(dev_link_t *link)
 {
     DEBUG(0, "axnet_release(0x%p)\n", link);
 
-    if (link->open) {
-       DEBUG(1, "axnet_cs: release postponed, '%s' still open\n",
-             ((axnet_dev_t *)(link->priv))->node.dev_name);
-       link->state |= DEV_STALE_CONFIG;
-       return;
-    }
-
     pcmcia_release_configuration(link->handle);
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
 
     link->state &= ~DEV_CONFIG;
-
-    if (link->state & DEV_STALE_CONFIG)
-           axnet_detach(link);
 }
 
 /*======================================================================
@@ -540,7 +518,7 @@ static int axnet_event(event_t event, int priority,
                       event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    axnet_dev_t *info = link->priv;
+    struct net_device *dev = link->priv;
 
     DEBUG(2, "axnet_event(0x%06x)\n", event);
 
@@ -548,7 +526,7 @@ static int axnet_event(event_t event, int priority,
     case CS_EVENT_CARD_REMOVAL:
        link->state &= ~DEV_PRESENT;
        if (link->state & DEV_CONFIG) {
-           netif_device_detach(&info->dev);
+           netif_device_detach(dev);
            axnet_release(link);
        }
        break;
@@ -562,7 +540,7 @@ static int axnet_event(event_t event, int priority,
     case CS_EVENT_RESET_PHYSICAL:
        if (link->state & DEV_CONFIG) {
            if (link->open)
-               netif_device_detach(&info->dev);
+               netif_device_detach(dev);
            pcmcia_release_configuration(link->handle);
        }
        break;
@@ -573,9 +551,9 @@ static int axnet_event(event_t event, int priority,
        if (link->state & DEV_CONFIG) {
            pcmcia_request_configuration(link->handle, &link->conf);
            if (link->open) {
-               axnet_reset_8390(&info->dev);
-               AX88190_init(&info->dev, 1);
-               netif_device_attach(&info->dev);
+               axnet_reset_8390(dev);
+               AX88190_init(dev, 1);
+               netif_device_attach(dev);
            }
        }
        break;
@@ -645,7 +623,7 @@ static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value)
 
 static int axnet_open(struct net_device *dev)
 {
-    axnet_dev_t *info = (axnet_dev_t *)dev;
+    axnet_dev_t *info = PRIV(dev);
     dev_link_t *link = &info->link;
     
     DEBUG(2, "axnet_open('%s')\n", dev->name);
@@ -660,7 +638,7 @@ static int axnet_open(struct net_device *dev)
     info->link_status = 0x00;
     init_timer(&info->watchdog);
     info->watchdog.function = &ei_watchdog;
-    info->watchdog.data = (u_long)info;
+    info->watchdog.data = (u_long)dev;
     info->watchdog.expires = jiffies + HZ;
     add_timer(&info->watchdog);
 
@@ -671,7 +649,7 @@ static int axnet_open(struct net_device *dev)
 
 static int axnet_close(struct net_device *dev)
 {
-    axnet_dev_t *info = (axnet_dev_t *)dev;
+    axnet_dev_t *info = PRIV(dev);
     dev_link_t *link = &info->link;
 
     DEBUG(2, "axnet_close('%s')\n", dev->name);
@@ -682,8 +660,6 @@ static int axnet_close(struct net_device *dev)
     link->open--;
     netif_stop_queue(dev);
     del_timer_sync(&info->watchdog);
-    if (link->state & DEV_STALE_CONFIG)
-       axnet_release(link);
 
     return 0;
 } /* axnet_close */
@@ -723,15 +699,15 @@ static void axnet_reset_8390(struct net_device *dev)
 
 static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
 {
-    axnet_dev_t *info = dev_id;
-    info->stale = 0;
+    struct net_device *dev = dev_id;
+    PRIV(dev)->stale = 0;
     return ax_interrupt(irq, dev_id, regs);
 }
 
 static void ei_watchdog(u_long arg)
 {
-    axnet_dev_t *info = (axnet_dev_t *)(arg);
-    struct net_device *dev = &info->dev;
+    struct net_device *dev = (struct net_device *)(arg);
+    axnet_dev_t *info = PRIV(dev);
     ioaddr_t nic_base = dev->base_addr;
     ioaddr_t mii_addr = nic_base + AXNET_MII_EEP;
     u_short link;
@@ -801,7 +777,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-    axnet_dev_t *info = (axnet_dev_t *)dev;
+    axnet_dev_t *info = PRIV(dev);
     u16 *data = (u16 *)&rq->ifr_data;
     ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
     switch (cmd) {
@@ -1050,14 +1026,7 @@ static void do_set_multicast_list(struct net_device *dev);
 static int ax_open(struct net_device *dev)
 {
        unsigned long flags;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
-
-       /* This can't happen unless somebody forgot to call axdev_init(). */
-       if (ei_local == NULL) 
-       {
-               printk(KERN_EMERG "%s: ax_open passed a non-existent device!\n", dev->name);
-               return -ENXIO;
-       }
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 
 #ifdef HAVE_TX_TIMEOUT
        /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
@@ -1083,7 +1052,7 @@ static int ax_open(struct net_device *dev)
        return 0;
 }
 
-#define dev_lock(dev) (((struct ei_device *)(dev)->priv)->page_lock)
+#define dev_lock(dev) (((struct ei_device *)netdev_priv(dev))->page_lock)
 
 /**
  * ax_close - shut down network device
@@ -1117,7 +1086,7 @@ int ax_close(struct net_device *dev)
 void ei_tx_timeout(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int txsr, isr, tickssofar = jiffies - dev->trans_start;
        unsigned long flags;
 
@@ -1163,7 +1132,7 @@ void ei_tx_timeout(struct net_device *dev)
 static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int length, send_length, output_page;
        unsigned long flags;
        u8 packet[ETH_ZLEN];
@@ -1309,7 +1278,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        }
     
        e8390_base = dev->base_addr;
-       ei_local = (struct ei_device *) dev->priv;
+       ei_local = (struct ei_device *) netdev_priv(dev);
 
        /*
         *      Protect the irq test too.
@@ -1421,7 +1390,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 static void ei_tx_err(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned char txsr = inb_p(e8390_base+EN0_TSR);
        unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
 
@@ -1462,7 +1431,7 @@ static void ei_tx_err(struct net_device *dev)
 static void ei_tx_intr(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int status = inb(e8390_base + EN0_TSR);
     
        /*
@@ -1543,7 +1512,7 @@ static void ei_tx_intr(struct net_device *dev)
 static void ei_receive(struct net_device *dev)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned char rxing_page, this_frame, next_frame;
        unsigned short current_offset;
        int rx_pkt_count = 0;
@@ -1663,7 +1632,7 @@ static void ei_rx_overrun(struct net_device *dev)
        axnet_dev_t *info = (axnet_dev_t *)dev;
        long e8390_base = dev->base_addr;
        unsigned char was_txing, must_resend = 0;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
     
        /*
         * Record whether a Tx was in progress and then issue the
@@ -1730,7 +1699,7 @@ static void ei_rx_overrun(struct net_device *dev)
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned long flags;
     
        /* If the card is stopped, just return the present stats. */
@@ -1783,39 +1752,30 @@ static void set_multicast_list(struct net_device *dev)
 }      
 
 /**
- * axdev_init - init rest of 8390 device struct
+ * axdev_setup - init rest of 8390 device struct
  * @dev: network device structure to init
  *
  * Initialize the rest of the 8390 device structure.  Do NOT __init
  * this, as it is used by 8390 based modular drivers too.
  */
 
-static int axdev_init(struct net_device *dev)
+static void axdev_setup(struct net_device *dev)
 {
+       struct ei_device *ei_local;
        if (ei_debug > 1)
                printk(version_8390);
     
        SET_MODULE_OWNER(dev);
 
-       if (dev->priv == NULL) 
-       {
-               struct ei_device *ei_local;
                
-               dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
-               if (dev->priv == NULL)
-                       return -ENOMEM;
-               memset(dev->priv, 0, sizeof(struct ei_device));
-               ei_local = (struct ei_device *)dev->priv;
-               spin_lock_init(&ei_local->page_lock);
-       }
+       ei_local = (struct ei_device *)netdev_priv(dev);
+       spin_lock_init(&ei_local->page_lock);
     
        dev->hard_start_xmit = &ei_start_xmit;
        dev->get_stats  = get_stats;
        dev->set_multicast_list = &set_multicast_list;
 
        ether_setup(dev);
-        
-       return 0;
 }
 
 /* This page of functions should be 8390 generic */
@@ -1831,9 +1791,9 @@ static int axdev_init(struct net_device *dev)
 
 static void AX88190_init(struct net_device *dev, int startp)
 {
-       axnet_dev_t *info = (axnet_dev_t *)dev;
+       axnet_dev_t *info = PRIV(dev);
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        int i;
        int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
     
@@ -1902,7 +1862,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
                                                                int start_page)
 {
        long e8390_base = dev->base_addr;
-       struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) dev->priv;
+       struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
     
        if (inb_p(e8390_base) & E8390_TRANS) 
        {
index bdba5c9..0a2bf40 100644 (file)
@@ -145,20 +145,6 @@ typedef struct com20020_dev_t {
     dev_node_t          node;
 } com20020_dev_t;
 
-static void com20020_setup(struct net_device *dev)
-{
-       struct arcnet_local *lp = dev->priv;
-
-       lp->timeout = timeout;
-       lp->backplane = backplane;
-       lp->clockp = clockp;
-       lp->clockm = clockm & 3;
-       lp->hw.owner = THIS_MODULE;
-
-       /* fill in our module parameters as defaults */
-       dev->dev_addr[0] = node;
-}
-
 /*======================================================================
 
     com20020_attach() creates an "instance" of the driver, allocating
@@ -187,14 +173,21 @@ static dev_link_t *com20020_attach(void)
     if (!info)
        goto fail_alloc_info;
 
-    dev = alloc_netdev(sizeof(struct arcnet_local), "arc%d",
-                      com20020_setup);
+    dev = alloc_arcdev("");
     if (!dev)
        goto fail_alloc_dev;
 
     memset(info, 0, sizeof(struct com20020_dev_t));
     memset(link, 0, sizeof(struct dev_link_t));
     lp = dev->priv;
+    lp->timeout = timeout;
+    lp->backplane = backplane;
+    lp->clockp = clockp;
+    lp->clockm = clockm & 3;
+    lp->hw.owner = THIS_MODULE;
+
+    /* fill in our module parameters as defaults */
+    dev->dev_addr[0] = node;
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts1 = 16;
@@ -270,11 +263,8 @@ static void com20020_detach(dev_link_t *link)
 
     dev = info->dev;
 
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
         com20020_release(link);
-        if (link->state & DEV_STALE_CONFIG)
-            return;
-    }
 
     if (link->handle)
         pcmcia_deregister_client(link->handle);
@@ -293,6 +283,8 @@ static void com20020_detach(dev_link_t *link)
 
                if (netif_running(dev))
                    dev->stop(dev);
+
+               unregister_netdev(dev);
            
                /*
                 * this is necessary because we register our IRQ separately
@@ -300,10 +292,7 @@ static void com20020_detach(dev_link_t *link)
                 */
                if (dev->irq)
                    free_irq(dev->irq, dev);
-               
                /* ...but I/O ports are done automatically by card services */
-               
-               unregister_netdev(dev);
            }
            
            DEBUG(1,"kfree...\n");
@@ -447,21 +436,11 @@ static void com20020_release(dev_link_t *link)
 
     DEBUG(0, "com20020_release(0x%p)\n", link);
 
-    if (link->open) {
-       DEBUG(1,"postpone...\n");
-       DEBUG(1, "com20020_cs: release postponed, device stll open\n");
-        link->state |= DEV_STALE_CONFIG;
-        return;
-    }
-
     pcmcia_release_configuration(link->handle);
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
 
     link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
-
-    if (link->state & DEV_STALE_CONFIG)
-           com20020_detach(link);
 }
 
 /*======================================================================
index c594ef4..b3d3e2c 100644 (file)
@@ -332,11 +332,8 @@ static void fmvj18x_detach(dev_link_t *link)
     if (*linkp == NULL)
        return;
 
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
        fmvj18x_release(link);
-       if (link->state & DEV_STALE_CONFIG)
-           return;
-    }
 
     /* Break the link with Card Services */
     if (link->handle)
@@ -344,12 +341,9 @@ static void fmvj18x_detach(dev_link_t *link)
     
     /* Unlink device structure, free pieces */
     *linkp = link->next;
-    if (link->dev) {
+    if (link->dev)
        unregister_netdev(dev);
-       free_netdev(dev);
-    } else
-       kfree(dev);
-    
+    free_netdev(dev);
 } /* fmvj18x_detach */
 
 /*====================================================================*/
@@ -723,17 +717,6 @@ static void fmvj18x_release(dev_link_t *link)
 
     DEBUG(0, "fmvj18x_release(0x%p)\n", link);
 
-    /*
-       If the device is currently in use, we won't release until it
-       is actually closed.
-    */
-    if (link->open) {
-       DEBUG(1, "fmvj18x_cs: release postponed, '%s' "
-             "still open\n", link->dev->dev_name);
-       link->state |= DEV_STALE_CONFIG;
-       return;
-    }
-
     /* Don't bother checking to see if these succeed or not */
     pcmcia_release_window(link->win);
     pcmcia_release_configuration(link->handle);
@@ -741,9 +724,6 @@ static void fmvj18x_release(dev_link_t *link)
     pcmcia_release_irq(link->handle, &link->irq);
     
     link->state &= ~DEV_CONFIG;
-
-    if (link->state & DEV_STALE_CONFIG)
-           fmvj18x_detach(link);
 }
 
 /*====================================================================*/
@@ -1251,8 +1231,6 @@ static int fjn_close(struct net_device *dev)
        outb(INTR_OFF, ioaddr + LAN_CTRL);
 
     link->open--;
-    if (link->state & DEV_STALE_CONFIG)
-           fmvj18x_release(link);
 
     return 0;
 } /* fjn_close */
index 7a0c9c7..a5047f7 100644 (file)
@@ -125,8 +125,7 @@ static void ibmtr_detach(dev_link_t *);
 
 static dev_link_t *dev_list;
 
-extern int ibmtr_probe(struct net_device *dev);
-extern int trdev_init(struct net_device *dev);
+extern int ibmtr_probe_card(struct net_device *dev);
 extern irqreturn_t tok_interrupt (int irq, void *dev_id, struct pt_regs *regs);
 
 /*====================================================================*/
@@ -199,7 +198,6 @@ static dev_link_t *ibmtr_attach(void)
 
     link->irq.Instance = info->dev = dev;
     
-    dev->init = &ibmtr_probe;
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
     /* Register with Card Services */
@@ -253,22 +251,22 @@ static void ibmtr_detach(dev_link_t *link)
         return;
 
     dev = info->dev;
+
+    if (link->dev)
+       unregister_netdev(dev);
+
     {
        struct tok_info *ti = (struct tok_info *)dev->priv;
        del_timer_sync(&(ti->tr_timer));
     }
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
         ibmtr_release(link);
-        if (link->state & DEV_STALE_CONFIG)
-            return;
-    }
 
     if (link->handle)
         pcmcia_deregister_client(link->handle);
 
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    unregister_netdev(dev);
     free_netdev(dev);
     kfree(info); 
 } /* ibmtr_detach */
@@ -369,7 +367,7 @@ static void ibmtr_config(dev_link_t *link)
         Adapters Technical Reference"  SC30-3585 for this info.  */
     ibmtr_hw_setup(dev, mmiobase);
 
-    i = register_netdev(dev);
+    i = ibmtr_probe_card(dev);
     
     if (i != 0) {
        printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
@@ -410,13 +408,6 @@ static void ibmtr_release(dev_link_t *link)
 
     DEBUG(0, "ibmtr_release(0x%p)\n", link);
 
-    if (link->open) {
-       DEBUG(1, "ibmtr_cs: release postponed, '%s' "
-             "still open\n", info->node.dev_name);
-        link->state |= DEV_STALE_CONFIG;
-        return;
-    }
-
     pcmcia_release_configuration(link->handle);
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
@@ -428,9 +419,6 @@ static void ibmtr_release(dev_link_t *link)
     }
 
     link->state &= ~DEV_CONFIG;
-
-    if (link->state & DEV_STALE_CONFIG)
-           ibmtr_detach(link);
 }
 
 /*======================================================================
@@ -482,7 +470,7 @@ static int ibmtr_event(event_t event, int priority,
         if (link->state & DEV_CONFIG) {
             pcmcia_request_configuration(link->handle, &link->conf);
             if (link->open) {
-               (dev->init)(dev);
+               ibmtr_probe(dev);       /* really? */
                netif_device_attach(dev);
             }
         }
index a1f6e86..e76bdf1 100644 (file)
@@ -551,23 +551,17 @@ static void nmclan_detach(dev_link_t *link)
     if (*linkp == NULL)
        return;
 
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
        nmclan_release(link);
-       if (link->state & DEV_STALE_CONFIG)
-           return;
-    }
 
     if (link->handle)
        pcmcia_deregister_client(link->handle);
 
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    if (link->dev) {
+    if (link->dev)
        unregister_netdev(dev);
-       free_netdev(dev);
-    } else
-       kfree(dev);
-
+    free_netdev(dev);
 } /* nmclan_detach */
 
 /* ----------------------------------------------------------------------------
@@ -812,21 +806,11 @@ static void nmclan_release(dev_link_t *link)
 
   DEBUG(0, "nmclan_release(0x%p)\n", link);
 
-  if (link->open) {
-    DEBUG(1, "nmclan_cs: release postponed, '%s' "
-         "still open\n", link->dev->dev_name);
-    link->state |= DEV_STALE_CONFIG;
-    return;
-  }
-
   pcmcia_release_configuration(link->handle);
   pcmcia_release_io(link->handle, &link->io);
   pcmcia_release_irq(link->handle, &link->irq);
 
   link->state &= ~DEV_CONFIG;
-
-  if (link->state & DEV_STALE_CONFIG)
-         nmclan_detach(link);
 }
 
 /* ----------------------------------------------------------------------------
@@ -993,8 +977,6 @@ static int mace_close(struct net_device *dev)
 
   link->open--;
   netif_stop_queue(dev);
-  if (link->state & DEV_STALE_CONFIG)
-         nmclan_release(link);
 
   return 0;
 } /* mace_close */
index 9d7c0b5..ca2fc02 100644 (file)
@@ -224,7 +224,6 @@ static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII };
 static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
 
 typedef struct pcnet_dev_t {
-    struct net_device  dev;    /* so &dev == &pcnet_dev_t */
     dev_link_t         link;
     dev_node_t         node;
     u_int              flags;
@@ -237,16 +236,10 @@ typedef struct pcnet_dev_t {
     u_long             mii_reset;
 } pcnet_dev_t;
 
-/*======================================================================
-
-    We never need to do anything when a pcnet device is "initialized"
-    by the net software, because we only register already-found cards.
-
-======================================================================*/
-
-static int pcnet_init(struct net_device *dev)
+static inline pcnet_dev_t *PRIV(struct net_device *dev)
 {
-    return 0;
+       char *p = netdev_priv(dev);
+       return (pcnet_dev_t *)(p + sizeof(struct ei_device));
 }
 
 /*======================================================================
@@ -268,11 +261,11 @@ static dev_link_t *pcnet_attach(void)
     DEBUG(0, "pcnet_attach()\n");
 
     /* Create new ethernet device */
-    info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
-    memset(info, 0, sizeof(*info));
-    link = &info->link; dev = &info->dev;
-    link->priv = info;
+    dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
+    if (!dev) return NULL;
+    info = PRIV(dev);
+    link = &info->link;
+    link->priv = dev;
 
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
@@ -284,9 +277,7 @@ static dev_link_t *pcnet_attach(void)
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    ethdev_init(dev);
     SET_MODULE_OWNER(dev);
-    dev->init = &pcnet_init;
     dev->open = &pcnet_open;
     dev->stop = &pcnet_close;
     dev->set_config = &set_config;
@@ -324,7 +315,7 @@ static dev_link_t *pcnet_attach(void)
 
 static void pcnet_detach(dev_link_t *link)
 {
-    pcnet_dev_t *info = link->priv;
+    struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
     DEBUG(0, "pcnet_detach(0x%p)\n", link);
@@ -335,23 +326,17 @@ static void pcnet_detach(dev_link_t *link)
     if (*linkp == NULL)
        return;
 
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
        pcnet_release(link);
-       if (link->state & DEV_STALE_CONFIG)
-           return;
-    }
 
     if (link->handle)
        pcmcia_deregister_client(link->handle);
 
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    if (link->dev) {
-       unregister_netdev(&info->dev);
-       free_netdev(&info->dev);
-    } else
-        kfree(info);
-
+    if (link->dev)
+       unregister_netdev(dev);
+    free_netdev(dev);
 } /* pcnet_detach */
 
 /*======================================================================
@@ -579,8 +564,8 @@ static int try_io_port(dev_link_t *link)
 static void pcnet_config(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
-    pcnet_dev_t *info = link->priv;
-    struct net_device *dev = &info->dev;
+    struct net_device *dev = link->priv;
+    pcnet_dev_t *info = PRIV(dev);
     tuple_t tuple;
     cisparse_t parse;
     int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
@@ -782,17 +767,10 @@ failed:
 
 static void pcnet_release(dev_link_t *link)
 {
-    pcnet_dev_t *info = link->priv;
+    pcnet_dev_t *info = PRIV(link->priv);
 
     DEBUG(0, "pcnet_release(0x%p)\n", link);
 
-    if (link->open) {
-       DEBUG(1, "pcnet_cs: release postponed, '%s' still open\n",
-             info->node.dev_name);
-       link->state |= DEV_STALE_CONFIG;
-       return;
-    }
-
     if (info->flags & USE_SHMEM) {
        iounmap(info->base);
        pcmcia_release_window(link->win);
@@ -802,9 +780,6 @@ static void pcnet_release(dev_link_t *link)
     pcmcia_release_irq(link->handle, &link->irq);
 
     link->state &= ~DEV_CONFIG;
-
-    if (link->state & DEV_STALE_CONFIG)
-           pcnet_detach(link);
 }
 
 /*======================================================================
@@ -820,7 +795,7 @@ static int pcnet_event(event_t event, int priority,
                       event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    pcnet_dev_t *info = link->priv;
+    struct net_device *dev = link->priv;
 
     DEBUG(2, "pcnet_event(0x%06x)\n", event);
 
@@ -828,7 +803,7 @@ static int pcnet_event(event_t event, int priority,
     case CS_EVENT_CARD_REMOVAL:
        link->state &= ~DEV_PRESENT;
        if (link->state & DEV_CONFIG) {
-           netif_device_detach(&info->dev);
+           netif_device_detach(dev);
            pcnet_release(link);
        }
        break;
@@ -842,7 +817,7 @@ static int pcnet_event(event_t event, int priority,
     case CS_EVENT_RESET_PHYSICAL:
        if (link->state & DEV_CONFIG) {
            if (link->open)
-               netif_device_detach(&info->dev);
+               netif_device_detach(dev);
            pcmcia_release_configuration(link->handle);
        }
        break;
@@ -853,9 +828,9 @@ static int pcnet_event(event_t event, int priority,
        if (link->state & DEV_CONFIG) {
            pcmcia_request_configuration(link->handle, &link->conf);
            if (link->open) {
-               pcnet_reset_8390(&info->dev);
-               NS8390_init(&info->dev, 1);
-               netif_device_attach(&info->dev);
+               pcnet_reset_8390(dev);
+               NS8390_init(dev, 1);
+               netif_device_attach(dev);
            }
        }
        break;
@@ -1035,7 +1010,7 @@ static void write_asic(ioaddr_t ioaddr, int location, short asic_data)
 static void set_misc_reg(struct net_device *dev)
 {
     ioaddr_t nic_base = dev->base_addr;
-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
+    pcnet_dev_t *info = PRIV(dev);
     u_char tmp;
     
     if (info->flags & HAS_MISC_REG) {
@@ -1065,7 +1040,7 @@ static void set_misc_reg(struct net_device *dev)
 
 static void mii_phy_probe(struct net_device *dev)
 {
-    pcnet_dev_t *info = (pcnet_dev_t *)dev;    
+    pcnet_dev_t *info = PRIV(dev);
     ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
     int i;
     u_int tmp, phyid;
@@ -1089,7 +1064,7 @@ static void mii_phy_probe(struct net_device *dev)
 
 static int pcnet_open(struct net_device *dev)
 {
-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
+    pcnet_dev_t *info = PRIV(dev);
     dev_link_t *link = &info->link;
     
     DEBUG(2, "pcnet_open('%s')\n", dev->name);
@@ -1106,7 +1081,7 @@ static int pcnet_open(struct net_device *dev)
     info->link_status = 0x00;
     init_timer(&info->watchdog);
     info->watchdog.function = &ei_watchdog;
-    info->watchdog.data = (u_long)info;
+    info->watchdog.data = (u_long)dev;
     info->watchdog.expires = jiffies + HZ;
     add_timer(&info->watchdog);
 
@@ -1117,7 +1092,7 @@ static int pcnet_open(struct net_device *dev)
 
 static int pcnet_close(struct net_device *dev)
 {
-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
+    pcnet_dev_t *info = PRIV(dev);
     dev_link_t *link = &info->link;
 
     DEBUG(2, "pcnet_close('%s')\n", dev->name);
@@ -1128,8 +1103,6 @@ static int pcnet_close(struct net_device *dev)
     link->open--;
     netif_stop_queue(dev);
     del_timer_sync(&info->watchdog);
-    if (link->state & DEV_STALE_CONFIG)
-           pcnet_release(link);
 
     return 0;
 } /* pcnet_close */
@@ -1170,7 +1143,7 @@ static void pcnet_reset_8390(struct net_device *dev)
 
 static int set_config(struct net_device *dev, struct ifmap *map)
 {
-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
+    pcnet_dev_t *info = PRIV(dev);
     if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
        if (!(info->flags & HAS_MISC_REG))
            return -EOPNOTSUPP;
@@ -1188,7 +1161,8 @@ static int set_config(struct net_device *dev, struct ifmap *map)
 
 static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
 {
-    pcnet_dev_t *info = dev_id;
+    struct net_device *dev = dev_id;
+    pcnet_dev_t *info = PRIV(dev);
     info->stale = 0;
     ei_interrupt(irq, dev_id, regs);
     /* FIXME! Was it really ours? */
@@ -1197,8 +1171,8 @@ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
 
 static void ei_watchdog(u_long arg)
 {
-    pcnet_dev_t *info = (pcnet_dev_t *)(arg);
-    struct net_device *dev = &info->dev;
+    struct net_device *dev = (struct net_device *)arg;
+    pcnet_dev_t *info = PRIV(dev);
     ioaddr_t nic_base = dev->base_addr;
     ioaddr_t mii_addr = nic_base + DLINK_GPIO;
     u_short link;
@@ -1301,7 +1275,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
+    pcnet_dev_t *info = PRIV(dev);
     u16 *data = (u16 *)&rq->ifr_data;
     ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
     switch (cmd) {
@@ -1412,7 +1386,7 @@ static void dma_block_output(struct net_device *dev, int count,
                             const u_char *buf, const int start_page)
 {
     ioaddr_t nic_base = dev->base_addr;
-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
+    pcnet_dev_t *info = PRIV(dev);
 #ifdef PCMCIA_DEBUG
     int retries = 0;
 #endif
@@ -1598,7 +1572,7 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,
                              int stop_pg, int cm_offset)
 {
     struct net_device *dev = link->priv;
-    pcnet_dev_t *info = link->priv;
+    pcnet_dev_t *info = PRIV(dev);
     win_req_t req;
     memreq_t mem;
     int i, window_size, offset, last_ret, last_fn;
index 1f34064..2ffb11e 100644 (file)
@@ -411,23 +411,17 @@ static void smc91c92_detach(dev_link_t *link)
     if (*linkp == NULL)
        return;
 
-    if (link->state & DEV_CONFIG) {
+    if (link->state & DEV_CONFIG)
        smc91c92_release(link);
-       if (link->state & DEV_STALE_CONFIG)
-           return;
-    }
 
     if (link->handle)
        pcmcia_deregister_client(link->handle);
 
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    if (link->dev) {
+    if (link->dev)
        unregister_netdev(dev);
-       free_netdev(dev);
-    } else
-       kfree(dev);
-
+    free_netdev(dev);
 } /* smc91c92_detach */
 
 /*====================================================================*/
@@ -1070,13 +1064,6 @@ static void smc91c92_release(dev_link_t *link)
 
     DEBUG(0, "smc91c92_release(0x%p)\n", link);
 
-    if (link->open) {
-       DEBUG(1, "smc91c92_cs: release postponed, '%s' still open\n",
-             link->dev->dev_name);
-       link->state |= DEV_STALE_CONFIG;
-       return;
-    }
-
     pcmcia_release_configuration(link->handle);
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
@@ -1088,9 +1075,6 @@ static void smc91c92_release(dev_link_t *link)
     }
 
     link->state &= ~DEV_CONFIG;
-
-    if (link->state & DEV_STALE_CONFIG)
-           smc91c92_detach(link);
 }
 
 /*======================================================================
@@ -1316,8 +1300,6 @@ static int smc_close(struct net_device *dev)
 
     link->open--;
     del_timer_sync(&smc->media);
-    if (link->state & DEV_STALE_CONFIG)
-           smc91c92_release(link);
 
     return 0;
 } /* smc_close */
index 1abaddb..f29b17c 100644 (file)
@@ -683,12 +683,9 @@ xirc2ps_detach(dev_link_t * link)
 
     /* Unlink device structure, free it */
     *linkp = link->next;
-    if (link->dev) {
+    if (link->dev)
        unregister_netdev(dev);
-       free_netdev(dev);
-    } else
-       kfree(dev);
-
+    free_netdev(dev);
 } /* xirc2ps_detach */
 
 /****************
index 722ffe0..8b82ba9 100644 (file)
@@ -808,11 +808,12 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
     dev->tx_timeout = pcnet32_tx_timeout;
     dev->watchdog_timeo = (5*HZ);
 
+    /* Fill in the generic fields of the device structure. */
+    if (register_netdev(dev))
+       goto err_free_consistent;
+
     lp->next = pcnet32_dev;
     pcnet32_dev = dev;
-
-    /* Fill in the generic fields of the device structure. */
-    register_netdev(dev);
     printk(KERN_INFO "%s: registered as %s\n",dev->name, lp->name);
     cards_found++;
     return 0;
index e4cd7b0..64a1df7 100644 (file)
@@ -277,19 +277,11 @@ inline static unsigned char read_status (struct net_device *dev)
    then calls us here.
 
    */
-static int
+static void
 plip_init_netdev(struct net_device *dev)
 {
        struct net_local *nl = dev->priv;
 
-       printk(KERN_INFO "%s", version);
-       if (dev->irq != -1)
-               printk(KERN_INFO "%s: Parallel port at %#3lx, using IRQ %d.\n",
-                      dev->name, dev->base_addr, dev->irq);
-       else
-               printk(KERN_INFO "%s: Parallel port at %#3lx, not using IRQ.\n",
-                      dev->name, dev->base_addr);
-
        /* Then, override parts of it */
        dev->hard_start_xmit     = plip_tx_packet;
        dev->open                = plip_open;
@@ -323,8 +315,6 @@ plip_init_netdev(struct net_device *dev)
                INIT_WORK(&nl->timer, (void (*)(void *))plip_timer_bh, dev);
 
        spin_lock_init(&nl->lock);
-
-       return 0;
 }
 \f
 /* Bottom half handler for the delayed request.
@@ -1282,14 +1272,13 @@ static void plip_attach (struct parport *port)
                }
 
                sprintf(name, "plip%d", unit);
-               dev = alloc_netdev(sizeof(struct net_local), name, 
-                                  ether_setup);
+               dev = alloc_etherdev(sizeof(struct net_local));
                if (!dev) {
                        printk(KERN_ERR "plip: memory squeeze\n");
                        return;
                }
                
-               dev->init = plip_init_netdev;
+               strcpy(dev->name, name);
 
                SET_MODULE_OWNER(dev);
                dev->irq = port->irq;
@@ -1306,17 +1295,35 @@ static void plip_attach (struct parport *port)
 
                if (!nl->pardev) {
                        printk(KERN_ERR "%s: parport_register failed\n", name);
-                       kfree(dev);
+                       goto err_free_dev;
                        return;
                }
 
+               plip_init_netdev(dev);
+
                if (register_netdev(dev)) {
                        printk(KERN_ERR "%s: network register failed\n", name);
-                       kfree(dev);
-               } else {
-                       dev_plip[unit++] = dev;
+                       goto err_parport_unregister;
                }
+
+               printk(KERN_INFO "%s", version);
+               if (dev->irq != -1)
+                       printk(KERN_INFO "%s: Parallel port at %#3lx, "
+                                        "using IRQ %d.\n",
+                                        dev->name, dev->base_addr, dev->irq);
+               else
+                       printk(KERN_INFO "%s: Parallel port at %#3lx, "
+                                        "not using IRQ.\n",
+                                        dev->name, dev->base_addr);
+               dev_plip[unit++] = dev;
        }
+       return;
+
+err_parport_unregister:
+       parport_unregister_device(nl->pardev);
+err_free_dev:
+       free_netdev(dev);
+       return;
 }
 
 /* plip_detach() is called (by the parport code) when a port is
index dc92895..e335aa8 100644 (file)
@@ -917,19 +917,14 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return err;
 }
 
-static int
-ppp_net_init(struct net_device *dev)
+static void ppp_setup(struct net_device *dev)
 {
        dev->hard_header_len = PPP_HDRLEN;
        dev->mtu = PPP_MTU;
-       dev->hard_start_xmit = ppp_start_xmit;
-       dev->get_stats = ppp_net_stats;
-       dev->do_ioctl = ppp_net_ioctl;
        dev->addr_len = 0;
        dev->tx_queue_len = 3;
        dev->type = ARPHRD_PPP;
        dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-       return 0;
 }
 
 /*
@@ -2272,23 +2267,13 @@ ppp_create_interface(int unit, int *retp)
        int i;
 
        ppp = kmalloc(sizeof(struct ppp), GFP_KERNEL);
-       if (ppp == 0)
-               goto err;
-       dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-       if (dev == 0)
-               goto err;
+       if (!ppp)
+               goto out;
+       dev = alloc_netdev(0, "", ppp_setup);
+       if (!dev)
+               goto out1;
        memset(ppp, 0, sizeof(struct ppp));
-       memset(dev, 0, sizeof(struct net_device));
 
-       ret = -EEXIST;
-       down(&all_ppp_sem);
-       if (unit < 0)
-               unit = cardmap_find_first_free(all_ppp_units);
-       else if (cardmap_get(all_ppp_units, unit) != NULL)
-               goto err_unlock;        /* unit already exists */
-
-       /* Initialize the new ppp unit */
-       ppp->file.index = unit;
        ppp->mru = PPP_MRU;
        init_ppp_file(&ppp->file, INTERFACE);
        ppp->file.hdrlen = PPP_HDRLEN - 2;      /* don't count proto bytes */
@@ -2301,20 +2286,29 @@ ppp_create_interface(int unit, int *retp)
        ppp->minseq = -1;
        skb_queue_head_init(&ppp->mrq);
 #endif /* CONFIG_PPP_MULTILINK */
-
        ppp->dev = dev;
-       dev->init = ppp_net_init;
-       sprintf(dev->name, "ppp%d", unit);
        dev->priv = ppp;
-       dev->destructor = free_netdev;
 
-       rtnl_lock();
-       ret = register_netdevice(dev);
-       rtnl_unlock();
+       dev->hard_start_xmit = ppp_start_xmit;
+       dev->get_stats = ppp_net_stats;
+       dev->do_ioctl = ppp_net_ioctl;
+
+       ret = -EEXIST;
+       down(&all_ppp_sem);
+       if (unit < 0)
+               unit = cardmap_find_first_free(all_ppp_units);
+       else if (cardmap_get(all_ppp_units, unit) != NULL)
+               goto out2;      /* unit already exists */
+
+       /* Initialize the new ppp unit */
+       ppp->file.index = unit;
+       sprintf(dev->name, "ppp%d", unit);
+
+       ret = register_netdev(dev);
        if (ret != 0) {
                printk(KERN_ERR "PPP: couldn't register device %s (%d)\n",
                       dev->name, ret);
-               goto err_unlock;
+               goto out2;
        }
 
        atomic_inc(&ppp_unit_count);
@@ -2323,14 +2317,13 @@ ppp_create_interface(int unit, int *retp)
        *retp = 0;
        return ppp;
 
- err_unlock:
+out2:
        up(&all_ppp_sem);
- err:
+       free_netdev(dev);
+out1:
+       kfree(ppp);
+out:
        *retp = ret;
-       if (ppp)
-               kfree(ppp);
-       if (dev)
-               kfree(dev);
        return NULL;
 }
 
@@ -2361,8 +2354,10 @@ static void ppp_shutdown_interface(struct ppp *ppp)
        ppp->dev = 0;
        ppp_unlock(ppp);
        /* This will call dev_close() for us. */
-       if (dev)
+       if (dev) {
                unregister_netdev(dev);
+               free_netdev(dev);
+       }
        cardmap_set(&all_ppp_units, ppp->file.index, NULL);
        ppp->file.dead = 1;
        ppp->owner = NULL;
index 011eaf2..733c729 100644 (file)
@@ -517,7 +517,7 @@ static int pppoe_create(struct socket *sock)
        sk->sk_protocol    = PX_PROTO_OE;
        sk->sk_destruct    = pppoe_sk_free;
 
-       po = pppox_sk(sk) = kmalloc(sizeof(*po), GFP_KERNEL);
+       po = sk->sk_protinfo = kmalloc(sizeof(*po), GFP_KERNEL);
        if (!po)
                goto frees;
        memset(po, 0, sizeof(*po));
index 4a8fcad..c7139e5 100644 (file)
@@ -996,11 +996,11 @@ static void __devexit saa9730_remove_one(struct pci_dev *pdev)
         struct net_device *dev = pci_get_drvdata(pdev);
 
         if (dev) {
-               
+                unregister_netdev(dev);
+
                if (dev->priv)
                        kfree(dev->priv);
 
-                unregister_netdev(dev);
                 free_netdev(dev);
                 pci_release_regions(pdev);
                 pci_disable_device(pdev);
@@ -1015,17 +1015,10 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
        unsigned char ethernet_addr[6];
        int ret = 0;
 
-       dev = init_etherdev(dev, 0);
-
-       if (!dev) 
-               return -ENOMEM;
-       
        dev->open = lan_saa9730_open_fail;
 
-       if (get_ethernet_addr(ethernet_addr)) {
-               ret = -ENODEV;
-               goto out;
-       }
+       if (get_ethernet_addr(ethernet_addr))
+               return -ENODEV;
        
        memcpy(dev->dev_addr, ethernet_addr, 6);
        dev->base_addr = ioaddr;
@@ -1040,10 +1033,8 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
                                                      GFP_DMA | GFP_KERNEL)
                                              + 7) & ~7);
 
-       if (!lp) {
-               ret = -ENOMEM;
-                goto out;
-        }
+       if (!lp)
+               return -ENOMEM;
 
        dev->priv = lp;
        memset(lp, 0, sizeof(*lp));
@@ -1057,6 +1048,7 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
                                                         SAA9730_EVM_REGS_ADDR);
 
        /* Allocate LAN RX/TX frame buffer space. */
+       /* FIXME: a leak */
        if ((ret = lan_saa9730_allocate_buffers(lp)))
                goto out;
 
@@ -1095,63 +1087,70 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
        dev->watchdog_timeo = (HZ >> 1);
        dev->dma = 0;
        
+       ret = register_netdev(dev);
+       if (ret)
+               goto out;
        return 0;
 
  out:
-       if (dev) {
-               if (dev->priv)
-                       kfree(dev->priv);
-               unregister_netdevice(dev);
-               free_netdev(dev);
-       }
-               
+       if (dev->priv)
+               kfree(dev->priv);
+       free_netdev(dev);
        return ret;
 }
 
 
 static int __devinit saa9730_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       struct net_device *dev = NULL;
+       struct net_device *dev;
        unsigned int pci_ioaddr;
        int err;
 
        if (lan_saa9730_debug > 1)
                printk("saa9730.c: PCI bios is present, checking for devices...\n");
 
+       err = -ENOMEM;
+       dev = alloc_etherdev(0);
+       if (!dev)
+               goto out;
+
+       SET_MODULE_OWNER(dev);
+
        err = pci_enable_device(pdev);
         if (err) {
                 printk(KERN_ERR "Cannot enable PCI device, aborting.\n");
-                goto out;
+                goto out1;
         }
 
        err = pci_request_regions(pdev, DRV_MODULE_NAME);
        if (err) {
                printk(KERN_ERR "Cannot obtain PCI resources, aborting.\n");
-               goto out_disable_pdev;
+               goto out2;
        }
 
        pci_irq_line = pdev->irq;
        /* LAN base address in located at BAR 1. */
-       
+
        pci_ioaddr = pci_resource_start(pdev, 1);
        pci_set_master(pdev);
-       
+
        printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
               pci_ioaddr, pci_irq_line);
 
        err = lan_saa9730_init(dev, pci_ioaddr, pci_irq_line);
        if (err) {
                printk("Lan init failed");
-               goto out_disable_pdev;
+               goto out2;
        }
-       
+
        pci_set_drvdata(pdev, dev);
        return 0;
        
- out_disable_pdev:
+out2:
        pci_disable_device(pdev);
- out:
-       pci_set_drvdata(pdev, NULL);
+out1:
+       free_netdev(dev);
+out:
        return err;
 }
 
index 68838bb..0c1e6b6 100644 (file)
@@ -2372,6 +2372,7 @@ static int sbmac_init(struct net_device *dev, int idx)
        unsigned char *eaddr;
        uint64_t ea_reg;
        int i;
+       int err;
        
        sc = (struct sbmac_softc *)dev->priv;
        
@@ -2430,7 +2431,6 @@ static int sbmac_init(struct net_device *dev, int idx)
        
        spin_lock_init(&(sc->sbm_lock));
        
-       ether_setup(dev);
        dev->open               = sbmac_open;
        dev->hard_start_xmit    = sbmac_start_tx;
        dev->stop               = sbmac_close;
@@ -2444,8 +2444,11 @@ static int sbmac_init(struct net_device *dev, int idx)
 
        /* This is needed for PASS2 for Rx H/W checksum feature */
        sbmac_set_iphdr_offset(sc);
-       
-       return 0;
+
+       err = register_netdev(dev);
+       if (err)
+               sbmac_uninitctx(sc);
+       return err;
 }
 
 
@@ -2811,13 +2814,12 @@ sbmac_setup_hwaddr(int chan,char *addr)
 }
 #endif
 
-static struct net_device *dev_sbmac[MAX_UNITS] = {0,0,0};
+static struct net_device *dev_sbmac[MAX_UNITS];
 
 static int __init
 sbmac_init_module(void)
 {
        int idx;
-       int macidx = 0;
        struct net_device *dev;
        sbmac_port_t port;
        int chip_max_units;
@@ -2884,26 +2886,24 @@ sbmac_init_module(void)
                 * Okay, cool.  Initialize this MAC.
                 */
 
-               dev = init_etherdev(NULL,sizeof(struct sbmac_softc));
+               dev = alloc_etherdev(sizeof(struct sbmac_softc));
                if (!dev) 
-                 return -ENOMEM;       /* return ENOMEM */
+                       return -ENOMEM; /* return ENOMEM */
 
                printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
 
                dev->irq = K_INT_MAC_0 + idx;
                dev->base_addr = port;
                dev->mem_end = 0;
-               /*dev->init = sbmac_init;*/
-               sbmac_init(dev, macidx);
-
-               dev_sbmac[macidx] = dev;
-               macidx++;
+               if (sbmac_init(dev, idx)) {
+                       port = A_MAC_CHANNEL_BASE(idx);
+                       SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR),
+                                       sbmac_orig_hwaddr[idx] );
+                       free_netdev(dev);
+                       continue;
+               }
+               dev_sbmac[idx++] = dev;
        }
-
-       /*
-        * Should we care, 'macidx' is the total number of enabled MACs.
-        */
-       
        return 0;
 }
 
@@ -2916,21 +2916,12 @@ sbmac_cleanup_module(void)
        sbmac_port_t port;
        for (idx = 0; idx < MAX_UNITS; idx++) {
                dev = dev_sbmac[idx];
-               if (dev == NULL)
-                       continue;
-               if (dev->priv != NULL) {
-                       struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv;
-                       
+               if (!dev) {
+                       struct sbmac_softc *sc = dev->priv;
                        unregister_netdev(dev);
-                       
                        sbmac_uninitctx(sc);
-                       
+                       free_netdev(dev);
                }
-
-               port = A_MAC_CHANNEL_BASE(idx);
-               SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] );
-               free_netdev(dev);
-               dev_sbmac[idx] = NULL;
        }
 }
 
index ab0ae12..90c483f 100644 (file)
@@ -78,8 +78,6 @@ struct net_local {
 
 /* Index to functions, as function prototypes. */
 
-extern int seeq8005_probe(struct net_device *dev);
-
 static int seeq8005_probe1(struct net_device *dev, int ioaddr);
 static int seeq8005_open(struct net_device *dev);
 static void seeq8005_timeout(struct net_device *dev);
@@ -102,22 +100,48 @@ static inline void wait_for_buffer(struct net_device *dev);
    If dev->base_addr == 1, always return failure.
    */
 
-int __init 
-seeq8005_probe(struct net_device *dev)
-{
-       int i;
-       int base_addr = dev ? dev->base_addr : 0;
-
-       if (base_addr > 0x1ff)          /* Check a single specified location. */
-               return seeq8005_probe1(dev, base_addr);
-       else if (base_addr != 0)        /* Don't probe at all. */
-               return -ENXIO;
+static int io = 0x320;
+static int irq = 10;
 
-       for (i = 0; seeq8005_portlist[i]; i++)
-               if (seeq8005_probe1(dev, seeq8005_portlist[i]) == 0)
-                       return 0;
+struct net_device * __init seeq8005_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       unsigned *port;
+       int err = 0;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+       }
 
-       return -ENODEV;
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = seeq8005_probe1(dev, io);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = seeq8005_portlist; *port; port++) {
+                       if (seeq8005_probe1(dev, *port) == 0)
+                               break;
+               }
+               if (!*port)
+                       err = -ENODEV;
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /* This is the real probe routine.  Linux has a history of friendly device
@@ -274,6 +298,7 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
 
        /* Fill in the 'dev' fields. */
        dev->base_addr = ioaddr;
+       dev->irq = irq;
 
        /* Retrieve and print the ethernet address. */
        for (i = 0; i < 6; i++)
@@ -307,13 +332,6 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
                 }
        }
 #endif
-
-       /* Initialize the device structure. */
-       dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (dev->priv == NULL)
-               return -ENOMEM;
-       memset(dev->priv, 0, sizeof(struct net_local));
-
        dev->open               = seeq8005_open;
        dev->stop               = seeq8005_close;
        dev->hard_start_xmit    = seeq8005_send_packet;
@@ -321,10 +339,6 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
        dev->watchdog_timeo     = HZ/20;
        dev->get_stats          = seeq8005_get_stats;
        dev->set_multicast_list = set_multicast_list;
-
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-       
        dev->flags &= ~IFF_MULTICAST;
 
        return 0;
@@ -721,9 +735,7 @@ inline void wait_for_buffer(struct net_device * dev)
        
 #ifdef MODULE
 
-static struct net_device dev_seeq = { .init = seeq8005_probe };
-static int io = 0x320;
-static int irq = 10;
+static struct net_device *dev_seeq;
 MODULE_LICENSE("GPL");
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -732,28 +744,17 @@ MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
 
 int init_module(void)
 {
-       dev_seeq.irq=irq;
-       dev_seeq.base_addr=io;
-       if (register_netdev(&dev_seeq) != 0)
-               return -EIO;
+       dev_seeq = seeq8005_probe(-1);
+       if (IS_ERR(dev_seeq))
+               return PTR_ERR(dev_seeq);
        return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev(&dev_seeq);
-
-       /*
-        *      Free up the private structure, or leak memory :-)
-        */
-
-       kfree(dev_seeq.priv);
-       dev_seeq.priv = NULL;   /* gets re-allocated by el1_probe1 */
-
-       /*
-        *      If we don't do this, we can't re-insmod it later.
-        */
-       release_region(dev_seeq.base_addr, SEEQ8005_IO_EXTENT);
+       unregister_netdev(dev_seeq);
+       release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
+       free_netdev(dev_seeq);
 }
 
 #endif /* MODULE */
index 203e4c2..6235a8d 100644 (file)
@@ -600,6 +600,7 @@ int sgiseeq_init(struct hpc3_regs* regs, int irq)
 {
        struct net_device *dev;
        struct sgiseeq_private *sp;
+       int err = -ENOMEM;
        int i;
        
        sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL);
@@ -609,19 +610,17 @@ int sgiseeq_init(struct hpc3_regs* regs, int irq)
                return -ENOMEM;
        }
 
-       dev = init_etherdev(NULL, 0);
+       dev = alloc_etherdev(0);
        if (!dev) {
                printk (KERN_ERR
                        "Seeq8003: Could not allocate memory for device.\n");
-               free_page((unsigned long) sp);
-               return -ENOMEM;
+               goto out;
        }
 
        if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
-               printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq);
-               free_page((unsigned long) sp);
-               unregister_netdev(dev);
-               return -EAGAIN;
+               printk(KERN_ERR "Seeq8003: Can't get irq %d\n", irq);
+               err = -EAGAIN;
+               goto out1;
        }
 
        printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
@@ -637,6 +636,8 @@ int sgiseeq_init(struct hpc3_regs* regs, int irq)
        }
        printk("\n");
 
+       SET_MODULE_OWNER(dev);
+
        dev->priv = sp;
 #ifdef DEBUG
        gpriv = sp;
@@ -677,12 +678,22 @@ int sgiseeq_init(struct hpc3_regs* regs, int irq)
        dev->set_multicast_list   = sgiseeq_set_multicast;
        dev->irq                  = irq;
        dev->dma                  = 0;
-       ether_setup(dev);
+
+       err = register_netdev(dev);
+       if (err)
+               goto out2;
 
        sp->next_module = root_sgiseeq_dev;
        root_sgiseeq_dev = dev;
 
        return 0;
+out2:
+       free_irq(dev->irq, dev);
+out1:
+       free_netdev(dev);
+out:
+       free_page((unsigned long) sp);
+       return err;
 }
 
 static int __init sgiseeq_probe(void)
@@ -701,9 +712,9 @@ static void __exit sgiseeq_exit(void)
        while (dev) {
                sp = (struct sgiseeq_private *) dev->priv;
                next = sp->next_module;
+               unregister_netdev(dev);
                free_irq(dev->irq, dev);
                free_page((unsigned long) sp);
-               unregister_netdev(dev);
                free_netdev(dev);
                dev = next;
        }
index 0e7f315..e7ae3e6 100644 (file)
@@ -718,8 +718,10 @@ static int __init shaper_init(void)
                if (!dev) 
                        break;
 
-               if (register_netdev(dev))
+               if (register_netdev(dev)) {
+                       free_netdev(dev);
                        break;
+               }
 
                devs[i] = dev;
                shapers_registered++;
@@ -737,9 +739,12 @@ static void __exit shaper_exit (void)
 {
        int i;
 
-       for (i = 0; i < shapers_registered; i++)
-               if (devs[i])
+       for (i = 0; i < shapers_registered; i++) {
+               if (devs[i]) {
                        unregister_netdev(devs[i]);
+                       free_netdev(devs[i]);
+               }
+       }
 
        kfree(devs);
        devs = NULL;
index 6cfa52b..17d858e 100644 (file)
@@ -837,7 +837,7 @@ SK_EVPARA EvPara;
 
                if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
                        unregister_netdev(pAC->dev[1]);
-                       kfree(pAC->dev[1]);
+                       free_netdev(pAC->dev[1]);
                }
 
                FreeResources(SkGeRootDev);
index 70c13d0..51c4bac 100644 (file)
@@ -457,8 +457,6 @@ struct priv
 /* static variables */
 
 static SK_RAM *board;  /* pointer to our memory mapped board components */
-static struct net_device *SK_dev;
-unsigned long SK_ioaddr;
 static spinlock_t SK_lock = SPIN_LOCK_UNLOCKED;
 
 /* Macros */
@@ -472,7 +470,6 @@ static spinlock_t SK_lock = SPIN_LOCK_UNLOCKED;
  * See for short explanation of each function its definitions header.
  */
 
-int          SK_init(struct net_device *dev);
 static int   SK_probe(struct net_device *dev, short ioaddr);
 
 static void  SK_timeout(struct net_device *dev);
@@ -530,84 +527,71 @@ void SK_print_ram(struct net_device *dev);
  *     YY/MM/DD  uid  Description
 -*/
 
+static int io; /* 0 == probe */
+
 /* 
  * Check for a network adaptor 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 SK_init(struct net_device *dev)
+struct net_device * __init SK_init(int unit)
 {
-       int ioaddr;                        /* I/O port address used for POS regs */
        int *port, ports[] = SK_IO_PORTS;  /* SK_G16 supported ports */
        static unsigned version_printed;
+       struct net_device *dev = alloc_etherdev(sizeof(struct priv));
+       int err = -ENODEV;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-       /* get preconfigured base_addr from dev which is done in Space.c */
-       int base_addr = dev->base_addr; 
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+       }
 
        if (version_printed++ == 0)
                PRINTK(("%s: %s", SK_NAME, rcsid));
 
-       if (base_addr > 0x0ff)        /* Check a single specified address */
-       {
-           int rc = -ENODEV;
-
-           ioaddr = base_addr;
-
-           /* Check if on specified address is a SK_G16 */
-           if (!request_region(ioaddr, ETHERCARD_TOTAL_SIZE, "sk_g16"))
-               return -EBUSY;
-
-           if ( (inb(SK_POS0) == SK_IDLOW) ||
-                (inb(SK_POS1) == SK_IDHIGH) )  
-           {
-               rc = SK_probe(dev, ioaddr);
-           }
-
-           if (rc)
-               release_region(ioaddr, ETHERCARD_TOTAL_SIZE);
-           return rc;
-       }
-       else if (base_addr > 0)       /* Don't probe at all */
-       {
-               return -ENXIO;
+       if (io > 0xff) {        /* Check a single specified address */
+               err = -EBUSY;
+               /* Check if on specified address is a SK_G16 */
+               if (request_region(io, ETHERCARD_TOTAL_SIZE, "sk_g16")) {
+                       err = SK_probe(dev, io);
+                       if (!err)
+                               goto got_it;
+                       release_region(io, ETHERCARD_TOTAL_SIZE);
+               }
+       } else if (io > 0) {       /* Don't probe at all */
+               err = -ENXIO;
+       } else {
+               /* Autoprobe base_addr */
+               for (port = &ports[0]; *port; port++) {
+                       io = *port;
+
+                       /* Check if I/O Port region is used by another board */
+                       if (!request_region(io, ETHERCARD_TOTAL_SIZE, "sk_g16"))
+                               continue;       /* Try next Port address */
+
+                       /* Check if at ioaddr is a SK_G16 */
+                       if (SK_probe(dev, io) == 0)
+                               goto got_it;
+
+                       release_region(io, ETHERCARD_TOTAL_SIZE);
+               }
        }
-
-       /* Autoprobe base_addr */
-
-       for (port = &ports[0]; *port; port++) 
-       {
-           ioaddr = *port;           /* we need ioaddr for accessing POS regs */
-
-           /* Check if I/O Port region is used by another board */
-
-           if (!request_region(ioaddr, ETHERCARD_TOTAL_SIZE, "sk_g16"))
-           {
-               continue;             /* Try next Port address */
-           }
-
-           /* Check if at ioaddr is a SK_G16 */
-
-           if ( !(inb(SK_POS0) == SK_IDLOW) ||
-                !(inb(SK_POS1) == SK_IDHIGH) )
-           {
-               release_region(ioaddr, ETHERCARD_TOTAL_SIZE);
-               continue;             /* Try next Port address */
-           }
-
-           dev->base_addr = ioaddr;  /* Set I/O Port Address */
-
-           if (SK_probe(dev, ioaddr) == 0)  
-           {
-               return 0; /* Card found and initialized */
-           }
-
-           release_region(ioaddr, ETHERCARD_TOTAL_SIZE);
+err_out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+
+got_it:
+       err = register_netdev(dev);
+       if (err) {
+               release_region(dev->base_addr, ETHERCARD_TOTAL_SIZE);
+               goto err_out;
        }
-
-       dev->base_addr = base_addr;   /* Write back original base_addr */
-
-       return -ENODEV;                /* Failed to find or init driver */
+       return dev;
 
 } /* End of SK_init */
 
@@ -620,54 +604,25 @@ MODULE_PARM_DESC(io, "0 to probe common ports (unsafe), or the I/O base of the b
 
 
 #ifdef MODULE
-static int io; /* 0 == probe */
+
+static struct net_device *SK_dev;
 
 static int __init SK_init_module (void)
 {
-       int rc;
-       
-       SK_dev = init_etherdev (NULL, 0);
-       if (!SK_dev)
-               return -ENOMEM;
-       
-       SK_dev->base_addr = io;
-
-       rc = SK_init (SK_dev);
-       if (rc) {
-               unregister_netdev (SK_dev);
-               kfree (SK_dev);
-               SK_dev = NULL;
-       }
-       
-       return rc;
+       SK_dev = SK_init(-1);
+       return IS_ERR(SK_dev) ? PTR_ERR(SK_dev) : 0;
 }
-#endif /* MODULE */
-
 
 static void __exit SK_cleanup_module (void)
 {
-       if (SK_dev) {
-               if (SK_dev->priv) {
-                       kfree(SK_dev->priv);
-                       SK_dev->priv = NULL;
-               }
-               unregister_netdev(SK_dev);
-               free_netdev(SK_dev);
-               SK_dev = NULL;
-       }
-       if (SK_ioaddr) {
-               release_region(SK_ioaddr, ETHERCARD_TOTAL_SIZE);
-               SK_ioaddr = 0;
-       }
-               
+       unregister_netdev(SK_dev);
+       release_region(SK_dev->base_addr, ETHERCARD_TOTAL_SIZE);
+       free_netdev(SK_dev);
 }
 
-
-#ifdef MODULE
 module_init(SK_init_module);
-#endif
 module_exit(SK_cleanup_module);
-
+#endif
 
 \f
 /*-
@@ -695,7 +650,11 @@ int __init SK_probe(struct net_device *dev, short ioaddr)
     int sk_addr_flag = 0;   /* SK ADDR correct? 1 - no, 0 - yes */
     unsigned int rom_addr;  /* used to store RAM address used for POS_ADDR */
 
-    struct priv *p;         /* SK_G16 private structure */
+    struct priv *p = dev->priv;         /* SK_G16 private structure */
+
+    if (inb(SK_POS0) != SK_IDLOW || inb(SK_POS1) != SK_IDHIGH)
+       return -ENODEV;
+    dev->base_addr = ioaddr;
 
     if (SK_ADDR & 0x3fff || SK_ADDR < 0xa0000)
     {
@@ -837,12 +796,6 @@ int __init SK_probe(struct net_device *dev, short ioaddr)
            dev->dev_addr[4],
            dev->dev_addr[5]);
 
-    /* Allocate memory for private structure */
-    p = dev->priv = (void *) kmalloc(sizeof(struct priv), GFP_KERNEL);
-    if (p == NULL) {
-          printk("%s: ERROR - no memory for driver data!\n", dev->name);
-          return -ENOMEM;
-    }
     memset((char *) dev->priv, 0, sizeof(struct priv)); /* clear memory */
 
     /* Assign our Device Driver functions */
@@ -856,10 +809,6 @@ int __init SK_probe(struct net_device *dev, short ioaddr)
     dev->watchdog_timeo                = HZ/7;
 
 
-    /* Set the generic fields of the device structure */
-
-    ether_setup(dev);
-    
     dev->flags &= ~IFF_MULTICAST;
 
     /* Initialize private structure */
@@ -884,12 +833,7 @@ int __init SK_probe(struct net_device *dev, short ioaddr)
     SK_print_pos(dev, "End of SK_probe");
     SK_print_ram(dev);
 #endif 
-
-    SK_dev = dev;
-    SK_ioaddr = ioaddr;
-
     return 0;                            /* Initialization done */
-
 } /* End of SK_probe() */
 
 \f
@@ -1280,7 +1224,7 @@ static int SK_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        memcpy_toio((tmdp->u.buffer & 0x00ffffff), skb->data, skb->len);
        if (len != skb->len)
-               memcpy_toio((tmdp->u.buffer & 0x00ffffff) + sb->len, pad, len-skb->len);
+               memcpy_toio((tmdp->u.buffer & 0x00ffffff) + skb->len, pad, len-skb->len);
 
        writew(-len, &tmdp->blen);            /* set length to transmit */
 
index 69a3c45..7c02aba 100644 (file)
@@ -1022,18 +1022,39 @@ static void skmca_set_multicast_list(struct net_device *dev)
 
 static int startslot;          /* counts through slots when probing multiple devices */
 
-int __init skmca_probe(struct net_device *dev)
+static void cleanup_card(struct net_device *dev)
 {
+       skmca_priv *priv = dev->priv;
+       DeinitBoard(dev);
+       if (dev->irq != 0)
+               free_irq(dev->irq, dev);
+       mca_mark_as_unused(priv->slot);
+       mca_set_adapter_procfn(priv->slot, NULL, NULL);
+}
+
+struct net_device * __init skmca_probe(int unit)
+{
+       struct net_device *dev;
        int force_detect = 0;
        int junior, slot, i;
        int base = 0, irq = 0;
        skmca_priv *priv;
        skmca_medium medium;
+       int err;
 
        /* can't work without an MCA bus ;-) */
 
        if (MCA_bus == 0)
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
+
+       dev = alloc_etherdev(sizeof(skmca_priv));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
 
        SET_MODULE_OWNER(dev);
 
@@ -1044,37 +1065,24 @@ int __init skmca_probe(struct net_device *dev)
 
        /* search through slots */
 
-       if (dev != NULL) {
-               base = dev->mem_start;
-               irq = dev->irq;
-       }
-       slot = dofind(&junior, startslot);
-
-       while (slot != -1) {
+       base = dev->mem_start;
+       irq = dev->base_addr;
+       for (slot = startslot; (slot = dofind(&junior, slot)) != -1; slot++) {
                /* deduce card addresses */
 
                getaddrs(slot, junior, &base, &irq, &medium);
 
                /* slot already in use ? */
 
-               if (mca_is_adapter_used(slot)) {
-                       slot = dofind(&junior, slot + 1);
+               if (mca_is_adapter_used(slot))
                        continue;
-               }
 
                /* were we looking for something different ? */
 
-               if ((dev->irq != 0) || (dev->mem_start != 0)) {
-                       if ((dev->irq != 0) && (dev->irq != irq)) {
-                               slot = dofind(&junior, slot + 1);
-                               continue;
-                       }
-                       if ((dev->mem_start != 0)
-                           && (dev->mem_start != base)) {
-                               slot = dofind(&junior, slot + 1);
-                               continue;
-                       }
-               }
+               if (dev->irq && dev->irq != irq)
+                       continue;
+               if (dev->mem_start && dev->mem_start != base)
+                       continue;
 
                /* found something that matches */
 
@@ -1083,8 +1091,10 @@ int __init skmca_probe(struct net_device *dev)
 
        /* nothing found ? */
 
-       if (slot == -1)
-               return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV;
+       if (slot == -1) {
+               free_netdev(dev);
+               return (base || irq) ? ERR_PTR(-ENXIO) : ERR_PTR(-ENODEV);
+       }
 
        /* make procfs entries */
 
@@ -1102,17 +1112,14 @@ int __init skmca_probe(struct net_device *dev)
               junior ? "Junior MC2" : "MC2+", slot + 1);
 
        /* allocate structure */
-       priv = dev->priv =
-           (skmca_priv *) kmalloc(sizeof(skmca_priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
+       priv = dev->priv;
        priv->slot = slot;
        priv->macbase = base + 0x3fc0;
        priv->ioregaddr = base + 0x3ff0;
        priv->ctrladdr = base + 0x3ff2;
        priv->cmdaddr = base + 0x3ff3;
        priv->medium = medium;
-       memset(&(priv->stat), 0, sizeof(struct net_device_stats));
+       memset(&priv->stat, 0, sizeof(struct net_device_stats));
        spin_lock_init(&priv->lock);
 
        /* set base + irq for this device (irq not allocated so far) */
@@ -1146,9 +1153,6 @@ int __init skmca_probe(struct net_device *dev)
        dev->set_multicast_list = skmca_set_multicast_list;
        dev->flags |= IFF_MULTICAST;
 
-       /* generic setup */
-       ether_setup(dev);
-
        /* copy out MAC address */
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = SKMCA_READB(priv->macbase + (i << 1));
@@ -1167,7 +1171,13 @@ int __init skmca_probe(struct net_device *dev)
 
        startslot = slot + 1;
 
-       return 0;
+       err = register_netdev(dev);
+       if (err) {
+               cleanup_card(dev);
+               free_netdev(dev);
+               dev = ERR_PTR(err);
+       }
+       return dev;
 }
 
 /* ------------------------------------------------------------------------
@@ -1179,51 +1189,34 @@ MODULE_LICENSE("GPL");
 
 #define DEVMAX 5
 
-static struct net_device moddevs[DEVMAX] = {
-       { .name = "    ", .init = skmca_probe },
-       { .name = "    ", .init = skmca_probe },
-       { .name = "    ", .init = skmca_probe },
-       { .name = "    ", .init = skmca_probe },
-       { .name = "    ", .init = skmca_probe }
-};
-
-int irq;
-int io;
+static struct net_device *moddevs[DEVMAX];
 
 int init_module(void)
 {
-       int z, res;
+       int z;
 
        startslot = 0;
        for (z = 0; z < DEVMAX; z++) {
-               strcpy(moddevs[z].name, "     ");
-               res = register_netdev(moddevs + z);
-               if (res != 0)
-                       return (z > 0) ? 0 : -EIO;
+               struct net_device *dev = skmca_probe(-1);
+               if (IS_ERR(dev))
+                       break;
+               moddevs[z] = dev;
        }
-
+       if (!z)
+               return -EIO;
        return 0;
 }
 
 void cleanup_module(void)
 {
-       struct net_device *dev;
-       skmca_priv *priv;
        int z;
 
        for (z = 0; z < DEVMAX; z++) {
-               dev = moddevs + z;
-               if (dev->priv != NULL) {
-                       priv = (skmca_priv *) dev->priv;
-                       DeinitBoard(dev);
-                       if (dev->irq != 0)
-                               free_irq(dev->irq, dev);
-                       dev->irq = 0;
+               struct net_device *dev = moddevs[z];
+               if (dev) {
                        unregister_netdev(dev);
-                       mca_mark_as_unused(priv->slot);
-                       mca_set_adapter_procfn(priv->slot, NULL, NULL);
-                       kfree(dev->priv);
-                       dev->priv = NULL;
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index d1b5250..da43d5b 100644 (file)
@@ -178,7 +178,4 @@ typedef struct {            /* LANCE Rx descriptor               */
 
 #endif                         /* _SK_MCA_DRIVER_ */
 
-extern int skmca_probe(struct net_device *);
-
-
 #endif /* _SK_MCA_INCLUDE_ */
index 5482c82..a7345c4 100644 (file)
  *   are skfddi.c, h/types.h, h/osdef1st.h, h/targetos.h.
  *   The others belong to the SysKonnect FDDI Hardware Module and
  *   should better not be changed.
- * NOTE:
- *   Compiling this driver produces some warnings, but I did not fix
- *   this, because the Hardware Module source is used for different
- *   drivers, and fixing it for Linux might bring problems on other
- *   projects. To keep the source common for all those drivers (and
- *   thus simplify fixes to it), please do not clean it up!
  *
  * Modification History:
  *              Date            Name    Description
@@ -58,6 +52,7 @@
  *             07-May-00       DM      64 bit fixes, new dma interface
  *             31-Jul-03       DB      Audit copy_*_user in skfp_ioctl
  *                                       Daniele Bellucci <bellucda@tiscali.it>
+ *             03-Dec-03       SH      Convert to PCI device model
  *
  * Compilation options (-Dxxx):
  *              DRIVERDEBUG     print lots of messages to log file
@@ -70,7 +65,7 @@
 
 /* Version information string - should be updated prior to */
 /* each new release!!! */
-#define VERSION                "2.06"
+#define VERSION                "2.07"
 
 static const char *boot_msg = 
        "SysKonnect FDDI PCI Adapter driver v" VERSION " for\n"
@@ -80,15 +75,11 @@ static const char *boot_msg =
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>       // isdigit
 #include <linux/netdevice.h>
 #include <linux/fddidevice.h>
 #include <linux/skbuff.h>
@@ -106,17 +97,7 @@ static const char *boot_msg =
 #include       "h/smtstate.h"
 
 
-// Define global routines
-int skfp_probe(struct net_device *dev);
-
-
 // Define module-wide (static) routines
-static struct net_device *alloc_device(struct net_device *dev, u_long iobase);
-static struct net_device *insert_device(struct net_device *dev,
-                                   int (*init) (struct net_device *));
-static int fddi_dev_index(unsigned char *s);
-static void init_dev(struct net_device *dev, u_long iobase);
-static void link_modules(struct net_device *dev, struct net_device *tmp);
 static int skfp_driver_init(struct net_device *dev);
 static int skfp_open(struct net_device *dev);
 static int skfp_close(struct net_device *dev);
@@ -193,15 +174,6 @@ MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
 // Define module-wide (static) variables
 
 static int num_boards; /* total number of adapters configured */
-static int num_fddi;
-static int autoprobed;
-
-#ifdef MODULE
-static struct net_device *unlink_modules(struct net_device *p);
-static int loading_module = 1;
-#else
-static int loading_module;
-#endif                         // MODULE
 
 #ifdef DRIVERDEBUG
 #define PRINTK(s, args...) printk(s, ## args)
@@ -212,9 +184,9 @@ static int loading_module;
 #define PRIV(dev) (&(((struct s_smc *)dev->priv)->os))
 
 /*
- * ==============
- * = skfp_probe =
- * ==============
+ * =================
+ * = skfp_init_one =
+ * =================
  *   
  * Overview:
  *   Probes for supported FDDI PCI controllers
@@ -223,30 +195,11 @@ static int loading_module;
  *   Condition code
  *       
  * Arguments:
- *   dev - pointer to device information
+ *   pdev - pointer to PCI device information
  *
  * Functional Description:
- *   This routine is called by the OS for each FDDI device name (fddi0,
- *   fddi1,...,fddi6, fddi7) specified in drivers/net/Space.c.
- *   If loaded as a module, it will detect and initialize all 
- *   adapters the first time it is called.
- *
- *   Let's say that skfp_probe() is getting called to initialize fddi0.
- *   Furthermore, let's say there are three supported controllers in the
- *   system.  Before skfp_probe() leaves, devices fddi0, fddi1, and fddi2
- *   will be initialized and a global flag will be set to indicate that
- *   skfp_probe() has already been called.
- *
- *   However...the OS doesn't know that we've already initialized
- *   devices fddi1 and fddi2 so skfp_probe() gets called again and again
- *   until it reaches the end of the device list for FDDI (presently,
- *   fddi7).  It's important that the driver "pretend" to probe for
- *   devices fddi1 and fddi2 and return success.  Devices fddi3
- *   through fddi7 will return failure since they weren't initialized.
- *
- *   This algorithm seems to work for the time being.  As other FDDI
- *   drivers are written for Linux, a more generic approach (perhaps
- *   similar to the Ethernet card approach) may need to be implemented.
+ *   This is now called by PCI driver registration process
+ *   for each board found.
  *   
  * Return Codes:
  *   0           - This device (fddi0, fddi1, etc) configured successfully
@@ -259,374 +212,176 @@ static int loading_module;
  *   initialized and the board resources are read and stored in
  *   the device structure.
  */
-int skfp_probe(struct net_device *dev)
+static int skfp_init_one(struct pci_dev *pdev,
+                               const struct pci_device_id *ent)
 {
-       int i;                  /* used in for loops */
-       struct pci_dev *pdev = NULL;    /* PCI device structure */
-#ifndef MEM_MAPPED_IO
-       u16 port;               /* temporary I/O (port) address */
-       int port_len;           /* length of port address range (in bytes) */
-#else
-       unsigned long port;
-#endif
-       u16 command;    /* PCI Configuration space Command register val */
+       struct net_device *dev;
        struct s_smc *smc;      /* board pointer */
-       struct net_device *tmp = dev;
-       u8 first_dev_used = 0;
-       u16 SubSysId;
-
-       PRINTK(KERN_INFO "entering skfp_probe\n");
-
-       /*
-        * Verify whether we're going through skfp_probe() again
-        *
-        * If so, see if we're going through for a subsequent fddi device that
-        * we've already initialized.  If we are, return success (0).  If not,
-        * return failure (-ENODEV).
-        */
-
-       if (autoprobed) {
-               PRINTK(KERN_INFO "Already entered skfp_probe\n");
-               if (dev != NULL) {
-                       if ((strncmp(dev->name, "fddi", 4) == 0) &&
-                           (dev->base_addr != 0)) {
-                               return (0);
-                       }
-                       return (-ENODEV);
-               }
-       }
-       autoprobed = 1;         /* set global flag */
-
-       printk("%s\n", boot_msg);
-
-       /* Scan for Syskonnect FDDI PCI controllers */
-       for (i = 0; i < SKFP_MAX_NUM_BOARDS; i++) {     // scan for PCI cards
-               PRINTK(KERN_INFO "Check device %d\n", i);
-               if ((pdev=pci_find_device(PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP,
-                       pdev)) == 0) {
-                       break;
-               }
-               if (pci_enable_device(pdev))
-                       continue;
-
-#ifndef MEM_MAPPED_IO
-               /* Verify that I/O enable bit is set (PCI slot is enabled) */
-               pci_read_config_word(pdev, PCI_COMMAND, &command);
-               if ((command & PCI_COMMAND_IO) == 0) {
-                       PRINTK("I/O enable bit not set!");
-                       PRINTK(" Verify that slot is enabled\n");
-                       continue;
-               }
-
-               /* Turn off memory mapped space and enable mastering */
-
-               PRINTK(KERN_INFO "Command Reg: %04x\n", command);
-               command |= PCI_COMMAND_MASTER;
-               command &= ~PCI_COMMAND_MEMORY;
-               pci_write_config_word(pdev, PCI_COMMAND, command);
-
-               /* Read I/O base address from PCI Configuration Space */
-
-               pci_read_config_word(pdev, PCI_BASE_ADDRESS_1, &port);
-               port &= PCI_BASE_ADDRESS_IO_MASK; // clear I/O bit (bit 0)
-
-               /* Verify port address range is not already being used */
-
-               port_len = FP_IO_LEN;
-               if (check_region(port, port_len) != 0) {
-                       printk("I/O range allocated to adapter");
-                       printk(" (0x%X-0x%X) is already being used!\n", port,
-                              (port + port_len - 1));
-                       continue;
-               }
-#else
-               /* Verify that MEM enable bit is set (PCI slot is enabled) */
-               pci_read_config_word(pdev, PCI_COMMAND, &command);
-               if ((command & PCI_COMMAND_MEMORY) == 0) {
-                       PRINTK("MEMORY-I/O enable bit not set!");
-                       PRINTK(" Verify that slot is enabled\n");
-                       continue;
-               }
-
-               /* Turn off IO mapped space and enable mastering */
-
-               PRINTK(KERN_INFO "Command Reg: %04x\n", command);
-               command |= PCI_COMMAND_MASTER;
-               command &= ~PCI_COMMAND_IO;
-               pci_write_config_word(pdev, PCI_COMMAND, command);
-
-               port = pci_resource_start(pdev, 0);
+       u32 port, len;
+       int err;
 
-               port = (unsigned long)ioremap(port, 0x4000);
-               if (!port){
-                       printk("skfp:  Unable to map MEMORY register, "
-                       "FDDI adapter will be disabled.\n");
-                       break;
-               }
-#endif
+       PRINTK(KERN_INFO "entering skfp_init_one\n");
 
-               if ((!loading_module) || first_dev_used) {
-                       /* Allocate a device structure for this adapter */
-                       tmp = alloc_device(dev, port);
-               }
-               first_dev_used = 1;     // only significant first time
-
-               pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &SubSysId);
-
-               if (tmp != NULL) {
-                       if (loading_module)
-                               link_modules(dev, tmp);
-                       dev = tmp;
-                       init_dev(dev, port);
-                       dev->irq = pdev->irq;
-
-                       /* Initialize board structure with bus-specific info */
-
-                       smc = (struct s_smc *) dev->priv;
-                       smc->os.dev = dev;
-                       smc->os.bus_type = SK_BUS_TYPE_PCI;
-                       smc->os.pdev = *pdev;
-                       smc->os.QueueSkb = MAX_TX_QUEUE_LEN;
-                       smc->os.MaxFrameSize = MAX_FRAME_SIZE;
-                       smc->os.dev = dev;
-                       smc->hw.slot = -1;
-                       smc->os.ResetRequested = FALSE;
-                       skb_queue_head_init(&smc->os.SendSkbQueue);
-
-                       if (skfp_driver_init(dev) == 0) {
-                               // only increment global board 
-                               // count on success
-                               num_boards++;
-                               request_region(dev->base_addr,
-                                              FP_IO_LEN, dev->name);
-                               if ((SubSysId & 0xff00) == 0x5500 ||
-                                       (SubSysId & 0xff00) == 0x5800) {
-                               printk("%s: SysKonnect FDDI PCI adapter"
-                                      " found (SK-%04X)\n", dev->name,
-                                       SubSysId);
-                               } else {
-                               printk("%s: FDDI PCI adapter found\n",
-                                       dev->name);
-                               }
-                       } else {
-                               kfree(dev);
-                               i = SKFP_MAX_NUM_BOARDS;        // stop search
+       if (num_boards == 0) 
+               printk("%s\n", boot_msg);
 
-                       }
-
-               }               // if (dev != NULL)
+       err = pci_enable_device(pdev);
+       if (err)
+               goto err_out1;
 
-       }                       // for SKFP_MAX_NUM_BOARDS
 
-       /*
-        * If we're at this point we're going through skfp_probe() for the
-        * first time. Return success (0) if we've initialized 1 or more
-        * boards. Otherwise, return failure (-ENODEV).
-        */
-
-       if (num_boards > 0)
-               return (0);
-       else {
-               printk("no SysKonnect FDDI adapter found\n");
-               return (-ENODEV);
+#ifdef MEM_MAPPED_IO
+       if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+               printk(KERN_ERR "skfp: region is not an MMIO resource\n");
+               err = -EIO;
+               goto err_out1;
        }
-}                              // skfp_probe
-
+       port = pci_resource_start(pdev, 0);
+       len = pci_resource_len(pdev, 0);
 
-/************************
- *
- * Search the entire 'fddi' device list for a fixed probe. If a match isn't
- * found then check for an autoprobe or unused device location. If they
- * are not available then insert a new device structure at the end of
- * the current list.
- *
- ************************/
-static struct net_device *alloc_device(struct net_device *dev, u_long iobase)
-{
-       struct net_device *adev = NULL;
-       int fixed = 0, new_dev = 0;
-
-       PRINTK(KERN_INFO "entering alloc_device\n");
-       if (!dev)
-               return dev;
-
-       num_fddi = fddi_dev_index(dev->name);
-       if (loading_module) {
-               num_fddi++;
-               dev = insert_device(dev, skfp_probe);
-               return dev;
+       if (len < 0x4000) {
+               printk(KERN_ERR "skfp: Invalid PCI region size: %d\n", len);
+               err = -EIO;
+               goto err_out1;
        }
-       while (1) {
-               if (((dev->base_addr == NO_ADDRESS) ||
-                    (dev->base_addr == 0)) && !adev) {
-                       adev = dev;
-               } else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
-                       fixed = 1;
-               } else {
-                       if (dev->next == NULL) {
-                               new_dev = 1;
-                       } else if (strncmp(dev->next->name, "fddi", 4) != 0) {
-                               new_dev = 1;
-                       }
-               }
-               if ((dev->next == NULL) || new_dev || fixed)
-                       break;
-               dev = dev->next;
-               num_fddi++;
-       }                       // while (1)
-
-       if (adev && !fixed) {
-               dev = adev;
-               num_fddi = fddi_dev_index(dev->name);
-               new_dev = 0;
+#else
+       if (!(pci_resource_flags(pdev, 1) & IO_RESOURCE_IO)) {
+               printk(KERN_ERR "skfp: region is not PIO resource\n");
+               err = -EIO;
+               goto err_out1;
        }
-       if (((dev->next == NULL) && ((dev->base_addr != NO_ADDRESS) &&
-                                    (dev->base_addr != 0)) && !fixed) ||
-           new_dev) {
-               num_fddi++;     /* New device */
-               dev = insert_device(dev, skfp_probe);
+
+       port = pci_resource_start(pdev, 1);
+       len = pci_resource_len(pdev, 1);
+       if (len < FP_IO_LEN) {
+               printk(KERN_ERR "skfp: Invalid PCI region size: %d\n",
+                      io_len);
+               err = -EIO;
+               goto err_out1;
        }
-       if (dev) {
-               if (!dev->priv) {
-                       /* Allocate space for private board structure */
-                       dev->priv = (void *) kmalloc(sizeof(struct s_smc),
-                                                    GFP_KERNEL);
-                       if (dev->priv == NULL) {
-                               printk("%s: Could not allocate memory for",
-                                       dev->name);
-                               printk(" private board structure!\n");
-                               return (NULL);
-                       }
-                       /* clear structure */
-                       memset(dev->priv, 0, sizeof(struct s_smc));
-               }
+#endif
+       err = pci_request_regions(pdev, "skfddi");
+       if (err)
+               goto err_out1;
+
+       pci_set_master(pdev);
+
+       dev = alloc_fddidev(sizeof(struct s_smc));
+       if (!dev) {
+               printk(KERN_ERR "skfp: Unable to allocate fddi device, "
+                               "FDDI adapter will be disabled.\n");
+               err = -ENOMEM;
+               goto err_out2;
        }
-       return dev;
-}                              // alloc_device
-
-
-
-/************************
- *
- * Initialize device structure
- *
- ************************/
-static void init_dev(struct net_device *dev, u_long iobase)
-{
-       /* Initialize new device structure */
 
-       dev->mem_end = 0;       /* shared memory isn't used */
-       dev->mem_start = 0;     /* shared memory isn't used */
-       dev->base_addr = iobase;        /* save port (I/O) base address */
-       dev->if_port = 0;       /* not applicable to FDDI adapters */
-       dev->dma = 0;           /* Bus Master DMA doesn't require channel */
-       dev->irq = 0;
-
-       netif_start_queue(dev);
+#ifdef MEM_MAPPED_IO
+       dev->base_addr = (unsigned long) ioremap(port, len);
+       if (!dev->base_addr) {
+               printk(KERN_ERR "skfp:  Unable to map MEMORY register, "
+                               "FDDI adapter will be disabled.\n");
+               err = -EIO;
+               goto err_out3;
+       }
+#else
+       dev->base_addr = port;
+#endif
 
+       dev->irq = pdev->irq;
        dev->get_stats = &skfp_ctl_get_stats;
        dev->open = &skfp_open;
        dev->stop = &skfp_close;
        dev->hard_start_xmit = &skfp_send_pkt;
-       dev->hard_header = NULL;        /* set in fddi_setup() */
-       dev->rebuild_header = NULL;     /* set in fddi_setup() */
        dev->set_multicast_list = &skfp_ctl_set_multicast_list;
        dev->set_mac_address = &skfp_ctl_set_mac_address;
        dev->do_ioctl = &skfp_ioctl;
-       dev->set_config = NULL; /* not supported for now &&& */
        dev->header_cache_update = NULL;        /* not supported */
-       dev->change_mtu = NULL; /* set in fddi_setup() */
 
        SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
 
-       /* Initialize remaining device structure information */
-       fddi_setup(dev);
-}                              // init_device
+       /* Initialize board structure with bus-specific info */
+       smc = (struct s_smc *) dev->priv;
+       smc->os.dev = dev;
+       smc->os.bus_type = SK_BUS_TYPE_PCI;
+       smc->os.pdev = *pdev;
+       smc->os.QueueSkb = MAX_TX_QUEUE_LEN;
+       smc->os.MaxFrameSize = MAX_FRAME_SIZE;
+       smc->os.dev = dev;
+       smc->hw.slot = -1;
+       smc->os.ResetRequested = FALSE;
+       skb_queue_head_init(&smc->os.SendSkbQueue);
+
+       err = skfp_driver_init(dev);
+       if (err)
+               goto err_out4;
+
+       err = register_netdev(dev);
+       if (err)
+               goto err_out5;
+
+       ++num_boards;
+       pci_set_drvdata(pdev, dev);
+
+       if ((pdev->subsystem_device & 0xff00) == 0x5500 ||
+           (pdev->subsystem_device & 0xff00) == 0x5800) 
+               printk("%s: SysKonnect FDDI PCI adapter"
+                      " found (SK-%04X)\n", dev->name, 
+                      pdev->subsystem_device);
+       else
+               printk("%s: FDDI PCI adapter found\n", dev->name);
 
+       return 0;
+err_out5:
+       if (smc->os.SharedMemAddr) 
+               pci_free_consistent(pdev, smc->os.SharedMemSize,
+                                   smc->os.SharedMemAddr, 
+                                   smc->os.SharedMemDMA);
+       pci_free_consistent(pdev, MAX_FRAME_SIZE,
+                           smc->os.LocalRxBuffer, smc->os.LocalRxBufferDMA);
+err_out4:
+#ifdef MEM_MAPPED_IO
+       iounmap((void *) dev->base_addr);
+#endif
+err_out3:
+       free_netdev(dev);
+err_out2:
+       pci_release_regions(pdev);
+err_out1:
+       return err;
+}
 
-/************************
- *
- * If at end of fddi device list and can't use current entry, malloc
- * one up. If memory could not be allocated, print an error message.
- *
-************************/
-static struct net_device *insert_device(struct net_device *dev,
-                                   int (*init) (struct net_device *))
+/*
+ * Called for each adapter board from pci_unregister_driver
+ */
+static void __devexit skfp_remove_one(struct pci_dev *pdev)
 {
-       struct net_device *new;
-       int len;
-
-       PRINTK(KERN_INFO "entering insert_device\n");
-       len = sizeof(struct net_device) + sizeof(struct s_smc);
-       new = (struct net_device *) kmalloc(len, GFP_KERNEL);
-       if (new == NULL) {
-               printk("fddi%d: Device not initialised, insufficient memory\n",
-                      num_fddi);
-               return NULL;
-       } else {
-               memset((char *) new, 0, len);
-               new->priv = (struct s_smc *) (new + 1);
-               new->init = init;       /* initialisation routine */
-               if (!loading_module) {
-                       new->next = dev->next;
-                       dev->next = new;
-               }
-               /* create new device name */
-               if (num_fddi > 999) {
-                       sprintf(new->name, "fddi????");
-               } else {
-                       sprintf(new->name, "fddi%d", num_fddi);
-               }
-       }
-       return new;
-}                              // insert_device
+       struct net_device *p = pci_get_drvdata(pdev);
+       struct s_smc *lp = p->priv;
 
+       unregister_netdev(p);
 
-/************************
- *
- * Get the number of a "fddiX" string
- *
- ************************/
-static int fddi_dev_index(unsigned char *s)
-{
-       int i = 0, j = 0;
-
-       for (; *s; s++) {
-               if (isdigit(*s)) {
-                       j = 1;
-                       i = (i * 10) + (*s - '0');
-               } else if (j)
-                       break;
+       if (lp->os.SharedMemAddr) {
+               pci_free_consistent(&lp->os.pdev,
+                                   lp->os.SharedMemSize,
+                                   lp->os.SharedMemAddr,
+                                   lp->os.SharedMemDMA);
+               lp->os.SharedMemAddr = NULL;
        }
-       return i;
-}                              // fddi_dev_index
-
-
-/************************
- *
- * Used if loaded as module only. Link the device structures
- * together. Needed to release them all at unload.
- *
-************************/
-static void link_modules(struct net_device *dev, struct net_device *tmp)
-{
-       struct net_device *p = dev;
-
-       if (p) {
-               while (((struct s_smc *) (p->priv))->os.next_module) {
-                       p = ((struct s_smc *) (p->priv))->os.next_module;
-               }
-
-               if (dev != tmp) {
-                       ((struct s_smc *) (p->priv))->os.next_module = tmp;
-               } else {
-                       ((struct s_smc *) (p->priv))->os.next_module = NULL;
-               }
+       if (lp->os.LocalRxBuffer) {
+               pci_free_consistent(&lp->os.pdev,
+                                   MAX_FRAME_SIZE,
+                                   lp->os.LocalRxBuffer,
+                                   lp->os.LocalRxBufferDMA);
+               lp->os.LocalRxBuffer = NULL;
        }
-       return;
-}                              // link_modules
-
+#ifdef MEM_MAPPED_IO
+       iounmap((void *) p->base_addr);
+#endif
+       pci_release_regions(pdev);
+       free_netdev(p);
 
+       pci_set_drvdata(pdev, NULL);
+}
 
 /*
  * ====================
@@ -653,11 +408,11 @@ static void link_modules(struct net_device *dev, struct net_device *tmp)
  *    0 - initialization succeeded
  *   -1 - initialization failed
  */
-static int skfp_driver_init(struct net_device *dev)
+static  int skfp_driver_init(struct net_device *dev)
 {
        struct s_smc *smc = (struct s_smc *) dev->priv;
        skfddi_priv *bp = PRIV(dev);
-       u8 val;                 /* used for I/O read/writes */
+       int err = -EIO;
 
        PRINTK(KERN_INFO "entering skfp_driver_init\n");
 
@@ -666,9 +421,7 @@ static int skfp_driver_init(struct net_device *dev)
        smc->hw.iop = dev->base_addr;
 
        // Get the interrupt level from the PCI Configuration Table
-       val = dev->irq;
-
-       smc->hw.irq = val;
+       smc->hw.irq = dev->irq;
 
        spin_lock_init(&bp->DriverLock);
        
@@ -738,7 +491,7 @@ fail:
                                    bp->LocalRxBuffer, bp->LocalRxBufferDMA);
                bp->LocalRxBuffer = NULL;
        }
-       return (-1);
+       return err;
 }                              // skfp_driver_init
 
 
@@ -766,14 +519,15 @@ fail:
 static int skfp_open(struct net_device *dev)
 {
        struct s_smc *smc = (struct s_smc *) dev->priv;
+       int err;
 
        PRINTK(KERN_INFO "entering skfp_open\n");
        /* Register IRQ - support shared interrupts by passing device ptr */
-       if (request_irq(dev->irq, (void *) skfp_interrupt, SA_SHIRQ,
-                       dev->name, dev)) {
-               printk("%s: Requested IRQ %d is busy\n", dev->name, dev->irq);
-               return (-EAGAIN);
-       }
+       err = request_irq(dev->irq, (void *) skfp_interrupt, SA_SHIRQ,
+                         dev->name, dev);
+       if (err)
+               return err;
+
        /*
         * Set current address to factory MAC address
         *
@@ -797,6 +551,7 @@ static int skfp_open(struct net_device *dev)
        /* Disable promiscuous filter settings */
        mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
 
+       netif_start_queue(dev);
        return (0);
 }                              // skfp_open
 
@@ -831,7 +586,6 @@ static int skfp_open(struct net_device *dev)
 static int skfp_close(struct net_device *dev)
 {
        struct s_smc *smc = (struct s_smc *) dev->priv;
-       struct sk_buff *skb;
        skfddi_priv *bp = PRIV(dev);
 
        CLI_FBI();
@@ -844,13 +598,8 @@ static int skfp_close(struct net_device *dev)
        /* Deregister (free) IRQ */
        free_irq(dev->irq, dev);
 
-       for (;;) {
-               skb = skb_dequeue(&bp->SendSkbQueue);
-               if (skb == NULL)
-                       break;
-               bp->QueueSkb++;
-               dev_kfree_skb(skb);
-       }
+       skb_queue_purge(&bp->SendSkbQueue);
+       bp->QueueSkb = MAX_TX_QUEUE_LEN;
 
        return (0);
 }                              // skfp_close
@@ -1285,6 +1034,8 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                break;
        default:
                printk("ioctl for %s: unknow cmd: %04x\n", dev->name, ioc.cmd);
+               status = -EOPNOTSUPP;
+
        }                       // switch
 
        return status;
@@ -2538,63 +2289,21 @@ void drv_reset_indication(struct s_smc *smc)
 
 }                              // drv_reset_indication
 
-
-static struct net_device *mdev;
+static struct pci_driver skfddi_pci_driver = {
+       .name           = "skfddi",
+       .id_table       = skfddi_pci_tbl,
+       .probe          = skfp_init_one,
+       .remove         = __devexit_p(skfp_remove_one),
+};
 
 static int __init skfd_init(void)
 {
-       struct net_device *p;
-
-       if ((mdev = insert_device(NULL, skfp_probe)) == NULL)
-               return -ENOMEM;
-
-       for (p = mdev; p != NULL; p = ((struct s_smc *)p->priv)->os.next_module) {
-               if (register_netdev(p) != 0) {
-                       printk("skfddi init_module failed\n");
-                       return -EIO;
-               }
-       }
-
-       return 0;
+       return pci_module_init(&skfddi_pci_driver);
 }
 
-static struct net_device *unlink_modules(struct net_device *p)
-{
-       struct net_device *next = NULL;
-
-       if (p->priv) {          /* Private areas allocated? */
-               struct s_smc *lp = (struct s_smc *) p->priv;
-
-               next = lp->os.next_module;
-
-               if (lp->os.SharedMemAddr) {
-                       pci_free_consistent(&lp->os.pdev,
-                                           lp->os.SharedMemSize,
-                                           lp->os.SharedMemAddr,
-                                           lp->os.SharedMemDMA);
-                       lp->os.SharedMemAddr = NULL;
-               }
-               if (lp->os.LocalRxBuffer) {
-                       pci_free_consistent(&lp->os.pdev,
-                                           MAX_FRAME_SIZE,
-                                           lp->os.LocalRxBuffer,
-                                           lp->os.LocalRxBufferDMA);
-                       lp->os.LocalRxBuffer = NULL;
-               }
-               release_region(p->base_addr, 
-                       (lp->os.bus_type == SK_BUS_TYPE_PCI ? FP_IO_LEN : 0));
-       }
-       unregister_netdev(p);
-       printk("%s: unloaded\n", p->name);
-       free_netdev(p);         /* Free the device structure */
-
-       return next;
-}                              // unlink_modules
-
 static void __exit skfd_exit(void)
 {
-       while (mdev)
-               mdev = unlink_modules(mdev);
+       pci_unregister_driver(&skfddi_pci_driver);
 }
 
 module_init(skfd_init);
index b9dc4a3..c2e153a 100644 (file)
@@ -202,22 +202,18 @@ int __init ultramca_probe(struct device *gen_dev)
                return -ENXIO;
 
         /* Adapter found. */
-       dev  = alloc_etherdev(0);
+       dev  = alloc_ei_netdev();
        if(!dev)
                return -ENODEV;
 
        SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, gen_dev);
-
-       rc = register_netdev(dev);
-       if (rc)
-               goto err_free_netdev;
-
-       printk(KERN_INFO "%s: %s found in slot %d\n",
-              dev->name, smc_mca_adapter_names[adapter], slot + 1);
-
        mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]);
        mca_device_set_claim(mca_dev, 1);
+
+       printk(KERN_INFO "smc_mca: %s found in slot %d\n",
+                      smc_mca_adapter_names[adapter], slot + 1);
+
        ultra_found++;
 
        dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase);
@@ -266,18 +262,18 @@ int __init ultramca_probe(struct device *gen_dev)
        /* sanity check, shouldn't happen */
        if (dev->mem_start == 0) {
                rc = -ENODEV;
-               goto err_unregister_netdev;
+               goto err_unclaim;
        }
 
        if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) {
                rc = -ENODEV;
-               goto err_unregister_netdev;
+               goto err_unclaim;
        }
 
        reg4 = inb(ioaddr + 4) & 0x7f;
        outb(reg4, ioaddr + 4);
 
-       printk(KERN_INFO "%s: Parameters: %#3x,", dev->name, ioaddr);
+       printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x,", slot + 1, ioaddr);
 
        for (i = 0; i < 6; i++)
                printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
@@ -299,14 +295,6 @@ int __init ultramca_probe(struct device *gen_dev)
 
        outb(reg4, ioaddr + 4);
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields.
-        */
-
-       rc = ethdev_init(dev);
-       if (rc) {
-               printk (", no memory for dev->priv.\n");
-               goto err_release_region;
-       }
        gen_dev->driver_data = dev;
 
        /* The 8390 isn't at the base address, so fake the offset
@@ -339,13 +327,16 @@ int __init ultramca_probe(struct device *gen_dev)
 
        NS8390_init(dev, 0);
 
+       rc = register_netdev(dev);
+       if (rc)
+               goto err_release_region;
+
        return 0;
 
 err_release_region:
        release_region(ioaddr, ULTRA_IO_EXTENT);
-err_unregister_netdev:
-       unregister_netdev(dev);
-err_free_netdev:
+err_unclaim:
+       mca_device_set_claim(mca_dev, 0);
        free_netdev(dev);
        return rc;
 }
@@ -463,14 +454,14 @@ static int ultramca_remove(struct device *gen_dev)
        struct mca_device *mca_dev = to_mca_device(gen_dev);
        struct net_device *dev = (struct net_device *)gen_dev->driver_data;
 
-       if(dev && dev->priv) {
+       if (dev) {
                /* NB: ultra_close_card() does free_irq */
                int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
 
+               unregister_netdev(dev);
                mca_device_set_claim(mca_dev, 0);
                release_region(ioaddr, ULTRA_IO_EXTENT);
-               unregister_netdev(dev);
-               kfree(dev->priv);
+               free_netdev(dev);
        }
        return 0;
 }
index 0bb885b..27880ad 100644 (file)
@@ -76,7 +76,6 @@ static const char version[] =
 static unsigned int ultra_portlist[] __initdata =
 {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
 
-int ultra_probe(struct net_device *dev);
 static int ultra_probe1(struct net_device *dev, int ioaddr);
 
 #ifdef __ISAPNP__
@@ -127,10 +126,11 @@ MODULE_DEVICE_TABLE(isapnp, ultra_device_ids);
        following.
 */
 
-int __init ultra_probe(struct net_device *dev)
+static int __init do_ultra_probe(struct net_device *dev)
 {
        int i;
        int base_addr = dev->base_addr;
+       int irq = dev->irq;
 
        SET_MODULE_OWNER(dev);
 
@@ -147,13 +147,51 @@ int __init ultra_probe(struct net_device *dev)
        printk(KERN_NOTICE "smc-ultra.c: No ISAPnP cards found, trying standard ones...\n");
 #endif
 
-       for (i = 0; ultra_portlist[i]; i++)
+       for (i = 0; ultra_portlist[i]; i++) {
+               dev->irq = irq;
                if (ultra_probe1(dev, ultra_portlist[i]) == 0)
                        return 0;
+       }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       /* NB: ultra_close_card() does free_irq */
+#ifdef __ISAPNP__
+       struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+       if (idev)
+               pnp_device_detach(idev);
+#endif
+       release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
+}
+
+struct net_device * __init ultra_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_ultra_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init ultra_probe1(struct net_device *dev, int ioaddr)
 {
        int i, retval;
@@ -226,13 +264,6 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
                eeprom_irq = 1;
        }
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (", no memory for dev->priv.\n");
-                retval = -ENOMEM;
-               goto out;
-        }
-
        /* The 8390 isn't at the base address, so fake the offset */
        dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
 
@@ -500,7 +531,7 @@ ultra_close_card(struct net_device *dev)
 \f
 #ifdef MODULE
 #define MAX_ULTRA_CARDS        4       /* Max number of Ultra cards per module */
-static struct net_device dev_ultra[MAX_ULTRA_CARDS];
+static struct net_device *dev_ultra[MAX_ULTRA_CARDS];
 static int io[MAX_ULTRA_CARDS];
 static int irq[MAX_ULTRA_CARDS];
 
@@ -516,26 +547,33 @@ ISA device autoprobes on a running machine are not recommended. */
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ultra[this_dev];
-               dev->irq = irq[this_dev];
-               dev->base_addr = io[this_dev];
-               dev->init = ultra_probe;
                if (io[this_dev] == 0)  {
                        if (this_dev != 0) break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) return 0;       /* Got at least one. */
-                       return -ENXIO;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               if (do_ultra_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_ultra[found++] = dev;
+                               continue;
+                       }
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -544,20 +582,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ultra[this_dev];
-               if (dev->priv != NULL) {
-                       /* NB: ultra_close_card() does free_irq */
-                       int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
-
-#ifdef __ISAPNP__
-                       struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
-                       if (idev)
-                               pnp_device_detach(idev);
-#endif
-
+               struct net_device *dev = dev_ultra[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       release_region(ioaddr, ULTRA_IO_EXTENT);
-                       kfree(dev->priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index aac76a5..c400ef7 100644 (file)
@@ -61,7 +61,6 @@ static const char *version = "smc-ultra32.c: 06/97 v1.00\n";
 
 #include "8390.h"
 
-int ultra32_probe(struct net_device *dev);
 static int ultra32_probe1(struct net_device *dev, int ioaddr);
 static int ultra32_open(struct net_device *dev);
 static void ultra32_reset_8390(struct net_device *dev);
@@ -98,26 +97,59 @@ static int ultra32_close(struct net_device *dev);
 #define ULTRA32_CFG6   (-0x15) /* 0xc8b */
 #define ULTRA32_CFG7   0x0d    /* 0xcad */
 
+static void cleanup_card(struct net_device *dev)
+{
+       int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET;
+       /* NB: ultra32_close_card() does free_irq */
+       release_region(ioaddr, ULTRA32_IO_EXTENT);
+}
 
 /*     Probe for the Ultra32.  This looks like a 8013 with the station
        address PROM at I/O ports <base>+8 to <base>+13, with a checksum
        following.
 */
 
-int __init ultra32_probe(struct net_device *dev)
+struct net_device * __init ultra32_probe(int unit)
 {
-       int ioaddr;
+       struct net_device *dev;
+       int base;
+       int irq;
+       int err = -ENODEV;
+
+       if (!EISA_bus)
+               return ERR_PTR(-ENODEV);
+
+       dev = alloc_ei_netdev();
 
-       if (!EISA_bus) return -ENODEV;
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
 
        SET_MODULE_OWNER(dev);
 
-       /* EISA spec allows for up to 16 slots, but 8 is typical. */
-       for (ioaddr = 0x1000 + ULTRA32_BASE; ioaddr < 0x9000; ioaddr += 0x1000)
-               if (ultra32_probe1(dev, ioaddr) == 0)
-                       return 0;
+       irq = dev->irq;
 
-       return -ENODEV;
+       /* EISA spec allows for up to 16 slots, but 8 is typical. */
+       for (base = 0x1000 + ULTRA32_BASE; base < 0x9000; base += 0x1000) {
+               if (ultra32_probe1(dev, base) == 0)
+                       break;
+               dev->irq = irq;
+       }
+       if (base >= 0x9000)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
@@ -210,13 +242,6 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
                dev->irq = irq;
        }
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (", no memory for dev->priv.\n");
-                retval = -ENOMEM;
-               goto out;
-        }
-
        /* The 8390 isn't at the base address, so fake the offset */
        dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET;
 
@@ -380,7 +405,7 @@ static void ultra32_block_output(struct net_device *dev,
 \f
 #ifdef MODULE
 #define MAX_ULTRA32_CARDS   4  /* Max number of Ultra cards per module */
-static struct net_device dev_ultra[MAX_ULTRA32_CARDS];
+static struct net_device *dev_ultra[MAX_ULTRA32_CARDS];
 
 MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver");
 MODULE_LICENSE("GPL");
@@ -390,18 +415,15 @@ int init_module(void)
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ultra[this_dev];
-               dev->init = ultra32_probe;
-               if (register_netdev(dev) != 0) {
-                       if (found > 0) { /* Got at least one. */
-                               return 0;
-                       }
-                       printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n");
-                       return -ENXIO;
-               }
-               found++;
+               struct net_device *dev = ultra32_probe(-1);
+               if (IS_ERR(dev))
+                       break;
+               dev_ultra[found++] = dev;
        }
-       return 0;
+       if (found)
+               return 0;
+       printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n");
+       return -ENXIO;
 }
 
 void cleanup_module(void)
@@ -409,14 +431,11 @@ void cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
-               struct net_device *dev = &dev_ultra[this_dev];
-               if (dev->priv != NULL) {
-                       int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET;
-                       void *priv = dev->priv;
-                       /* NB: ultra32_close_card() does free_irq */
-                       release_region(ioaddr, ULTRA32_IO_EXTENT);
+               struct net_device *dev = dev_ultra[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index 4d24343..9bac2d6 100644 (file)
@@ -191,7 +191,7 @@ struct smc_local {
  .
  . NB:This shouldn't be static since it is referred to externally.
 */
-int smc_init(struct net_device *dev);
+struct net_device *smc_init(int unit);
 
 /*
  . The kernel calls this function when someone wants to use the device,
@@ -672,7 +672,7 @@ static void smc_hardware_send_packet( struct net_device * dev )
 
 /*-------------------------------------------------------------------------
  |
- | smc_init( struct net_device * dev )
+ | smc_init(int unit)
  |   Input parameters:
  |     dev->base_addr == 0, try to find all possible locations
  |     dev->base_addr == 1, return failure code
@@ -680,31 +680,56 @@ static void smc_hardware_send_packet( struct net_device * dev )
  |     dev->base_addr == <anything else>   this is the address to check
  |
  |   Output:
- |     0 --> there is a device
- |     anything else, error
+ |     pointer to net_device or ERR_PTR(error)
  |
  ---------------------------------------------------------------------------
 */
-int __init smc_init(struct net_device *dev)
+static int io;
+static int irq;
+static int ifport;
+
+struct net_device * __init smc_init(int unit)
 {
-       int i;
-       int base_addr = dev->base_addr;
+       struct net_device *dev = alloc_etherdev(sizeof(struct smc_local));
+       unsigned *port;
+       int err = 0;
+
+       if (!dev)
+               return ERR_PTR(-ENODEV);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+       }
 
        SET_MODULE_OWNER(dev);
 
-       /*  try a specific location */
-       if (base_addr > 0x1ff)
-               return smc_probe(dev, base_addr);
-       else if (base_addr != 0)
-               return -ENXIO;
-
-       /* check every ethernet address */
-       for (i = 0; smc_portlist[i]; i++)
-               if (smc_probe(dev, smc_portlist[i]) == 0)
-                       return 0;
-
-       /* couldn't find anything */
-       return -ENODEV;
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = smc_probe(dev, io);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+               for (port = smc_portlist; *port; port++) {
+                       if (smc_probe(dev, *port) == 0)
+                               break;
+               }
+               if (!*port)
+                       err = -ENODEV;
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, SMC_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /*----------------------------------------------------------------------
@@ -821,6 +846,9 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
        if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name))
                return -EBUSY;
 
+       dev->irq = irq;
+       dev->if_port = ifport;
+
        /* First, see if the high byte is 0x33 */
        bank = inw( ioaddr + BANK_SELECT );
        if ( (bank & 0xFF00) != 0x3300 ) {
@@ -969,28 +997,14 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
                printk("%2.2x:", dev->dev_addr[i] );
        printk("%2.2x \n", dev->dev_addr[5] );
 
-
-       /* Initialize the private structure. */
-       if (dev->priv == NULL) {
-               dev->priv = kmalloc(sizeof(struct smc_local), GFP_KERNEL);
-               if (dev->priv == NULL) {
-                       retval = -ENOMEM;
-                       goto err_out;
-               }
-       }
        /* set the private data to zero by default */
        memset(dev->priv, 0, sizeof(struct smc_local));
 
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-
        /* Grab the IRQ */
        retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
        if (retval) {
                printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
                        dev->irq, retval);
-               kfree(dev->priv);
-               dev->priv = NULL;
                goto err_out;
        }
 
@@ -1524,10 +1538,7 @@ static void smc_set_multicast_list(struct net_device *dev)
 
 #ifdef MODULE
 
-static struct net_device devSMC9194;
-static int io;
-static int irq;
-static int ifport;
+static struct net_device *devSMC9194;
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(io, "i");
@@ -1539,32 +1550,23 @@ MODULE_PARM_DESC(ifport, "SMC 99194 interface port (0-default, 1-TP, 2-AUI)");
 
 int init_module(void)
 {
-       int result;
-
        if (io == 0)
                printk(KERN_WARNING
                CARDNAME": You shouldn't use auto-probing with insmod!\n" );
 
        /* copy the parameters from insmod into the device structure */
-       devSMC9194.base_addr = io;
-       devSMC9194.irq       = irq;
-       devSMC9194.if_port      = ifport;
-       devSMC9194.init         = smc_init;
-       if ((result = register_netdev(&devSMC9194)) != 0)
-               return result;
-
+       devSMC9194 = smc_init(-1);
+       if (IS_ERR(devSMC9194))
+               return PTR_ERR(devSMC9194);
        return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev(&devSMC9194);
-
-       free_irq(devSMC9194.irq, &devSMC9194);
-       release_region(devSMC9194.base_addr, SMC_IO_EXTENT);
-
-       if (devSMC9194.priv)
-               kfree(devSMC9194.priv);
+       unregister_netdev(devSMC9194);
+       free_irq(devSMC9194->irq, devSMC9194);
+       release_region(devSMC9194->base_addr, SMC_IO_EXTENT);
+       free_netdev(devSMC9194);
 }
 
 #endif /* MODULE */
index 3b8cbb3..74a0707 100644 (file)
@@ -98,28 +98,20 @@ STNIC_WRITE (int reg, byte val)
   STNIC_DELAY ();
 }
 \f
-int __init stnic_probe(void)
+static int __init stnic_probe(void)
 {
   struct net_device *dev;
-  int i;
+  int i, err;
 
   /* If we are not running on a SolutionEngine, give up now */
   if (! MACH_SE)
     return -ENODEV;
 
   /* New style probing API */
-  dev = init_etherdev (NULL, 0);
+  dev = alloc_ei_netdev();
   if (!dev)
        return -ENOMEM;
   SET_MODULE_OWNER(dev);
-  stnic_dev = dev;
-
-  /* Allocate dev->priv and fill in 8390 specific dev fields. */
-  if (ethdev_init (dev))
-    {
-      printk (KERN_EMERG "Unable to get memory for dev->priv.\n");
-      return -ENOMEM;
-    }
 
 #ifdef CONFIG_SH_STANDARD_BIOS 
   sh_bios_get_node_addr (stnic_eadr);
@@ -135,13 +127,11 @@ int __init stnic_probe(void)
 
   /* Snarf the interrupt now.  There's no point in waiting since we cannot
      share and the board will usually be enabled. */
-  i = request_irq (dev->irq, ei_interrupt, 0, dev->name, dev);
-  if (i)  {
+  err = request_irq (dev->irq, ei_interrupt, 0, dev->name, dev);
+  if (err)  {
       printk (KERN_EMERG " unable to get IRQ %d.\n", dev->irq);
-      unregister_netdev(dev);
-      kfree(dev->priv);
-      kfree(dev);
-      return i;
+      free_netdev(dev);
+      return err;
     }
 
   ei_status.name = dev->name;
@@ -162,6 +152,14 @@ int __init stnic_probe(void)
 
   stnic_init (dev);
 
+  err = register_netdev(dev);
+  if (err) {
+    free_irq(dev->irq, dev);
+    free_netdev(dev);
+    return err;
+  }
+  stnic_dev = dev;
+
   printk (KERN_INFO "NS ST-NIC 83902A\n");
 
   return 0;
@@ -305,15 +303,13 @@ stnic_init (struct net_device *dev)
   return;
 }
 
-/* Hardware interrupt handler.  */
-irqreturn_t ei_interrupt (int irq, void *dev_id, struct pt_regs *regs);
-
-irqreturn_t
-do_stnic_intr (int irq, void *dev_id, struct pt_regs *regs)
+static void __exit stnic_cleanup(void)
 {
-  return ei_interrupt (0, stnic_dev, regs);
+       unregister_netdev(stnic_dev);
+       free_irq(stnic_dev->irq, stnic_dev);
+       free_netdev(stnic_dev);
 }
 
 module_init(stnic_probe);
-/* No cleanup routine. */
+module_exit(stnic_cleanup);
 MODULE_LICENSE("GPL");
index 632cc04..669a02f 100644 (file)
@@ -55,6 +55,7 @@ static int fifo=0x8;  /* don't change */
 
 #define DEBUG       /* debug on */
 #define SYSBUSVAL 0 /* 16 Bit */
+#define SUN3_82586_TOTAL_SIZE  PAGE_SIZE
 
 #define sun3_attn586()  {*(volatile unsigned char *)(dev->base_addr) |= IEOB_ATTEN; *(volatile unsigned char *)(dev->base_addr) &= ~IEOB_ATTEN;}
 #define sun3_reset586() {*(volatile unsigned char *)(dev->base_addr) = 0; udelay(100); *(volatile unsigned char *)(dev->base_addr) = IEOB_NORSET;}
@@ -277,10 +278,12 @@ static void alloc586(struct net_device *dev)
        memset((char *)p->scb,0,sizeof(struct scb_struct));
 }
 
-int __init sun3_82586_probe(struct net_device *dev)
+struct net_device * __init sun3_82586_probe(int unit)
 {
+       struct net_device *dev;
        unsigned long ioaddr;
        static int found = 0;
+       int err = -ENOMEM;
        
        /* check that this machine has an onboard 82586 */
        switch(idprom->id_machtype) {
@@ -290,31 +293,51 @@ int __init sun3_82586_probe(struct net_device *dev)
                break;
 
        default:
-               return(-ENODEV);
+               return ERR_PTR(-ENODEV);
        }
 
-       if(found)
-               return -ENODEV;
+       if (found)
+               return ERR_PTR(-ENODEV);
        
-       ioaddr = (unsigned long)ioremap(IE_OBIO, PAGE_SIZE);
+       ioaddr = (unsigned long)ioremap(IE_OBIO, SUN3_82586_TOTAL_SIZE);
+       if (!ioaddr)
+               return ERR_PTR(-ENOMEM);
        found = 1;
        
+       dev = alloc_etherdev(sizeof(struct priv));
+       if (!dev)
+               goto out;
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
        SET_MODULE_OWNER(dev);
 
        dev->irq = IE_IRQ;
        dev->base_addr = ioaddr;
-       if(sun3_82586_probe1(dev, ioaddr) == 0)
-               return 0;
-
-       return -ENODEV;
+       err = sun3_82586_probe1(dev, ioaddr);
+       if (err)
+               goto out1;
+       err = register_netdev(dev);
+       if (err)
+               goto out2;
+       return dev;
+
+out2:
+       release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
+out1:
+       free_netdev(dev);
+out:
+       iounmap((void *)ioaddr);
+       return ERR_PTR(err);
 }
 
 static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
 {
        int i, size, retval;
 
-//     if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
-//             return -EBUSY;
+       if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
+               return -EBUSY;
 
        /* copy in the ethernet address from the prom */
        for(i = 0; i < 6 ; i++)
@@ -341,16 +364,6 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
                goto out;
        }
 
-       dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
-       if(dev->priv == NULL) {
-               printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
-               retval = -ENOMEM;
-               goto out;
-       }
-
-       /* warning: we don't free it on errors */
-       memset((char *) dev->priv,0,sizeof(struct priv));
-
        ((struct priv *) (dev->priv))->memtop = (char *)dvma_btov(dev->mem_start);
        ((struct priv *) (dev->priv))->base = (unsigned long) dvma_btov(0);
        alloc586(dev);
@@ -374,11 +387,9 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
        dev->set_multicast_list = set_multicast_list;
 
        dev->if_port            = 0;
-
-       ether_setup(dev);
-
        return 0;
 out:
+       release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
        return retval;
 }
 
@@ -1138,21 +1149,23 @@ static void set_multicast_list(struct net_device *dev)
 
 #ifdef MODULE
 #error This code is not currently supported as a module
-static struct net_device dev_sun3_82586;
+static struct net_device *dev_sun3_82586;
 
 int init_module(void)
 {
-       dev_sun3_82586.init = sun3_82586_probe;
-       if (register_netdev(&dev_sun3_82586) != 0)
-               return -EIO;
+       dev_sun3_82586 = sun3_82586_probe(-1);
+       if (IS_ERR(dev_sun3_82586))
+               return PTR_ERR(dev_sun3_82586);
        return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev(&dev_sun3_82586);
-       kfree(dev_sun3_82586.priv);
-       dev_sun3_82586.priv = NULL;
+       unsigned long ioaddr = dev_sun3_82586->base_addr;
+       unregister_netdev(dev_sun3_82586);
+       release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
+       iounmap((void *)ioaddr);
+       free_netdev(dev_sun3_82586);
 }
 #endif /* MODULE */
 
index 5bfad9b..f445f1f 100644 (file)
@@ -246,9 +246,11 @@ static void set_multicast_list( struct net_device *dev );
 
 /************************* End of Prototypes **************************/
 
-int __init sun3lance_probe( struct net_device *dev )
-{      
+struct net_device * __init sun3lance_probe(int unit)
+{
+       struct net_device *dev;
        static int found;
+       int err = -ENODEV;
 
        /* check that this machine has an onboard lance */
        switch(idprom->id_machtype) {
@@ -259,18 +261,37 @@ int __init sun3lance_probe( struct net_device *dev )
                break;
 
        default:
-               return(-ENODEV);
+               return ERR_PTR(-ENODEV);
        }
 
-       if(found)
-               return(-ENODEV);
+       if (found)
+               return ERR_PTR(-ENODEV);
 
-       if (lance_probe(dev)) {
-                       found = 1;
-                       return( 0 );
+       dev = alloc_etherdev(sizeof(struct lance_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
        }
+       SET_MODULE_OWNER(dev);
+
+       if (!lance_probe(dev))
+               goto out;
 
-       return( -ENODEV );
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       found = 1;
+       return dev;
+
+out1:
+#ifdef CONFIG_SUN3
+       iounmap((void *)dev->base_addr);
+#endif
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 static int __init lance_probe( struct net_device *dev)
@@ -285,6 +306,8 @@ static int __init lance_probe( struct net_device *dev)
 
 #ifdef CONFIG_SUN3
        ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
+       if (!ioaddr)
+               return 0;
 #else
        ioaddr = SUN3X_LANCE;
 #endif
@@ -303,17 +326,15 @@ static int __init lance_probe( struct net_device *dev)
                ioaddr_probe[0] = tmp1;
                ioaddr_probe[1] = tmp2;
 
+#ifdef CONFIG_SUN3
+               iounmap((void *)ioaddr);
+#endif
                return 0;
        }
 
-       init_etherdev( dev, sizeof(struct lance_private) );
-       if (!dev->priv) {
-               dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
-               if (!dev->priv)
-                       return 0;
-       }
        lp = (struct lance_private *)dev->priv;
 
+       /* XXX - leak? */
        MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
 
        lp->iobase = (volatile unsigned short *)ioaddr;
@@ -921,32 +942,24 @@ static void set_multicast_list( struct net_device *dev )
 
 
 #ifdef MODULE
-static char devicename[9];
 
-static struct net_device sun3lance_dev =
-{
-       devicename,     /* filled in by register_netdev() */
-       0, 0, 0, 0,     /* memory */
-       0, 0,           /* base, irq */
-       0, 0, 0, NULL, sun3lance_probe,
-};
+static struct net_device *sun3lance_dev;
 
 int init_module(void)
 {
-       int err;
-
-       if ((err = register_netdev( &sun3lance_dev ))) {
-               if (err == -EIO)  {
-                       printk( "SUN3 Lance not detected.  Module not loaded.\n");
-               }
-               return( err );
-       }
-       return( 0 );
+       sun3lance_dev = sun3lance_probe(-1);
+       if (IS_ERR(sun3lance_dev))
+               return PTR_ERR(sun3lance_dev);
+       return 0;
 }
 
 void cleanup_module(void)
 {
-       unregister_netdev( &sun3lance_dev );
+       unregister_netdev(sun3lance_dev);
+#ifdef CONFIG_SUN3
+       iounmap((void *)sun3lance_dev->base_addr);
+#endif
+       free_netdev(sun3lance_dev);
 }
 
 #endif /* MODULE */
index 934f348..d7be146 100644 (file)
@@ -463,7 +463,6 @@ static void tc35815_set_multicast_list(struct net_device *dev);
 static void    tc35815_chip_reset(struct net_device *dev);
 static void    tc35815_chip_init(struct net_device *dev);
 static void    tc35815_phy_chip_init(struct net_device *dev);
-static int     tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
 
 /* A list of all installed tc35815 devices. */
 static struct net_device *root_tc35815_dev = NULL;
@@ -482,78 +481,76 @@ int
 tc35815_probe(struct pci_dev *pdev,
                const struct pci_device_id *ent)
 {
-       static int called = 0;
        int err = 0;
        int ret;
+       unsigned long pci_memaddr;
+       unsigned int pci_irq_line;
 
-       if (called)
-               return -ENODEV;
-       called++;
+       printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device);
 
-       if (pdev) {
-               unsigned int pci_memaddr;
-               unsigned int pci_irq_line;
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
 
-               printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device);
+        pci_memaddr = pci_resource_start (pdev, 1);
 
-               pci_memaddr = pci_resource_start (pdev, 1);
+        printk(KERN_INFO "    pci_memaddr=%#08lx  resource_flags=%#08lx\n", pci_memaddr, pci_resource_flags (pdev, 0));
 
-               printk(KERN_INFO "    pci_memaddr=%#08lx  resource_flags=%#08lx\n", pci_memaddr, pci_resource_flags (pdev, 0));
+       if (!pci_memaddr) {
+               printk(KERN_WARNING "no PCI MEM resources, aborting\n");
+               ret = -ENODEV;
+               goto err_out;
+       }
+       pci_irq_line = pdev->irq;
+       /* irq disabled. */
+       if (pci_irq_line == 0) {
+               printk(KERN_WARNING "no PCI irq, aborting\n");
+               ret = -ENODEV;
+               goto err_out;
+       }
 
-               if (!pci_memaddr) {
-                       printk(KERN_WARNING "no PCI MEM resources, aborting\n");
-                       return -ENODEV;
-               }
-               pci_irq_line = pdev->irq;
-               /* irq disabled. */
-               if (pci_irq_line == 0) {
-                       printk(KERN_WARNING "no PCI irq, aborting\n");
-                       return -ENODEV;
-               }
+       ret =  tc35815_probe1(pdev, pci_memaddr, pci_irq_line);
+       if (ret)
+               goto err_out;
 
-               ret =  tc35815_probe1(pdev, pci_memaddr, pci_irq_line);
+       pci_set_master(pdev);
 
-               if (!ret) {
-                       if ((err = pci_enable_device(pdev)) < 0) {
-                           printk(KERN_ERR "tc35815_probe: failed to enable device -- err=%d\n", err);
-                           return err;
-                       }
-                       pci_set_master(pdev);
-               }
+       return 0;
 
-               return ret;
-       }
-       return -ENODEV;
+err_out:
+       pci_disable_device(pdev);
+       return ret;
 }
 
 static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq)
 {
        static unsigned version_printed = 0;
-       int i;
+       int i, ret;
        struct tc35815_local *lp;
        struct tc35815_regs *tr;
        struct net_device *dev;
 
        /* Allocate a new 'dev' if needed. */
-       dev = init_etherdev(NULL, sizeof(struct tc35815_local));
+       dev = alloc_etherdev(sizeof(struct tc35815_local));
        if (dev == NULL)
                return -ENOMEM;
 
        /*
-        * init_etherdev allocs and zeros dev->priv
+        * alloc_etherdev allocs and zeros dev->priv
         */
        lp = dev->priv;
 
        if (tc35815_debug  &&  version_printed++ == 0)
                printk(KERN_DEBUG "%s", version);
 
-       printk(KERN_INFO "%s: %s found at %#x, irq %d\n",
-              dev->name, cardname, base_addr, irq);
-
        /* Fill in the 'dev' fields. */
        dev->irq = irq;
        dev->base_addr = (unsigned long)ioremap(base_addr,
                                                sizeof(struct tc35815_regs));
+       if (!dev->base_addr) {
+               ret = -ENOMEM;
+               goto err_out;
+       }
        tr = (struct tc35815_regs*)dev->base_addr;
 
        tc35815_chip_reset(dev);
@@ -570,9 +567,6 @@ static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr
                dev->dev_addr[i] = data & 0xff;
                dev->dev_addr[i+1] = data >> 8;
        }
-       for (i = 0; i < 6; i++)
-               printk(" %2.2x", dev->dev_addr[i]);
-       printk("\n");
 
        /* Initialize the device structure. */
        lp->pdev = pdev;
@@ -594,8 +588,6 @@ static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr
 
        /* do auto negotiation */
        tc35815_phy_chip_init(dev);
-       printk(KERN_INFO "%s: linkspeed %dMbps, %s Duplex\n",
-              dev->name, lp->linkspeed, lp->fullduplex ? "Full" : "Half");
 
        dev->open               = tc35815_open;
        dev->stop               = tc35815_close;
@@ -604,20 +596,34 @@ static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr
        dev->hard_start_xmit    = tc35815_send_packet;
        dev->get_stats          = tc35815_get_stats;
        dev->set_multicast_list = tc35815_set_multicast_list;
+       SET_MODULE_OWNER(dev);
 
-#if 0  /* XXX called in init_etherdev */
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(dev);
-#endif
+       ret = register_netdev(dev);
+       if (ret)
+               goto err_out_iounmap;
+
+       printk(KERN_INFO "%s: %s found at %#x, irq %d, MAC",
+              dev->name, cardname, base_addr, irq);
+       for (i = 0; i < 6; i++)
+               printk(" %2.2x", dev->dev_addr[i]);
+       printk("\n");
+       printk(KERN_INFO "%s: linkspeed %dMbps, %s Duplex\n",
+              dev->name, lp->linkspeed, lp->fullduplex ? "Full" : "Half");
 
        return 0;
+
+err_out_iounmap:
+       iounmap((void *) dev->base_addr);
+err_out:
+       free_netdev(dev);
+       return ret;
 }
 
 
 static int
 tc35815_init_queues(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        int i;
        unsigned long fd_addr;
 
@@ -702,7 +708,7 @@ tc35815_init_queues(struct net_device *dev)
 static void
 tc35815_clear_queues(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        int i;
 
        for (i = 0; i < TX_FD_NUM; i++) {
@@ -719,7 +725,7 @@ tc35815_clear_queues(struct net_device *dev)
 static void
 tc35815_free_queues(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        int i;
 
        if (lp->tfd_base) {
@@ -805,7 +811,7 @@ dump_frfd(struct FrFD *fd)
 static void
 panic_queues(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        int i;
 
        printk("TxFD base %p, start %d, end %d\n",
@@ -823,6 +829,7 @@ panic_queues(struct net_device *dev)
        panic("%s: Illegal queue state.", dev->name);
 }
 
+#if 0
 static void print_buf(char *add, int length)
 {
        int i;
@@ -839,6 +846,7 @@ static void print_buf(char *add, int length)
        }
        printk("\n");
 }
+#endif
 
 static void print_eth(char *add)
 {
@@ -864,7 +872,7 @@ static void print_eth(char *add)
 static int
 tc35815_open(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        /*
         * This is used if the interrupt line can turned off (shared).
         * See 3c503.c for an example of selecting the IRQ at config-time.
@@ -888,19 +896,17 @@ tc35815_open(struct net_device *dev)
        lp->tbusy = 0;
        netif_start_queue(dev);
 
-       MOD_INC_USE_COUNT;
-
        return 0;
 }
 
 static void tc35815_tx_timeout(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr;
-       int flags;
+       unsigned long flags;
 
        spin_lock_irqsave(&lp->lock, flags);
-       printk(KERN_WARNING "%s: transmit timed out, status %#x\n",
+       printk(KERN_WARNING "%s: transmit timed out, status %#lx\n",
               dev->name, tc_readl(&tr->Tx_Stat));
        /* Try to restart the adaptor. */
        tc35815_chip_reset(dev);
@@ -914,7 +920,7 @@ static void tc35815_tx_timeout(struct net_device *dev)
 
 static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr;
 
        if (netif_queue_stopped(dev)) {
@@ -925,7 +931,7 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
                int tickssofar = jiffies - dev->trans_start;
                if (tickssofar < 5)
                        return 1;
-               printk(KERN_WARNING "%s: transmit timed out, status %#x\n",
+               printk(KERN_WARNING "%s: transmit timed out, status %#lx\n",
                       dev->name, tc_readl(&tr->Tx_Stat));
                /* Try to restart the adaptor. */
                tc35815_chip_reset(dev);
@@ -947,7 +953,7 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
                unsigned char *buf = skb->data;
                struct TxFD *txfd = &lp->tfd_base[lp->tfd_start];
-               int flags;
+               unsigned long flags;
                lp->stats.tx_bytes += skb->len;
 
 
@@ -1051,7 +1057,7 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id, struct pt_regs * reg
        }
 
        tr = (struct tc35815_regs*)dev->base_addr;
-       lp = (struct tc35815_local *)dev->priv;
+       lp = dev->priv;
 
        do {
                status = tc_readl(&tr->Int_Src);
@@ -1107,7 +1113,7 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id, struct pt_regs * reg
 static void
 tc35815_rx(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
        unsigned int fdctl;
        int i;
@@ -1157,7 +1163,9 @@ tc35815_rx(struct net_device *dev)
                                offset += len;
                                cur_bd++;
                        }
-       //              print_buf(data,pkt_len);
+#if 0
+                       print_buf(data,pkt_len);
+#endif
                        if (tc35815_debug > 3)
                                print_eth(data);
                        skb->protocol = eth_type_trans(skb, dev);
@@ -1247,7 +1255,7 @@ tc35815_rx(struct net_device *dev)
 static void
 tc35815_check_tx_stat(struct net_device *dev, int status)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        const char *msg = NULL;
 
        /* count collisions */
@@ -1304,7 +1312,7 @@ tc35815_check_tx_stat(struct net_device *dev, int status)
 static void
 tc35815_txdone(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
        struct TxFD *txfd;
        unsigned int fdctl;
@@ -1379,7 +1387,7 @@ tc35815_txdone(struct net_device *dev)
 static int
 tc35815_close(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
 
        lp->tbusy = 1;
        netif_stop_queue(dev);
@@ -1391,8 +1399,6 @@ tc35815_close(struct net_device *dev)
 
        tc35815_free_queues(dev);
 
-       MOD_DEC_USE_COUNT;
-
        return 0;
 }
 
@@ -1402,7 +1408,7 @@ tc35815_close(struct net_device *dev)
  */
 static struct net_device_stats *tc35815_get_stats(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
        unsigned long flags;
 
@@ -1456,7 +1462,7 @@ static void tc35815_set_cam_entry(struct tc35815_regs *tr, int index, unsigned c
                int i;
                for (i = cam_index / 4; i < cam_index / 4 + 2; i++) {
                        tc_writel(i * 4, &tr->CAM_Adr);
-                       printk("CAM 0x%x: %08x",
+                       printk("CAM 0x%x: %08lx",
                               i * 4, tc_readl(&tr->CAM_Data));
                }
        }
@@ -1513,9 +1519,9 @@ tc35815_set_multicast_list(struct net_device *dev)
 
 static unsigned long tc_phy_read(struct net_device *dev, struct tc35815_regs *tr, int phy, int phy_reg)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        unsigned long data;
-       int flags;
+       unsigned long flags;
        
        spin_lock_irqsave(&lp->lock, flags);
 
@@ -1529,8 +1535,8 @@ static unsigned long tc_phy_read(struct net_device *dev, struct tc35815_regs *tr
 
 static void tc_phy_write(struct net_device *dev, unsigned long d, struct tc35815_regs *tr, int phy, int phy_reg)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
-       int flags;
+       struct tc35815_local *lp = dev->priv;
+       unsigned long flags;
 
        spin_lock_irqsave(&lp->lock, flags);
 
@@ -1543,7 +1549,7 @@ static void tc_phy_write(struct net_device *dev, unsigned long d, struct tc35815
 
 static void tc35815_phy_chip_init(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
        static int first = 1;
        unsigned short ctl;
@@ -1648,9 +1654,9 @@ static void tc35815_chip_reset(struct net_device *dev)
 
 static void tc35815_chip_init(struct net_device *dev)
 {
-       struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+       struct tc35815_local *lp = dev->priv;
        struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
-       int flags;
+       unsigned long flags;
        unsigned long txctl = TX_CTL_CMD;
 
        tc35815_phy_chip_init(dev);
@@ -1696,40 +1702,6 @@ static void tc35815_chip_init(struct net_device *dev)
        spin_unlock_irqrestore(&lp->lock, flags);
 }
 
-static int tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
-{
-       int len = 0;
-       off_t pos = 0;
-       off_t begin = 0;
-       struct net_device *dev;
-
-       len += sprintf(buffer, "TC35815 statistics:\n");
-       for (dev = root_tc35815_dev; dev; dev = ((struct tc35815_local *)dev->priv)->next_module) {
-               struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
-               len += sprintf(buffer + len,
-                              "%s: tx_ints %d, rx_ints %d, max_tx_qlen %d\n",
-                              dev->name,
-                              lp->lstats.tx_ints,
-                              lp->lstats.rx_ints,
-                              lp->lstats.max_tx_qlen);
-               pos = begin + len;
-
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-    
-               if (pos > offset+length) break;
-       }
-
-       *start = buffer + (offset - begin);
-       len -= (offset - begin);
-  
-       if (len > length) len = length;
-  
-       return len;
-}
-
 /* XXX */
 void
 tc35815_killall(void)
index a70d32b..f52c8fb 100644 (file)
@@ -5850,10 +5850,12 @@ static int tg3_get_regs_len(struct net_device *dev)
        return TG3_REGDUMP_LEN;
 }
 
-static void tg3_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
+static void tg3_get_regs(struct net_device *dev,
+               struct ethtool_regs *regs, void *_p)
 {
+       u32 *p = _p;
        struct tg3 *tp = dev->priv;
-       u8 *orig_p = p;
+       u8 *orig_p = _p;
        int i;
 
        regs->version = 0;
@@ -5863,15 +5865,15 @@ static void tg3_get_regs(struct net_device *dev, struct ethtool_regs *regs, void
        spin_lock_irq(&tp->lock);
        spin_lock(&tp->tx_lock);
 
-#define __GET_REG32(reg)       (*((u32 *)(p))++ = tr32(reg))
+#define __GET_REG32(reg)       (*(p)++ = tr32(reg))
 #define GET_REG32_LOOP(base,len)               \
-do {   p = orig_p + (base);                    \
+do {   p = (u32 *)(orig_p + (base));           \
        for (i = 0; i < len; i += 4)            \
                __GET_REG32((base) + i);        \
 } while (0)
-#define GET_REG32_1(reg)       \
-do {   p = orig_p + (reg);     \
-       __GET_REG32((reg));     \
+#define GET_REG32_1(reg)                       \
+do {   p = (u32 *)(orig_p + (reg));            \
+       __GET_REG32((reg));                     \
 } while (0)
 
        GET_REG32_LOOP(TG3PCI_VENDOR, 0xb0);
index c97573a..943850c 100644 (file)
@@ -314,7 +314,6 @@ int __devinit xl_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        dev->irq=pdev->irq;
        dev->base_addr=pci_resource_start(pdev,0) ; 
-       dev->init=NULL ; /* Must be null with new api, otherwise get called twice */
        xl_priv->xl_card_name = pci_name(pdev);
        xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE);
        xl_priv->pdev = pdev ; 
@@ -332,7 +331,7 @@ int __devinit xl_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                
        if((i = xl_init(dev))) {
                iounmap(xl_priv->xl_mmio) ; 
-               kfree(dev) ; 
+               free_netdev(dev) ; 
                pci_release_regions(pdev) ; 
                return i ; 
        }                               
@@ -352,7 +351,7 @@ int __devinit xl_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                printk(KERN_ERR "3C359, register netdev failed\n") ;  
                pci_set_drvdata(pdev,NULL) ; 
                iounmap(xl_priv->xl_mmio) ; 
-               kfree(dev) ; 
+               free_netdev(dev) ; 
                pci_release_regions(pdev) ; 
                return i ; 
        }
index 5f2c6fd..af51032 100644 (file)
@@ -181,7 +181,7 @@ err_out_irq:
 err_out_region:
        release_region(pci_ioaddr, ABYSS_IO_EXTENT);
 err_out_trdev:
-       kfree(dev);
+       free_netdev(dev);
        return ret;
 }
 
index 832c82f..83b03d3 100644 (file)
@@ -187,7 +187,7 @@ char __devinit *adapter_def(char type)
 #define TRC_INITV 0x02         /*  verbose init trace points     */
 unsigned char ibmtr_debug_trace = 0;
 
-int            ibmtr_probe(struct net_device *dev);
+static int     ibmtr_probe(struct net_device *dev);
 static int     ibmtr_probe1(struct net_device *dev, int ioaddr);
 static unsigned char get_sram_size(struct tok_info *adapt_info);
 static int     trdev_init(struct net_device *dev);
@@ -313,6 +313,39 @@ static void __devinit find_turbo_adapters(int *iolist) {
        }
 }
 
+static void ibmtr_cleanup_card(struct net_device *dev)
+{
+       if (dev->base_addr) {
+               outb(0,dev->base_addr+ADAPTRESET);
+               
+               schedule_timeout(TR_RST_TIME); /* wait 50ms */
+
+               outb(0,dev->base_addr+ADAPTRESETREL);
+       }
+
+#ifndef PCMCIA
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, IBMTR_IO_EXTENT);
+
+       { 
+               struct tok_info *ti = (struct tok_info *) dev->priv;
+               iounmap((u32 *)ti->mmio);
+               iounmap((u32 *)ti->sram_virt);
+       }
+#endif         
+}
+
+int ibmtr_probe_card(struct net_device *dev)
+{
+       int err = ibmtr_probe(dev);
+       if (!err) {
+               err = register_netdev(dev);
+               if (err)
+                       ibmtr_cleanup_card(dev);
+       }
+       return err;
+}
+
 /****************************************************************************
  *     ibmtr_probe():  Routine specified in the network device structure
  *     to probe for an IBM Token Ring Adapter.  Routine outline:
@@ -325,7 +358,7 @@ static void __devinit find_turbo_adapters(int *iolist) {
  *     which references it.
  ****************************************************************************/
 
-int __devinit ibmtr_probe(struct net_device *dev)
+static int ibmtr_probe(struct net_device *dev)
 {
        int i;
        int base_addr = dev->base_addr;
@@ -1925,23 +1958,24 @@ static int __init ibmtr_init(void)
        find_turbo_adapters(io);
 
        for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) {
+               struct net_device *dev;
                irq[i] = 0;
                mem[i] = 0;
-               dev_ibmtr[i] = alloc_trdev(sizeof(struct tok_info));
-               if (dev_ibmtr[i] == NULL) { 
+               dev = alloc_trdev(sizeof(struct tok_info));
+               if (dev == NULL) { 
                        if (i == 0)
                                return -ENOMEM;
                        break;
                }
-               dev_ibmtr[i]->base_addr = io[i];
-               dev_ibmtr[i]->irq = irq[i];
-               dev_ibmtr[i]->mem_start = mem[i];
-               dev_ibmtr[i]->init = &ibmtr_probe;
-               if (register_netdev(dev_ibmtr[i]) != 0) {
-                       kfree(dev_ibmtr[i]);
-                       dev_ibmtr[i] = NULL;
+               dev->base_addr = io[i];
+               dev->irq = irq[i];
+               dev->mem_start = mem[i];
+
+               if (ibmtr_probe_card(dev)) {
+                       free_netdev(dev);
                        continue;
                }
+               dev_ibmtr[i] = dev;
                count++;
        }
        if (count) return 0;
@@ -1957,27 +1991,9 @@ static void __exit ibmtr_cleanup(void)
        for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){
                if (!dev_ibmtr[i])
                        continue;
-               if (dev_ibmtr[i]->base_addr) {
-                       outb(0,dev_ibmtr[i]->base_addr+ADAPTRESET);
-                       
-                       schedule_timeout(TR_RST_TIME); /* wait 50ms */
-
-                        outb(0,dev_ibmtr[i]->base_addr+ADAPTRESETREL);
-                }
-
                unregister_netdev(dev_ibmtr[i]);
-               free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]);
-               release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
-#ifndef PCMCIA
-               { 
-                       struct tok_info *ti = (struct tok_info *)
-                               dev_ibmtr[i]->priv;
-                       iounmap((u32 *)ti->mmio);
-                       iounmap((u32 *)ti->sram_virt);
-               }
-#endif         
+               ibmtr_cleanup_card(dev_ibmtr[i]);
                free_netdev(dev_ibmtr[i]);
-               dev_ibmtr[i] = NULL;
        }
 }
 module_exit(ibmtr_cleanup);
index ac6552d..ddbd3e2 100644 (file)
@@ -197,7 +197,7 @@ static int __init madgemc_probe(void)
                card = kmalloc(sizeof(struct madgemc_card), GFP_KERNEL);
                if (card==NULL) {
                        printk("madgemc: unable to allocate card struct\n");
-                       kfree(dev);
+                       free_netdev(dev);
                        if (madgemc_card_list)
                                return 0;
                        return -1;
@@ -360,7 +360,7 @@ static int __init madgemc_probe(void)
                        
                        kfree(card);
                        tmsdev_term(dev);
-                       kfree(dev);
+                       free_netdev(dev);
                        if (madgemc_card_list)
                                return 0;
                        return -1;
@@ -399,7 +399,7 @@ static int __init madgemc_probe(void)
                               MADGEMC_IO_EXTENT); 
        getout1:
                kfree(card);
-               kfree(dev);
+               free_netdev(dev);
                slot++;
        }
 
index e419eef..3b15c21 100644 (file)
@@ -228,7 +228,6 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
 #endif
        dev->irq=pdev->irq;
        dev->base_addr=pci_resource_start(pdev, 0);
-       dev->init=NULL; /* Must be NULL otherwise we get called twice */
        olympic_priv->olympic_card_name = pci_name(pdev);
        olympic_priv->pdev = pdev; 
        olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
index fe9bc7a..5ceee62 100644 (file)
@@ -63,7 +63,7 @@ static int dmalist[] __initdata = {
 
 static char cardname[] = "Proteon 1392\0";
 
-int proteon_probe(struct net_device *dev);
+struct net_device *proteon_probe(int unit);
 static int proteon_open(struct net_device *dev);
 static int proteon_close(struct net_device *dev);
 static void proteon_read_eeprom(struct net_device *dev);
@@ -89,80 +89,69 @@ static void proteon_sifwritew(struct net_device *dev, unsigned short val, unsign
        outw(val, dev->base_addr + reg);
 }
 
-struct proteon_card {
-       struct net_device *dev;
-       struct proteon_card *next;
-};
-
-static struct proteon_card *proteon_card_list;
-
-static int __init proteon_probe1(int ioaddr)
+static int __init proteon_probe1(struct net_device *dev, int ioaddr)
 {
        unsigned char chk1, chk2;
        int i;
 
+       if (!request_region(ioaddr, PROTEON_IO_EXTENT, cardname))
+               return -ENODEV;
+               
+
        chk1 = inb(ioaddr + 0x1f);      /* Get Proteon ID reg 1 */
-       if (chk1 != 0x1f)
-               return (-1);
+       if (chk1 != 0x1f) 
+               goto nodev;
+
        chk1 = inb(ioaddr + 0x1e) & 0x07;       /* Get Proteon ID reg 0 */
        for (i=0; i<16; i++) {
                chk2 = inb(ioaddr + 0x1e) & 0x07;
                if (((chk1 + 1) & 0x07) != chk2)
-                       return (-1);
+                       goto nodev;
                chk1 = chk2;
        }
+
+       dev->base_addr = ioaddr;
        return (0);
+nodev:
+       release_region(ioaddr, PROTEON_IO_EXTENT); 
+       return -ENODEV;
 }
 
-int __init proteon_probe(struct net_device *dev)
+struct net_device * __init proteon_probe(int unit)
 {
-        static int versionprinted;
+       struct net_device *dev = alloc_trdev(sizeof(struct net_local));
        struct net_local *tp;
-       int i,j;
-       struct proteon_card *card;
+        static int versionprinted;
+       const unsigned *port;
+       int j,err = 0;
 
-#ifndef MODULE
-       netdev_boot_setup_check(dev);
-       tr_setup(dev);
-#endif
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-       SET_MODULE_OWNER(dev);
-       if (!dev->base_addr)
-       {
-               for(i = 0; portlist[i]; i++)
-               {
-                       if (!request_region(portlist[i], PROTEON_IO_EXTENT, cardname))
-                               continue;
-
-                       if(proteon_probe1(portlist[i]))
-                       {
-                               release_region(dev->base_addr, PROTEON_IO_EXTENT); 
-                               continue;
-                       }
+       if (unit >= 0) {
+               sprintf(dev->name, "tr%d", unit);
+               netdev_boot_setup_check(dev);
+       }
 
-                       dev->base_addr = portlist[i];
-                       break;
+       SET_MODULE_OWNER(dev);
+       if (dev->base_addr)     /* probe specific location */
+               err = proteon_probe1(dev, dev->base_addr);
+       else {
+               for (port = portlist; *port; port++) {
+                       err = proteon_probe1(dev, *port);
+                       if (!err)
+                               break;
                }
-               if(!dev->base_addr)
-                       return -1;
        }
-       else
-       {
-               if (!request_region(dev->base_addr, PROTEON_IO_EXTENT, cardname))
-                       return -1;
-
-               if(proteon_probe1(dev->base_addr))
-               {
-                       release_region(dev->base_addr, PROTEON_IO_EXTENT); 
-                       return -1;
-               }
-       } 
+       if (err)
+               goto out4;
 
        /* At this point we have found a valid card. */
 
        if (versionprinted++ == 0)
                printk(KERN_DEBUG "%s", version);
 
+       err = -EIO;
        if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
                goto out4;
 
@@ -264,14 +253,11 @@ int __init proteon_probe(struct net_device *dev)
        printk(KERN_DEBUG "%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
               dev->name, dev->base_addr, dev->irq, dev->dma);
                
-       /* Enlist in the card list */
-       card = kmalloc(sizeof(struct proteon_card), GFP_KERNEL);
-       if (!card)
+       err = register_netdev(dev);
+       if (err)
                goto out;
-       card->next = proteon_card_list;
-       proteon_card_list = card;
-       card->dev = dev;
-       return 0;
+
+       return dev;
 out:
        free_dma(dev->dma);
 out2:
@@ -280,7 +266,8 @@ out3:
        tmsdev_term(dev);
 out4:
        release_region(dev->base_addr, PROTEON_IO_EXTENT); 
-       return -1;
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /*
@@ -370,50 +357,50 @@ MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
 MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
 
-static int __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
+static struct net_device *proteon_dev[ISATR_MAX_ADAPTERS];
+
+static struct net_device * __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
 {
-       int res = -ENOMEM;
-       struct proteon_card *this_card;
-       struct net_device *dev = alloc_trdev(0);
-
-       if (dev) {
-               dev->base_addr = io;
-               dev->irq       = irq;
-               dev->dma       = dma;
-               res = -ENODEV;
-               if (proteon_probe(dev) == 0) {
-                       res = register_netdev(dev);
-                       if (!res)
-                               return 0;
-                       release_region(dev->base_addr, PROTEON_IO_EXTENT);
-                       free_irq(dev->irq, dev);
-                       free_dma(dev->dma);
-                       tmsdev_term(dev);
-                       this_card = proteon_card_list;
-                       proteon_card_list = this_card->next;
-                       kfree(this_card);
-               }
-               kfree(dev);
-       }
-       return res;
+       struct net_device *dev = alloc_trdev(sizeof(struct net_local));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       dev->irq = irq;
+       dev->dma = dma;
+       err = proteon_probe1(dev, io);
+       if (err) 
+               goto out;
+               
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+ out1:
+       release_region(dev->base_addr, PROTEON_IO_EXTENT);
+       free_irq(dev->irq, dev);
+       free_dma(dev->dma);
+       tmsdev_term(dev);
+ out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 int init_module(void)
 {
-       int i, num;
-
-       num = 0;
-       if (io[0]) { /* Only probe addresses from command line */
-               for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
-                       if (io[i] && setup_card(io[i], irq[i], dma[i]) == 0)
-                               num++;
-               }
-       } else {
-               for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
-                       if (setup_card(portlist[i], irq[num], dma[num]) == 0)
-                               num++;
+       struct net_device *dev;
+       int i, num = 0;
+
+       for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
+               dev = io[0] ? setup_card(io[i], irq[i], dma[i])
+                       : proteon_probe(-1);
+               if (!IS_ERR(dev)) {
+                       proteon_dev[i] = dev;
+                       ++num;
                }
        }
+
        printk(KERN_NOTICE "proteon.c: %d cards found.\n", num);
        /* Probe for cards. */
        if (num == 0) {
@@ -425,11 +412,13 @@ int init_module(void)
 
 void cleanup_module(void)
 {
-       struct net_device *dev;
-       struct proteon_card *this_card;
+       int i;
 
-       while (proteon_card_list) {
-               dev = proteon_card_list->dev;
+       for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
+               struct net_device *dev = proteon_dev[i];
+               
+               if (!dev) 
+                       continue;
                
                unregister_netdev(dev);
                release_region(dev->base_addr, PROTEON_IO_EXTENT);
@@ -437,9 +426,6 @@ void cleanup_module(void)
                free_dma(dev->dma);
                tmsdev_term(dev);
                free_netdev(dev);
-               this_card = proteon_card_list;
-               proteon_card_list = this_card->next;
-               kfree(this_card);
        }
 }
 #endif /* MODULE */
index b0bc243..8989753 100644 (file)
@@ -56,7 +56,7 @@ static unsigned int portlist[] __initdata = {
 /* A zero-terminated list of IRQs to be probed. 
  * Used again after initial probe for sktr_chipset_init, called from sktr_open.
  */
-static unsigned short irqlist[] = {
+static const unsigned short irqlist[] = {
        3, 5, 9, 10, 11, 12, 15,
        0
 };
@@ -69,7 +69,6 @@ static int dmalist[] __initdata = {
 
 static char isa_cardname[] = "SK NET TR 4/16 ISA\0";
 
-int sk_isa_probe(struct net_device *dev);
 static int sk_isa_open(struct net_device *dev);
 static int sk_isa_close(struct net_device *dev);
 static void sk_isa_read_eeprom(struct net_device *dev);
@@ -95,17 +94,14 @@ static void sk_isa_sifwritew(struct net_device *dev, unsigned short val, unsigne
        outw(val, dev->base_addr + reg);
 }
 
-struct sk_isa_card {
-       struct net_device *dev;
-       struct sk_isa_card *next;
-};
-
-static struct sk_isa_card *sk_isa_card_list;
 
-static int __init sk_isa_probe1(int ioaddr)
+static int __init sk_isa_probe1(struct net_device *dev, int ioaddr)
 {
        unsigned char old, chk1, chk2;
 
+       if (!request_region(ioaddr, SK_ISA_IO_EXTENT, isa_cardname))
+               return -ENODEV;
+
        old = inb(ioaddr + SIFADR);     /* Get the old SIFADR value */
 
        chk1 = 0;       /* Begin with check value 0 */
@@ -122,8 +118,10 @@ static int __init sk_isa_probe1(int ioaddr)
                chk2 = inb(ioaddr + SIFADD);
                chk2 ^= 0x0FE;
 
-               if(chk1 != chk2)
-                       return (-1);    /* No adapter */
+               if(chk1 != chk2) {
+                       release_region(ioaddr, SK_ISA_IO_EXTENT);
+                       return -ENODEV;
+               }
 
                chk1 -= 2;
        } while(chk1 != 0);     /* Repeat 128 times (all byte values) */
@@ -131,58 +129,45 @@ static int __init sk_isa_probe1(int ioaddr)
        /* Restore the SIFADR value */
        outb(old, ioaddr + SIFADR);
 
-       return (0);
+       dev->base_addr = ioaddr;
+       return 0;
 }
 
-int __init sk_isa_probe(struct net_device *dev)
+struct net_device * __init sk_isa_probe(int unit)
 {
-        static int versionprinted;
+       struct net_device *dev = alloc_trdev(sizeof(struct net_local));
        struct net_local *tp;
-       int i,j;
-       struct sk_isa_card *card;
+        static int versionprinted;
+       const unsigned *port;
+       int j, err = 0;
 
-#ifndef MODULE
-       netdev_boot_setup_check(dev);
-       tr_setup(dev);
-#endif
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-       SET_MODULE_OWNER(dev);
-       if (!dev->base_addr)
-       {
-               for(i = 0; portlist[i]; i++)
-               {
-                       if (!request_region(portlist[i], SK_ISA_IO_EXTENT, isa_cardname))
-                               continue;
-
-                       if(sk_isa_probe1(portlist[i]))
-                       {
-                               release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
-                               continue;
-                       }
+       if (unit >= 0) {
+               sprintf(dev->name, "tr%d", unit);
+               netdev_boot_setup_check(dev);
+       }
 
-                       dev->base_addr = portlist[i];
-                       break;
+       SET_MODULE_OWNER(dev);
+       if (dev->base_addr)     /* probe specific location */
+               err = sk_isa_probe1(dev, dev->base_addr);
+       else {
+               for (port = portlist; *port; port++) {
+                       err = sk_isa_probe1(dev, *port);
+                       if (!err)
+                               break;
                }
-               if(!dev->base_addr)
-                       return -1;
        }
-       else
-       {
-               if (!request_region(dev->base_addr, SK_ISA_IO_EXTENT, isa_cardname))
-                       return -1;
-
-               if(sk_isa_probe1(dev->base_addr))
-               {
-                       release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
-                       return -1;
-               }
-       } 
+       if (err)
+               goto out4;
 
        /* At this point we have found a valid card. */
 
        if (versionprinted++ == 0)
                printk(KERN_DEBUG "%s", version);
 
+       err = -EIO;
        if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
                goto out4;
 
@@ -284,14 +269,11 @@ int __init sk_isa_probe(struct net_device *dev)
        printk(KERN_DEBUG "%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
               dev->name, dev->base_addr, dev->irq, dev->dma);
                
-       /* Enlist in the card list */
-       card = kmalloc(sizeof(struct sk_isa_card), GFP_KERNEL);
-       if (!card)
+       err = register_netdev(dev);
+       if (err)
                goto out;
-       card->next = sk_isa_card_list;
-       sk_isa_card_list = card;
-       card->dev = dev;
-       return 0;
+
+       return dev;
 out:
        free_dma(dev->dma);
 out2:
@@ -300,7 +282,8 @@ out3:
        tmsdev_term(dev);
 out4:
        release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
-       return -1;
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 /*
@@ -373,6 +356,8 @@ static int sk_isa_close(struct net_device *dev)
 
 #define ISATR_MAX_ADAPTERS 3
 
+static struct net_device *sk_isa_dev[ISATR_MAX_ADAPTERS];
+
 static int io[ISATR_MAX_ADAPTERS];
 static int irq[ISATR_MAX_ADAPTERS];
 static int dma[ISATR_MAX_ADAPTERS];
@@ -383,50 +368,54 @@ MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
 MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
 
-static int __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
+static struct net_device * __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
 {
-       int res = -ENOMEM;
-       struct sk_isa_card *this_card;
-       struct net_device *dev = alloc_trdev(0);
-
-       if (dev) {
-               dev->base_addr = io;
-               dev->irq       = irq;
-               dev->dma       = dma;
-               res = -ENODEV;
-               if (sk_isa_probe(dev) == 0) {
-                       res = register_netdev(dev);
-                       if (!res)
-                               return 0;
-                       release_region(dev->base_addr, SK_ISA_IO_EXTENT);
-                       free_irq(dev->irq, dev);
-                       free_dma(dev->dma);
-                       tmsdev_term(dev);
-                       this_card = sk_isa_card_list;
-                       sk_isa_card_list = this_card->next;
-                       kfree(this_card);
-               }
-               kfree(dev);
-       }
-       return res;
+       struct net_device *dev = alloc_trdev(sizeof(struct net_local));
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       dev->base_addr = io;
+       dev->irq       = irq;
+       dev->dma       = dma;
+
+       err = sk_isa_probe1(dev, io);
+       if (err)
+               goto out;
+
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+
+ out1:
+       release_region(dev->base_addr, SK_ISA_IO_EXTENT);
+       free_irq(dev->irq, dev);
+       free_dma(dev->dma);
+       tmsdev_term(dev);
+ out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
 int init_module(void)
 {
+       struct net_device *dev;
        int i, num;
 
        num = 0;
-       if (io[0]) { /* Only probe addresses from command line */
-               for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
-                       if (io[i] && setup_card(io[i], irq[i], dma[i]) == 0)
-                               num++;
-               }
-       } else {
-               for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
-                       if (setup_card(portlist[i], irq[num], dma[num]) == 0)
-                               num++;
+       for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
+               if (io[0])  /* Only probe addresses from command line */
+                       dev = setup_card(io[i], irq[i], dma[i]);
+               else
+                       dev = sk_isa_probe(-1);
+               if (!IS_ERR(dev)) {
+                       sk_isa_dev[i] = dev;
+                       ++num;
                }
        }
+
        printk(KERN_NOTICE "skisa.c: %d cards found.\n", num);
        /* Probe for cards. */
        if (num == 0) {
@@ -438,11 +427,13 @@ int init_module(void)
 
 void cleanup_module(void)
 {
-       struct net_device *dev;
-       struct sk_isa_card *this_card;
+       int i;
+
+       for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
+               struct net_device *dev = sk_isa_dev[i];
 
-       while (sk_isa_card_list) {
-               dev = sk_isa_card_list->dev;
+               if (!dev) 
+                       continue;
                
                unregister_netdev(dev);
                release_region(dev->base_addr, SK_ISA_IO_EXTENT);
@@ -450,9 +441,6 @@ void cleanup_module(void)
                free_dma(dev->dma);
                tmsdev_term(dev);
                free_netdev(dev);
-               this_card = sk_isa_card_list;
-               sk_isa_card_list = this_card->next;
-               kfree(this_card);
        }
 }
 #endif /* MODULE */
index 0bca145..3863d22 100644 (file)
@@ -69,13 +69,6 @@ static const char cardname[] = "smctr";
 
 #define SMCTR_IO_EXTENT   20
 
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int smctr_portlist[] __initdata = {
-        0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300,
-        0x320, 0x340, 0x360, 0x380,
-        0
-};
-
 #ifdef CONFIG_MCA
 static unsigned int smctr_posid = 0x6ec6;
 #endif
@@ -219,7 +212,7 @@ static int smctr_open(struct net_device *dev);
 static int smctr_open_tr(struct net_device *dev);
 
 /* P */
-int __init smctr_probe (struct net_device *dev);
+struct net_device *smctr_probe(int unit);
 static int __init smctr_probe1(struct net_device *dev, int ioaddr);
 static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
         struct net_device *dev, __u16 rx_status);
@@ -3583,71 +3576,72 @@ out:
         return (err);
 }
 
-/* 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.
+/* Check for a network adapter of this type, 
+ * and return device structure if one exists.
  */
-int __init smctr_probe (struct net_device *dev)
-{
-        int i;
-        int base_addr;
+struct net_device __init *smctr_probe(int unit)
+{
+       struct net_device *dev = alloc_trdev(sizeof(struct net_local));
+       static const unsigned ports[] = {
+               0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300,
+               0x320, 0x340, 0x360, 0x380, 0
+       };
+       const unsigned *port;
+        int err = 0;
 
-#ifndef MODULE
-       netdev_boot_setup_check(dev);
-       tr_setup(dev);
-#endif
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-        base_addr = dev->base_addr;
-        if(base_addr > 0x1ff)    /* Check a single specified location. */
-                return (smctr_probe1(dev, base_addr));
-        else if(base_addr != 0)  /* Don't probe at all. */
-                return (-ENXIO);
+       SET_MODULE_OWNER(dev);
 
-        for(i = 0; smctr_portlist[i]; i++)
-        {
-                int ioaddr = smctr_portlist[i];
-                if (!smctr_probe1(dev, ioaddr))
-                        return (0);
-        }
-
-        return (-ENODEV);
-}
+       if (unit >= 0) {
+               sprintf(dev->name, "tr%d", unit);
+               netdev_boot_setup_check(dev);
+       }
 
-static void cleanup_card(struct net_device *dev)
-{
+        if (dev->base_addr > 0x1ff)    /* Check a single specified location. */
+               err = smctr_probe1(dev, dev->base_addr);
+        else if(dev->base_addr != 0)  /* Don't probe at all. */
+                err =-ENXIO;
+       else {
+               for (port = ports; *port; port++) {
+                       err = smctr_probe1(dev, *port);
+                       if (!err)
+                               break;
+               }
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
 #ifdef CONFIG_MCA
-       struct net_local *tp = (struct net_local *)dev->priv;
-       if (tp->slot_num)
+       { struct net_local *tp = (struct net_local *)dev->priv;
+         if (tp->slot_num)
                mca_mark_as_unused(tp->slot_num);
+       }
 #endif
        release_region(dev->base_addr, SMCTR_IO_EXTENT);
-       if (dev->irq)
-               free_irq(dev->irq, dev);
-       if (dev->priv)
-               kfree(dev->priv);
+       free_irq(dev->irq, dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
 }
 
+
 static int __init smctr_probe1(struct net_device *dev, int ioaddr)
 {
         static unsigned version_printed;
-        struct net_local *tp;
+        struct net_local *tp = dev->priv;
         int err;
         __u32 *ram;
 
         if(smctr_debug && version_printed++ == 0)
                 printk(version);
 
-        /* Setup this devices private information structure */
-        tp = (struct net_local *)kmalloc(sizeof(struct net_local),
-                GFP_KERNEL);
-        if(tp == NULL) {
-               err = -ENOMEM;
-               goto out;
-       }
-        memset(tp, 0, sizeof(struct net_local));
         spin_lock_init(&tp->lock);
-        
-        dev->priv = tp;
         dev->base_addr = ioaddr;
 
        /* Actually detect an adapter now. */
@@ -3656,7 +3650,7 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
         {
                if ((err = smctr_chk_mca(dev)) < 0) {
                        err = -ENODEV;
-                       goto out_tp;
+                       goto out;
                }
         }
 
@@ -3671,7 +3665,6 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
         if(err != UCODE_PRESENT && err != SUCCESS)
         {
                 printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err);
-               cleanup_card(dev);
                err = -EIO;
                goto out;
         }
@@ -3696,8 +3689,6 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
         dev->set_multicast_list = &smctr_set_multicast_list;
         return (0);
 
-out_tp:
-       kfree(tp);
 out:
        return err;
 }
@@ -5669,47 +5660,59 @@ static int smctr_wait_while_cbusy(struct net_device *dev)
 static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS];
 static int io[SMCTR_MAX_ADAPTERS];
 static int irq[SMCTR_MAX_ADAPTERS];
-static int mem[SMCTR_MAX_ADAPTERS];
 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io,  "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+MODULE_PARM(io, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
-MODULE_PARM(ringspeed, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+MODULE_PARM(ringspeed, "i");
+
+static struct net_device *setup_card(int n)
+{
+       struct net_device *dev = alloc_trdev(sizeof(struct net_local));
+       int err;
+       
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       dev->irq = irq[n];
+       err = smctr_probe1(dev, io[n]);
+       if (err) 
+               goto out;
+               
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+ out1:
+#ifdef CONFIG_MCA
+       { struct net_local *tp = (struct net_local *)dev->priv;
+         if (tp->slot_num)
+               mca_mark_as_unused(tp->slot_num);
+       }
+#endif
+       release_region(dev->base_addr, SMCTR_IO_EXTENT);
+       free_irq(dev->irq, dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+                       
 
 int init_module(void)
 {
-        int i;
+        int i, found = 0;
+       struct net_device *dev;
 
         for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) {
-               struct net_device *dev = alloc_trdev(0);
-                irq[i] = 0;
-                mem[i] = 0;
-               if (!dev)
-                       return -ENOMEM;
-                dev->base_addr = io[i];
-                dev->irq       = irq[i];
-                dev->mem_start = mem[i];
-
-               if (smctr_probe(dev) != 0) {
-                        kfree(dev);
-                        if (i == 0) {
-                                printk(KERN_ERR "%s: smctr_probe failed.\n",
-                                        cardname);
-                                return -EIO;
-                        }
-                       return 0;
-                }
-               if (register_netdev(dev) != 0) {
-                        cleanup_card(dev);
-                       kfree(dev);
-                       continue;
-                }
-                dev_smctr[i] = dev;
+               dev = io[0]? setup_card(i) : smctr_probe(-1);
+               if (!IS_ERR(dev)) {
+                       ++found;
+                       dev_smctr[i] = dev;
+               }
         }
 
-        return (0);
+        return found ? 0 : -ENODEV;
 }
 
 void cleanup_module(void)
@@ -5718,9 +5721,20 @@ void cleanup_module(void)
 
         for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) {
                struct net_device *dev = dev_smctr[i];
+
                if (dev) {
+
                        unregister_netdev(dev);
-                       cleanup_card(dev);
+#ifdef CONFIG_MCA
+                       { struct net_local *tp = dev->priv;
+                       if (tp->slot_num)
+                               mca_mark_as_unused(tp->slot_num);
+                       }
+#endif
+                       release_region(dev->base_addr, SMCTR_IO_EXTENT);
+                       if (dev->irq)
+                               free_irq(dev->irq, dev);
+
                        free_netdev(dev);
                }
         }
index 1931a5b..e781c81 100644 (file)
@@ -147,7 +147,6 @@ static void         tms380tr_hardware_send_packet(struct net_device *dev,
                        struct net_local* tp);
 /* "I" */
 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_device *dev);
@@ -232,15 +231,6 @@ static int madgemc_sifprobe(struct net_device *dev)
 }
 #endif
 
-/* Dummy function */
-static int tms380tr_init_card(struct net_device *dev)
-{
-       if(tms380tr_debug > 3)
-               printk(KERN_DEBUG "%s: tms380tr_init_card\n", dev->name);
-
-       return (0);
-}
-
 /*
  * Open/initialize the board. This is called sometime after
  * booting when the 'ifconfig' program is run.
@@ -2386,7 +2376,6 @@ int tmsdev_init(struct net_device *dev, unsigned long dmalimit,
        }
        
        /* 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; 
index 7ce6044..56dfea6 100644 (file)
@@ -179,7 +179,7 @@ err_out_irq:
 err_out_region:
        release_region(pci_ioaddr, TMS_PCI_IO_EXTENT);
 err_out_trdev:
-       kfree(dev);
+       free_netdev(dev);
        return ret;
 }
 
index dbd677e..02bc6d3 100644 (file)
@@ -68,6 +68,26 @@ config TULIP_MMIO
          obscure bugs if your mainboard has memory controller timing issues.
          If in doubt, say N.
 
+config TULIP_NAPI
+       bool "Use NAPI RX polling "
+       depends on TULIP
+       ---help---
+         This is of useful for servers and routers dealing with high network loads.
+         See <file:Documentation/networking/NAPI_HOWTO.txt>.
+
+         If in doubt, say N.
+
+config TULIP_NAPI_HW_MITIGATION
+       bool "Use Interrupt Mitigation "
+       depends on TULIP_NAPI
+       ---help---
+         Use HW to reduce RX interrupts. Not strict necessary since NAPI reduces
+         RX interrupts but itself. Although this reduces RX interrupts even at
+         low levels traffic at the cost of a small latency.
+
+         If in doubt, say Y.
+
 config DE4X5
        tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
        depends on NET_TULIP && (PCI || EISA)
index d0cf6fe..8c454f3 100644 (file)
@@ -2084,7 +2084,7 @@ err_out_res:
 err_out_disable:
        pci_disable_device(pdev);
 err_out_free:
-       kfree(dev);
+       free_netdev(dev);
        return rc;
 }
 
index 0b0143b..402d69c 100644 (file)
@@ -457,7 +457,7 @@ err_out_disable:
        pci_disable_device(pdev);
 err_out_free:
        pci_set_drvdata(pdev, NULL);
-       kfree(dev);
+       free_netdev(dev);
 
        return err;
 }
index 6067504..a97d9c0 100644 (file)
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
 
-
 int tulip_rx_copybreak;
 unsigned int tulip_max_interrupt_work;
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-
+#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
 #define MIT_SIZE 15
+#define MIT_TABLE 15 /* We use 0 or max */
+
 unsigned int mit_table[MIT_SIZE+1] =
 {
         /*  CRS11 21143 hardware Mitigation Control Interrupt
@@ -99,16 +99,28 @@ int tulip_refill_rx(struct net_device *dev)
        return refilled;
 }
 
+#ifdef CONFIG_TULIP_NAPI
 
-static int tulip_rx(struct net_device *dev)
+void oom_timer(unsigned long data)
+{
+        struct net_device *dev = (struct net_device *)data;
+       netif_rx_schedule(dev);
+}
+
+int tulip_poll(struct net_device *dev, int *budget)
 {
        struct tulip_private *tp = (struct tulip_private *)dev->priv;
        int entry = tp->cur_rx % RX_RING_SIZE;
-       int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
+       int rx_work_limit = *budget;
        int received = 0;
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-        int drop = 0, mit_sel = 0;
+       if (!netif_running(dev))
+               goto done;
+
+       if (rx_work_limit > dev->quota)
+               rx_work_limit = dev->quota;
+
+#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
 
 /* that one buffer is needed for mit activation; or might be a
    bug in the ring buffer code; check later -- JHS*/
@@ -119,6 +131,237 @@ static int tulip_rx(struct net_device *dev)
        if (tulip_debug > 4)
                printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
                           tp->rx_ring[entry].status);
+
+       do {
+               /* Acknowledge current RX interrupt sources. */
+               outl((RxIntr | RxNoBuf), dev->base_addr + CSR5);
+               /* If we own the next entry, it is a new packet. Send it up. */
+               while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
+                       s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+                       if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
+                               break;
+                       if (tulip_debug > 5)
+                               printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
+                                      dev->name, entry, status);
+                       if (--rx_work_limit < 0)
+                               goto not_done;
+                       if ((status & 0x38008300) != 0x0300) {
+                               if ((status & 0x38000300) != 0x0300) {
+                                /* Ingore earlier buffers. */
+                                       if ((status & 0xffff) != 0x7fff) {
+                                               if (tulip_debug > 1)
+                                                       printk(KERN_WARNING "%s: Oversized Ethernet frame "
+                                                              "spanned multiple buffers, status %8.8x!\n",
+                                                              dev->name, status);
+                                               tp->stats.rx_length_errors++;
+                                       }
+                               } else if (status & RxDescFatalErr) {
+                                /* There was a fatal error. */
+                                       if (tulip_debug > 2)
+                                               printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
+                                                      dev->name, status);
+                                       tp->stats.rx_errors++; /* end of a packet.*/
+                                       if (status & 0x0890) tp->stats.rx_length_errors++;
+                                       if (status & 0x0004) tp->stats.rx_frame_errors++;
+                                       if (status & 0x0002) tp->stats.rx_crc_errors++;
+                                       if (status & 0x0001) tp->stats.rx_fifo_errors++;
+                               }
+                       } else {
+                               /* Omit the four octet CRC from the length. */
+                               short pkt_len = ((status >> 16) & 0x7ff) - 4;
+                               struct sk_buff *skb;
+  
+#ifndef final_version
+                               if (pkt_len > 1518) {
+                                       printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
+                                              dev->name, pkt_len, pkt_len);
+                                       pkt_len = 1518;
+                                       tp->stats.rx_length_errors++;
+                               }
+#endif
+                               /* Check if the packet is long enough to accept without copying
+                                  to a minimally-sized skbuff. */
+                               if (pkt_len < tulip_rx_copybreak
+                                   && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+                                       skb->dev = dev;
+                                       skb_reserve(skb, 2);    /* 16 byte align the IP header */
+                                       pci_dma_sync_single(tp->pdev,
+                                                           tp->rx_buffers[entry].mapping,
+                                                           pkt_len, PCI_DMA_FROMDEVICE);
+#if ! defined(__alpha__)
+                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+                                                        pkt_len, 0);
+                                       skb_put(skb, pkt_len);
+#else
+                                       memcpy(skb_put(skb, pkt_len),
+                                              tp->rx_buffers[entry].skb->tail,
+                                              pkt_len);
+#endif
+                               } else {        /* Pass up the skb already on the Rx ring. */
+                                       char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
+                                                            pkt_len);
+  
+#ifndef final_version
+                                       if (tp->rx_buffers[entry].mapping !=
+                                           le32_to_cpu(tp->rx_ring[entry].buffer1)) {
+                                               printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
+                                                      "do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
+                                                      dev->name,
+                                                      le32_to_cpu(tp->rx_ring[entry].buffer1),
+                                                      tp->rx_buffers[entry].mapping,
+                                                      skb->head, temp);
+                                       }
+#endif
+  
+                                       pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
+                                                        PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+  
+                                       tp->rx_buffers[entry].skb = NULL;
+                                       tp->rx_buffers[entry].mapping = 0;
+                               }
+                               skb->protocol = eth_type_trans(skb, dev);
+  
+                               netif_receive_skb(skb);
+                               dev->last_rx = jiffies;
+                               tp->stats.rx_packets++;
+                               tp->stats.rx_bytes += pkt_len;
+                       }
+                       received++;
+
+                       entry = (++tp->cur_rx) % RX_RING_SIZE;
+                       if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4)
+                               tulip_refill_rx(dev);
+                }
+               /* New ack strategy... irq does not ack Rx any longer
+                  hopefully this helps */
+               /* Really bad things can happen here... If new packet arrives
+                * and an irq arrives (tx or just due to occasionally unset
+                * mask), it will be acked by irq handler, but new thread
+                * is not scheduled. It is major hole in design.
+                * No idea how to fix this if "playing with fire" will fail
+                * tomorrow (night 011029). If it will not fail, we won
+                * finally: amount of IO did not increase at all. */
+       } while ((inl(dev->base_addr + CSR5) & RxIntr));
+done:
+ #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+  
+          /* We use this simplistic scheme for IM. It's proven by
+             real life installations. We can have IM enabled
+            continuesly but this would cause unnecessary latency. 
+            Unfortunely we can't use all the NET_RX_* feedback here. 
+            This would turn on IM for devices that is not contributing 
+            to backlog congestion with unnecessary latency. 
+  
+             We monitor the the device RX-ring and have:
+  
+             HW Interrupt Mitigation either ON or OFF.
+  
+            ON:  More then 1 pkt received (per intr.) OR we are dropping 
+             OFF: Only 1 pkt received
+            
+             Note. We only use min and max (0, 15) settings from mit_table */
+  
+  
+          if( tp->flags &  HAS_INTR_MITIGATION) {
+                 if( received > 1 ) {
+                         if( ! tp->mit_on ) {
+                                 tp->mit_on = 1;
+                                 outl(mit_table[MIT_TABLE], dev->base_addr + CSR11);
+                         }
+                  }
+                 else {
+                         if( tp->mit_on ) {
+                                 tp->mit_on = 0;
+                                 outl(0, dev->base_addr + CSR11);
+                         }
+                  }
+          }
+
+#endif /* CONFIG_TULIP_NAPI_HW_MITIGATION */
+         dev->quota -= received;
+         *budget -= received;
+         tulip_refill_rx(dev);
+         
+         /* If RX ring is not full we are out of memory. */
+         if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom;
+         /* Remove us from polling list and enable RX intr. */
+         netif_rx_complete(dev);
+         outl(tulip_tbl[tp->chip_id].valid_intrs, dev->base_addr+CSR7);
+         /* The last op happens after poll completion. Which means the following:
+          * 1. it can race with disabling irqs in irq handler
+          * 2. it can race with dise/enabling irqs in other poll threads
+          * 3. if an irq raised after beginning loop, it will be immediately
+          *    triggered here.
+          *
+          * Summarizing: the logic results in some redundant irqs both
+          * due to races in masking and due to too late acking of already
+          * processed irqs. But it must not result in losing events.
+          */
+         return 0;
+ not_done:
+         if (!received) {
+
+                 received = dev->quota; /* Not to happen */
+         }
+         dev->quota -= received;
+         *budget -= received;
+         if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+             tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                 tulip_refill_rx(dev);
+         if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom;
+         return 1;
+ oom:    /* Executed with RX ints disabled */
+         
+         /* Start timer, stop polling, but do not enable rx interrupts. */
+         mod_timer(&tp->oom_timer, jiffies+1);
+       
+         /* Think: timer_pending() was an explicit signature of bug.
+          * Timer can be pending now but fired and completed
+          * before we did netif_rx_complete(). See? We would lose it. */
+         /* remove ourselves from the polling list */
+         netif_rx_complete(dev);
+         return 0;
+}
+
+#else /* CONFIG_TULIP_NAPI */
+
+static int tulip_rx(struct net_device *dev)
+{
+       struct tulip_private *tp = (struct tulip_private *)dev->priv;
+       int entry = tp->cur_rx % RX_RING_SIZE;
+       int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
+       int received = 0;
+
+       if (tulip_debug > 4)
+               printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
+                          tp->rx_ring[entry].status);
        /* If we own the next entry, it is a new packet. Send it up. */
        while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
                s32 status = le32_to_cpu(tp->rx_ring[entry].status);
@@ -163,11 +406,6 @@ static int tulip_rx(struct net_device *dev)
                        }
 #endif
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                        drop = atomic_read(&netdev_dropping);
-                        if (drop)
-                                goto throttle;
-#endif
                        /* Check if the packet is long enough to accept without copying
                           to a minimally-sized skbuff. */
                        if (pkt_len < tulip_rx_copybreak
@@ -209,44 +447,9 @@ static int tulip_rx(struct net_device *dev)
                                tp->rx_buffers[entry].mapping = 0;
                        }
                        skb->protocol = eth_type_trans(skb, dev);
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                        mit_sel =
-#endif
-                       netif_rx(skb);
-
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                        switch (mit_sel) {
-                        case NET_RX_SUCCESS:
-                        case NET_RX_CN_LOW:
-                        case NET_RX_CN_MOD:
-                                break;
-
-                        case NET_RX_CN_HIGH:
-                                rx_work_limit -= NET_RX_CN_HIGH; /* additional*/
-                                break;
-                        case NET_RX_DROP:
-                                rx_work_limit = -1;
-                                break;
-                        default:
-                                printk("unknown feedback return code %d\n", mit_sel);
-                                break;
-                        }
-
-                        drop = atomic_read(&netdev_dropping);
-                        if (drop) {
-throttle:
-                                rx_work_limit = -1;
-                                mit_sel = NET_RX_DROP;
 
-                                if (tp->fc_bit) {
-                                        long ioaddr = dev->base_addr;
+                       netif_rx(skb);
 
-                                        /* disable Rx & RxNoBuf ints. */
-                                        outl(tulip_tbl[tp->chip_id].valid_intrs&RX_A_NBF_STOP, ioaddr + CSR7);
-                                        set_bit(tp->fc_bit, &netdev_fc_xoff);
-                                }
-                        }
-#endif
                        dev->last_rx = jiffies;
                        tp->stats.rx_packets++;
                        tp->stats.rx_bytes += pkt_len;
@@ -254,42 +457,9 @@ throttle:
                received++;
                entry = (++tp->cur_rx) % RX_RING_SIZE;
        }
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-
-        /* We use this simplistic scheme for IM. It's proven by
-           real life installations. We can have IM enabled
-           continuesly but this would cause unnecessary latency.
-           Unfortunely we can't use all the NET_RX_* feedback here.
-           This would turn on IM for devices that is not contributing
-           to backlog congestion with unnecessary latency.
-
-           We monitor the device RX-ring and have:
-
-           HW Interrupt Mitigation either ON or OFF.
-
-           ON:  More then 1 pkt received (per intr.) OR we are dropping
-           OFF: Only 1 pkt received
-
-           Note. We only use min and max (0, 15) settings from mit_table */
-
-
-        if( tp->flags &  HAS_INTR_MITIGATION) {
-                if((received > 1 || mit_sel == NET_RX_DROP)
-                   && tp->mit_sel != 15 ) {
-                        tp->mit_sel = 15;
-                        tp->mit_change = 1; /* Force IM change */
-                }
-                if((received <= 1 && mit_sel != NET_RX_DROP) && tp->mit_sel != 0 ) {
-                        tp->mit_sel = 0;
-                        tp->mit_change = 1; /* Force IM change */
-                }
-        }
-
-        return RX_RING_SIZE+1; /* maxrx+1 */
-#else
        return received;
-#endif
 }
+#endif  /* CONFIG_TULIP_NAPI */
 
 static inline unsigned int phy_interrupt (struct net_device *dev)
 {
@@ -323,7 +493,6 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        struct tulip_private *tp = (struct tulip_private *)dev->priv;
        long ioaddr = dev->base_addr;
        int csr5;
-       int entry;
        int missed;
        int rx = 0;
        int tx = 0;
@@ -331,6 +500,11 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        int maxrx = RX_RING_SIZE;
        int maxtx = TX_RING_SIZE;
        int maxoi = TX_RING_SIZE;
+#ifdef CONFIG_TULIP_NAPI
+       int rxd = 0;
+#else
+       int entry;
+#endif
        unsigned int work_count = tulip_max_interrupt_work;
        unsigned int handled = 0;
 
@@ -346,22 +520,41 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        tp->nir++;
 
        do {
+
+#ifdef CONFIG_TULIP_NAPI
+
+               if (!rxd && (csr5 & (RxIntr | RxNoBuf))) {
+                       rxd++;
+                       /* Mask RX intrs and add the device to poll list. */
+                       outl(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
+                       netif_rx_schedule(dev);
+                       
+                       if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
+                               break;
+               }
+               
+               /* Acknowledge the interrupt sources we handle here ASAP
+                  the poll function does Rx and RxNoBuf acking */
+               
+               outl(csr5 & 0x0001ff3f, ioaddr + CSR5);
+
+#else 
                /* Acknowledge all of the current interrupt sources ASAP. */
                outl(csr5 & 0x0001ffff, ioaddr + CSR5);
 
-               if (tulip_debug > 4)
-                       printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
-                                  dev->name, csr5, inl(dev->base_addr + CSR5));
 
                if (csr5 & (RxIntr | RxNoBuf)) {
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                        if ((!tp->fc_bit) ||
-                           (!test_bit(tp->fc_bit, &netdev_fc_xoff)))
-#endif
                                rx += tulip_rx(dev);
                        tulip_refill_rx(dev);
                }
 
+#endif /*  CONFIG_TULIP_NAPI */
+               
+               if (tulip_debug > 4)
+                       printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
+                              dev->name, csr5, inl(dev->base_addr + CSR5));
+               
+
                if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
                        unsigned int dirty_tx;
 
@@ -462,15 +655,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                        }
                        if (csr5 & RxDied) {            /* Missed a Rx frame. */
                                 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                               if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
-                                       tp->stats.rx_errors++;
-                                       tulip_start_rxtx(tp);
-                               }
-#else
                                tp->stats.rx_errors++;
                                tulip_start_rxtx(tp);
-#endif
                        }
                        /*
                         * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this
@@ -504,10 +690,6 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                        if (tulip_debug > 2)
                                printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
                                           dev->name, csr5);
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                        if (tp->fc_bit && (test_bit(tp->fc_bit, &netdev_fc_xoff)))
-                          if (net_ratelimit()) printk("BUG!! enabling interrupt when FC off (timerintr.) \n");
-#endif
                        outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
                        tp->ttimer = 0;
                        oi++;
@@ -520,16 +702,9 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                        /* Acknowledge all interrupt sources. */
                         outl(0x8001ffff, ioaddr + CSR5);
                         if (tp->flags & HAS_INTR_MITIGATION) {
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-                                if(tp->mit_change) {
-                                        outl(mit_table[tp->mit_sel], ioaddr + CSR11);
-                                        tp->mit_change = 0;
-                                }
-#else
                      /* Josip Loncaric at ICASE did extensive experimentation
                        to develop a good interrupt mitigation setting.*/
                                 outl(0x8b240000, ioaddr + CSR11);
-#endif
                         } else if (tp->chip_id == LC82C168) {
                                /* the LC82C168 doesn't have a hw timer.*/
                                outl(0x00, ioaddr + CSR7);
@@ -537,10 +712,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                        } else {
                           /* Mask all interrupting sources, set timer to
                                re-enable. */
-#ifndef CONFIG_NET_HW_FLOWCONTROL
                                 outl(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt, ioaddr + CSR7);
                                 outl(0x0012, ioaddr + CSR11);
-#endif
                         }
                        break;
                }
@@ -550,6 +723,21 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                        break;
 
                csr5 = inl(ioaddr + CSR5);
+
+#ifdef CONFIG_TULIP_NAPI
+               if (rxd)
+                       csr5 &= ~RxPollInt;
+       } while ((csr5 & (TxNoBuf | 
+                         TxDied | 
+                         TxIntr | 
+                         TimerInt |
+                         /* Abnormal intr. */
+                         RxDied | 
+                         TxFIFOUnderflow | 
+                         TxJabber | 
+                         TPLnkFail |  
+                         SytemError )) != 0);
+#else 
        } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0);
 
        tulip_refill_rx(dev);
@@ -574,6 +762,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                        }
                }
        }
+#endif /* CONFIG_TULIP_NAPI */
 
        if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
                tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
index 49c60dc..b00c566 100644 (file)
@@ -126,6 +126,7 @@ enum pci_cfg_driver_reg {
        CFDD_Snooze = (1 << 30),
 };
 
+#define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber)
 
 /* The bits in the CSR5 status registers, mostly interrupt sources. */
 enum status_bits {
@@ -251,9 +252,9 @@ enum t21143_csr6_bits {
    Making the Tx ring too large decreases the effectiveness of channel
    bonding and packet priority.
    There are no ill effects from too-large receive rings. */
-#define TX_RING_SIZE   16
-#define RX_RING_SIZE   32
 
+#define TX_RING_SIZE   32
+#define RX_RING_SIZE   128 
 #define MEDIA_MASK     31
 
 #define PKT_BUF_SZ             1536    /* Size of each temporary Rx buffer. */
@@ -343,17 +344,15 @@ struct tulip_private {
        int flags;
        struct net_device_stats stats;
        struct timer_list timer;        /* Media selection timer. */
+       struct timer_list oom_timer;    /* Out of memory timer. */
        u32 mc_filter[2];
        spinlock_t lock;
        spinlock_t mii_lock;
        unsigned int cur_rx, cur_tx;    /* The next free ring entry */
        unsigned int dirty_rx, dirty_tx;        /* The ring entries to be free()ed. */
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-#define RX_A_NBF_STOP 0xffffff3f /* To disable RX and RX-NOBUF ints. */
-        int fc_bit;
-        int mit_sel;
-        int mit_change; /* Signal for Interrupt Mitigtion */
+#ifdef         CONFIG_TULIP_NAPI_HW_MITIGATION
+        int mit_on;
 #endif
        unsigned int full_duplex:1;     /* Full-duplex operation requested. */
        unsigned int full_duplex_lock:1;
@@ -415,6 +414,10 @@ extern unsigned int tulip_max_interrupt_work;
 extern int tulip_rx_copybreak;
 irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 int tulip_refill_rx(struct net_device *dev);
+#ifdef CONFIG_TULIP_NAPI
+int tulip_poll(struct net_device *dev, int *budget);
+#endif
+
 
 /* media.c */
 int tulip_mdio_read(struct net_device *dev, int phy_id, int location);
@@ -438,6 +441,7 @@ extern int tulip_debug;
 extern const char * const medianame[];
 extern const char tulip_media_cap[];
 extern struct tulip_chip_table tulip_tbl[];
+void oom_timer(unsigned long data);
 extern u8 t21040_csr13[];
 
 #ifndef USE_IO_OPS
index fe866a3..537e479 100644 (file)
 
 */
 
+#include <linux/config.h>
+
 #define DRV_NAME       "tulip"
+#ifdef CONFIG_TULIP_NAPI
+#define DRV_VERSION    "1.1.13-NAPI" /* Keep at least for test */
+#else
 #define DRV_VERSION    "1.1.13"
+#endif
 #define DRV_RELDATE    "May 11, 2002"
 
-#include <linux/config.h>
+
 #include <linux/module.h>
 #include "tulip.h"
 #include <linux/pci.h>
@@ -466,29 +472,16 @@ media_picked:
           to an alternate media type. */
        tp->timer.expires = RUN_AT(next_tick);
        add_timer(&tp->timer);
-}
-
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-/* Enable receiver */
-void tulip_xon(struct net_device *dev)
-{
-        struct tulip_private *tp = (struct tulip_private *)dev->priv;
-
-        clear_bit(tp->fc_bit, &netdev_fc_xoff);
-        if (netif_running(dev)){
-
-                tulip_refill_rx(dev);
-                outl(tulip_tbl[tp->chip_id].valid_intrs,  dev->base_addr+CSR7);
-        }
-}
+#ifdef CONFIG_TULIP_NAPI
+       init_timer(&tp->oom_timer);
+        tp->oom_timer.data = (unsigned long)dev;
+        tp->oom_timer.function = oom_timer;
 #endif
+}
 
 static int
 tulip_open(struct net_device *dev)
 {
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-        struct tulip_private *tp = (struct tulip_private *)dev->priv;
-#endif
        int retval;
 
        if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev)))
@@ -498,10 +491,6 @@ tulip_open(struct net_device *dev)
 
        tulip_up (dev);
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-        tp->fc_bit = netdev_register_fc(dev, tulip_xon);
-#endif
-
        netif_start_queue (dev);
 
        return 0;
@@ -582,10 +571,7 @@ static void tulip_tx_timeout(struct net_device *dev)
 #endif
 
        /* Stop and restart the chip's Tx processes . */
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-        if (tp->fc_bit && test_bit(tp->fc_bit,&netdev_fc_xoff))
-                printk("BUG tx_timeout restarting rx when fc on\n");
-#endif
+
        tulip_restart_rxtx(tp);
        /* Trigger an immediate transmit demand. */
        outl(0, ioaddr + CSR1);
@@ -742,7 +728,9 @@ static void tulip_down (struct net_device *dev)
        unsigned long flags;
 
        del_timer_sync (&tp->timer);
-
+#ifdef CONFIG_TULIP_NAPI
+       del_timer_sync (&tp->oom_timer);
+#endif
        spin_lock_irqsave (&tp->lock, flags);
 
        /* Disable interrupts by clearing the interrupt mask. */
@@ -781,13 +769,6 @@ static int tulip_close (struct net_device *dev)
 
        netif_stop_queue (dev);
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-        if (tp->fc_bit) {
-                int bit = tp->fc_bit;
-                tp->fc_bit = 0;
-                netdev_unregister_fc(bit);
-        }
-#endif
        tulip_down (dev);
 
        if (tulip_debug > 1)
@@ -1629,6 +1610,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        dev->hard_start_xmit = tulip_start_xmit;
        dev->tx_timeout = tulip_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_TULIP_NAPI
+       dev->poll = tulip_poll;
+       dev->weight = 16;
+#endif
        dev->stop = tulip_close;
        dev->get_stats = tulip_get_stats;
        dev->do_ioctl = private_ioctl;
@@ -1725,7 +1710,7 @@ err_out_free_res:
        pci_release_regions (pdev);
 
 err_out_free_netdev:
-       kfree (dev);
+       free_netdev (dev);
        return -ENODEV;
 }
 
index 76056f5..4bcfbd6 100644 (file)
@@ -530,7 +530,7 @@ err_out_free_res:
 #endif
        pci_release_regions(pdev);
 err_out_netdev:
-       kfree (dev);
+       free_netdev (dev);
        return -ENODEV;
 }
 
index 0457794..5e8ea05 100644 (file)
@@ -648,8 +648,7 @@ err_out_cleardev:
        pci_set_drvdata(pdev, NULL);
        pci_release_regions(pdev);
 err_out_free_netdev:
-       unregister_netdev(dev);
-       kfree(dev);
+       free_netdev(dev);
        return -ENODEV;
 }
 
index 784a41d..a1b55e5 100644 (file)
@@ -377,6 +377,7 @@ static struct tun_struct *tun_get_by_name(const char *name)
 static int tun_set_iff(struct file *file, struct ifreq *ifr)
 {
        struct tun_struct *tun;
+       struct net_device *dev;
        int err;
 
        tun = tun_get_by_name(ifr->ifr_name);
@@ -394,7 +395,6 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
        else {
                char *name;
                unsigned long flags = 0;
-               struct net_device *dev;
 
                err = -EINVAL;
 
@@ -424,16 +424,13 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
 
                if (strchr(dev->name, '%')) {
                        err = dev_alloc_name(dev, dev->name);
-                       if (err < 0) {
-                               kfree(dev);
-                               goto failed;
-                       }
+                       if (err < 0)
+                               goto err_free_dev;
                }
 
-               if ((err = register_netdevice(tun->dev))) {
-                       kfree(dev);
-                       goto failed;
-               }
+               err = register_netdevice(tun->dev);
+               if (err < 0)
+                       goto err_free_dev;
        
                list_add(&tun->list, &tun_dev_list);
        }
@@ -451,6 +448,9 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
 
        strcpy(ifr->ifr_name, tun->dev->name);
        return 0;
+
+ err_free_dev:
+       free_netdev(dev);
  failed:
        return err;
 }
index 03cdaab..7c1f06d 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 1999-2002 3Com Corporation.  All Rights Reserved.    
+ * Copyright 1999-2003 3Com Corporation.  All Rights Reserved.    
  *
- * Redistribution and use in source and binary forms of the 3CR990img.h
+ * Redistribution and use in source and binary forms of the 3c990img.h
  * microcode software are permitted provided that the following conditions
  * are met:
  * 1. Redistribution of source code must retain the above copyright
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3CR990img.h
+ * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3c990img.h
  * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY
  * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS
  * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT)
  * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN
- * COMBINATION WITH THE 3CR990img.h microcode SOFTWARE
+ * COMBINATION WITH THE 3c990img.h MICROCODE SOFTWARE
  */ 
+
 const u8 typhoon_firmware_image[] = {
 0x54, 0x59, 0x50, 0x48, 0x4f, 0x4f, 0x4e, 0x00, 0x02, 0x00, 0x00, 0x00, 
-0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x40, 0x01, 0x00, 0x00, 
-0x6c, 0xef, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, 
-0x05, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 
-0x02, 0x00, 0x00, 0xea, 0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, 
-0xa5, 0x14, 0x00, 0xea, 0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, 
-0x00, 0x10, 0x0f, 0xe1, 0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, 
-0xfe, 0xff, 0xff, 0xea, 0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, 
-0x01, 0x00, 0x50, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, 
-0x00, 0xa0, 0xa0, 0xe1, 0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 
-0xa8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, 
-0x00, 0x00, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, 
-0x01, 0x00, 0x80, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, 
-0x00, 0xf0, 0x21, 0xe1, 0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, 
-0x00, 0xf0, 0x21, 0xe1, 0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, 
-0x00, 0xf0, 0x21, 0xe1, 0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, 
-0x00, 0xf0, 0x21, 0xe1, 0x6c, 0xd0, 0x9f, 0xe5, 0x7b, 0x14, 0x00, 0xeb, 
-0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, 
-0x60, 0x00, 0x9f, 0xe5, 0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, 
-0xdb, 0xff, 0xff, 0xeb, 0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, 
-0x00, 0x20, 0xa0, 0xe3, 0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, 
-0x54, 0x10, 0x9f, 0xe5, 0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, 
-0x0b, 0xf0, 0xa0, 0xe1, 0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 
-0xd4, 0xff, 0xff, 0xeb, 0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, 
-0xc6, 0xff, 0xff, 0xea, 0xbd, 0x20, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, 
-0x1c, 0x00, 0x10, 0x00, 0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 
-0xfc, 0x3f, 0x00, 0x80, 0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, 
-0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 0xa8, 0xbc, 0x00, 0x00, 
-0x24, 0xab, 0x20, 0x40, 0x34, 0x29, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, 
-0x6d, 0xc8, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xd8, 0x56, 0x00, 0x00, 0x06, 0x24, 0x00, 0x00, 
-0x60, 0x01, 0xff, 0xff, 0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x00, 0x25, 
-0xe0, 0x6b, 0x00, 0x28, 0x1d, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, 
-0x37, 0xfd, 0xe1, 0x6b, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x14, 0xd0, 
-0x38, 0x01, 0x0d, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 
-0x41, 0x6b, 0x80, 0x29, 0x0b, 0xd2, 0x01, 0x31, 0x41, 0x63, 0xe0, 0x6b, 
-0xc1, 0x69, 0xc0, 0x46, 0xe1, 0x63, 0x39, 0x07, 0x41, 0x60, 0xc7, 0x62, 
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 
-0x28, 0x17, 0x00, 0x80, 0xee, 0x05, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 
-0x02, 0x49, 0xca, 0x6b, 0xc0, 0x46, 0xc2, 0x61, 0xc8, 0x63, 0x70, 0x47, 
-0x28, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 
-0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, 
-0x00, 0x10, 0xa0, 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
-0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, 
+0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xcd, 0x57, 0xc3, 
+0xba, 0x01, 0x2c, 0xe8, 0xcd, 0xef, 0xa9, 0xd9, 0x6f, 0xbb, 0x76, 0x2f, 
+0x86, 0x49, 0xac, 0x1b, 0x40, 0x01, 0x00, 0x00, 0x8a, 0xe4, 0x00, 0x00, 
+0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0xea, 
+0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea, 
+0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, 0xc0, 0x14, 0x00, 0xea, 
+0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0x0f, 0xe1, 
+0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea, 
+0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, 0x01, 0x00, 0x50, 0xe1, 
+0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, 0x00, 0xa0, 0xa0, 0xe1, 
+0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0xa8, 0x10, 0x9f, 0xe5, 
+0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5, 
+0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe3, 
+0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x6c, 0xd0, 0x9f, 0xe5, 0x96, 0x14, 0x00, 0xeb, 0xd3, 0x00, 0xa0, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, 0x60, 0x00, 0x9f, 0xe5, 
+0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, 0xdb, 0xff, 0xff, 0xeb, 
+0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, 0x00, 0x20, 0xa0, 0xe3, 
+0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, 0x54, 0x10, 0x9f, 0xe5, 
+0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, 0x0b, 0xf0, 0xa0, 0xe1, 
+0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0xd4, 0xff, 0xff, 0xeb, 
+0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, 0xc6, 0xff, 0xff, 0xea, 
+0x01, 0x21, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x10, 0x00, 
+0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80, 
+0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, 
+0xad, 0xde, 0xad, 0xde, 0x5c, 0xbc, 0x00, 0x00, 0x24, 0xab, 0x20, 0x40, 
+0x48, 0x29, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, 0x8d, 0xd2, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x44, 0x57, 0x00, 0x00, 0x71, 0xaf, 0x00, 0x00, 0x60, 0x01, 0xff, 0xff, 
+0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x00, 0x25, 0x20, 0x68, 0x00, 0x28, 
+0x1d, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, 0x71, 0xfd, 0x21, 0x68, 
+0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x14, 0xd0, 0x38, 0x01, 0x0d, 0x49, 
+0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x80, 0x29, 
+0x0b, 0xd2, 0x01, 0x31, 0x41, 0x63, 0x20, 0x68, 0xc1, 0x69, 0xc0, 0x46, 
+0x21, 0x60, 0x39, 0x07, 0x41, 0x60, 0xc7, 0x62, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x28, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0xe8, 0x17, 0x00, 0x80, 
+0xee, 0x05, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 
+0xc0, 0x46, 0xc2, 0x61, 0x08, 0x60, 0x70, 0x47, 
+0xe8, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 
+0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, 0x00, 0x10, 0xa0, 0xe1, 
+0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 
-0x40, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
-0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, 
-0x00, 0xf0, 0x21, 0xe1, 0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, 
-0x00, 0x00, 0x50, 0xe3, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, 
+0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
+0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x40, 0x00, 0x80, 0xe3, 
 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 
-0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
-0x91, 0x00, 0x00, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, 
-0x01, 0x00, 0x80, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, 
-0x64, 0x28, 0x04, 0xd3, 0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, 
-0x03, 0xe0, 0x38, 0x63, 0x04, 0x49, 0x05, 0xf0, 0xc1, 0xfa, 0x78, 0x63, 
-0xb8, 0x63, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
-0x88, 0x13, 0x00, 0x00, 0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, 
-0x64, 0x2f, 0x03, 0xd2, 0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, 
-0x10, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, 
-0xbb, 0x42, 0x05, 0xd2, 0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, 
-0xc8, 0x63, 0xf1, 0xe7, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, 
-0x04, 0x48, 0xc1, 0x6b, 0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, 
-0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 
-0x90, 0xb5, 0x07, 0x1c, 0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, 
-0x0b, 0xd2, 0xb9, 0x6e, 0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, 
-0x91, 0x42, 0x07, 0xd2, 0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, 
-0x21, 0x64, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, 
-0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xe7, 0xfd, 0x38, 0x1c, 
-0x02, 0xf0, 0xa4, 0xfa, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, 
-0xc8, 0x72, 0x05, 0x49, 0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, 
-0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0xe4, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
-0x78, 0x2a, 0x00, 0x80, 0x10, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, 
-0xc0, 0x6d, 0x02, 0x23, 0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, 
-0x03, 0xd0, 0xd1, 0x63, 0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, 
-0x07, 0x68, 0x7b, 0x1c, 0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, 
-0xf3, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
-0x60, 0x01, 0x00, 0x80, 0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, 
-0x10, 0x18, 0x0a, 0x04, 0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, 
-0x01, 0x0c, 0x05, 0xd0, 0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, 
-0x01, 0x0c, 0xf9, 0xd1, 0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, 
-0x00, 0x22, 0x00, 0x29, 0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f, 
+0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x50, 0xe3, 
+0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, 0x00, 0xf0, 0x21, 0xe1, 
+0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x91, 0x00, 0x00, 0xe0, 
+0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, 0x01, 0x00, 0x80, 0xe0, 
+0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, 0x64, 0x28, 0x04, 0xd3, 
+0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, 0x03, 0xe0, 0x38, 0x63, 
+0x04, 0x49, 0x05, 0xf0, 0xf7, 0xfa, 0x78, 0x63, 0xb8, 0x63, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x88, 0x13, 0x00, 0x00, 
+0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, 0x64, 0x2f, 0x03, 0xd2, 
+0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, 0x10, 0x1c, 0x80, 0xbc, 
+0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, 0xbb, 0x42, 0x05, 0xd2, 
+0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, 0xc8, 0x63, 0xf1, 0xe7, 
+0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x04, 0x48, 0xc1, 0x6b, 
+0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, 0x68, 0x0e, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, 
+0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, 0x0b, 0xd2, 0xb9, 0x6e, 
+0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, 0x91, 0x42, 0x07, 0xd2, 
+0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, 0x21, 0x64, 0x90, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 
+0x38, 0x6b, 0x02, 0xf0, 0x23, 0xfe, 0x38, 0x1c, 0x02, 0xf0, 0xde, 0xfa, 
+0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x73, 0x05, 0x49, 
+0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, 0x8a, 0x6d, 0x12, 0x18, 
+0x8a, 0x65, 0xe4, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 
+0xa4, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, 0xc0, 0x6d, 0x02, 0x23, 
+0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, 0x03, 0xd0, 0xd1, 0x63, 
+0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, 0x07, 0x68, 0x7b, 0x1c, 
+0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, 0xf3, 0xe7, 0x00, 0x00, 
+0xa4, 0x2a, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0xe0, 0x01, 0x00, 0x80, 
+0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, 0x10, 0x18, 0x0a, 0x04, 
+0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, 0x01, 0x0c, 0x05, 0xd0, 
+0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, 0x01, 0x0c, 0xf9, 0xd1, 
+0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, 0x00, 0x22, 0x00, 0x29, 
+0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f, 
 0x06, 0xd0, 0x07, 0x88, 0xba, 0x18, 0x02, 0x30, 0x1f, 0x1c, 0x01, 0x3b, 
-0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, 
-0x00, 0x88, 0x00, 0x06, 0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, 
-0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 
-0x10, 0x04, 0x00, 0x0c, 0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, 
-0xc7, 0x89, 0xfb, 0x18, 0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, 
-0x40, 0x7a, 0x00, 0x02, 0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, 
-0x00, 0x0c, 0x3b, 0x0c, 0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, 
-0x11, 0x1c, 0xff, 0xf7, 0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 
-0xb0, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, 
-0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, 
-0x93, 0x69, 0x01, 0x33, 0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, 
-0x00, 0x68, 0x1c, 0x18, 0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, 
-0xac, 0xff, 0xc0, 0x43, 0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, 
-0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, 
-0x52, 0x09, 0x0e, 0xd3, 0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, 
-0xcb, 0x68, 0x02, 0x68, 0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, 
-0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, 
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 
-0x90, 0xb5, 0x80, 0x23, 0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, 
-0x15, 0xd0, 0x4a, 0x68, 0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, 
-0x01, 0x33, 0xd3, 0x61, 0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, 
-0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, 
-0x00, 0x28, 0x00, 0xd1, 0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, 
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 
-0xff, 0xff, 0x00, 0x00, 0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, 
-0x38, 0x69, 0xb9, 0x68, 0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, 
-0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, 
-0x04, 0x1c, 0xb8, 0x68, 0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, 
-0x0c, 0xd2, 0x2a, 0x68, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 
-0x05, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 
-0x26, 0xff, 0x04, 0x1c, 0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, 
-0x1a, 0xd3, 0xb8, 0x6a, 0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, 
-0xed, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, 
-0x20, 0x23, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, 
-0x01, 0x63, 0x07, 0xe0, 0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, 
-0xb9, 0x61, 0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 
-0xb8, 0x6b, 0x41, 0x09, 0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, 
-0x39, 0x30, 0x00, 0x7b, 0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 
-0x53, 0xf8, 0x01, 0x1c, 0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69, 
+0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, 0x00, 0x88, 0x00, 0x06, 
+0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 
+0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 
+0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, 0xc7, 0x89, 0xfb, 0x18, 
+0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, 0x40, 0x7a, 0x00, 0x02, 
+0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, 0x00, 0x0c, 0x3b, 0x0c, 
+0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, 0x11, 0x1c, 0xff, 0xf7, 
+0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xff, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, 0x82, 0x68, 0x1a, 0x40, 
+0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, 0x93, 0x69, 0x01, 0x33, 
+0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, 0x00, 0x68, 0x1c, 0x18, 
+0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43, 
+0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, 0x82, 0x68, 0x1a, 0x40, 
+0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, 0x52, 0x09, 0x0e, 0xd3, 
+0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, 0xcb, 0x68, 0x02, 0x68, 
+0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68, 
+0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x80, 0x23, 
+0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, 0x15, 0xd0, 0x4a, 0x68, 
+0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, 0x01, 0x33, 0xd3, 0x61, 
+0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, 
+0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, 0x00, 0x28, 0x00, 0xd1, 
+0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 
+0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, 0x38, 0x69, 0xb9, 0x68, 
+0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, 0xc0, 0x43, 0x01, 0x04, 
+0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x04, 0x1c, 0xb8, 0x68, 
+0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, 0x0c, 0xd2, 0x2a, 0x68, 
+0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x05, 0xf9, 0xc0, 0x43, 
+0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x26, 0xff, 0x04, 0x1c, 
+0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, 0x1a, 0xd3, 0xb8, 0x6a, 
+0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, 0xed, 0xf8, 0xc0, 0x43, 
+0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, 0x20, 0x23, 0xb9, 0x69, 
+0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x07, 0xe0, 
+0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x41, 0x6a, 
+0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x0c, 0x2b, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x41, 0x09, 
+0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b, 
+0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0x53, 0xf8, 0x01, 0x1c, 
+0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69, 
 0x19, 0x43, 0xb9, 0x61, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x07, 0xe0, 
-0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, 
-0xb9, 0x61, 0xc1, 0x6a, 0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 
-0xb8, 0x6b, 0x81, 0x09, 0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, 
-0x39, 0x30, 0x00, 0x7b, 0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, 
-0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, 
-0x05, 0x04, 0x2d, 0x0c, 0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 
-0x1f, 0xf8, 0x00, 0x28, 0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, 
-0x98, 0x42, 0x07, 0xd0, 0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 
-0x60, 0x6b, 0x01, 0x30, 0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, 
-0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, 
-0x00, 0x20, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 
-0xff, 0xff, 0x00, 0x00, 0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, 
-0xe0, 0x6b, 0x61, 0x6c, 0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, 
-0x00, 0x20, 0x8a, 0x08, 0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, 
-0x9f, 0x58, 0x03, 0xae, 0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, 
-0xf7, 0xd8, 0x60, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, 
-0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, 
-0xff, 0xf7, 0x87, 0xfe, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 
-0xff, 0xf7, 0x6d, 0xfe, 0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, 
-0x61, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 
-0xc0, 0x46, 0x01, 0x91, 0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, 
-0x0c, 0xd2, 0xa2, 0x6a, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 
-0x2f, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 
-0x50, 0xfe, 0x07, 0x1c, 0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, 
-0x08, 0x18, 0x69, 0x8a, 0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, 
-0xa1, 0x6c, 0x62, 0x6c, 0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 
-0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, 
-0x05, 0xd0, 0x08, 0x04, 0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, 
-0xf9, 0xd1, 0x38, 0x1c, 0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, 
-0x00, 0x0c, 0x7f, 0xb0, 0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xb0, 0xb4, 0x00, 0x22, 0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, 
-0xdc, 0x00, 0x47, 0x18, 0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, 
-0xff, 0x00, 0x80, 0x08, 0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, 
-0x4d, 0x1e, 0x02, 0xc8, 0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, 
-0x09, 0xd0, 0x0c, 0x04, 0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, 
-0x02, 0xc8, 0x1c, 0x1c, 0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, 
-0x08, 0x1c, 0xf8, 0x40, 0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, 
-0x42, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 
-0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 
-0x70, 0x47, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, 
-0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23, 
+0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0xc1, 0x6a, 
+0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x0c, 0x2b, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x81, 0x09, 
+0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b, 
+0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, 0x40, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, 0x05, 0x04, 0x2d, 0x0c, 
+0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0x00, 0x28, 
+0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, 0x98, 0x42, 0x07, 0xd0, 
+0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x60, 0x6b, 0x01, 0x30, 
+0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, 0xb8, 0x69, 0x18, 0x43, 
+0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, 0x00, 0x20, 0xb0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 
+0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, 0xe0, 0x6b, 0x61, 0x6c, 
+0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, 0x00, 0x20, 0x8a, 0x08, 
+0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, 0x9f, 0x58, 0x03, 0xae, 
+0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, 0xf7, 0xd8, 0x60, 0x6a, 
+0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 
+0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, 0xff, 0xf7, 0x87, 0xfe, 
+0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x6d, 0xfe, 
+0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, 0x61, 0x6a, 0x01, 0x23, 
+0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x01, 0x91, 
+0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, 0x0c, 0xd2, 0xa2, 0x6a, 
+0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x2f, 0xf8, 0xc0, 0x43, 
+0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0x07, 0x1c, 
+0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, 0x08, 0x18, 0x69, 0x8a, 
+0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, 0xa1, 0x6c, 0x62, 0x6c, 
+0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 0x12, 0x0a, 0x11, 0x43, 
+0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, 0x05, 0xd0, 0x08, 0x04, 
+0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, 0xf9, 0xd1, 0x38, 0x1c, 
+0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x7f, 0xb0, 
+0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb4, 0x00, 0x22, 
+0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, 0xdc, 0x00, 0x47, 0x18, 
+0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, 0xff, 0x00, 0x80, 0x08, 
+0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, 0x4d, 0x1e, 0x02, 0xc8, 
+0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, 0x09, 0xd0, 0x0c, 0x04, 
+0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, 0x02, 0xc8, 0x1c, 0x1c, 
+0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, 0x08, 0x1c, 0xf8, 0x40, 
+0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, 0x42, 0x18, 0x10, 0x0c, 
+0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 
+0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 
+0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, 0x42, 0x00, 0x12, 0x18, 
+0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23, 
 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x03, 0x1b, 0x0b, 0x8a, 0x58, 
-0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, 
-0x01, 0x30, 0x04, 0x28, 0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, 
-0x09, 0x0b, 0x07, 0x48, 0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, 
-0x02, 0xd0, 0x38, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 
-0x28, 0x03, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
-0x98, 0xb4, 0x14, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, 
-0xc0, 0x58, 0x07, 0x03, 0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, 
-0x12, 0x0b, 0x11, 0x48, 0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, 
-0xe4, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, 
-0xcc, 0x00, 0x01, 0x21, 0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, 
-0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, 
-0x18, 0x1a, 0x84, 0x42, 0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, 
-0x55, 0x55, 0x55, 0x55, 0xa0, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, 
-0x88, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, 
-0x00, 0xd0, 0x01, 0x3a, 0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, 
-0xc0, 0x46, 0x3b, 0x60, 0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, 
-0x08, 0x32, 0x10, 0x4b, 0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, 
-0x12, 0x58, 0x0f, 0x4b, 0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 
-0x1b, 0x68, 0x9b, 0x00, 0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, 
-0x0a, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, 
-0x70, 0x47, 0x08, 0x4b, 0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, 
-0x00, 0x20, 0xf6, 0xe7, 0x88, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, 
-0xa0, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
-0x90, 0x03, 0x00, 0x80, 0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, 
-0x01, 0xb6, 0xa0, 0xe3, 0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, 
-0x01, 0x7a, 0xa0, 0xe3, 0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, 
-0xc8, 0x60, 0x9f, 0xe5, 0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, 
-0x00, 0x00, 0x54, 0xe3, 0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, 
-0x11, 0x00, 0x00, 0x0a, 0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, 
-0x21, 0x00, 0x00, 0x0a, 0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, 
-0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 
-0x1c, 0x00, 0x85, 0xe5, 0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, 
-0x02, 0x0a, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 
-0x02, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 
-0x14, 0x80, 0x85, 0xe5, 0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 
-0x1c, 0x00, 0x96, 0xe5, 0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 
-0x1c, 0x00, 0x85, 0xe5, 0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, 
-0x40, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, 
-0x02, 0x0b, 0x14, 0xe3, 0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, 
-0x20, 0x00, 0x00, 0x1b, 0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, 
-0x18, 0x00, 0x89, 0xe5, 0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, 
+0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, 0x01, 0x30, 0x04, 0x28, 
+0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, 0x09, 0x0b, 0x07, 0x48, 
+0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, 0x02, 0xd0, 0x38, 0x1c, 
+0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0xa8, 0x03, 0x00, 0x80, 
+0x00, 0x40, 0x14, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x98, 0xb4, 0x14, 0x4a, 
+0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, 0xc0, 0x58, 0x07, 0x03, 
+0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, 0x12, 0x0b, 0x11, 0x48, 
+0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, 0xe4, 0x58, 0x01, 0x23, 
+0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, 0xcc, 0x00, 0x01, 0x21, 
+0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, 0x98, 0x42, 0x03, 0xd9, 
+0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, 0x18, 0x1a, 0x84, 0x42, 
+0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, 0x55, 0x55, 0x55, 0x55, 
+0x20, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x08, 0x04, 0x00, 0x80, 
+0x18, 0x04, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, 0x00, 0xd0, 0x01, 0x3a, 
+0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, 0xc0, 0x46, 0x3b, 0x60, 
+0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, 0x08, 0x32, 0x10, 0x4b, 
+0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, 0x12, 0x58, 0x0f, 0x4b, 
+0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x1b, 0x68, 0x9b, 0x00, 
+0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, 0x0a, 0x48, 0xc1, 0x68, 
+0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x08, 0x4b, 
+0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, 0x00, 0x20, 0xf6, 0xe7, 
+0x08, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x20, 0x04, 0x00, 0x80, 
+0x18, 0x04, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x10, 0x04, 0x00, 0x80, 
+0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, 0x01, 0xb6, 0xa0, 0xe3, 
+0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, 0x01, 0x7a, 0xa0, 0xe3, 
+0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, 0xc8, 0x60, 0x9f, 0xe5, 
+0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, 0x00, 0x00, 0x54, 0xe3, 
+0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, 0x11, 0x00, 0x00, 0x0a, 
+0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x21, 0x00, 0x00, 0x0a, 
+0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 
 0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 
+0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, 0x02, 0x0a, 0x14, 0xe3, 
+0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 0x02, 0x0a, 0xc0, 0xe3, 
+0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 0x14, 0x80, 0x85, 0xe5, 
+0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 
+0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 
+0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x00, 0x1b, 
+0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, 0x02, 0x0b, 0x14, 0xe3, 
+0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, 0x20, 0x00, 0x00, 0x1b, 
+0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, 0x18, 0x00, 0x89, 0xe5, 
+0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3, 
+0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 
 0x14, 0x70, 0x85, 0xe5, 0xe1, 0xff, 0xff, 0xea, 0xff, 0x5f, 0xbd, 0xe8, 
-0x04, 0xf0, 0x5e, 0xe2, 0xe8, 0x0d, 0x00, 0x80, 
-0x08, 0x83, 0x20, 0x40, 0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, 
-0x00, 0x20, 0xc3, 0xe1, 0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 
-0x0c, 0x20, 0x81, 0xe5, 0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, 
-0x18, 0x10, 0x9f, 0xe5, 0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, 
-0xb0, 0x24, 0xc1, 0xe1, 0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, 
-0x3c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, 
-0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, 
-0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, 
-0x24, 0x20, 0x91, 0xe5, 0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 
-0x24, 0x20, 0x80, 0xe5, 0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, 
-0x28, 0x10, 0x80, 0xe5, 0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, 
-0x2c, 0x20, 0x80, 0xe5, 0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, 
-0x1e, 0xff, 0x2f, 0x11, 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 
-0x01, 0x10, 0x81, 0xe2, 0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, 
-0x0b, 0x02, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
-0xb0, 0x03, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, 
-0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, 
+0x04, 0xf0, 0x5e, 0xe2, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40, 
+0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, 0x00, 0x20, 0xc3, 0xe1, 
+0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x0c, 0x20, 0x81, 0xe5, 
+0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0x18, 0x10, 0x9f, 0xe5, 
+0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, 0xb0, 0x24, 0xc1, 0xe1, 
+0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, 0x3c, 0x00, 0x81, 0xe5, 
+0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, 0xff, 0xff, 0xff, 0xea, 
+0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, 0x01, 0x16, 0xa0, 0xe3, 
+0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, 0x24, 0x20, 0x91, 0xe5, 
+0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x24, 0x20, 0x80, 0xe5, 
+0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0x80, 0xe5, 
+0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, 0x2c, 0x20, 0x80, 0xe5, 
+0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, 
+0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x10, 0x81, 0xe2, 
+0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, 0x0b, 0x02, 0xa0, 0xe3, 
+0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x04, 0x00, 0x80, 
+0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, 
+0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2, 
+0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1, 
+0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3, 
+0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5, 
+0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0x00, 
+0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 
+0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, 
+0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0c, 0x10, 0xa0, 0xe3, 
 0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, 
 0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, 
 0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, 
-0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, 
+0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x4c, 0x00, 0x1f, 0xe5, 
 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, 
-0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 
-0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 
-0x0c, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 
-0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 
-0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 
-0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 
-0x4c, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 
-0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, 
-0x01, 0x06, 0xa0, 0xe3, 0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
-0x80, 0x21, 0x1f, 0xe5, 0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x30, 0x80, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x81, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, 
-0x01, 0x06, 0xa0, 0xe3, 0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, 
-0x1c, 0x10, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, 
-0x1e, 0xff, 0x2f, 0xe1, 0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 
-0x1c, 0x10, 0x82, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, 
-0x0c, 0x00, 0x81, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 
-0x1c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, 
-0x38, 0x1c, 0x00, 0xf0, 0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 
-0x00, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 
-0x09, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x68, 0xf8, 
-0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, 
-0x3a, 0x78, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, 
-0xff, 0x22, 0x01, 0x32, 0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, 
-0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, 
-0x5b, 0x02, 0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, 
-0x82, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, 
-0x1a, 0x43, 0x08, 0x2a, 0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, 
-0x41, 0x60, 0x81, 0x68, 0x0e, 0x31, 0x2c, 0xe0, 0x13, 0x02, 0x12, 0x0a, 
-0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x2e, 0x3a, 
-0x16, 0x4b, 0x9a, 0x42, 0x24, 0xd8, 0x01, 0x25, 0x42, 0x68, 0x15, 0x43, 
-0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x12, 0x4b, 
-0x9a, 0x42, 0x19, 0xd1, 0xfb, 0x1d, 0x09, 0x33, 0x44, 0xcb, 0x9b, 0x07, 
-0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33, 0x9e, 0x40, 0x16, 0x43, 
-0x03, 0x2e, 0x0f, 0xd1, 0x39, 0x7d, 0x7b, 0x7d, 0x1b, 0x02, 0x19, 0x43, 
-0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43, 0x41, 0x60, 0x81, 0x68, 
-0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x01, 0xe0, 0x00, 0x21, 0x84, 0x60, 
-0x08, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xae, 0x05, 0x00, 0x00, 
-0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68, 0xd1, 0x08, 0x3f, 0xd3, 
-0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39, 0x8f, 0x78, 0x3f, 0x07, 
-0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d, 0x0d, 0x32, 0xc2, 0x60, 
-0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60, 0x08, 0x23, 0x1a, 0x43, 
-0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f, 0x92, 0x00, 0x02, 0x61, 
-0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, 
-0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x61, 
-0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23, 0x42, 0x68, 0x1a, 0x43, 
-0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23, 0x42, 0x68, 0x1a, 0x43, 
-0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23, 0x42, 0x68, 0x1a, 0x43, 
-0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23, 0x42, 0x68, 0x1a, 0x43, 
-0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76, 0x80, 0xbc, 0x70, 0x47, 
-0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78, 0x1b, 0x02, 0x1a, 0x43, 
-0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43, 0x02, 0x60, 0xc9, 0x78, 
-0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x07, 0x1c, 
-0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a, 0xc9, 0x68, 0x40, 0x18, 
-0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 
-0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42, 0x18, 0xd1, 0x78, 0x6a, 
-0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xb0, 0xf8, 
-0x38, 0x1c, 0x01, 0xf0, 0x6d, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, 
-0xc8, 0x72, 0x07, 0x49, 0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, 
-0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0x20, 0xfa, 0xe7, 0x98, 0x19, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 
-0x10, 0x2a, 0x00, 0x80, 0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, 
-0x01, 0x23, 0x9b, 0x07, 0x01, 0x1d, 0x18, 0x43, 
-0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02, 0x12, 0x0e, 0x12, 0x06, 
-0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40, 0x10, 0x43, 0x0a, 0x0a, 
-0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02, 0x1b, 0x0a, 0x19, 0x40, 
-0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 
-0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04, 0x1a, 0x40, 0x11, 0x43, 
-0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43, 0x00, 0x0e, 0x08, 0x43, 
-0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23, 0x81, 0x6b, 0x19, 0x40, 
-0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d, 0x39, 0x37, 0x39, 0x7b, 
-0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1, 0x01, 0x6b, 0xc0, 0x46, 
-0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d, 0x2d, 0x35, 0x00, 0x22, 
-0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50, 0x01, 0x32, 0x07, 0x2a, 
-0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63, 0x82, 0x6a, 0xc0, 0x46, 
-0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33, 0x5a, 0x83, 0x40, 0x6a, 
-0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27, 0x42, 0x68, 0x00, 0x2a, 
-0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1, 0x42, 0x69, 0x00, 0x2a, 
-0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a, 0x02, 0x29, 0x02, 0xd3, 
-0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0, 0x13, 0xf8, 0x09, 0xe0, 
-0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x03, 0xe0, 
-0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61, 0x38, 0x1c, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0xec, 0x05, 0x00, 0x80, 
-0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68, 0x00, 0x2b, 0x34, 0xd0, 
-0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68, 0x9b, 0x6a, 0xc0, 0x46, 
-0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19, 0x7f, 0x02, 0x17, 0x4b, 
-0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63, 0x07, 0x63, 0xcb, 0x1d, 
-0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69, 0x00, 0x2b, 0x01, 0xd0, 
-0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61, 0x0f, 0x1c, 0xc9, 0x68, 
-0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63, 0xf8, 0x1d, 0xff, 0x30, 
-0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60, 0xc2, 0x60, 0x38, 0x1c, 
-0x00, 0xf0, 0xc4, 0xfa, 0x38, 0x6a, 0x01, 0x30, 0x38, 0x62, 0x38, 0x1c, 
-0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 
-0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 
-0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31, 0x88, 0x6a, 0xc2, 0x1d, 
-0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32, 0x1a, 0x43, 0xc8, 0x6a, 
-0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18, 0x82, 0x79, 0xc3, 0x79, 
-0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 
-0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38, 0x92, 0x04, 0x92, 0x0c, 
-0x00, 0x26, 0x25, 0x4d, 0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, 
-0x04, 0xd0, 0x20, 0x8a, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, 
-0x01, 0x23, 0x9b, 0x07, 0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, 
-0x12, 0x04, 0x12, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 
-0x10, 0x43, 0x03, 0x1c, 0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, 
-0xc8, 0x6b, 0x19, 0x1c, 0x01, 0xf0, 0xd8, 0xff, 0x00, 0x28, 0x04, 0xda, 
-0x20, 0x8a, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 
-0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x08, 0x60, 0x01, 0x04, 
-0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8, 0x00, 0x28, 0x14, 0xd1, 
-0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43, 0x20, 0x82, 0x21, 0x8a, 
-0x38, 0x1c, 0x00, 0xf0, 0x98, 0xfb, 0xe8, 0x68, 0x01, 0x23, 0x9b, 0x07, 
-0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xe8, 0x60, 0x30, 0x1c, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0xfa, 0xe7, 0x00, 0x00, 
-0xec, 0x05, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0xfc, 0x1d, 0xf9, 0x34, 
-0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35, 0x33, 0x48, 0xc0, 0x6a, 
-0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18, 0x01, 0x20, 0x80, 0x07, 
-0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x90, 0x01, 0x23, 
-0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43, 0x00, 0x68, 0x38, 0x1c, 
-0x29, 0x1c, 0x00, 0xf0, 0xb8, 0xfa, 0xa8, 0x88, 0x40, 0x07, 0x01, 0xd0, 
-0x00, 0x20, 0x47, 0xe0, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a, 
+0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, 0x01, 0x06, 0xa0, 0xe3, 
+0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x21, 0x1f, 0xe5, 
+0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0xe5, 
+0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, 0x01, 0x06, 0xa0, 0xe3, 
+0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x92, 0xe5, 
+0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x82, 0xe5, 
+0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, 0x0c, 0x00, 0x81, 0xe5, 
+0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x81, 0xe5, 
+0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 
+0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 
+0x00, 0xf0, 0x92, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x00, 0x28, 
+0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x84, 0xf8, 0x00, 0x20, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, 0x3a, 0x78, 0xd2, 0x07, 
+0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, 0xff, 0x22, 0x01, 0x32, 
+0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, 
+0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, 0x5b, 0x02, 0x42, 0x68, 
+0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, 0x82, 0x60, 0x00, 0xe0, 
+0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x08, 0x2a, 
+0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, 
+0x0e, 0x31, 0x3c, 0xe0, 0xc1, 0x23, 0xdb, 0x00, 0x9a, 0x42, 0x03, 0xd1, 
+0x41, 0x68, 0x24, 0x4b, 0x19, 0x43, 0x3e, 0xe0, 0x23, 0x4b, 0x9a, 0x42, 
+0x04, 0xd1, 0x01, 0x23, 0x1b, 0x03, 0x41, 0x68, 0x19, 0x43, 0x36, 0xe0, 
+0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 
+0x12, 0x0c, 0x2e, 0x3a, 0x1c, 0x4b, 0x9a, 0x42, 0x2d, 0xd8, 0x01, 0x25, 
+0x42, 0x68, 0x15, 0x43, 0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02, 
+0x1a, 0x43, 0x18, 0x4b, 0x9a, 0x42, 0x22, 0xd1, 0xfb, 0x1d, 0x09, 0x33, 
+0x44, 0xcb, 0x9b, 0x07, 0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33, 
+0x9e, 0x40, 0x16, 0x43, 0x03, 0x2e, 0x18, 0xd1, 0x39, 0x7d, 0x7b, 0x7d, 
+0x1b, 0x02, 0x19, 0x43, 0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43, 
+0x41, 0x60, 0x81, 0x68, 0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x0a, 0xe0, 
+0xc1, 0x23, 0xdb, 0x00, 0x99, 0x42, 0x04, 0xd1, 0x01, 0x21, 0x89, 0x03, 
+0x29, 0x43, 0x41, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x00, 0x21, 0x08, 0x1c, 
+0xf0, 0xbc, 0x70, 0x47, 0x02, 0x40, 0x00, 0x00, 0x81, 0x80, 0x00, 0x00, 
+0xae, 0x05, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68, 
+0xd1, 0x08, 0x3f, 0xd3, 0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39, 
+0x8f, 0x78, 0x3f, 0x07, 0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d, 
+0x0d, 0x32, 0xc2, 0x60, 0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60, 
+0x08, 0x23, 0x1a, 0x43, 0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f, 
+0x92, 0x00, 0x02, 0x61, 0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43, 
+0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 
+0x12, 0x0c, 0x42, 0x61, 0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23, 
+0x42, 0x68, 0x1a, 0x43, 0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23, 
+0x42, 0x68, 0x1a, 0x43, 0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23, 
+0x42, 0x68, 0x1a, 0x43, 0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23, 
+0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76, 
+0x80, 0xbc, 0x70, 0x47, 0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78, 
+0x1b, 0x02, 0x1a, 0x43, 0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43, 
+0x02, 0x60, 0xc9, 0x78, 0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47, 
+0x80, 0xb5, 0x07, 0x1c, 0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a, 
+0xc9, 0x68, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43, 
+0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42, 
+0x18, 0xd1, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 
+0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xd0, 0xf8, 0x38, 0x1c, 0x01, 0xf0, 
+0x8b, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x07, 0x49, 
+0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, 0x8a, 0x6d, 0x12, 0x18, 
+0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0xfa, 0xe7, 
+0x18, 0x1a, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, 
+0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x01, 0x23, 0x9b, 0x07, 
+0x01, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02, 
+0x12, 0x0e, 0x12, 0x06, 0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40, 
+0x10, 0x43, 0x0a, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02, 
+0x1b, 0x0a, 0x19, 0x40, 0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07, 
+0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04, 
+0x1a, 0x40, 0x11, 0x43, 0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43, 
+0x00, 0x0e, 0x08, 0x43, 0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23, 
+0x81, 0x6b, 0x19, 0x40, 0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d, 
+0x39, 0x37, 0x39, 0x7b, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1, 
+0x01, 0x6b, 0xc0, 0x46, 0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d, 
+0x2d, 0x35, 0x00, 0x22, 0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50, 
+0x01, 0x32, 0x07, 0x2a, 0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63, 
+0x82, 0x6a, 0xc0, 0x46, 0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33, 
+0x5a, 0x83, 0x40, 0x6a, 0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27, 
+0x42, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1, 
+0x42, 0x69, 0x00, 0x2a, 0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a, 
+0x02, 0x29, 0x02, 0xd3, 0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0, 
+0x13, 0xf8, 0x09, 0xe0, 0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61, 
+0xc1, 0x60, 0x03, 0xe0, 0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61, 
+0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 
+0x6c, 0x06, 0x00, 0x80, 0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68, 
+0x00, 0x2b, 0x34, 0xd0, 0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68, 
+0x9b, 0x6a, 0xc0, 0x46, 0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19, 
+0x7f, 0x02, 0x17, 0x4b, 0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63, 
+0x07, 0x63, 0xcb, 0x1d, 0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69, 
+0x00, 0x2b, 0x01, 0xd0, 0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61, 
+0x0f, 0x1c, 0xc9, 0x68, 0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63, 
+0xf8, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60, 
+0xc2, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xce, 0xfa, 0x38, 0x6a, 0x01, 0x30, 
+0x38, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 
+0x1c, 0xad, 0x20, 0x40, 0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31, 
+0x88, 0x6a, 0xc2, 0x1d, 0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32, 
+0x1a, 0x43, 0xc8, 0x6a, 0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18, 
+0x82, 0x79, 0xc3, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, 
+0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38, 
+0x92, 0x04, 0x92, 0x0c, 0x00, 0x26, 0x25, 0x4d, 
+0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, 0x04, 0xd0, 0x20, 0x8a, 
+0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, 0x01, 0x23, 0x9b, 0x07, 
+0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, 0x12, 0x30, 
+0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x10, 0x43, 0x03, 0x1c, 
+0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, 0xc8, 0x6b, 0x19, 0x1c, 
+0x01, 0xf0, 0xf8, 0xff, 0x00, 0x28, 0x04, 0xda, 0x20, 0x8a, 0xff, 0x23, 
+0x01, 0x33, 0x18, 0x43, 0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 
+0x08, 0x60, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8, 
+0x00, 0x28, 0x14, 0xd1, 0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43, 
+0x20, 0x82, 0x21, 0x8a, 0x38, 0x1c, 0x00, 0xf0, 0xa2, 0xfb, 0xe8, 0x68, 
+0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 
+0xe8, 0x60, 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 
+0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 
+0xfc, 0x1d, 0xf9, 0x34, 0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35, 
+0x38, 0x48, 0xc0, 0x6a, 0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18, 
+0x01, 0x20, 0x80, 0x07, 0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 
+0x00, 0x90, 0x01, 0x23, 0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43, 
+0x00, 0x68, 0x38, 0x1c, 0x29, 0x1c, 0x00, 0xf0, 0xc2, 0xfa, 0xa8, 0x88, 
+0x41, 0x07, 0x01, 0xd0, 0x00, 0x20, 0x51, 0xe0, 0x29, 0x89, 0x09, 0x18, 
+0x60, 0x6b, 0x81, 0x42, 0xf8, 0xd8, 0x69, 0x89, 0xea, 0x88, 0x89, 0x18, 
+0x81, 0x42, 0xf3, 0xd8, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a, 
 0xf1, 0x6b, 0x40, 0x18, 0x71, 0x6c, 0xfa, 0x1d, 0xcd, 0x32, 0x01, 0xf0, 
-0x2b, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69, 
+0x29, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69, 
 0x40, 0x18, 0xc3, 0x1d, 0x03, 0x33, 0x00, 0x20, 0x81, 0x00, 0x5e, 0x58, 
 0xc9, 0x19, 0xff, 0x31, 0x01, 0x31, 0x4e, 0x61, 0x01, 0x30, 0x04, 0x28, 
 0xf6, 0xd3, 0xe0, 0x6a, 0x51, 0x69, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 
 0x00, 0x20, 0x00, 0x22, 0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, 
-0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xd4, 0xfb, 
+0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xae, 0xfb, 
 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 0x01, 0x20, 0x21, 0x6b, 
-0xff, 0xf7, 0xcc, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 
-0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0xc4, 0xfb, 0xa1, 0x6b, 0x08, 0x4a, 
-0x01, 0x20, 0xff, 0xf7, 0xbf, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46, 
+0xff, 0xf7, 0xa6, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 
+0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0x9e, 0xfb, 0xa1, 0x6b, 0x08, 0x4a, 
+0x01, 0x20, 0xff, 0xf7, 0x99, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46, 
 0x48, 0x62, 0x01, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0xc8, 0x29, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00, 
-0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a, 
+0x4c, 0x2a, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00, 
+0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a, 
 0xd5, 0x1d, 0xf9, 0x35, 0x68, 0x62, 0x01, 0x20, 0x00, 0x05, 0xb3, 0x49, 
 0xc0, 0x46, 0x08, 0x60, 0xa8, 0x6a, 0xc4, 0x1d, 0x2d, 0x34, 0xb1, 0x48, 
 0xc0, 0x6a, 0xd7, 0x1d, 0xff, 0x37, 0x3a, 0x37, 0x39, 0x68, 0x4b, 0x00, 
@@ -409,18 +418,18 @@ const u8 typhoon_firmware_image[] = {
 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, 
 0xc0, 0x46, 0x09, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x18, 0x40, 0x00, 0x0a, 
 0x0a, 0x90, 0x0a, 0x98, 0xa4, 0x4e, 0x01, 0x28, 0x59, 0xd1, 0x28, 0x6b, 
-0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69, 0x09, 0x04, 0x09, 0x0c, 
-0x01, 0xf0, 0x1e, 0xf9, 0x28, 0x6b, 0x79, 0x69, 0x40, 0x18, 0xc1, 0x1d, 
-0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b, 0xd3, 0x18, 0xff, 0x33, 
-0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50, 0x01, 0x30, 0x04, 0x28, 
-0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 
-0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, 0xb3, 0x50, 0x01, 0x30, 
-0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90, 0x90, 0x49, 0x42, 0x00, 
-0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0, 0x8e, 0x48, 0xc1, 0x89, 
-0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28, 
+0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69, 
+0x09, 0x04, 0x09, 0x0c, 0x01, 0xf0, 0x1c, 0xf9, 0x28, 0x6b, 0x79, 0x69, 
+0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b, 
+0xd3, 0x18, 0xff, 0x33, 0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50, 
+0x01, 0x30, 0x04, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00, 
+0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, 
+0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90, 
+0x90, 0x49, 0x42, 0x00, 0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0, 
+0x8e, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28, 
 0x03, 0xd1, 0x38, 0x8a, 0x10, 0x23, 0x18, 0x43, 0x71, 0xe0, 0x38, 0x8a, 
 0x40, 0x23, 0x18, 0x43, 0x6d, 0xe0, 0x00, 0xf0, 0x11, 0xf9, 0x01, 0xf0, 
-0x47, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98, 
+0x5d, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98, 
 0x00, 0x28, 0x0c, 0xd1, 0xb8, 0x68, 0x41, 0x1c, 0xb9, 0x60, 0x00, 0x28, 
 0x03, 0xd1, 0x38, 0x8a, 0x01, 0x23, 0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, 
 0x04, 0x23, 0x18, 0x43, 0x38, 0x82, 0x78, 0x68, 0x01, 0x30, 0x78, 0x60, 
@@ -452,20 +461,20 @@ const u8 typhoon_firmware_image[] = {
 0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 
 0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, 0x00, 0x04, 
 0x00, 0x0c, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0xbc, 0xd1, 
-0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d, 0x05, 0x31, 0x19, 0x43, 
-0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60, 0xe8, 0x6a, 0xc0, 0x46, 
-0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x92, 0xfc, 0x20, 0x7e, 0x33, 0x28, 
-0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21, 0x14, 0x4c, 0xc0, 0x46, 
-0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x85, 0xf8, 0x28, 0x6b, 
-0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c, 0xff, 0xf7, 0xca, 0xfd, 
-0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20, 0x30, 0x72, 0x11, 0xe0, 
-0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1, 0x07, 0x1c, 0x00, 0xf0, 
-0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xba, 0xfd, 
-0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x50, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc, 
+0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d, 
+0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60, 
+0xe8, 0x6a, 0xc0, 0x46, 0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x88, 0xfc, 
+0x20, 0x7e, 0x33, 0x28, 0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21, 
+0x14, 0x4c, 0xc0, 0x46, 0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0, 
+0x85, 0xf8, 0x28, 0x6b, 0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c, 
+0xff, 0xf7, 0xc0, 0xfd, 0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20, 
+0x30, 0x72, 0x11, 0xe0, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1, 
+0x07, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xfd, 
+0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x66, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc, 
 0x08, 0xbc, 0x18, 0x47, 0x00, 0xf0, 0x12, 0xf8, 0xf6, 0xe7, 0x00, 0x00, 
-0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x29, 0x00, 0x80, 
-0x1c, 0xad, 0x20, 0x40, 0xc0, 0x06, 0x00, 0x80, 0x02, 0x07, 0x00, 0x80, 
-0x78, 0x2a, 0x00, 0x80, 0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48, 
+0x6c, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x4c, 0x2a, 0x00, 0x80, 
+0x1c, 0xad, 0x20, 0x40, 0x40, 0x07, 0x00, 0x80, 0x82, 0x07, 0x00, 0x80, 
+0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48, 
 0x41, 0x68, 0x01, 0x31, 0x41, 0x60, 0x24, 0x4f, 0xf9, 0x1d, 0xf9, 0x31, 
 0x00, 0x24, 0x88, 0x6a, 0xfa, 0x68, 0xc0, 0x46, 0x94, 0x61, 0x04, 0x22, 
 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x60, 0x10, 0x22, 0xfb, 0x68, 0xc0, 0x46, 
@@ -476,10 +485,10 @@ const u8 typhoon_firmware_image[] = {
 0x4a, 0x6b, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x81, 0x0a, 0x6b, 0xc0, 0x46, 
 0x82, 0x62, 0xc4, 0x62, 0xc3, 0x1d, 0x39, 0x33, 0x4a, 0x6b, 0xc0, 0x46, 
 0x5a, 0x83, 0x04, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, 0x88, 0x6a, 
-0x01, 0xf0, 0x14, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 
+0x01, 0xf0, 0x28, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 
 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 
-0x2c, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a, 
+0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 
+0xac, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a, 
 0x01, 0x23, 0x9b, 0x07, 0xd1, 0x1d, 0x45, 0x31, 0x19, 0x43, 0x09, 0x68, 
 0x0b, 0x06, 0x1b, 0x0e, 0x01, 0x27, 0xc1, 0x1d, 0xff, 0x31, 0x4a, 0x31, 
 0x33, 0x2b, 0x05, 0xd1, 0x8b, 0x70, 0x01, 0x1c, 0x10, 0x1c, 0x00, 0xf0, 
@@ -495,15 +504,15 @@ const u8 typhoon_firmware_image[] = {
 0xf8, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1d, 
 0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 
 0xd0, 0x63, 0x90, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xca, 0x1d, 0xf9, 0x32, 
-0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d, 0xff, 0x37, 0x4a, 0x37, 
-0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d, 0xff, 0x34, 0x3a, 0x34, 
-0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30, 0xe8, 0x60, 0x60, 0x69, 
-0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07, 0x38, 0x1d, 0x18, 0x43, 
-0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 
-0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63, 0xf8, 0x1d, 0x03, 0x30, 
-0xff, 0xf7, 0x06, 0xfc, 0x20, 0x62, 0xf8, 0x1d, 0x07, 0x30, 0xff, 0xf7, 
-0x01, 0xfc, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76, 0xb0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98, 
+0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d, 
+0xff, 0x37, 0x4a, 0x37, 0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d, 
+0xff, 0x34, 0x3a, 0x34, 0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30, 
+0xe8, 0x60, 0x60, 0x69, 0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07, 
+0x38, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43, 
+0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63, 
+0xf8, 0x1d, 0x03, 0x30, 0xff, 0xf7, 0xfc, 0xfb, 0x20, 0x62, 0xf8, 0x1d, 
+0x07, 0x30, 0xff, 0xf7, 0xf7, 0xfb, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98, 
 0xc7, 0x1d, 0xf9, 0x37, 0xb8, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 
 0x05, 0x34, 0x23, 0x43, 0x1c, 0x68, 0xff, 0x23, 0xfe, 0x33, 0x23, 0x40, 
 0x7f, 0x6b, 0x3f, 0x04, 0x3b, 0x43, 0x0b, 0x60, 0x34, 0x30, 0x1c, 0x1c, 
@@ -537,86 +546,85 @@ const u8 typhoon_firmware_image[] = {
 0x04, 0x23, 0x90, 0x6a, 0xc0, 0x46, 0xc3, 0x60, 0x10, 0x23, 0x83, 0x61, 
 0xcb, 0x0a, 0x01, 0xd3, 0x18, 0x23, 0x83, 0x61, 0xc1, 0x83, 0x51, 0x6b, 
 0xc0, 0x46, 0xc1, 0x81, 0x51, 0x6b, 0xc2, 0x1d, 0x39, 0x32, 0x51, 0x83, 
-0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xa4, 0xf8, 
-0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x1b, 0x4c, 
-0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20, 0xe7, 0x1d, 0x19, 0x37, 
-0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30, 0x00, 0x29, 0x15, 0xd0, 
-0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25, 0x0a, 0xe0, 0xff, 0xf7, 
-0x93, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a, 0x02, 0x28, 0x00, 0xd3, 
-0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, 
-0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x6a, 0x00, 0x28, 
-0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69, 0x00, 0x28, 0x04, 0xd0, 
-0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0x8e, 0xfc, 
+0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xb8, 0xf8, 
+0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 
+0xb0, 0xb5, 0x1b, 0x4c, 0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20, 
+0xe7, 0x1d, 0x19, 0x37, 0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30, 
+0x00, 0x29, 0x15, 0xd0, 0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25, 
+0x0a, 0xe0, 0xff, 0xf7, 0x89, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a, 
+0x02, 0x28, 0x00, 0xd3, 0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0, 
+0x38, 0x79, 0x00, 0x28, 0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x40, 0x6a, 0x00, 0x28, 0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69, 
+0x00, 0x28, 0x04, 0xd0, 0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0x9e, 0xfc, 
 0xef, 0xe7, 0x60, 0x68, 0x00, 0x28, 0xec, 0xd0, 0x00, 0xf0, 0x50, 0xf8, 
-0xe9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xb4, 0x03, 0x00, 0x80, 
+0xe9, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x34, 0x04, 0x00, 0x80, 
 0xb0, 0xb5, 0x07, 0x1c, 0x20, 0x23, 0xb8, 0x68, 0x18, 0x40, 0x00, 0x25, 
 0x00, 0x28, 0x03, 0xd1, 0x28, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
 0xc4, 0x23, 0x48, 0x68, 0x18, 0x40, 0x01, 0x24, 0x00, 0x28, 0x03, 0xd1, 
-0x38, 0x6a, 0x00, 0xf0, 0x0d, 0xfc, 0x2f, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 
-0x1d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x7e, 0xfa, 0xb8, 0x68, 0xc0, 0x08, 
-0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xd2, 0xfb, 0xb8, 0x68, 0x39, 0x6a, 
+0x38, 0x6a, 0x00, 0xf0, 0x09, 0xfc, 0x2f, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 
+0x19, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x78, 0xfa, 0xb8, 0x68, 0xc0, 0x08, 
+0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xce, 0xfb, 0xb8, 0x68, 0x39, 0x6a, 
 0xc0, 0x46, 0x88, 0x60, 0x38, 0x6a, 0xc0, 0x46, 0xc5, 0x60, 0x0f, 0x48, 
 0x41, 0x68, 0x00, 0x29, 0x11, 0xd1, 0xc1, 0x68, 0x00, 0x29, 0x09, 0xd1, 
 0x41, 0x69, 0x00, 0x29, 0x06, 0xd1, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 
 0x41, 0x60, 0x00, 0xf0, 0x11, 0xf8, 0x0b, 0xe0, 0x39, 0x6a, 0xc0, 0x46, 
 0x81, 0x60, 0x41, 0x60, 0x06, 0xe0, 0x39, 0x6a, 0x82, 0x68, 0xc0, 0x46, 
 0xd1, 0x60, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x20, 0x1c, 0xc0, 0xe7, 
-0xec, 0x05, 0x00, 0x80, 0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, 
+0x6c, 0x06, 0x00, 0x80, 0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, 
 0x0f, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x28, 0x0a, 0xd1, 
 0x60, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x60, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
-0xc7, 0xfb, 0x00, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 
-0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 
+0xc3, 0xfb, 0x00, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 
+0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 
 0xfe, 0x1d, 0x49, 0x36, 0x30, 0x78, 0x40, 0x00, 0xc0, 0x19, 0x85, 0x8b, 
-0x2d, 0x4b, 0x9d, 0x42, 0x56, 0xd0, 0x2d, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 
-0x2a, 0x1c, 0x00, 0xf0, 0x23, 0xf9, 0xa0, 0x88, 0x40, 0x07, 0x4d, 0xd1, 
-0x29, 0x48, 0x80, 0x6a, 0x58, 0x21, 0x69, 0x43, 0x40, 0x18, 0x01, 0x23, 
-0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x25, 0x4d, 
-0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, 0xc0, 0x19, 0xc1, 0x1d, 0x19, 0x31, 
-0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x09, 0x7b, 0xea, 0x1d, 0x21, 0x32, 
-0x00, 0xf0, 0xe2, 0xfc, 0x30, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 
-0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x00, 0x22, 
-0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, 0xfa, 0xd3, 0x21, 0x1c, 
-0x16, 0x4a, 0x00, 0x20, 0xfe, 0xf7, 0x9a, 0xff, 0x01, 0x22, 0x52, 0x04, 
-0x78, 0x68, 0x02, 0x43, 0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x92, 0xff, 
-0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, 
-0xfe, 0xf7, 0x8a, 0xff, 0x0d, 0x49, 0x0e, 0x4a, 0x01, 0x20, 0xfe, 0xf7, 
-0x85, 0xff, 0x01, 0x20, 0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, 
-0xea, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0x20, 0xfa, 0xe7, 0xff, 0xff, 0x00, 0x00, 0x98, 0xad, 0x20, 0x40, 
-0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 
-0x84, 0xad, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, 0xf0, 0xb5, 0x83, 0xb0, 
-0x00, 0x21, 0x58, 0x48, 0xc2, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0x01, 0x21, 
-0xc9, 0x04, 0x56, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0xc1, 0x1d, 0x19, 0x31, 
-0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x53, 0x48, 0x00, 0x68, 0x03, 0xf0, 
-0x97, 0xfb, 0x98, 0xe0, 0x4e, 0x48, 0x47, 0x68, 0xfc, 0x1d, 0x49, 0x34, 
-0x22, 0x78, 0x50, 0x00, 0xc0, 0x19, 0x80, 0x8b, 
-0x4d, 0x49, 0x89, 0x6a, 0x58, 0x23, 0x58, 0x43, 0x0d, 0x18, 0x01, 0x23, 
-0x9b, 0x07, 0xe9, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x35, 
+0x33, 0x4c, 0x34, 0x4b, 0x9d, 0x42, 0x3c, 0xd0, 0x38, 0x1c, 0x21, 0x1c, 
+0x2a, 0x1c, 0x00, 0xf0, 0x1d, 0xf9, 0x31, 0x48, 0x80, 0x6a, 0x58, 0x21, 
+0x69, 0x43, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 
+0x00, 0x04, 0x00, 0x0c, 0x2c, 0x4d, 0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, 
+0xc0, 0x19, 0xc1, 0x1d, 0x19, 0x31, 0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 
+0x09, 0x7b, 0xea, 0x1d, 0x21, 0x32, 0x00, 0xf0, 0xe3, 0xfc, 0x30, 0x78, 
+0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, 
+0x05, 0x31, 0x00, 0x20, 0x00, 0x23, 0x42, 0x00, 0x8b, 0x52, 0x01, 0x30, 
+0x06, 0x28, 0xfa, 0xd3, 0xa0, 0x88, 0x41, 0x07, 0x0b, 0xd1, 0x21, 0x89, 
+0x09, 0x18, 0x78, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x81, 0x42, 0x04, 0xd8, 
+0x61, 0x89, 0xe2, 0x88, 0x89, 0x18, 0x81, 0x42, 0x03, 0xd9, 0x00, 0x20, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x21, 0x1c, 0x14, 0x4a, 0x00, 0x20, 
+0xfe, 0xf7, 0x64, 0xff, 0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43, 
+0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x5c, 0xff, 0x01, 0x22, 0x52, 0x04, 
+0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, 
+0xfe, 0xf7, 0x54, 0xff, 0x0b, 0x49, 0x0c, 0x4a, 0x01, 0x20, 0xfe, 0xf7, 
+0x4f, 0xff, 0x01, 0x20, 0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, 
+0xea, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0xd9, 0xe7, 0x98, 0xad, 0x20, 0x40, 
+0xff, 0xff, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 
+0x54, 0x00, 0x03, 0x00, 0x84, 0xad, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, 
+0xf0, 0xb5, 0x83, 0xb0, 0x00, 0x21, 0x4f, 0x48, 0xc2, 0x1d, 0xf9, 0x32, 
+0x51, 0x62, 0x01, 0x21, 0xc9, 0x04, 0x4d, 0x4a, 0xc0, 0x46, 0x11, 0x60, 
+0xc1, 0x1d, 0x19, 0x31, 0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x4a, 0x48, 
+0x00, 0x68, 0x03, 0xf0, 0x9b, 0xfb, 0x87, 0xe0, 0x45, 0x48, 0x47, 0x68, 
+0xfc, 0x1d, 0x49, 0x34, 0x21, 0x78, 0x48, 0x00, 0xc0, 0x19, 0x80, 0x8b, 
+0x44, 0x4a, 0x92, 0x6a, 0x58, 0x23, 0x58, 0x43, 0x15, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0xea, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x08, 0x35, 
 0x2b, 0x43, 0x1d, 0x68, 0xff, 0x23, 0x1b, 0x02, 0x2b, 0x40, 0x1b, 0x0a, 
-0x45, 0x4d, 0x01, 0x2b, 0x24, 0xd1, 0xd0, 0x19, 0xc1, 0x1d, 0x19, 0x31, 
-0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x42, 0x4a, 0x09, 0x7b, 0x00, 0xf0, 
-0xd3, 0xfc, 0x20, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 
+0x3c, 0x4d, 0x01, 0x2b, 0x24, 0xd1, 0xc8, 0x19, 0xc1, 0x1d, 0x19, 0x31, 
+0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x39, 0x4a, 0x09, 0x7b, 0x00, 0xf0, 
+0xc5, 0xfc, 0x20, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 
 0x41, 0x18, 0x00, 0x20, 0x82, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 
 0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf7, 0xd3, 0xca, 0x1d, 0x05, 0x32, 
 0x69, 0x46, 0x00, 0x20, 0x43, 0x00, 0xcd, 0x5a, 0xc0, 0x46, 0xd5, 0x52, 
-0x01, 0x30, 0x06, 0x28, 0xf8, 0xd3, 0x3e, 0xe0, 0x02, 0x2b, 0x3c, 0xd1, 
-0x09, 0x0a, 0x3a, 0xd3, 0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, 
+0x01, 0x30, 0x06, 0x28, 0xf8, 0xd3, 0x2d, 0xe0, 0x02, 0x2b, 0x2b, 0xd1, 
+0x11, 0x0a, 0x29, 0xd3, 0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, 
 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf7, 0xd3, 0x21, 0x78, 
 0x49, 0x00, 0xc9, 0x19, 0x09, 0x8f, 0x3a, 0x68, 0x8b, 0x18, 0x6a, 0x46, 
 0x00, 0x21, 0x4d, 0x00, 0x56, 0x5b, 0xc0, 0x46, 0x5e, 0x53, 0x01, 0x31, 
-0x06, 0x29, 0xf8, 0xd3, 0x22, 0x49, 0x8a, 0x6a, 0x12, 0x18, 0x01, 0x23, 
-0x9b, 0x07, 0xd5, 0x1d, 0x49, 0x35, 0x2b, 0x43, 0x6e, 0x46, 0x1d, 0x68, 
-0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x6b, 0x40, 0x1e, 0x4d, 
-0xee, 0x68, 0x73, 0x40, 0x13, 0x65, 0x89, 0x6a, 0x08, 0x18, 0x01, 0x23, 
-0x9b, 0x07, 0xc1, 0x1d, 0x4d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x6a, 0x46, 
-0x08, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x51, 0x40, 0xaa, 0x69, 0x51, 0x40, 
-0x41, 0x65, 0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, 0x0d, 0xd0, 
-0x38, 0x1c, 0xff, 0xf7, 0xef, 0xfe, 0x00, 0x28, 0x0d, 0xd1, 0x09, 0x4a, 
-0x50, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
-0xa3, 0xfa, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x72, 0xfa, 0x01, 0xf0, 
-0xc3, 0xfa, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xb8, 0x03, 0x00, 0x80, 
-0xc8, 0x29, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 0x14, 0x06, 0x00, 0x80, 
+0x06, 0x29, 0xf8, 0xd3, 0x19, 0x49, 0x8a, 0x6a, 0x13, 0x18, 0x1a, 0x6d, 
+0x00, 0x9d, 0x55, 0x40, 0x19, 0x4a, 0xd6, 0x68, 0x75, 0x40, 0x1d, 0x65, 
+0x89, 0x6a, 0x08, 0x18, 0x41, 0x6d, 0x02, 0x9b, 0x59, 0x40, 0x92, 0x69, 
+0x51, 0x40, 0x41, 0x65, 0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, 
+0x0d, 0xd0, 0x38, 0x1c, 0xff, 0xf7, 0xf4, 0xfe, 0x00, 0x28, 0x0d, 0xd1, 
+0x08, 0x4a, 0x50, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, 
+0x00, 0xf0, 0xa4, 0xfa, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x73, 0xfa, 
+0x01, 0xf0, 0xde, 0xfa, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x6c, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x38, 0x04, 0x00, 0x80, 
+0x4c, 0x2a, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 0x94, 0x06, 0x00, 0x80, 
 0x08, 0x83, 0x20, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 0x69, 0x4b, 0x9f, 0x6a, 
 0x58, 0x23, 0x5a, 0x43, 0xba, 0x18, 0xc3, 0x1d, 0x49, 0x33, 0x1f, 0x78, 
 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x01, 0x34, 0x23, 0x43, 0x1d, 0x68, 
@@ -625,14 +633,14 @@ const u8 typhoon_firmware_image[] = {
 0xff, 0x26, 0x36, 0x02, 0x2e, 0x40, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 
 0x74, 0xd1, 0x6b, 0x0c, 0x2b, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79, 
 0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x4c, 0x89, 
-0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, 0x01, 0x96, 0xb3, 0x18, 
-0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 
-0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 
-0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x1d, 0x36, 
-0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0x76, 0x18, 
-0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 0x06, 0xe0, 0x00, 0x23, 
-0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, 0x0c, 0x60, 0x23, 0x1c, 
-0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, 
+0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, 
+0x01, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, 
+0x33, 0x43, 0x1b, 0x68, 0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, 
+0x05, 0x2c, 0xf0, 0xd3, 0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, 
+0xde, 0x1d, 0x1d, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 
+0x00, 0x9e, 0x76, 0x18, 0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 
+0x06, 0xe0, 0x00, 0x23, 0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, 
+0x0c, 0x60, 0x23, 0x1c, 0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, 
 0x1b, 0x79, 0x10, 0x33, 0x0b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 
 0x0f, 0x89, 0xdb, 0x1b, 0x8b, 0x80, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 
 0x35, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x63, 0x01, 0x23, 
@@ -653,29 +661,29 @@ const u8 typhoon_firmware_image[] = {
 0x05, 0x28, 0xf2, 0xd3, 0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, 
 0x1d, 0x34, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, 
 0xbb, 0x62, 0x01, 0x30, 0x05, 0x28, 0xf2, 0xd3, 0x02, 0xb0, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xc8, 0x29, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, 
+0x08, 0xbc, 0x18, 0x47, 0x4c, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, 
 0x3b, 0x0c, 0x18, 0xd2, 0x17, 0x6d, 0x11, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 
 0x52, 0x6d, 0xc0, 0x46, 0x1a, 0x61, 0xc7, 0x60, 0x1a, 0x69, 0xc0, 0x46, 
 0x02, 0x61, 0xd8, 0x68, 0xc0, 0x46, 0x08, 0x80, 0xd8, 0x68, 0x00, 0x0c, 
 0x48, 0x80, 0x18, 0x69, 0xc0, 0x46, 0x88, 0x80, 0x18, 0x69, 0x00, 0x0c, 
 0xc8, 0x80, 0x80, 0xbc, 0x70, 0x47, 0x4a, 0x88, 0x12, 0x04, 0x0b, 0x88, 
 0x1a, 0x43, 0xc2, 0x60, 0x8a, 0x88, 0xc9, 0x88, 0x09, 0x04, 0x11, 0x43, 
-0x01, 0x61, 0xf2, 0xe7, 0xac, 0x06, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, 
+0x01, 0x61, 0xf2, 0xe7, 0x2c, 0x07, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, 
 0x00, 0x22, 0x08, 0x98, 0x00, 0x6a, 0x08, 0x9b, 0x99, 0x68, 0x49, 0x0a, 
 0x02, 0xd3, 0x01, 0x27, 0xff, 0x03, 0x00, 0xe0, 0x00, 0x27, 0x03, 0x8b, 
-0x00, 0x2b, 0x19, 0xd0, 0xa2, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 
+0x00, 0x2b, 0x19, 0xd0, 0xa3, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 
 0x63, 0x43, 0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 
 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x02, 0xd1, 0x08, 0x23, 
 0x1f, 0x43, 0x07, 0xe0, 0x41, 0x8b, 0x00, 0x29, 0x02, 0xd0, 0x0c, 0x23, 
 0x1f, 0x43, 0x01, 0xe0, 0x04, 0x23, 0x1f, 0x43, 0x83, 0x8a, 0x00, 0x2b, 
-0x18, 0xd0, 0x94, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 
-0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68, 
-0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, 0x0f, 0x43, 0x07, 0xe0, 
-0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, 0x1f, 0x43, 0x01, 0xe0, 
-0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, 0x07, 0x91, 0x4b, 0x89, 
-0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, 0x08, 0x9d, 0x2d, 0x68, 
-0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, 0x1a, 0xd3, 0x1a, 0x1c, 
-0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, 
+0x18, 0xd0, 0x95, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 
+0x58, 0x23, 0x63, 0x43, 0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 
+0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, 
+0x0f, 0x43, 0x07, 0xe0, 0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, 
+0x1f, 0x43, 0x01, 0xe0, 0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, 
+0x07, 0x91, 0x4b, 0x89, 0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, 
+0x08, 0x9d, 0x2d, 0x68, 0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, 
+0x1a, 0xd3, 0x1a, 0x1c, 0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, 
 0x92, 0x89, 0xc0, 0x46, 0x1a, 0x73, 0x07, 0x9a, 0x12, 0x89, 0xc0, 0x46, 
 0x02, 0x86, 0x04, 0x87, 0x82, 0x8a, 0x01, 0x3a, 0x82, 0x83, 0x01, 0x22, 
 0x19, 0x71, 0x08, 0x9b, 0x1b, 0x68, 0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, 
@@ -684,7 +692,7 @@ const u8 typhoon_firmware_image[] = {
 0x07, 0x9b, 0x9b, 0x89, 0xc0, 0x46, 0x2b, 0x73, 0x07, 0x9b, 0x1b, 0x89, 
 0x2e, 0x1c, 0x55, 0x00, 0x2d, 0x18, 0x05, 0x95, 0x2b, 0x86, 0x00, 0x2a, 
 0x01, 0xd0, 0xc3, 0x8a, 0x00, 0xe0, 0x83, 0x8a, 0x01, 0x3b, 0x05, 0x9d, 
-0xc0, 0x46, 0xab, 0x83, 0x31, 0x71, 0x64, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, 
+0xc0, 0x46, 0xab, 0x83, 0x31, 0x71, 0x65, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, 
 0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, 
 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, 
 0x01, 0xd1, 0x08, 0x31, 0x00, 0xe0, 0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 
@@ -692,7 +700,7 @@ const u8 typhoon_firmware_image[] = {
 0x24, 0x0c, 0x05, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 
 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x06, 0x9d, 0x40, 0x35, 0x2b, 0x70, 
 0x2b, 0x78, 0x02, 0x33, 0xe3, 0x1a, 0x1c, 0x04, 0x24, 0x0c, 0x01, 0x32, 
-0xbb, 0x08, 0x9b, 0x07, 0x6b, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, 
+0xbb, 0x08, 0x9b, 0x07, 0x6d, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, 
 0x19, 0x72, 0x01, 0x9b, 0x5d, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 
 0x1b, 0x68, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9e, 0xc0, 0x46, 
 0x33, 0x73, 0x00, 0x95, 0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 
@@ -701,102 +709,103 @@ const u8 typhoon_firmware_image[] = {
 0x2b, 0x43, 0x55, 0x00, 0x2d, 0x18, 0x2b, 0x86, 0x04, 0x9b, 0xc0, 0x46, 
 0x59, 0x72, 0x04, 0x9b, 0x1b, 0x7b, 0x2e, 0x1c, 0x04, 0x9d, 0xc0, 0x46, 
 0x6b, 0x73, 0x33, 0x8e, 0xc0, 0x46, 0x73, 0x86, 0x00, 0x9d, 0x2b, 0x78, 
-0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x59, 0x18, 0x04, 0x25, 0x3d, 0x40, 
-0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, 0xb3, 0x83, 0x13, 0x1c, 
-0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, 0x5b, 0x18, 0x5b, 0x78, 
-0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, 0x3b, 0x09, 0x37, 0xd3, 
-0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, 0x03, 0x8b, 0x55, 0x00, 
-0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, 0x03, 0x93, 0x20, 0x33, 
-0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, 0x1b, 0x18, 0x02, 0x93, 
-0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, 
-0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, 
-0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0, 0x10, 0x31, 0x81, 0x23, 
-0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 
-0x1c, 0x04, 0x24, 0x0c, 0x02, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 
-0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x03, 0x9c, 0x40, 0x34, 
-0x23, 0x70, 0x01, 0x32, 0x07, 0x9b, 0xc0, 0x46, 0xd9, 0x80, 0x51, 0x1e, 
-0xc3, 0x1d, 0x49, 0x33, 0x19, 0x70, 0x07, 0x61, 0x04, 0x2a, 0x06, 0xd2, 
-0x06, 0x49, 0x53, 0x00, 0x1b, 0x18, 0x99, 0x83, 0x01, 0x32, 0x04, 0x2a, 
-0xf9, 0xd3, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0xc8, 0x29, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 
-0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 0x12, 0x48, 0x01, 0x68, 
-0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x78, 0x68, 
-0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x0d, 0x48, 
-0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
-0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, 0x10, 0x23, 0x02, 0x98, 
-0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, 0xcd, 0xff, 0x68, 0x46, 
-0x02, 0xf0, 0x82, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x8c, 0xb0, 
-0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 
-0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, 0x02, 0xf0, 0x6c, 0xfe, 
-0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 
-0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, 0x40, 0x68, 0xc0, 0x46, 
-0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, 0x90, 0x80, 0xc8, 0x68, 
-0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, 0x10, 0x81, 0x88, 0x68, 
-0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, 0x90, 0x73, 0x08, 0x69, 
-0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, 0x08, 0x68, 0x00, 0x28, 
-0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, 0x0a, 0x60, 0xfa, 0xe7, 
-0xec, 0x05, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 0xc0, 0x46, 0xc2, 0x60, 
-0x08, 0x60, 0x70, 0x47, 0xec, 0x05, 0x00, 0x80, 0xb0, 0xb4, 0x00, 0x22, 
-0x12, 0x4f, 0x3b, 0x7f, 0x01, 0x33, 0x3b, 0x77, 0x03, 0x23, 0xfc, 0x1d, 
-0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, 0x0e, 0x4c, 0x25, 0x68, 
-0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x10, 0xd1, 0x24, 0x68, 
-0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0xfb, 0x62, 
-0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x99, 0x60, 0x58, 0x60, 
-0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, 0x10, 0x1c, 0x38, 0x64, 
-0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 
-0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00, 
-0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, 0x47, 0x4d, 0x07, 0x23, 
-0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, 0xe0, 0x6a, 0x01, 0x30, 
-0xe0, 0x62, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x43, 0x48, 0x41, 0x69, 
-0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 
-0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 
-0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 
-0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x3a, 0xfe, 0x38, 0x68, 0x01, 0x28, 
-0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 
-0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 
-0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 
-0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 
-0x1f, 0xfe, 0x38, 0x68, 0x02, 0x28, 0x2f, 0xd1, 0xbb, 0x23, 0x1b, 0x01, 
-0xee, 0x18, 0x70, 0x7a, 0x00, 0x28, 0x03, 0xd0, 0x00, 0x20, 0x70, 0x72, 
-0x00, 0xf0, 0x30, 0xfd, 0x30, 0x7a, 0x00, 0x28, 0x02, 0xd0, 0x78, 0x68, 
-0x02, 0xf0, 0x96, 0xff, 0x1b, 0x23, 0xdb, 0x01, 0xe8, 0x18, 0x40, 0x8b, 
-0x04, 0x26, 0x06, 0x40, 0xa0, 0x6a, 0xb0, 0x42, 
-0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x19, 0x28, 0x11, 0xd3, 
-0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, 0xff, 0x30, 0x41, 0x30, 
-0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, 0x02, 0xf0, 0x7c, 0xff, 
-0x00, 0x20, 0xf8, 0x60, 0xa6, 0x62, 0x01, 0xe0, 0x00, 0x20, 0xf8, 0x60, 
-0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, 0x79, 0x34, 0xa0, 0x6b, 
-0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, 0xef, 0xfb, 0x02, 0x23, 
-0xa0, 0x6b, 0x98, 0x43, 0xa0, 0x63, 0x38, 0x68, 0x01, 0x30, 0x38, 0x60, 
-0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xbc, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0xd0, 0x2c, 0x00, 0x80, 
-0x50, 0x2c, 0x00, 0x80, 0xa8, 0x04, 0x00, 0x80, 0x90, 0xb4, 0x1c, 0x48, 
-0x02, 0x8a, 0x1c, 0x49, 0x0f, 0x8a, 0x01, 0x23, 0xba, 0x42, 0x03, 0xd1, 
-0xc2, 0x89, 0x4f, 0x8a, 0xba, 0x42, 0x10, 0xd0, 0x02, 0x7b, 0x00, 0x2a, 
-0x0d, 0xd0, 0x42, 0x7b, 0x00, 0x2a, 0x0a, 0xd0, 0xc7, 0x8a, 0x8a, 0x8a, 
-0x97, 0x42, 0x04, 0xdc, 0x13, 0x4a, 0xc0, 0x46, 0x53, 0x60, 0x8b, 0x82, 
-0x01, 0xe0, 0x01, 0x32, 0x8a, 0x82, 0x42, 0x8b, 0x57, 0x1c, 0x47, 0x83, 
-0x07, 0x8b, 0xba, 0x42, 0x0e, 0xdb, 0x07, 0x8a, 0x84, 0x8a, 0x00, 0x22, 
-0xa7, 0x42, 0x05, 0xda, 0xc7, 0x89, 0x44, 0x8a, 0xa7, 0x42, 0x01, 0xda, 
-0x42, 0x73, 0x00, 0xe0, 0x43, 0x73, 0xc2, 0x81, 0x02, 0x82, 0x42, 0x83, 
-0xc2, 0x89, 0xc0, 0x46, 0x4a, 0x82, 0x00, 0x8a, 0xc0, 0x46, 0x08, 0x82, 
-0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xbc, 0x03, 0x00, 0x80, 
-0x40, 0x01, 0x18, 0x00, 0xf7, 0xb5, 0x91, 0xb0, 0x6b, 0x46, 0x84, 0x1e, 
-0x12, 0x99, 0x14, 0x29, 0x1a, 0xd9, 0x00, 0x20, 0x81, 0x00, 0x67, 0x58, 
-0xc0, 0x46, 0x57, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 
-0xf6, 0xd3, 0x00, 0x21, 0x05, 0x20, 0x87, 0x00, 0xd6, 0x59, 0x4f, 0x1c, 
-0x3d, 0x06, 0x2d, 0x0e, 0x0f, 0x1c, 0xbf, 0x00, 0xde, 0x51, 0x29, 0x1c, 
-0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 0xf1, 0xd3, 0x09, 0xe0, 
-0x00, 0x20, 0x81, 0x00, 0x63, 0x58, 0xc0, 0x46, 0x53, 0x50, 0x01, 0x30, 
-0x00, 0x06, 0x00, 0x0e, 0x06, 0x28, 0xf6, 0xd3, 0x00, 0x20, 0xe0, 0x70, 
-0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, 0x20, 0x73, 0x60, 0x73, 0x12, 0x99, 
-0x14, 0x29, 0x37, 0xd9, 0x69, 0x46, 0x8e, 0x1c, 0x91, 0x78, 0x09, 0x07, 
-0x09, 0x0f, 0x89, 0x00, 0x14, 0x39, 0x0d, 0x06, 0x2d, 0x16, 0x00, 0x27, 
-0x00, 0x2d, 0x1b, 0xdd, 0xf0, 0x19, 0x10, 0xa9, 0x00, 0xf0, 0x3d, 0xf8, 
-0x00, 0x28, 0x0e, 0xd0, 0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, 
-0x09, 0xdd, 0x00, 0x22, 0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, 
+0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x1b, 0x04, 0x1b, 0x0c, 0x59, 0x18, 
+0x04, 0x25, 0x3d, 0x40, 0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, 
+0xb3, 0x83, 0x13, 0x1c, 0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, 
+0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, 
+0x3b, 0x09, 0x37, 0xd3, 0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, 
+0x03, 0x8b, 0x55, 0x00, 0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, 
+0x03, 0x93, 0x20, 0x33, 0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, 
+0x1b, 0x18, 0x02, 0x93, 0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 
+0xdd, 0x1d, 0x01, 0x35, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 
+0x2b, 0x0e, 0x5b, 0x06, 0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0, 
+0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 0x1d, 0x40, 
+0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, 0x24, 0x0c, 
+0x02, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 0x1b, 0x19, 
+0x10, 0x3b, 0x9b, 0x7b, 0x03, 0x9c, 0x40, 0x34, 0x23, 0x70, 0x01, 0x32, 
+0x07, 0x9b, 0xc0, 0x46, 0xd9, 0x80, 0x51, 0x1e, 0xc3, 0x1d, 0x49, 0x33, 
+0x19, 0x70, 0x07, 0x61, 0x04, 0x2a, 0x06, 0xd2, 0x06, 0x49, 0x53, 0x00, 
+0x1b, 0x18, 0x99, 0x83, 0x01, 0x32, 0x04, 0x2a, 0xf9, 0xd3, 0x09, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 
+0xff, 0xff, 0x00, 0x00, 0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 
+0x12, 0x48, 0x01, 0x68, 0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, 
+0x00, 0x90, 0x78, 0x68, 0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, 
+0x02, 0x90, 0x0d, 0x48, 0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, 
+0x38, 0x1c, 0x00, 0xf0, 0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, 
+0x10, 0x23, 0x02, 0x98, 0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, 
+0xe1, 0xff, 0x68, 0x46, 0x02, 0xf0, 0x9a, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 
+0x00, 0xb5, 0x8c, 0xb0, 0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 
+0x05, 0x4b, 0x19, 0x43, 0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, 
+0x02, 0xf0, 0x84, 0xfe, 0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xa0, 0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, 
+0x40, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, 
+0x90, 0x80, 0xc8, 0x68, 0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, 
+0x10, 0x81, 0x88, 0x68, 0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, 
+0x90, 0x73, 0x08, 0x69, 0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, 
+0x08, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, 
+0x0a, 0x60, 0xfa, 0xe7, 0x6c, 0x06, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 
+0xc0, 0x46, 0xc2, 0x60, 0x08, 0x60, 0x70, 0x47, 0x6c, 0x06, 0x00, 0x80, 
+0xb0, 0xb4, 0x00, 0x22, 0x12, 0x4f, 0x7c, 0x7f, 0x01, 0x34, 0x7c, 0x77, 
+0x03, 0x23, 0xfc, 0x1d, 0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, 
+0x0e, 0x4c, 0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 
+0x10, 0xd1, 0x24, 0x68, 0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, 
+0xc0, 0x46, 0xfb, 0x62, 0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 
+0x99, 0x60, 0x58, 0x60, 0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, 
+0x10, 0x1c, 0x38, 0x64, 0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, 
+0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, 
+0x40, 0x01, 0x18, 0x00, 0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, 
+0x47, 0x4d, 0x07, 0x23, 0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, 
+0x20, 0x6b, 0x01, 0x30, 0x20, 0x63, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, 
+0x43, 0x48, 0x41, 0x69, 0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 
+0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 
+0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 
+0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x50, 0xfe, 
+0x38, 0x68, 0x01, 0x28, 0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29, 
+0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 
+0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 
+0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 
+0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x35, 0xfe, 0x38, 0x68, 
+0x02, 0x28, 0x2f, 0xd1, 0xbb, 0x23, 0x1b, 0x01, 0xee, 0x18, 0x70, 0x7b, 
+0x00, 0x28, 0x03, 0xd0, 0x00, 0x20, 0x70, 0x73, 0x00, 0xf0, 0x4a, 0xfd, 
+0x30, 0x7b, 0x00, 0x28, 0x02, 0xd0, 0x78, 0x68, 0x02, 0xf0, 0xaa, 0xff, 
+0x1b, 0x23, 0xdb, 0x01, 0xe8, 0x18, 0xc0, 0x8b, 0x04, 0x26, 0x06, 0x40, 
+0xe0, 0x6a, 0xb0, 0x42, 0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 
+0x19, 0x28, 0x11, 0xd3, 0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, 
+0xff, 0x30, 0x41, 0x30, 0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, 
+0x02, 0xf0, 0x90, 0xff, 0x00, 0x20, 0xf8, 0x60, 0xe6, 0x62, 0x01, 0xe0, 
+0x00, 0x20, 0xf8, 0x60, 0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, 
+0x79, 0x34, 0xe0, 0x6b, 0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, 
+0x07, 0xfc, 0x02, 0x23, 0xe0, 0x6b, 0x98, 0x43, 0xe0, 0x63, 0x38, 0x68, 
+0x01, 0x30, 0x38, 0x60, 0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x80, 
+0xa0, 0x82, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 
+0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 
+0xb0, 0xb4, 0x1d, 0x48, 0x84, 0x8a, 0x1d, 0x4a, 0x13, 0x8a, 0xc1, 0x1d, 
+0x09, 0x31, 0x01, 0x27, 0x9c, 0x42, 0x03, 0xd1, 0x43, 0x8a, 0x54, 0x8a, 
+0xa3, 0x42, 0x10, 0xd0, 0x0b, 0x78, 0x00, 0x2b, 0x0d, 0xd0, 0x4b, 0x78, 
+0x00, 0x2b, 0x0a, 0xd0, 0x44, 0x8b, 0x93, 0x8a, 0x9c, 0x42, 0x04, 0xdc, 
+0x13, 0x4b, 0xc0, 0x46, 0x5f, 0x60, 0x97, 0x82, 0x01, 0xe0, 0x01, 0x33, 
+0x93, 0x82, 0xc3, 0x8b, 0x5c, 0x1c, 0xc4, 0x83, 0x84, 0x8b, 0xa3, 0x42, 
+0x0e, 0xdb, 0x84, 0x8a, 0x05, 0x8b, 0x00, 0x23, 0xac, 0x42, 0x05, 0xda, 
+0x44, 0x8a, 0xc5, 0x8a, 0xac, 0x42, 0x01, 0xda, 0x4b, 0x70, 0x00, 0xe0, 
+0x4f, 0x70, 0x43, 0x82, 0x83, 0x82, 0xc3, 0x83, 0x41, 0x8a, 0xc0, 0x46, 
+0x51, 0x82, 0x80, 0x8a, 0xc0, 0x46, 0x10, 0x82, 0xb0, 0xbc, 0x70, 0x47, 
+0xe8, 0x0e, 0x00, 0x80, 0x3c, 0x04, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 
+0xf7, 0xb5, 0x91, 0xb0, 0x6b, 0x46, 0x84, 0x1e, 0x12, 0x99, 0x14, 0x29, 
+0x1a, 0xd9, 0x00, 0x20, 0x81, 0x00, 0x67, 0x58, 0xc0, 0x46, 0x57, 0x50, 
+0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 0xf6, 0xd3, 0x00, 0x21, 
+0x05, 0x20, 0x87, 0x00, 0xd6, 0x59, 0x4f, 0x1c, 0x3d, 0x06, 0x2d, 0x0e, 
+0x0f, 0x1c, 0xbf, 0x00, 0xde, 0x51, 0x29, 0x1c, 0x01, 0x30, 0x00, 0x06, 
+0x00, 0x0e, 0x10, 0x28, 0xf1, 0xd3, 0x09, 0xe0, 0x00, 0x20, 0x81, 0x00, 
+0x63, 0x58, 0xc0, 0x46, 0x53, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 
+0x06, 0x28, 0xf6, 0xd3, 0x00, 0x20, 0xe0, 0x70, 0x20, 0x72, 0x60, 0x72, 
+0xa0, 0x72, 0x20, 0x73, 0x60, 0x73, 0x12, 0x99, 0x14, 0x29, 0x37, 0xd9, 
+0x69, 0x46, 0x8e, 0x1c, 0x91, 0x78, 0x09, 0x07, 0x09, 0x0f, 0x89, 0x00, 
+0x14, 0x39, 0x0d, 0x06, 0x2d, 0x16, 0x00, 0x27, 0x00, 0x2d, 0x1b, 0xdd, 
+0xf0, 0x19, 0x10, 0xa9, 0x00, 0xf0, 0x3d, 0xf8, 0x00, 0x28, 0x0e, 0xd0, 
+0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, 0x09, 0xdd, 0x00, 0x22, 
+0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, 
 0x00, 0x0e, 0x10, 0xa9, 0x09, 0x78, 0x88, 0x42, 0xf6, 0xdb, 0x10, 0xa8, 
 0x00, 0x78, 0x38, 0x18, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 0xe3, 0xdb, 
 0x68, 0x46, 0xe2, 0x1d, 0x0d, 0x32, 0x00, 0x21, 0xab, 0x08, 0x5f, 0x1c, 
@@ -804,257 +813,261 @@ const u8 typhoon_firmware_image[] = {
 0x09, 0x06, 0x09, 0x0e, 0x8f, 0x42, 0xf6, 0xd8, 0x14, 0xb0, 0xf0, 0xbc, 
 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb4, 0x87, 0x1e, 0x00, 0x20, 0x89, 0x08, 
 0x4b, 0x1c, 0x08, 0xd0, 0x81, 0x00, 0x54, 0x58, 0xc0, 0x46, 0x7c, 0x50, 
-0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x83, 0x42, 
-0xf6, 0xd8, 0x90, 0xbc, 0x70, 0x47, 0x80, 0xb4, 0x02, 0x78, 0xd2, 0x06, 
-0xd2, 0x0e, 0x00, 0x23, 0x01, 0x27, 0x01, 0x2a, 0x01, 0xdc, 0x0f, 0x70, 
-0x11, 0xe0, 0x40, 0x78, 0xc0, 0x46, 0x08, 0x70, 0x14, 0x2a, 0x04, 0xd1, 
-0x08, 0x48, 0x01, 0x7a, 0x01, 0x31, 0x01, 0x72, 0x07, 0xe0, 0x02, 0x2a, 
-0x05, 0xd0, 0x05, 0x2a, 0x03, 0xd0, 0x06, 0x2a, 0x01, 0xd0, 0x15, 0x2a, 
-0x02, 0xd1, 0x18, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x38, 0x1c, 0xfb, 0xe7, 
-0xe0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x0f, 0x48, 0x01, 0x23, 0x1b, 0x06, 
-0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 
-0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 0x19, 0x1c, 0x09, 0x4a, 0xc0, 0x46, 
-0x11, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, 
-0x03, 0xd0, 0x02, 0xf0, 0x4f, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x04, 0x48, 
-0x41, 0x88, 0x01, 0x31, 0x41, 0x80, 0xf8, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0x00, 0x00, 0xb0, 0xe0, 0x82, 0x20, 0x40, 0x70, 0x47, 0x00, 0x00, 
-0xf0, 0xb5, 0x85, 0xb0, 0x94, 0x49, 0xc8, 0x68, 0xcf, 0x1d, 0x79, 0x37, 
-0x01, 0x28, 0x0b, 0xd1, 0xb8, 0x88, 0x00, 0x28, 0x08, 0xd1, 0xc3, 0x1e, 
-0xca, 0x6f, 0x1a, 0x40, 0xca, 0x67, 0x8f, 0x48, 0xc0, 0x46, 0x02, 0x60, 
-0x14, 0x20, 0xb8, 0x80, 0x8d, 0x4c, 0x62, 0x6a, 0x8d, 0x48, 0xc3, 0x6b, 
-0x9a, 0x18, 0xc2, 0x63, 0xa0, 0x6a, 0x19, 0x23, 0xdb, 0x01, 0xcc, 0x18, 
-0x60, 0x62, 0xe2, 0x69, 0x12, 0x03, 0x12, 0x0b, 0x82, 0x42, 0x05, 0xd1, 
-0x01, 0x20, 0x40, 0x04, 0x86, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xef, 0xe0, 
-0x3b, 0x8a, 0x58, 0x1c, 0x38, 0x82, 0xbd, 0x8a, 0x01, 0x20, 0x00, 0x22, 
-0xab, 0x42, 0x02, 0xdb, 0x78, 0x73, 0x3a, 0x82, 0x7a, 0x83, 0x33, 0x23, 
-0x9b, 0x01, 0xcb, 0x18, 0x04, 0x93, 0x1b, 0x69, 0x0f, 0x2b, 0x73, 0xd2, 
-0x00, 0x22, 0x2f, 0x23, 0x9b, 0x01, 0xcf, 0x18, 0xfa, 0x60, 0xe1, 0x69, 
-0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x4b, 0x68, 0x1e, 0x0c, 0x36, 0x04, 
-0x76, 0x4d, 0x05, 0xd1, 0x3b, 0x2a, 0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, 
-0x9a, 0x42, 0x01, 0xd9, 0xa8, 0x72, 0xc7, 0xe0, 0x01, 0x23, 0x9b, 0x07, 
-0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, 
-0x09, 0x88, 0x01, 0x31, 0x09, 0x04, 0x09, 0x0c, 0xf9, 0x81, 0x49, 0x09, 
-0x05, 0x31, 0x09, 0x06, 0x09, 0x0e, 0x6a, 0x4a, 0xc0, 0x46, 0x02, 0x92, 
-0x06, 0x1c, 0x69, 0x48, 0x43, 0x6a, 0xc0, 0x46, 0x01, 0x93, 0x83, 0x6a, 
-0xc0, 0x46, 0x00, 0x93, 0xc2, 0x1d, 0x11, 0x32, 0x80, 0x69, 0x00, 0x03, 
-0x00, 0x0b, 0x92, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, 
-0x90, 0x42, 0x01, 0xd1, 0x30, 0x1c, 0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, 
-0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b, 0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, 
-0x12, 0x1a, 0x01, 0x20, 0x09, 0x01, 0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, 
-0x01, 0x28, 0x62, 0xd1, 0xe0, 0x68, 0x00, 0x28, 0x60, 0xd0, 0x04, 0x99, 
-0x08, 0x69, 0x01, 0x30, 0x08, 0x61, 0x02, 0x20, 0xe1, 0x69, 0xc0, 0x46, 
-0x08, 0x60, 0x00, 0xf0, 0x8f, 0xfc, 0x38, 0x63, 0x4e, 0x49, 0xc0, 0x46, 
-0x79, 0x60, 0xe1, 0x69, 0x62, 0x6b, 0x8a, 0x18, 0x23, 0x6b, 0x9a, 0x42, 
-0x00, 0xd9, 0xe1, 0x6a, 0xc0, 0x46, 0x79, 0x62, 0x79, 0x6a, 0x0c, 0x31, 
-0xb9, 0x62, 0x00, 0x21, 0xb9, 0x61, 0x03, 0xa9, 0x49, 0x88, 0xc9, 0x09, 
-0x03, 0xd3, 0x00, 0xe0, 0x78, 0xe0, 0x31, 0x1c, 
-0x00, 0xe0, 0x00, 0x21, 0x39, 0x60, 0x39, 0x68, 0xc0, 0x46, 0x01, 0x60, 
-0xf8, 0x89, 0x41, 0x4e, 0x60, 0x28, 0x04, 0xdc, 0x30, 0x83, 0xf8, 0x89, 
-0xc0, 0x46, 0x70, 0x83, 0x08, 0xe0, 0x60, 0x20, 0x30, 0x83, 0xf9, 0x89, 
-0xb8, 0x6a, 0x42, 0x18, 0x23, 0x6b, 0x9a, 0x42, 0x03, 0xd8, 0x71, 0x83, 
-0x00, 0x21, 0xf9, 0x62, 0x05, 0xe0, 0xe1, 0x6a, 0xc0, 0x46, 0xf9, 0x62, 
-0x21, 0x6b, 0x08, 0x1a, 0x70, 0x83, 0x38, 0x6b, 0x41, 0x68, 0xc0, 0x46, 
-0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x01, 0x69, 0xc0, 0x46, 
-0x39, 0x61, 0x40, 0x69, 0xc0, 0x46, 0x78, 0x61, 0x38, 0x1c, 0x00, 0xf0, 
-0x23, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xe0, 0xfa, 
-0xf8, 0x89, 0x71, 0x8b, 0x88, 0x42, 0x04, 0xd1, 0xb9, 0x6a, 0x08, 0x18, 
-0x04, 0xe0, 0x38, 0xe0, 0x32, 0xe0, 0xfa, 0x6a, 0x10, 0x18, 0x40, 0x1a, 
-0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x21, 0x6b, 
-0x09, 0x1a, 0x62, 0x6b, 0x91, 0x42, 0x00, 0xd2, 0xe0, 0x6a, 0xc0, 0x46, 
-0xe0, 0x61, 0xe8, 0x7a, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x21, 0xe9, 0x72, 
-0x04, 0x99, 0x08, 0x69, 0x01, 0x38, 0x08, 0x61, 0x38, 0x6b, 0x00, 0xf0, 
-0x5d, 0xfa, 0x18, 0x48, 0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, 
-0x0a, 0xd1, 0xe0, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x0c, 0x4c, 0xa1, 0x6a, 
-0x88, 0x42, 0x03, 0xd0, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x01, 0x20, 0x40, 0x04, 0x09, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x05, 0xe0, 
-0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x9f, 0xfa, 0xae, 0x72, 
-0xee, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
-0x00, 0x40, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 
-0x98, 0x19, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, 
-0xe8, 0x19, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, 
+0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x83, 0x42, 0xf6, 0xd8, 0x90, 0xbc, 
+0x70, 0x47, 0x80, 0xb4, 0x02, 0x78, 0xd2, 0x06, 0xd2, 0x0e, 0x00, 0x23, 
+0x01, 0x27, 0x01, 0x2a, 0x01, 0xdc, 0x0f, 0x70, 0x11, 0xe0, 0x40, 0x78, 
+0xc0, 0x46, 0x08, 0x70, 0x14, 0x2a, 0x04, 0xd1, 0x08, 0x48, 0x01, 0x7a, 
+0x01, 0x31, 0x01, 0x72, 0x07, 0xe0, 0x02, 0x2a, 0x05, 0xd0, 0x05, 0x2a, 
+0x03, 0xd0, 0x06, 0x2a, 0x01, 0xd0, 0x15, 0x2a, 0x02, 0xd1, 0x18, 0x1c, 
+0x80, 0xbc, 0x70, 0x47, 0x38, 0x1c, 0xfb, 0xe7, 0xe0, 0x82, 0x20, 0x40, 
+0x00, 0xb5, 0x0f, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 
+0x1a, 0x09, 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 
+0x91, 0x61, 0x19, 0x1c, 0x09, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0x1b, 0x23, 
+0xdb, 0x01, 0xc0, 0x18, 0x80, 0x69, 0x00, 0x28, 0x03, 0xd0, 0x02, 0xf0, 
+0x61, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x04, 0x48, 0x41, 0x88, 0x01, 0x31, 
+0x41, 0x80, 0xf8, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 
+0xe0, 0x82, 0x20, 0x40, 0x70, 0x47, 0x00, 0x00, 0xf0, 0xb5, 0x86, 0xb0, 
+0x95, 0x4a, 0xd0, 0x68, 0xd7, 0x1d, 0x79, 0x37, 0x01, 0x28, 0x09, 0xd1, 
+0x38, 0x89, 0x00, 0x28, 0x06, 0xd1, 0xd0, 0x6f, 0x02, 0x23, 0x01, 0x68, 
+0x99, 0x43, 0x01, 0x60, 0x14, 0x20, 0x38, 0x81, 0x8e, 0x4c, 0x61, 0x6a, 
+0x8e, 0x48, 0xc3, 0x6b, 0x59, 0x18, 0xc1, 0x63, 0xa0, 0x6a, 0x19, 0x23, 
+0xdb, 0x01, 0xd4, 0x18, 0xa0, 0x62, 0x21, 0x6a, 0x09, 0x03, 0x09, 0x0b, 
+0x81, 0x42, 0x05, 0xd1, 0x01, 0x20, 0x40, 0x04, 0x87, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0xf3, 0xe0, 0xbb, 0x8a, 0x58, 0x1c, 0xb8, 0x82, 0x3d, 0x8b, 
+0x01, 0x20, 0x00, 0x21, 0xab, 0x42, 0x04, 0xdb, 0xd3, 0x1d, 0x89, 0x33, 
+0x58, 0x70, 0xb9, 0x82, 0xf9, 0x83, 0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 
+0x05, 0x93, 0x5b, 0x69, 0x0f, 0x2b, 0x73, 0xd2, 0x00, 0x21, 0x7c, 0x4f, 
+0xc0, 0x46, 0x39, 0x61, 0x21, 0x6a, 0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, 
+0x4b, 0x68, 0x1e, 0x0c, 0x36, 0x04, 0xfd, 0x1f, 0x09, 0x3d, 0x00, 0x2e, 
+0x05, 0xd1, 0x3b, 0x2a, 0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, 0x9a, 0x42, 
+0x01, 0xd9, 0xa8, 0x73, 0xc8, 0xe0, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, 
+0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, 0x09, 0x88, 
+0x01, 0x31, 0x09, 0x04, 0x09, 0x0c, 0x79, 0x82, 0x49, 0x09, 0x05, 0x31, 
+0x09, 0x06, 0x09, 0x0e, 0x69, 0x4e, 0xc0, 0x46, 0x02, 0x96, 0x69, 0x48, 
+0x43, 0x6a, 0xc0, 0x46, 0x01, 0x93, 0x83, 0x6a, 0xc0, 0x46, 0x00, 0x93, 
+0xc2, 0x1d, 0x11, 0x32, 0x80, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x92, 0x68, 
+0xb3, 0x07, 0x1a, 0x43, 0x12, 0x68, 0x90, 0x42, 0x01, 0xd1, 0x01, 0x20, 
+0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, 0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b, 
+0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, 0x12, 0x1a, 
+0x01, 0x20, 0x09, 0x01, 0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, 0x01, 0x28, 
+0x65, 0xd1, 0x51, 0x49, 0x20, 0x69, 0x00, 0x28, 0x62, 0xd0, 0x05, 0x99, 
+0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x02, 0x20, 0x21, 0x6a, 0xc0, 0x46, 
+0x08, 0x60, 0x00, 0xf0, 0xa7, 0xfc, 0x78, 0x63, 0xbe, 0x60, 0x49, 0x49, 
+0x22, 0x6a, 0xa3, 0x6b, 0xd3, 0x18, 0x66, 0x6b, 0xb3, 0x42, 0x00, 0xd9, 
+0x22, 0x6b, 0xc0, 0x46, 0xba, 0x62, 0xba, 0x6a, 0x0c, 0x32, 0xfa, 0x62, 
+0x00, 0x22, 0xfa, 0x61, 0x03, 0xaa, 0x52, 0x88, 0xd2, 0x09, 0x03, 0xd3, 
+0x01, 0x22, 0x00, 0xe0, 0x7b, 0xe0, 0x00, 0xe0, 0x00, 0x22, 0x7a, 0x60, 
+0x7a, 0x68, 0xc0, 0x46, 0x02, 0x60, 0x78, 0x8a, 0x41, 0x4e, 0x60, 0x28, 
+0x04, 0xdc, 0xb0, 0x83, 0x78, 0x8a, 0xc0, 0x46, 0xf0, 0x83, 0x08, 0xe0, 
+0x60, 0x20, 0xb0, 0x83, 0x79, 0x8a, 0xf8, 0x6a, 0x42, 0x18, 0x63, 0x6b, 
+0x9a, 0x42, 0x03, 0xd8, 0xf1, 0x83, 0x00, 0x22, 0x3a, 0x63, 0x05, 0xe0, 
+0x21, 0x6b, 0xc0, 0x46, 0x39, 0x63, 0x61, 0x6b, 0x08, 0x1a, 0xf0, 0x83, 
+0x2d, 0x49, 0x78, 0x6b, 0x42, 0x68, 0xc0, 0x46, 0xba, 0x60, 0x82, 0x68, 
+0xc0, 0x46, 0xfa, 0x60, 0x02, 0x69, 0xc0, 0x46, 0x7a, 0x61, 0x40, 0x69, 
+0xc0, 0x46, 0xb8, 0x61, 0x2e, 0x4b, 0xc8, 0x18, 0x04, 0x90, 0x00, 0xf0, 
+0x37, 0xf9, 0x04, 0x98, 0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xf6, 0xfa, 
+0x78, 0x8a, 0xf1, 0x8b, 0x88, 0x42, 0x04, 0xd1, 0xf9, 0x6a, 0x08, 0x18, 
+0x04, 0xe0, 0x38, 0xe0, 0x32, 0xe0, 0x3a, 0x6b, 0x10, 0x18, 0x40, 0x1a, 
+0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x61, 0x6b, 
+0x09, 0x1a, 0xa2, 0x6b, 0x91, 0x42, 0x00, 0xd2, 0x20, 0x6b, 0xc0, 0x46, 
+0x20, 0x62, 0xe8, 0x7b, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x22, 0xea, 0x73, 
+0x05, 0x99, 0x48, 0x69, 0x01, 0x38, 0x48, 0x61, 0x78, 0x6b, 0x00, 0xf0, 
+0x73, 0xfa, 0x18, 0x48, 0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, 
+0x0a, 0xd1, 0x20, 0x6a, 0x00, 0x03, 0x00, 0x0b, 0x0b, 0x4c, 0xa1, 0x6a, 
+0x88, 0x42, 0x03, 0xd0, 0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x01, 0x20, 0x40, 0x04, 0x08, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x06, 0xe0, 
+0xe0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0xb5, 0xfa, 0x01, 0x20, 
+0xa8, 0x73, 0xed, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, 
+0xa4, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x28, 0x1a, 0x00, 0x80, 
+0x55, 0x55, 0x55, 0x55, 0xa8, 0x03, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, 
+0xc4, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, 
 0x78, 0x6a, 0x40, 0x89, 0xff, 0x21, 0x01, 0x31, 0x01, 0x40, 0x10, 0x48, 
 0x02, 0xd1, 0x81, 0x6c, 0x01, 0x31, 0x81, 0x64, 0x79, 0x6a, 0x49, 0x89, 
 0x49, 0x0b, 0x02, 0xd2, 0x41, 0x6c, 0x01, 0x31, 0x41, 0x64, 0x0b, 0x48, 
 0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 
-0x48, 0x62, 0x38, 0x6b, 0x00, 0xf0, 0xe2, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 
-0x9f, 0xf8, 0x01, 0x20, 0x04, 0x49, 0xc0, 0x46, 0xc8, 0x72, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
-0x98, 0x19, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, 
+0x48, 0x62, 0x38, 0x6b, 0x00, 0xf0, 0xf8, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 
+0xb3, 0xf8, 0x01, 0x20, 0x04, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xa4, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x18, 0x1a, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, 
 0x61, 0x31, 0x0d, 0x1c, 0x78, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x40, 0x89, 
 0x03, 0x0c, 0x01, 0xd2, 0x40, 0x0a, 0x03, 0xd2, 0x38, 0x1c, 0xff, 0xf7, 
-0xc1, 0xff, 0x54, 0xe0, 0x2b, 0x48, 0x80, 0x6b, 0x00, 0x09, 0x1f, 0xd3, 
-0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, 0x43, 0x00, 0xcc, 0x5a, 
-0x27, 0x4e, 0x9e, 0x19, 0x65, 0x23, 0x5b, 0x01, 0xf3, 0x18, 0x9b, 0x8b, 
-0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, 
-0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
-0x13, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x60, 0xf8, 0x33, 0xe0, 0x01, 0x30, 
-0x03, 0x28, 0xe3, 0xd3, 0x1a, 0x48, 0x0b, 0x23, 0x1b, 0x02, 0xc1, 0x18, 
-0x09, 0x69, 0x00, 0x29, 0x24, 0xd0, 0x7d, 0x63, 0x00, 0x99, 0x49, 0x89, 
-0x09, 0x0c, 0x1f, 0xd2, 0x00, 0x24, 0x2d, 0x23, 
-0x9b, 0x01, 0xc1, 0x18, 0x89, 0x6b, 0x00, 0x29, 0x18, 0xd0, 0x05, 0x1c, 
-0xfe, 0x1d, 0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, 0x9b, 0x01, 
-0xd2, 0x18, 0x92, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, 0x7e, 0xfc, 
-0x01, 0x28, 0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x2d, 0x23, 
-0x9b, 0x01, 0xc0, 0x18, 0x80, 0x6b, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, 
-0x01, 0x2a, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0xf8, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x1a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
-0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, 
-0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x78, 0x6a, 0x40, 0x89, 
-0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, 0x38, 0x68, 0x40, 0x08, 
-0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x10, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 
-0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 
-0xff, 0xf7, 0x44, 0xff, 0x01, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, 0x01, 0x60, 0x70, 0x47, 
-0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, 0x89, 0x08, 0x09, 0x04, 
-0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, 0x00, 0x20, 0x00, 0x29, 
-0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 
-0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 
-0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xa0, 0xb0, 
-0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, 0x19, 0x43, 0x09, 0x68, 
-0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, 0x19, 0x43, 0x1f, 0x91, 
-0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, 0x1e, 0x92, 0x17, 0xab, 
-0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, 0x0a, 0x6a, 0x13, 0x43, 
-0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, 0x09, 0x0b, 0x22, 0x69, 
-0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, 0x39, 0x34, 0x64, 0x8b, 
-0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, 0x1c, 0x94, 0x56, 0x1a, 
-0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x26, 
-0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, 0x32, 0x1c, 0x0b, 0xe0, 
-0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, 0xb5, 0x18, 0x00, 0xe0, 
-0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42, 0x00, 0xd3, 0x00, 0x22, 
-0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43, 0x09, 0x68, 0xc0, 0x46, 
-0x39, 0x60, 0x93, 0x07, 0x01, 0x1d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
-0x79, 0x60, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
-0xb9, 0x60, 0x1f, 0x99, 0x09, 0x68, 0x1e, 0x9a, 0xc0, 0x46, 0x51, 0x83, 
-0xc1, 0x1d, 0x1d, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x38, 0x63, 
-0x79, 0x62, 0xc1, 0x1d, 0x11, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
-0xb9, 0x61, 0xc1, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
-0xf9, 0x60, 0xc1, 0x1d, 0x17, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
-0xf9, 0x83, 0x0e, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x81, 
-0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x60, 0xfb, 
-0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x58, 0xff, 
-0x20, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x03, 0x00, 0x80, 
-0x55, 0x55, 0x55, 0x55, 0xf8, 0xb5, 0x07, 0x1c, 
-0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x38, 0x4a, 0x91, 0x42, 0x00, 0xdd, 
-0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x20, 0x3a, 0x1d, 
-0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x12, 0xff, 0x32, 0x4a, 0xc0, 0x46, 
-0x00, 0x92, 0x32, 0x4e, 0x30, 0x6a, 0x32, 0x4c, 0xe1, 0x6d, 0x41, 0x18, 
-0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, 0x72, 0x6a, 0x02, 0xf0, 
-0xff, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0xb1, 0x6a, 0x81, 0x42, 0x00, 0xd8, 
-0x00, 0x20, 0xe0, 0x65, 0x17, 0x23, 0xdb, 0x01, 0x20, 0x1c, 0xe1, 0x6d, 
-0xe4, 0x18, 0xe2, 0x6b, 0x92, 0x00, 0x27, 0x4b, 0xc0, 0x46, 0x99, 0x50, 
-0x26, 0x4d, 0xa8, 0x6b, 0x41, 0x08, 0x05, 0xd3, 0x40, 0x08, 0x40, 0x00, 
-0xa8, 0x63, 0x01, 0x20, 0x01, 0xf0, 0xd8, 0xff, 0x22, 0x4a, 0x1f, 0x48, 
-0x29, 0x7b, 0x00, 0x29, 0x02, 0xd0, 0x69, 0x7b, 0x00, 0x29, 0x00, 0xd1, 
-0x1f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x05, 0x1c, 0xe0, 0x6b, 0x80, 0x00, 
-0x19, 0x4b, 0xc3, 0x18, 0x05, 0xce, 0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, 
-0x02, 0xf0, 0xce, 0xfe, 0xe0, 0x6b, 0x01, 0x30, 0xe0, 0x63, 0x17, 0x28, 
-0x01, 0xd3, 0x00, 0x20, 0xe0, 0x63, 0x00, 0x20, 0x39, 0x6b, 0xc0, 0x46, 
-0x08, 0x65, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x33, 0x23, 
-0x9b, 0x01, 0xe8, 0x18, 0x41, 0x68, 0x00, 0x29, 0x03, 0xd1, 0x39, 0x6b, 
-0xc0, 0x46, 0x41, 0x60, 0x04, 0xe0, 0x39, 0x6b, 0x82, 0x68, 0xc0, 0x46, 
-0x11, 0x65, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, 0xf8, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0x18, 0x00, 0x14, 0x02, 
-0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x44, 0x82, 0x20, 0x40, 
-0x68, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x03, 
-0xf0, 0xb5, 0x11, 0x4e, 0xff, 0x25, 0x01, 0x35, 0x10, 0x4f, 0xc0, 0x46, 
-0x35, 0x60, 0x38, 0x69, 0x01, 0x38, 0x38, 0x61, 0x7c, 0x68, 0x00, 0x2c, 
-0x10, 0xd0, 0x20, 0x6d, 0xc0, 0x46, 0x78, 0x60, 0x20, 0x1c, 0x00, 0xf0, 
-0x21, 0xf8, 0x20, 0x1c, 0x00, 0xf0, 0x04, 0xfa, 0x08, 0x48, 0x80, 0x6a, 
-0x00, 0x0c, 0x00, 0x07, 0xe9, 0xd1, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x05, 0x48, 0xc1, 0x79, 0x01, 0x31, 0xc1, 0x71, 0xf7, 0xe7, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xb0, 0xa8, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 
-0xa0, 0x82, 0x20, 0x40, 0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, 
-0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, 
+0xc1, 0xff, 0x67, 0xe0, 0x35, 0x48, 0xc0, 0x6b, 
+0x00, 0x09, 0x1f, 0xd3, 0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, 
+0x43, 0x00, 0xcc, 0x5a, 0x31, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, 
+0xf3, 0x18, 0x1b, 0x88, 0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, 
+0xc0, 0x46, 0x88, 0x61, 0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 
+0x38, 0x1c, 0x00, 0xf0, 0x27, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x74, 0xf8, 
+0x46, 0xe0, 0x01, 0x30, 0x03, 0x28, 0xe3, 0xdb, 0x02, 0x20, 0x43, 0x00, 
+0x5c, 0x18, 0xe4, 0x88, 0x22, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, 
+0xf3, 0x18, 0x1b, 0x88, 0x9c, 0x42, 0x03, 0xd1, 0x01, 0x23, 0x01, 0x38, 
+0xd8, 0x42, 0xf0, 0xdc, 0x01, 0x23, 0xd8, 0x42, 0xc4, 0xd0, 0x1b, 0x4e, 
+0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, 0x40, 0x69, 0x00, 0x28, 0x24, 0xd0, 
+0x7d, 0x63, 0x00, 0x98, 0x40, 0x89, 0x00, 0x0c, 0x1f, 0xd2, 0x00, 0x24, 
+0x2d, 0x23, 0x9b, 0x01, 0xf0, 0x18, 0xc0, 0x6b, 0x35, 0x1c, 0x00, 0x28, 
+0x17, 0xd0, 0xfe, 0x1d, 0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, 
+0x9b, 0x01, 0xd2, 0x18, 0xd2, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, 
+0x7b, 0xfc, 0x01, 0x28, 0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 
+0x2d, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc0, 0x6b, 0x00, 0x28, 0xea, 0xd1, 
+0x01, 0xe0, 0x01, 0x2a, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 
+0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 
+0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, 
+0xc0, 0x46, 0x88, 0x61, 0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 
+0x78, 0x6a, 0x40, 0x89, 0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, 
+0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x0c, 0xfc, 
+0x38, 0x1c, 0x00, 0xf0, 0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 
+0x02, 0xe0, 0x38, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x01, 0x20, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, 
+0x01, 0x60, 0x70, 0x47, 0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, 
+0x89, 0x08, 0x09, 0x04, 0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, 
+0x00, 0x20, 0x00, 0x29, 0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, 
+0x9b, 0x07, 0x2b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, 
+0x00, 0x04, 0x00, 0x0c, 0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, 
+0xf0, 0xb5, 0xa0, 0xb0, 0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, 
+0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, 
+0x19, 0x43, 0x1f, 0x91, 0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, 
+0x1e, 0x92, 0x17, 0xab, 0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, 
+0x0a, 0x6a, 0x13, 0x43, 0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, 
+0x09, 0x0b, 0x22, 0x69, 0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, 
+0x39, 0x34, 0x64, 0x8b, 0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, 
+0x1c, 0x94, 0x56, 0x1a, 0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, 
+0x00, 0x92, 0x01, 0x26, 0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, 
+0x32, 0x1c, 0x0b, 0xe0, 0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, 
+0xb5, 0x18, 0x00, 0xe0, 0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42, 
+0x00, 0xd3, 0x00, 0x22, 0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43, 
+0x09, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x93, 0x07, 
+0x01, 0x1d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x79, 0x60, 0xc1, 0x1d, 
+0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x1f, 0x99, 
+0x09, 0x68, 0x1e, 0x9a, 0xc0, 0x46, 0x51, 0x83, 0xc1, 0x1d, 0x1d, 0x31, 
+0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x38, 0x63, 0x79, 0x62, 0xc1, 0x1d, 
+0x11, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xb9, 0x61, 0xc1, 0x1d, 
+0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0xc1, 0x1d, 
+0x17, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0xf9, 0x83, 0x0e, 0x30, 
+0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x81, 0x38, 0x68, 0x40, 0x08, 
+0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x5c, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 
+0x0b, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x58, 0xff, 0x20, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xa8, 0x03, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, 
+0xf8, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x39, 0x4a, 
+0x91, 0x42, 0x00, 0xdd, 0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, 
+0x01, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x0e, 0xff, 
+0x33, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x33, 0x4e, 0x30, 0x6a, 0x33, 0x4c, 
+0xe1, 0x6d, 0x41, 0x18, 0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, 
+0x72, 0x6a, 0x02, 0xf0, 0xfb, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0x00, 0x25, 
+0xb1, 0x6a, 0x81, 0x42, 0x01, 0xd8, 0xe5, 0x65, 0x00, 0xe0, 0xe0, 0x65, 
+0x2f, 0x23, 0x9b, 0x01, 0x20, 0x1c, 0xe1, 0x6d, 0xe4, 0x18, 0x22, 0x68, 
+0x92, 0x00, 0x27, 0x4b, 0xc0, 0x46, 0x99, 0x50, 0x26, 0x48, 0xc1, 0x6b, 
+0x4a, 0x08, 0x05, 0xd3, 0x49, 0x08, 0x49, 0x00, 0xc1, 0x63, 0x01, 0x20, 
+0x01, 0xf0, 0xd6, 0xff, 0x22, 0x4a, 0x1f, 0x48, 0xc1, 0x1d, 0x89, 0x31, 
+0x0b, 0x78, 0x00, 0x2b, 0x02, 0xd0, 0x49, 0x78, 0x00, 0x29, 0x00, 0xd1, 
+0x1e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x20, 0x68, 0x80, 0x00, 0x19, 0x4b, 
+0xc3, 0x18, 0x05, 0xce, 0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, 0x02, 0xf0, 
+0xc7, 0xfe, 0x14, 0x48, 0x21, 0x68, 0x01, 0x31, 0x21, 0x60, 0x17, 0x29, 
+0x00, 0xd3, 0x25, 0x60, 0x39, 0x6b, 0xc0, 0x46, 0x0d, 0x65, 0x79, 0x6a, 
+0x3a, 0x6b, 0xc0, 0x46, 0x51, 0x62, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 
+0x81, 0x68, 0x00, 0x29, 0x03, 0xd1, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, 
+0x04, 0xe0, 0x39, 0x6b, 0xc2, 0x68, 0xc0, 0x46, 0x11, 0x65, 0x39, 0x6b, 
+0xc0, 0x46, 0xc1, 0x60, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xea, 0x05, 0x00, 0x00, 0x18, 0x00, 0x14, 0x02, 0x7c, 0x29, 0x00, 0x80, 
+0x68, 0x0e, 0x00, 0x80, 0x44, 0x82, 0x20, 0x40, 0xe8, 0x0e, 0x00, 0x80, 
+0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x03, 0xf0, 0xb5, 0x11, 0x4e, 
+0xff, 0x25, 0x01, 0x35, 0x10, 0x4f, 0xc0, 0x46, 0x35, 0x60, 0x78, 0x69, 
+0x01, 0x38, 0x78, 0x61, 0xbc, 0x68, 0x00, 0x2c, 0x10, 0xd0, 0x20, 0x6d, 
+0xc0, 0x46, 0xb8, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x21, 0xf8, 0x20, 0x1c, 
+0x00, 0xf0, 0x04, 0xfa, 0x08, 0x48, 0x80, 0x6a, 0x00, 0x0c, 0x00, 0x07, 
+0xe9, 0xd1, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x05, 0x48, 0xc1, 0x79, 
+0x01, 0x31, 0xc1, 0x71, 0xf7, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
+0x28, 0x1b, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0xa0, 0x82, 0x20, 0x40, 
+0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x70, 0x47, 
+0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, 
 0x38, 0x68, 0xc0, 0x08, 0x09, 0xd3, 0x1d, 0x48, 0x01, 0x6a, 0x01, 0x39, 
 0x01, 0x62, 0x20, 0x30, 0x00, 0x79, 0x00, 0x28, 0x01, 0xd0, 0xfe, 0xf7, 
-0x09, 0xfe, 0x01, 0x23, 0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, 
-0x00, 0x68, 0x16, 0x4c, 0x21, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, 
+0xf3, 0xfd, 0x01, 0x23, 0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, 
+0x00, 0x68, 0x16, 0x4c, 0x61, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, 
 0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x01, 0x29, 0x1a, 0xd1, 
-0x00, 0xf0, 0x22, 0xf8, 0x20, 0x62, 0x20, 0x6a, 0xe1, 0x69, 0x88, 0x42, 
+0x00, 0xf0, 0x22, 0xf8, 0x60, 0x62, 0x60, 0x6a, 0x21, 0x6a, 0x88, 0x42, 
 0x05, 0xd0, 0x01, 0x21, 0x89, 0x07, 0x01, 0x43, 0x09, 0x68, 0x09, 0x04, 
-0xf2, 0xd0, 0x51, 0x21, 0x89, 0x03, 0x22, 0x6a, 0xe3, 0x6a, 0x9a, 0x42, 
-0x02, 0xd1, 0x20, 0x6b, 0x62, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, 
+0xf2, 0xd0, 0x51, 0x21, 0x89, 0x03, 0x62, 0x6a, 0x23, 0x6b, 0x9a, 0x42, 
+0x02, 0xd1, 0x60, 0x6b, 0xa2, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, 
 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x79, 0x6a, 0xc0, 0x46, 
-0x08, 0x60, 0xf7, 0xe7, 0xec, 0x05, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, 
-0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x01, 0x31, 
-0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x18, 0x0d, 0x30, 
-0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x04, 0x49, 
-0x4a, 0x6b, 0x12, 0x18, 0x0b, 0x6b, 0x9a, 0x42, 0x00, 0xd9, 0xc8, 0x6a, 
-0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x00, 0xb5, 0x04, 0x48, 
-0x80, 0x68, 0x10, 0x28, 0x01, 0xd3, 0x00, 0xf0, 0x05, 0xf8, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x88, 0xb5, 0x0c, 0x4f, 
-0x38, 0x78, 0x00, 0x28, 0x11, 0xd1, 0x0b, 0x49, 0x10, 0x20, 0x02, 0xf0, 
-0xfb, 0xfd, 0x00, 0x28, 0x0b, 0xd0, 0x01, 0x20, 0x38, 0x70, 0x08, 0x4a, 
-0xc0, 0x46, 0x00, 0x92, 0x07, 0x48, 0x42, 0x68, 0x07, 0x4b, 0x01, 0x68, 
-0x00, 0x20, 0x02, 0xf0, 0xe5, 0xfd, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x78, 0x1a, 0x00, 0x80, 0x69, 0x2c, 0xff, 0xff, 0x10, 0x00, 0x35, 0x02, 
-0xf8, 0x28, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x90, 0xb5, 0x01, 0x20, 
-0x40, 0x02, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4f, 0x10, 0x21, 
-0xf8, 0x1d, 0x3d, 0x30, 0x02, 0xf0, 0x52, 0xfc, 0x19, 0x23, 0xdb, 0x01, 
-0xfc, 0x18, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x14, 0xf8, 
-0x00, 0x20, 0xc9, 0x23, 0x1b, 0x01, 0xf9, 0x18, 0x08, 0x70, 0xa0, 0x68, 
-0x10, 0x28, 0x04, 0xd3, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xf9, 0x18, 
-0x48, 0x72, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 
-0xe8, 0x0d, 0x00, 0x80, 0xf8, 0xb5, 0x37, 0x48, 0x19, 0x23, 0xdb, 0x01, 
-0xc1, 0x18, 0x89, 0x68, 0x35, 0x4d, 0x10, 0x29, 0x00, 0xd9, 0x10, 0x21, 
-0x29, 0x62, 0x32, 0x48, 0xc1, 0x6c, 0x00, 0x6e, 0x81, 0x42, 0x07, 0xd9, 
-0x08, 0x1a, 0x07, 0x09, 0x00, 0x24, 0x28, 0x6a, 0xb8, 0x42, 0x12, 0xd2, 
-0x07, 0x1c, 0x10, 0xe0, 0x81, 0x42, 0x2a, 0xd2, 0x2c, 0x4a, 0x52, 0x6b, 
-0x10, 0x1a, 0x07, 0x09, 0x28, 0x6a, 0xb8, 0x42, 0x05, 0xd9, 0x0c, 0x09, 
-0x39, 0x19, 0x88, 0x42, 0x03, 0xd2, 0xc4, 0x1b, 0x01, 0xe0, 0x00, 0x24, 
-0x07, 0x1c, 0x3e, 0x19, 0x30, 0x01, 0x25, 0x49, 0x02, 0xf0, 0x8a, 0xfd, 
-0x00, 0x28, 0x3d, 0xd0, 0x23, 0x48, 0x00, 0x2c, 0x1a, 0xd1, 0x1e, 0x49, 
-0x3a, 0x01, 0x2f, 0x62, 0x09, 0x6e, 0x8c, 0x18, 0x1d, 0x4d, 0x6b, 0x6b, 
-0xa3, 0x42, 0x00, 0xd8, 0xe4, 0x1a, 0x1e, 0x4b, 0x1a, 0x43, 0x00, 0x92, 
-0xea, 0x6a, 0x51, 0x18, 0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, 
-0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x00, 0x20, 0x28, 0x62, 0xf8, 0xbc, 
+0x08, 0x60, 0xf7, 0xe7, 0x6c, 0x06, 0x00, 0x80, 0xe8, 0x1a, 0x00, 0x80, 
+0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 
+0x09, 0x04, 0x09, 0x0c, 0x08, 0x18, 0x0d, 0x30, 0x81, 0x07, 0x02, 0xd0, 
+0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x04, 0x49, 0x8a, 0x6b, 0x12, 0x18, 
+0x4b, 0x6b, 0x9a, 0x42, 0x00, 0xd9, 0x08, 0x6b, 0x70, 0x47, 0x00, 0x00, 
+0xe8, 0x1a, 0x00, 0x80, 0x00, 0xb5, 0x04, 0x48, 0xc0, 0x68, 0x10, 0x28, 
+0x01, 0xd3, 0x00, 0xf0, 0x05, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xe8, 0x1a, 0x00, 0x80, 0x88, 0xb5, 0x0c, 0x4f, 0x38, 0x79, 0x00, 0x28, 
+0x11, 0xd1, 0x0b, 0x49, 0x10, 0x20, 0x02, 0xf0, 0xf5, 0xfd, 0x00, 0x28, 
+0x0b, 0xd0, 0x01, 0x20, 0x38, 0x71, 0x08, 0x4a, 0xc0, 0x46, 0x00, 0x92, 
+0x07, 0x48, 0x42, 0x68, 0x07, 0x4b, 0x01, 0x68, 0x00, 0x20, 0x02, 0xf0, 
+0xdf, 0xfd, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x1a, 0x00, 0x80, 
+0xe1, 0x2c, 0xff, 0xff, 0x10, 0x00, 0x35, 0x02, 0x7c, 0x29, 0x00, 0x80, 
+0x44, 0x80, 0x20, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x02, 0x10, 0x49, 
+0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4f, 0x10, 0x21, 0xf8, 0x1d, 0x3d, 0x30, 
+0x02, 0xf0, 0x4c, 0xfc, 0x19, 0x23, 0xdb, 0x01, 0xfc, 0x18, 0xe0, 0x68, 
+0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x14, 0xf8, 0x00, 0x20, 0xc9, 0x23, 
+0x1b, 0x01, 0xf9, 0x18, 0x08, 0x71, 0xe0, 0x68, 0x10, 0x28, 0x04, 0xd3, 
+0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xf9, 0x18, 0x48, 0x73, 0x90, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 
+0xf8, 0xb5, 0x37, 0x48, 0x19, 0x23, 0xdb, 0x01, 0xc1, 0x18, 0xc9, 0x68, 
+0x35, 0x4d, 0x10, 0x29, 0x00, 0xd9, 0x10, 0x21, 0x69, 0x62, 0x32, 0x48, 
+0xc1, 0x6c, 0x00, 0x6e, 0x81, 0x42, 0x07, 0xd9, 0x08, 0x1a, 0x07, 0x09, 
+0x00, 0x24, 0x68, 0x6a, 0xb8, 0x42, 0x12, 0xd2, 0x07, 0x1c, 0x10, 0xe0, 
+0x81, 0x42, 0x2a, 0xd2, 0x2c, 0x4a, 0x52, 0x6b, 0x10, 0x1a, 0x07, 0x09, 
+0x68, 0x6a, 0xb8, 0x42, 0x05, 0xd9, 0x0c, 0x09, 0x39, 0x19, 0x88, 0x42, 
+0x03, 0xd2, 0xc4, 0x1b, 0x01, 0xe0, 0x00, 0x24, 0x07, 0x1c, 0x3e, 0x19, 
+0x30, 0x01, 0x25, 0x49, 0x02, 0xf0, 0x84, 0xfd, 0x00, 0x28, 0x3d, 0xd0, 
+0x23, 0x48, 0x00, 0x2c, 0x1a, 0xd1, 0x1e, 0x49, 0x3a, 0x01, 0x6f, 0x62, 
+0x09, 0x6e, 0x8c, 0x18, 0x1d, 0x4d, 0x6b, 0x6b, 0xa3, 0x42, 0x00, 0xd8, 
+0xe4, 0x1a, 0x1e, 0x4b, 0x1a, 0x43, 0x00, 0x92, 0xea, 0x6a, 0x51, 0x18, 
+0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, 0x01, 0x6b, 0x01, 0x31, 
+0x01, 0x63, 0x00, 0x20, 0x68, 0x62, 0xf8, 0xbc, 
 0x08, 0xbc, 0x18, 0x47, 0x10, 0x49, 0x24, 0x01, 0x3f, 0x01, 0x11, 0x22, 
-0x52, 0x05, 0x3a, 0x43, 0x2e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, 
+0x52, 0x05, 0x3a, 0x43, 0x6e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, 
 0x09, 0x6e, 0x51, 0x18, 0x03, 0x1c, 0x06, 0x1c, 0x00, 0x20, 0x2a, 0x6b, 
-0x02, 0xf0, 0x50, 0xfd, 0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, 
-0xe9, 0x6a, 0x2a, 0x6b, 0x00, 0x20, 0x02, 0xf0, 0x47, 0xfd, 0x03, 0x48, 
+0x02, 0xf0, 0x4a, 0xfd, 0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, 
+0xe9, 0x6a, 0x2a, 0x6b, 0x00, 0x20, 0x02, 0xf0, 0x41, 0xfd, 0x03, 0x48, 
 0xc0, 0x46, 0x04, 0x66, 0x00, 0xf0, 0x10, 0xf8, 0x01, 0x20, 0xda, 0xe7, 
-0xe8, 0x0d, 0x00, 0x80, 0xa8, 0x1a, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 
-0xd1, 0x2d, 0xff, 0xff, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, 
+0x68, 0x0e, 0x00, 0x80, 0x28, 0x1b, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 
+0x49, 0x2e, 0xff, 0xff, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, 
 0xa0, 0x82, 0x20, 0x40, 0x04, 0x48, 0x01, 0x6e, 0x04, 0x4a, 0x80, 0x30, 
-0xd1, 0x60, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x70, 0x47, 
-0xe8, 0x0d, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 
-0x01, 0x20, 0x80, 0x02, 0x1c, 0x49, 0xc0, 0x46, 
-0x08, 0x60, 0x00, 0x27, 0x1b, 0x4e, 0x33, 0x23, 0x9b, 0x01, 0xf5, 0x18, 
-0x28, 0x6a, 0x00, 0x28, 0x1d, 0xd9, 0x19, 0x4c, 0x68, 0x46, 0x10, 0x21, 
-0x02, 0xf0, 0x96, 0xfb, 0x68, 0x46, 0x00, 0xf0, 0x33, 0xf8, 0x00, 0x28, 
-0x04, 0xd0, 0x15, 0x49, 0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x0a, 0xe0, 
-0x13, 0x49, 0x60, 0x7b, 0x01, 0x30, 0x60, 0x73, 0x88, 0x79, 0x01, 0x30, 
-0x88, 0x71, 0x11, 0x48, 0x00, 0x68, 0x02, 0xf0, 0x6b, 0xf9, 0x28, 0x6a, 
-0x01, 0x37, 0xb8, 0x42, 0xe2, 0xd8, 0xbb, 0x23, 0x1b, 0x01, 0xf0, 0x18, 
-0x81, 0x7a, 0x00, 0x29, 0x03, 0xd0, 0x00, 0x21, 0x81, 0x72, 0xff, 0xf7, 
-0x1d, 0xfb, 0xff, 0xf7, 0xe3, 0xfe, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 
-0xb0, 0x82, 0x20, 0x40, 0x08, 0x83, 0x20, 0x40, 0xa0, 0x82, 0x20, 0x40, 
-0xd8, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x17, 0x4f, 0x19, 0x23, 0xdb, 0x01, 
-0xf9, 0x18, 0x00, 0x22, 0x8b, 0x68, 0x00, 0x2b, 0x23, 0xd0, 0x01, 0x3b, 
-0x8b, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xff, 0x18, 0x7b, 0x69, 0x1c, 0x6d, 
-0xc0, 0x46, 0x7c, 0x61, 0x04, 0x68, 0xc0, 0x46, 0x5c, 0x60, 0x44, 0x68, 
-0xc0, 0x46, 0x9c, 0x60, 0x84, 0x68, 0xc0, 0x46, 0x1c, 0x61, 0xc0, 0x68, 
-0xc0, 0x46, 0x58, 0x61, 0x1a, 0x65, 0xc8, 0x68, 0x42, 0x1c, 0xca, 0x60, 
-0x00, 0x28, 0x03, 0xd0, 0xf8, 0x69, 0xc0, 0x46, 0x03, 0x65, 0x00, 0xe0, 
-0xbb, 0x61, 0xfb, 0x61, 0x18, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x10, 0x1c, 
-0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x0a, 0x4a, 0x33, 0x23, 
-0x9b, 0x01, 0xd1, 0x18, 0x88, 0x69, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 
-0xd3, 0x68, 0x00, 0x2b, 0x06, 0xd0, 0x01, 0x3b, 0xd3, 0x60, 0x8a, 0x69, 
-0x12, 0x6d, 0xc0, 0x46, 0x8a, 0x61, 0x70, 0x47, 0x00, 0x21, 0xd1, 0x60, 
-0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x06, 0x4a, 0xd1, 0x68, 
-0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x91, 0x69, 
-0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, 0x70, 0x47, 0x00, 0x00, 
-0x68, 0x1a, 0x00, 0x80, 0x06, 0x4a, 0x91, 0x68, 0x4b, 0x1c, 0x93, 0x60, 
-0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x51, 0x69, 0x00, 0xe0, 0x00, 0x21, 
-0x01, 0x65, 0x50, 0x61, 0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 
-0x90, 0xb4, 0x00, 0x21, 0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, 
-0x1b, 0x18, 0x9b, 0x8a, 0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, 
+0xd1, 0x60, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x70, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 
+0x01, 0x20, 0x80, 0x02, 0x1c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x27, 
+0x1b, 0x4e, 0x33, 0x23, 0x9b, 0x01, 0xf5, 0x18, 0x68, 0x6a, 0x00, 0x28, 
+0x1d, 0xd9, 0x19, 0x4c, 0x68, 0x46, 0x10, 0x21, 0x02, 0xf0, 0x90, 0xfb, 
+0x68, 0x46, 0x00, 0xf0, 0x33, 0xf8, 0x00, 0x28, 0x04, 0xd0, 0x15, 0x49, 
+0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x0a, 0xe0, 0x13, 0x49, 0x60, 0x7b, 
+0x01, 0x30, 0x60, 0x73, 0x88, 0x79, 0x01, 0x30, 0x88, 0x71, 0x11, 0x48, 
+0x00, 0x68, 0x02, 0xf0, 0x65, 0xf9, 0x68, 0x6a, 0x01, 0x37, 0xb8, 0x42, 
+0xe2, 0xd8, 0xbb, 0x23, 0x1b, 0x01, 0xf0, 0x18, 0x81, 0x7b, 0x00, 0x29, 
+0x03, 0xd0, 0x00, 0x21, 0x81, 0x73, 0xff, 0xf7, 0x05, 0xfb, 0xff, 0xf7, 
+0xe3, 0xfe, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 0xb0, 0x82, 0x20, 0x40, 
+0x08, 0x83, 0x20, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x58, 0x04, 0x00, 0x80, 
+0x90, 0xb4, 0x17, 0x4f, 0x19, 0x23, 0xdb, 0x01, 0xf9, 0x18, 0x00, 0x22, 
+0xcb, 0x68, 0x00, 0x2b, 0x23, 0xd0, 0x01, 0x3b, 0xcb, 0x60, 0x33, 0x23, 
+0x9b, 0x01, 0xff, 0x18, 0xbb, 0x69, 0x1c, 0x6d, 0xc0, 0x46, 0xbc, 0x61, 
+0x04, 0x68, 0xc0, 0x46, 0x5c, 0x60, 0x44, 0x68, 0xc0, 0x46, 0x9c, 0x60, 
+0x84, 0x68, 0xc0, 0x46, 0x1c, 0x61, 0xc0, 0x68, 0xc0, 0x46, 0x58, 0x61, 
+0x1a, 0x65, 0x08, 0x69, 0x42, 0x1c, 0x0a, 0x61, 0x00, 0x28, 0x03, 0xd0, 
+0x38, 0x6a, 0xc0, 0x46, 0x03, 0x65, 0x00, 0xe0, 0xfb, 0x61, 0x3b, 0x62, 
+0x18, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x10, 0x1c, 0xfb, 0xe7, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0x0a, 0x4a, 0x33, 0x23, 0x9b, 0x01, 0xd1, 0x18, 
+0xc8, 0x69, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0x13, 0x69, 0x00, 0x2b, 
+0x06, 0xd0, 0x01, 0x3b, 0x13, 0x61, 0xca, 0x69, 0x12, 0x6d, 0xc0, 0x46, 
+0xca, 0x61, 0x70, 0x47, 0x00, 0x21, 0x11, 0x61, 0xfb, 0xe7, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0x06, 0x4a, 0x11, 0x69, 0x4b, 0x1c, 0x13, 0x61, 
+0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0xd1, 0x69, 0x00, 0xe0, 0x00, 0x21, 
+0x01, 0x65, 0xd0, 0x61, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 
+0x06, 0x4a, 0xd1, 0x68, 0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, 
+0x01, 0xd0, 0x91, 0x69, 0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, 
+0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, 
+0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, 0x1b, 0x18, 0x9b, 0x8a, 
+0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, 
 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 0xd3, 0x18, 0xdc, 0x1f, 0x49, 0x3c, 
 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 
 0x03, 0x2b, 0x02, 0xd0, 0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x31, 
-0x04, 0x29, 0xe4, 0xd3, 0x01, 0x20, 0xf8, 0xe7, 0xc8, 0x29, 0x00, 0x80, 
+0x04, 0x29, 0xe4, 0xd3, 0x01, 0x20, 0xf8, 0xe7, 0x4c, 0x2a, 0x00, 0x80, 
 0xf7, 0xb5, 0x86, 0xb0, 0x3d, 0x4a, 0x07, 0x1c, 0xd1, 0x69, 0x8f, 0x40, 
 0x03, 0x1c, 0x14, 0x6a, 0xe3, 0x40, 0x5f, 0x40, 0x07, 0x9e, 0x8e, 0x40, 
 0x77, 0x40, 0xcf, 0x40, 0x94, 0x69, 0xc0, 0x46, 0x05, 0x94, 0x03, 0x1c, 
@@ -1062,85 +1075,85 @@ const u8 typhoon_firmware_image[] = {
 0x5d, 0xd9, 0x1c, 0x1c, 0x32, 0x4e, 0x26, 0x43, 0x94, 0x69, 0xe6, 0x40, 
 0x33, 0x1c, 0x03, 0x96, 0x53, 0x6a, 0xc0, 0x46, 0x02, 0x93, 0xd2, 0x6a, 
 0xc0, 0x46, 0x01, 0x92, 0xbb, 0x00, 0x02, 0x9a, 0xd2, 0x58, 0x13, 0x1c, 
-0x05, 0x9c, 0xe3, 0x40, 0x03, 0x9c, 0xa3, 0x42, 
-0x3e, 0xd1, 0x8a, 0x40, 0xca, 0x40, 0x14, 0x1c, 0x63, 0x00, 0x1b, 0x19, 
-0x5b, 0x01, 0x01, 0x9a, 0xd2, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 
-0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, 
-0x2c, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x51, 0x36, 0x33, 0x43, 
-0x1b, 0x68, 0x07, 0x9e, 0x1e, 0x40, 0x00, 0x96, 0x01, 0x23, 0x9b, 0x07, 
-0xd6, 0x1d, 0x49, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x83, 0x42, 0x1b, 0xd1, 
-0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x4d, 0x36, 0x33, 0x43, 0x1b, 0x68, 
-0x00, 0x9e, 0xb3, 0x42, 0x12, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 
-0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x08, 0x9b, 0x32, 0x2b, 0x04, 0xd1, 
-0x02, 0x2a, 0x07, 0xd1, 0x20, 0x04, 0x00, 0x14, 0x0f, 0xe0, 0x08, 0x9b, 
-0x33, 0x2b, 0x01, 0xd1, 0x01, 0x2a, 0xf7, 0xd0, 0x04, 0x9a, 0x01, 0x37, 
-0x97, 0x42, 0x00, 0xd3, 0x00, 0x27, 0x04, 0x9a, 0x01, 0x35, 0xaa, 0x42, 
-0xae, 0xd8, 0x00, 0x20, 0xc0, 0x43, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
-0xf0, 0xb5, 0x27, 0x4d, 0x68, 0x69, 0x00, 0x28, 0x06, 0xd0, 0x26, 0x48, 
-0x00, 0x68, 0x02, 0xf0, 0x31, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x23, 0x4c, 0x00, 0x26, 0xa0, 0x68, 0x23, 0x4f, 0x00, 0x28, 0x16, 0xd0, 
-0x0f, 0xe0, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 
-0x0f, 0xe0, 0xa6, 0x60, 0xfd, 0xf7, 0x08, 0xff, 0x00, 0x28, 0xea, 0xd1, 
-0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 
-0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe9, 0xd0, 0x68, 0x68, 
-0x00, 0x28, 0x1b, 0xd0, 0x01, 0x20, 0xa0, 0x60, 0xfe, 0xf7, 0xd2, 0xfb, 
-0x00, 0x28, 0xd6, 0xd1, 0x68, 0x68, 0x00, 0x28, 0xf6, 0xd1, 0x11, 0xe0, 
-0x00, 0x28, 0xd0, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 
-0x38, 0x71, 0xca, 0xe7, 0xa6, 0x60, 0xfd, 0xf7, 0xe3, 0xfe, 0x00, 0x28, 
-0xc5, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 
-0xe8, 0x68, 0x00, 0x28, 0xbd, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe7, 0xd0, 
-0xb9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xdc, 0x03, 0x00, 0x80, 
-0xc8, 0x29, 0x00, 0x80, 0x0c, 0x06, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 
-0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, 
-0x1d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 0x9f, 0xfc, 0x03, 0x23, 
+0x05, 0x9c, 0xe3, 0x40, 0x03, 0x9c, 0xa3, 0x42, 0x3e, 0xd1, 0x8a, 0x40, 
+0xca, 0x40, 0x14, 0x1c, 0x63, 0x00, 0x1b, 0x19, 0x5b, 0x01, 0x01, 0x9a, 
+0xd2, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x01, 0x36, 0x33, 0x43, 
+0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, 0x2c, 0xd1, 0x01, 0x23, 
+0x9b, 0x07, 0xd6, 0x1d, 0x51, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x07, 0x9e, 
+0x1e, 0x40, 0x00, 0x96, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x49, 0x36, 
+0x33, 0x43, 0x1b, 0x68, 0x83, 0x42, 0x1b, 0xd1, 0x01, 0x23, 0x9b, 0x07, 
+0xd6, 0x1d, 0x4d, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0xb3, 0x42, 
+0x12, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, 
+0x12, 0x0c, 0x08, 0x9b, 0x32, 0x2b, 0x04, 0xd1, 0x02, 0x2a, 0x07, 0xd1, 
+0x20, 0x04, 0x00, 0x14, 0x0f, 0xe0, 0x08, 0x9b, 0x33, 0x2b, 0x01, 0xd1, 
+0x01, 0x2a, 0xf7, 0xd0, 0x04, 0x9a, 0x01, 0x37, 0x97, 0x42, 0x00, 0xd3, 
+0x00, 0x27, 0x04, 0x9a, 0x01, 0x35, 0xaa, 0x42, 0xae, 0xd8, 0x00, 0x20, 
+0xc0, 0x43, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x27, 0x4d, 
+0x68, 0x69, 0x00, 0x28, 0x06, 0xd0, 0x26, 0x48, 0x00, 0x68, 0x02, 0xf0, 
+0x2b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x23, 0x4c, 0x00, 0x26, 
+0xa0, 0x68, 0x23, 0x4f, 0x00, 0x28, 0x16, 0xd0, 0x0f, 0xe0, 0x28, 0x6a, 
+0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 0x0f, 0xe0, 0xa6, 0x60, 
+0xfd, 0xf7, 0xe8, 0xfe, 0x00, 0x28, 0xea, 0xd1, 0x28, 0x6a, 0x02, 0x28, 
+0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, 0x02, 0xd0, 
+0x38, 0x79, 0x00, 0x28, 0xe9, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x1b, 0xd0, 
+0x01, 0x20, 0xa0, 0x60, 0xfe, 0xf7, 0xbc, 0xfb, 0x00, 0x28, 0xd6, 0xd1, 
+0x68, 0x68, 0x00, 0x28, 0xf6, 0xd1, 0x11, 0xe0, 0x00, 0x28, 0xd0, 0xd1, 
+0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xca, 0xe7, 
+0xa6, 0x60, 0xfd, 0xf7, 0xc3, 0xfe, 0x00, 0x28, 0xc5, 0xd1, 0x28, 0x6a, 
+0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, 
+0xbd, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe7, 0xd0, 0xb9, 0xe7, 0x00, 0x00, 
+0x6c, 0x06, 0x00, 0x80, 0x5c, 0x04, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, 
+0x8c, 0x06, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 
+0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, 0x1d, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x01, 0xf0, 0x9d, 0xfc, 0x03, 0x23, 
 0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0c, 0x0f, 0x61, 0x01, 0x09, 0x1b, 
 0x89, 0x00, 0x18, 0x4a, 0x8f, 0x18, 0x01, 0x21, 0x39, 0x80, 0x81, 0x6a, 
 0xc0, 0x46, 0x79, 0x65, 0x41, 0x6a, 0xc0, 0x46, 0x79, 0x67, 0xb9, 0x6c, 
 0xfa, 0x6c, 0x89, 0x18, 0xb9, 0x64, 0x00, 0x21, 0xf9, 0x64, 0xba, 0x6b, 
 0x3b, 0x6d, 0xd2, 0x18, 0xba, 0x63, 0x39, 0x65, 0x42, 0x6a, 0x20, 0x32, 
 0x51, 0x71, 0x79, 0x6d, 0x7a, 0x6f, 0xd2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 
-0xfd, 0xf7, 0x10, 0xf8, 0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, 
+0xfc, 0xf7, 0xd4, 0xff, 0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, 
 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0x78, 0x6f, 
-0x01, 0xf0, 0xc8, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, 
+0x01, 0xf0, 0xc6, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 
 0xf0, 0xb5, 0x40, 0x20, 0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 
-0x5b, 0xfc, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, 
-0x1b, 0x07, 0x18, 0x40, 0x06, 0x0f, 0x70, 0x01, 0x80, 0x1b, 0x80, 0x00, 
-0x0c, 0x49, 0x44, 0x18, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x78, 0x6a, 
-0xc0, 0x46, 0x60, 0x67, 0x80, 0x6f, 0x05, 0x1d, 0xe5, 0x63, 0xb9, 0x69, 
-0x28, 0x1c, 0x02, 0xf0, 0x8f, 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0x32, 0x1c, 
-0x2b, 0x1c, 0x00, 0xf0, 0x20, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0xf0, 0xb5, 0x4b, 0x6f, 
-0x9b, 0x6f, 0x1f, 0x1d, 0xcf, 0x63, 0x05, 0x68, 0x00, 0x23, 0x84, 0x69, 
-0xa4, 0x08, 0x08, 0xd0, 0x9c, 0x00, 0x2e, 0x59, 0xc0, 0x46, 0x3e, 0x51, 
-0x84, 0x69, 0xa4, 0x08, 0x01, 0x33, 0x9c, 0x42, 0xf6, 0xd8, 0x3b, 0x1c, 
-0x00, 0xf0, 0x03, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 
-0x81, 0xb0, 0x04, 0x1c, 0x1d, 0x1c, 0x0f, 0x1c, 0x46, 0x48, 0x01, 0x69, 
-0x01, 0x31, 0x01, 0x61, 0xf9, 0x1d, 0x51, 0x31, 0xbd, 0x65, 0x00, 0x91, 
-0x20, 0x1c, 0xfd, 0xf7, 0xa3, 0xfc, 0xf8, 0x6d, 0x40, 0x09, 0x36, 0xd2, 
-0xb8, 0x6d, 0x06, 0x7b, 0x43, 0x7b, 0x1b, 0x02, 0x1e, 0x43, 0x17, 0x21, 
-0x49, 0x02, 0x01, 0x73, 0x0b, 0x0a, 0x43, 0x73, 0x00, 0x99, 0x20, 0x1c, 
-0xfd, 0xf7, 0x92, 0xfc, 0xb8, 0x6d, 0xc0, 0x46, 0x06, 0x73, 0x33, 0x0a, 
-0x43, 0x73, 0xf8, 0x6d, 0x40, 0x09, 0x20, 0xd2, 0x60, 0x68, 0x01, 0x04, 
-0x09, 0x0c, 0x03, 0x98, 0x01, 0xf0, 0xce, 0xfc, 0x60, 0x68, 0x32, 0x4b, 
-0x18, 0x43, 0x60, 0x60, 0x20, 0x1c, 0x01, 0xf0, 0x37, 0xfd, 0x00, 0x25, 
-0x7d, 0x60, 0xbd, 0x60, 0x3d, 0x64, 0x7d, 0x64, 0x20, 0x1c, 0xfc, 0xf7, 
-0x77, 0xff, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0x7d, 0x62, 
-0x29, 0x48, 0xc0, 0x46, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xa0, 0xfb, 
-0x44, 0xe0, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 
-0x00, 0x68, 0xc0, 0x46, 0x78, 0x64, 0x60, 0x68, 0x02, 0x04, 0x12, 0x0c, 
-0x78, 0x6e, 0x01, 0x26, 0xc1, 0x1d, 0x0d, 0x31, 0x8a, 0x42, 0x02, 0xd2, 
-0x3a, 0x64, 0x08, 0x1c, 0x0e, 0xe0, 0x41, 0x19, 0x89, 0x89, 0xf0, 0x23, 
-0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, 
-0x61, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x81, 0x42, 0x16, 0xd2, 0x39, 0x64, 
-0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, 
-0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 
-0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, 
+0x59, 0xfc, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 
+0x06, 0x0f, 0x70, 0x01, 0x80, 0x1b, 0x80, 0x00, 0x0c, 0x49, 0x44, 0x18, 
+0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x78, 0x6a, 0xc0, 0x46, 0x60, 0x67, 
+0x80, 0x6f, 0x05, 0x1d, 0xe5, 0x63, 0xb9, 0x69, 0x28, 0x1c, 0x02, 0xf0, 
+0x89, 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0x32, 0x1c, 0x2b, 0x1c, 0x00, 0xf0, 
+0x20, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 
+0x5c, 0x2b, 0x00, 0x80, 0xf0, 0xb5, 0x4b, 0x6f, 0x9b, 0x6f, 0x1f, 0x1d, 
+0xcf, 0x63, 0x05, 0x68, 0x00, 0x23, 0x84, 0x69, 0xa4, 0x08, 0x08, 0xd0, 
+0x9c, 0x00, 0x2e, 0x59, 0xc0, 0x46, 0x3e, 0x51, 0x84, 0x69, 0xa4, 0x08, 
+0x01, 0x33, 0x9c, 0x42, 0xf6, 0xd8, 0x3b, 0x1c, 0x00, 0xf0, 0x03, 0xf8, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 0x81, 0xb0, 0x04, 0x1c, 
+0x1d, 0x1c, 0x0f, 0x1c, 0x46, 0x48, 0x01, 0x69, 0x01, 0x31, 0x01, 0x61, 
+0xf9, 0x1d, 0x51, 0x31, 0xbd, 0x65, 0x00, 0x91, 0x20, 0x1c, 0xfd, 0xf7, 
+0x67, 0xfc, 0xf8, 0x6d, 0x40, 0x09, 0x36, 0xd2, 0xb8, 0x6d, 0x06, 0x7b, 
+0x43, 0x7b, 0x1b, 0x02, 0x1e, 0x43, 0x17, 0x21, 0x49, 0x02, 0x01, 0x73, 
+0x0b, 0x0a, 0x43, 0x73, 0x00, 0x99, 0x20, 0x1c, 0xfd, 0xf7, 0x56, 0xfc, 
+0xb8, 0x6d, 0xc0, 0x46, 0x06, 0x73, 0x33, 0x0a, 0x43, 0x73, 0xf8, 0x6d, 
+0x40, 0x09, 0x20, 0xd2, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0x03, 0x98, 
+0x01, 0xf0, 0xcc, 0xfc, 0x60, 0x68, 0x32, 0x4b, 0x18, 0x43, 0x60, 0x60, 
+0x20, 0x1c, 0x01, 0xf0, 0x35, 0xfd, 0x00, 0x25, 0x7d, 0x60, 0xbd, 0x60, 
+0x3d, 0x64, 0x7d, 0x64, 0x20, 0x1c, 0xfc, 0xf7, 0x3b, 0xff, 0x38, 0x88, 
+0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0x7d, 0x62, 0x29, 0x48, 0xc0, 0x46, 
+0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xa0, 0xfb, 0x44, 0xe0, 0x20, 0x68, 
+0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 
+0x78, 0x64, 0x60, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x78, 0x6e, 0x01, 0x26, 
+0xc1, 0x1d, 0x0d, 0x31, 0x8a, 0x42, 0x02, 0xd2, 0x3a, 0x64, 0x08, 0x1c, 
+0x0e, 0xe0, 0x41, 0x19, 0x89, 0x89, 0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, 
+0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, 0x61, 0x68, 0x09, 0x04, 
+0x09, 0x0c, 0x81, 0x42, 0x16, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, 
+0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61, 
+0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b, 
+0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, 
 0x20, 0x1c, 0x00, 0xf0, 0xbf, 0xfb, 0x0b, 0xe0, 0xb9, 0x68, 0x08, 0x1a, 
 0x00, 0x25, 0x78, 0x62, 0xbd, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x3c, 0xfc, 
 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x64, 0xf8, 0x05, 0xb0, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
+0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
 0x01, 0x00, 0x00, 0xc0, 0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x6c, 
 0xf9, 0x6b, 0x0d, 0x18, 0x21, 0x68, 0x41, 0x18, 0x00, 0x20, 0xa2, 0x69, 
 0x00, 0x2a, 0x0b, 0xd9, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 
@@ -1148,127 +1161,127 @@ const u8 typhoon_firmware_image[] = {
 0x82, 0x42, 0xf3, 0xd8, 0x78, 0x6e, 0xf9, 0x6b, 0x09, 0x18, 0x89, 0x89, 
 0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 
 0xf9, 0x61, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 
-0x01, 0x68, 0x78, 0x6c, 0xfc, 0xf7, 0xdb, 0xff, 
-0x78, 0x64, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0xf8, 0x68, 0x81, 0x42, 
-0x19, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 
-0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 
-0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 
-0x56, 0xfa, 0x01, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x5e, 0xfb, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb9, 0x68, 0x08, 0x1a, 0x78, 0x62, 
-0x00, 0x20, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xd9, 0xfb, 0x20, 0x1c, 
-0x39, 0x1c, 0x00, 0xf0, 0x01, 0xf8, 0xef, 0xe7, 0xf0, 0xb5, 0x84, 0xb0, 
-0x04, 0x1c, 0x0f, 0x1c, 0x8e, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 
-0x03, 0x20, 0x00, 0x07, 0x61, 0x68, 0x08, 0x40, 0x06, 0x0f, 0x0a, 0x04, 
-0x12, 0x0c, 0x20, 0x68, 0x11, 0x18, 0xfb, 0x68, 0xd2, 0x1a, 0x7b, 0x68, 
-0x9d, 0x1a, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 
-0x26, 0xfa, 0x00, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x2e, 0xfb, 
-0x60, 0x68, 0x40, 0x19, 0x01, 0x04, 0x09, 0x0c, 0x60, 0x60, 0x30, 0x1c, 
-0x01, 0xf0, 0xe2, 0xfb, 0x7d, 0x4e, 0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, 
-0xc0, 0x68, 0x00, 0x28, 0x19, 0xd0, 0x00, 0x25, 0x2d, 0x23, 0x9b, 0x01, 
-0xf0, 0x18, 0x80, 0x68, 0x00, 0x28, 0x12, 0xd0, 0xaa, 0x00, 0x92, 0x19, 
-0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x92, 0x68, 0x20, 0x1c, 0x39, 0x1c, 
-0x01, 0xf0, 0x22, 0xfe, 0x01, 0x35, 0xa8, 0x00, 0x80, 0x19, 0x2d, 0x23, 
-0x9b, 0x01, 0xc0, 0x18, 0x80, 0x68, 0x00, 0x28, 0xec, 0xd1, 0xf8, 0x6b, 
-0x01, 0x1f, 0x8a, 0x1c, 0xfa, 0x63, 0xfa, 0x68, 0x7d, 0x6c, 0x00, 0xf0, 
-0xbb, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, 0xfc, 0xf7, 
-0x56, 0xff, 0x03, 0x90, 0xf9, 0x6b, 0x3a, 0x6e, 0x8e, 0x18, 0x20, 0x68, 
-0x12, 0x18, 0x01, 0x92, 0x7a, 0x6e, 0x8d, 0x18, 0x11, 0x18, 0x02, 0x91, 
-0xc8, 0x1d, 0x09, 0x30, 0xe0, 0x60, 0xb1, 0x88, 0x08, 0x02, 0x09, 0x0a, 
-0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x78, 0x61, 
-0x68, 0x68, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 
-0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 
-0x00, 0x06, 0x08, 0x43, 0x38, 0x61, 0xa8, 0x89, 0x09, 0x23, 0x1b, 0x02, 
-0x18, 0x40, 0xb8, 0x61, 0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, 
-0x02, 0x99, 0xc0, 0x46, 0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, 
+0x01, 0x68, 0x78, 0x6c, 0xfc, 0xf7, 0x9f, 0xff, 0x78, 0x64, 0x60, 0x68, 
+0x01, 0x04, 0x09, 0x0c, 0xf8, 0x68, 0x81, 0x42, 0x19, 0xd2, 0x39, 0x64, 
+0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, 
+0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 
+0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 0x56, 0xfa, 0x01, 0x20, 
+0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x5e, 0xfb, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0xb9, 0x68, 0x08, 0x1a, 0x78, 0x62, 0x00, 0x20, 0xb8, 0x62, 
+0x38, 0x1c, 0x00, 0xf0, 0xd9, 0xfb, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 
+0x01, 0xf8, 0xef, 0xe7, 0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, 
+0x8e, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x03, 0x20, 0x00, 0x07, 
+0x61, 0x68, 0x08, 0x40, 0x06, 0x0f, 0x0a, 0x04, 0x12, 0x0c, 0x20, 0x68, 
+0x11, 0x18, 0xfb, 0x68, 0xd2, 0x1a, 0x7b, 0x68, 0x9d, 0x1a, 0xc3, 0x1f, 
+0x05, 0x3b, 0x38, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0x26, 0xfa, 0x00, 0x20, 
+0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x2e, 0xfb, 0x60, 0x68, 0x40, 0x19, 
+0x01, 0x04, 0x09, 0x0c, 0x60, 0x60, 0x30, 0x1c, 0x01, 0xf0, 0xe0, 0xfb, 
+0x7d, 0x4e, 0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, 0x00, 0x69, 0x00, 0x28, 
+0x19, 0xd0, 0x00, 0x25, 0x2d, 0x23, 0x9b, 0x01, 0xf0, 0x18, 0xc0, 0x68, 
+0x00, 0x28, 0x12, 0xd0, 0xaa, 0x00, 0x92, 0x19, 0x2d, 0x23, 0x9b, 0x01, 
+0xd2, 0x18, 0xd2, 0x68, 0x20, 0x1c, 0x39, 0x1c, 0x01, 0xf0, 0x1c, 0xfe, 
+0x01, 0x35, 0xa8, 0x00, 0x80, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xc0, 0x18, 
+0xc0, 0x68, 0x00, 0x28, 0xec, 0xd1, 0xf8, 0x6b, 0x01, 0x1f, 0x8a, 0x1c, 
+0xfa, 0x63, 0xfa, 0x68, 0x7d, 0x6c, 0x00, 0xf0, 0xbb, 0xf9, 0xc0, 0x43, 
+0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, 0xfc, 0xf7, 0x1a, 0xff, 0x03, 0x90, 
+0xf9, 0x6b, 0x3a, 0x6e, 0x8e, 0x18, 0x20, 0x68, 0x12, 0x18, 0x01, 0x92, 
+0x7a, 0x6e, 0x8d, 0x18, 0x11, 0x18, 0x02, 0x91, 0xc8, 0x1d, 0x09, 0x30, 
+0xe0, 0x60, 0xb1, 0x88, 0x08, 0x02, 0x09, 0x0a, 0x09, 0x06, 0x09, 0x0e, 
+0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x78, 0x61, 0x68, 0x68, 0x01, 0x0e, 
+0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 
+0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x08, 0x43, 
+0x38, 0x61, 0xa8, 0x89, 0x09, 0x23, 0x1b, 0x02, 0x18, 0x40, 0xb8, 0x61, 
+0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, 0x02, 0x99, 0xc0, 0x46, 
+0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, 
 0x70, 0x81, 0x68, 0x60, 0x28, 0x82, 0xb9, 0x6e, 0x30, 0x1c, 0xfc, 0xf7, 
-0x2e, 0xff, 0x38, 0x86, 0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 
-0x49, 0xff, 0x78, 0x86, 0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, 
-0x0e, 0xff, 0x00, 0x90, 0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, 
+0xf2, 0xfe, 0x38, 0x86, 0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 
+0x0d, 0xff, 0x78, 0x86, 0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, 
+0xd2, 0xfe, 0x00, 0x90, 0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, 
 0x41, 0x1a, 0x09, 0x04, 0x09, 0x0c, 0x7a, 0x6e, 0x82, 0x1a, 0x13, 0x04, 
 0x1b, 0x0c, 0x1a, 0x02, 0x1b, 0x0a, 0x1a, 0x43, 0x16, 0x04, 0x36, 0x0c, 
 0xba, 0x68, 0x82, 0x42, 0x01, 0xd2, 0x00, 0x20, 0x00, 0xe0, 0x10, 0x1a, 
 0xb8, 0x60, 0x08, 0x02, 0x09, 0x12, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 
 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x28, 0x1c, 
-0xfc, 0xf7, 0xe9, 0xfe, 0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, 
-0xe4, 0xfe, 0x06, 0x1c, 0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, 
-0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 
-0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0xd5, 0xfe, 
-0x79, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x79, 0x61, 0x01, 0x9a, 0xc0, 0x46, 
-0x50, 0x81, 0x38, 0x69, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 
-0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 
-0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x30, 0x1c, 0xfc, 0xf7, 0xbd, 0xfe, 
-0x39, 0x69, 0x7a, 0x68, 0x89, 0x18, 0x39, 0x61, 0xb9, 0x68, 0x00, 0x29, 
-0x09, 0xd1, 0x02, 0x99, 0x89, 0x89, 0xba, 0x69, 0x11, 0x43, 0x02, 0x9a, 
-0xc0, 0x46, 0x91, 0x81, 0xb9, 0x69, 0xfc, 0xf7, 0xac, 0xfe, 0x20, 0x82, 
-0x00, 0x20, 0x60, 0x82, 0xf8, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 
-0x0a, 0xd3, 0x60, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 
-0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x08, 0x82, 0x09, 0xe0, 
-0x60, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 
-0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x88, 0x81, 0x04, 0xb0, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
-0xf1, 0xb5, 0x84, 0xb0, 0x6e, 0x4d, 0x28, 0x69, 0x01, 0x22, 0x04, 0x99, 
-0x8a, 0x40, 0x90, 0x43, 0x28, 0x61, 0x04, 0x98, 0x43, 0x01, 0x18, 0x1a, 
-0x80, 0x00, 0x16, 0x1c, 0x69, 0x49, 0x44, 0x18, 0xe0, 0x6b, 0xc0, 0x46, 
-0x00, 0x90, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x00, 0x26, 0x26, 0xe0, 
-0x65, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x04, 0x98, 0xfc, 0xf7, 
-0x4f, 0xfd, 0x07, 0x1c, 0x03, 0xd1, 0x28, 0x69, 0x30, 0x43, 0x28, 0x61, 
-0xb5, 0xe0, 0xa0, 0x68, 0x65, 0x68, 0xa8, 0x42, 0x00, 0xd2, 0x05, 0x1c, 
-0xa1, 0x6c, 0xa9, 0x42, 0x16, 0xd2, 0x40, 0x1a, 0x62, 0x6a, 0x10, 0x1a, 
-0x00, 0x26, 0x60, 0x62, 0xa6, 0x60, 0xa6, 0x62, 0x20, 0x88, 0x48, 0x23, 
-0x18, 0x43, 0x20, 0x80, 0x0d, 0x1c, 0x09, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, 
-0x5f, 0xfd, 0x03, 0x20, 0x60, 0x80, 0x66, 0x60, 0x20, 0x1c, 0x00, 0xf0, 
-0x8d, 0xf9, 0x96, 0xe0, 0xe1, 0x68, 0x38, 0x68, 0x09, 0x18, 0xc3, 0x1f, 
-0x05, 0x3b, 0x20, 0x1c, 0x02, 0x39, 0x2a, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 
-0x38, 0x1c, 0x00, 0xf0, 0xd7, 0xf9, 0xe0, 0x68, 0x46, 0x19, 0x78, 0x68, 
-0x30, 0x43, 0x78, 0x60, 0x04, 0x98, 0x31, 0x1c, 0x01, 0xf0, 0x8a, 0xfa, 
-0x21, 0x6e, 0x00, 0x98, 0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, 
-0x00, 0x0c, 0x61, 0x6e, 0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 
+0xfc, 0xf7, 0xad, 0xfe, 0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, 
+0xa8, 0xfe, 0x06, 0x1c, 0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, 
+0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 
+0x81, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0x99, 0xfe, 0x79, 0x69, 0x01, 0x31, 
+0xc0, 0x43, 0x79, 0x61, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x81, 0x38, 0x69, 
+0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 
+0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 
+0x01, 0x43, 0x30, 0x1c, 0xfc, 0xf7, 0x81, 0xfe, 0x39, 0x69, 0x7a, 0x68, 
+0x89, 0x18, 0x39, 0x61, 0xb9, 0x68, 0x00, 0x29, 0x09, 0xd1, 0x02, 0x99, 
+0x89, 0x89, 0xba, 0x69, 0x11, 0x43, 0x02, 0x9a, 0xc0, 0x46, 0x91, 0x81, 
+0xb9, 0x69, 0xfc, 0xf7, 0x70, 0xfe, 0x20, 0x82, 0x00, 0x20, 0x60, 0x82, 
+0xf8, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, 0x60, 0x68, 
+0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 
+0x21, 0x68, 0xc0, 0x46, 0x08, 0x82, 0x09, 0xe0, 0x60, 0x68, 0x0c, 0x38, 
+0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 
+0xc0, 0x46, 0x88, 0x81, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x0c, 0x2b, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0xf1, 0xb5, 0x84, 0xb0, 
+0x6e, 0x4d, 0x28, 0x69, 0x01, 0x22, 0x04, 0x99, 0x8a, 0x40, 0x90, 0x43, 
+0x28, 0x61, 0x04, 0x98, 0x43, 0x01, 0x18, 0x1a, 0x80, 0x00, 0x16, 0x1c, 
+0x69, 0x49, 0x44, 0x18, 0xe0, 0x6b, 0xc0, 0x46, 0x00, 0x90, 0xa0, 0x68, 
+0x00, 0x28, 0x01, 0xd1, 0x00, 0x26, 0x26, 0xe0, 0x65, 0x48, 0x41, 0x69, 
+0x01, 0x31, 0x41, 0x61, 0x04, 0x98, 0xfc, 0xf7, 0x13, 0xfd, 0x07, 0x1c, 
+0x03, 0xd1, 0x28, 0x69, 0x30, 0x43, 0x28, 0x61, 0xb5, 0xe0, 0xa0, 0x68, 
+0x65, 0x68, 0xa8, 0x42, 0x00, 0xd2, 0x05, 0x1c, 0xa1, 0x6c, 0xa9, 0x42, 
+0x16, 0xd2, 0x40, 0x1a, 0x62, 0x6a, 0x10, 0x1a, 0x00, 0x26, 0x60, 0x62, 
+0xa6, 0x60, 0xa6, 0x62, 0x20, 0x88, 0x48, 0x23, 0x18, 0x43, 0x20, 0x80, 
+0x0d, 0x1c, 0x09, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, 0x23, 0xfd, 0x03, 0x20, 
+0x60, 0x80, 0x66, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x8d, 0xf9, 0x96, 0xe0, 
+0xe1, 0x68, 0x38, 0x68, 0x09, 0x18, 0xc3, 0x1f, 0x05, 0x3b, 0x20, 0x1c, 
+0x02, 0x39, 0x2a, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 
+0xd7, 0xf9, 0xe0, 0x68, 0x46, 0x19, 0x78, 0x68, 0x30, 0x43, 0x78, 0x60, 
+0x04, 0x98, 0x31, 0x1c, 0x01, 0xf0, 0x88, 0xfa, 0x21, 0x6e, 0x00, 0x98, 
+0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x61, 0x6e, 
+0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 
 0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x91, 0x01, 0x02, 
 0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 
-0x41, 0x80, 0x20, 0x8e, 0xfc, 0xf7, 0x11, 0xfe, 0x06, 0x1c, 0x60, 0x8e, 
-0x02, 0x99, 0xfc, 0xf7, 0x0c, 0xfe, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, 
+0x41, 0x80, 0x20, 0x8e, 0xfc, 0xf7, 0xd5, 0xfd, 0x06, 0x1c, 0x60, 0x8e, 
+0x02, 0x99, 0xfc, 0xf7, 0xd0, 0xfd, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, 
 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 
-0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xfd, 0xfd, 
+0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xc1, 0xfd, 
 0x61, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x61, 0x61, 0x01, 0x99, 0xc0, 0x46, 
 0x48, 0x81, 0x60, 0x6e, 0x00, 0x99, 0x46, 0x18, 0x20, 0x69, 0x01, 0x0e, 
 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 
 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 
-0x71, 0x60, 0x03, 0x98, 0xfc, 0xf7, 0xe1, 0xfd, 0x21, 0x69, 0x49, 0x19, 
-0x21, 0x61, 0xa1, 0x68, 0x49, 0x1b, 0xa1, 0x60, 
-0x06, 0xd1, 0xb1, 0x89, 0xa2, 0x69, 0x11, 0x43, 0xb1, 0x81, 0xa1, 0x69, 
-0xfc, 0xf7, 0xd3, 0xfd, 0x38, 0x82, 0x61, 0x6e, 0x38, 0x68, 0x09, 0x18, 
-0x0e, 0x31, 0xf9, 0x60, 0xe2, 0x68, 0x00, 0x99, 0x04, 0x38, 0x00, 0xf0, 
-0x4c, 0xf8, 0x02, 0x20, 0x78, 0x82, 0xe0, 0x6d, 0x41, 0x08, 0x16, 0xd3, 
-0x80, 0x0a, 0x0a, 0xd3, 0x78, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 
-0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0xc8, 0x81, 
-0x09, 0xe0, 0x78, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 
-0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0x48, 0x81, 0x05, 0xb0, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, 
-0xc8, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 0xf7, 0xb5, 0x03, 0x1c, 
-0x0f, 0x1c, 0x00, 0x20, 0x1c, 0x68, 0x26, 0x04, 0x31, 0x1c, 0x1d, 0x1d, 
-0xfc, 0xf7, 0x97, 0xfd, 0x40, 0xc7, 0x02, 0x9a, 0xd1, 0x1c, 0x89, 0x08, 
-0x01, 0x39, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 0x0d, 0xd0, 0x21, 0x0c, 
-0x10, 0xcd, 0x22, 0x04, 0x0a, 0x43, 0x11, 0x1c, 0x16, 0x1c, 0xfc, 0xf7, 
-0x86, 0xfd, 0x40, 0xc7, 0x02, 0x99, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 
-0xf1, 0xd1, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x08, 
-0x80, 0x00, 0x89, 0x08, 0x89, 0x00, 0x03, 0x32, 0x93, 0x08, 0x5a, 0x1e, 
-0x00, 0x2b, 0x05, 0xd0, 0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, 0x3a, 
-0x00, 0x2b, 0xf9, 0xd1, 0x70, 0x47, 0xff, 0xb5, 0x86, 0xb0, 0x17, 0x1c, 
-0x00, 0x26, 0x06, 0x98, 0x80, 0x6c, 0xc0, 0x1b, 0x06, 0x99, 0xc0, 0x46, 
-0x88, 0x64, 0x01, 0x20, 0xc0, 0x05, 0x06, 0x99, 0x89, 0x6b, 0xc0, 0x46, 
-0x01, 0x91, 0x06, 0x99, 0x4c, 0x6b, 0x67, 0xe0, 0x21, 0x68, 0xc0, 0x46, 
-0x02, 0x91, 0x61, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa1, 0x68, 0xc0, 0x46, 
-0x04, 0x91, 0x02, 0xa9, 0x49, 0x88, 0xb9, 0x42, 0x08, 0xd2, 0x02, 0xad, 
-0x6d, 0x88, 0x02, 0xa9, 0x49, 0x88, 0x7f, 0x1a, 0x00, 0x21, 0x02, 0xab, 
-0x59, 0x80, 0x19, 0xe0, 0x02, 0xa9, 0x49, 0x88, 0xc9, 0x1b, 0x02, 0xab, 
-0x59, 0x80, 0x3d, 0x1c, 0x00, 0x27, 0x01, 0x21, 0x49, 0x06, 0x07, 0x9b, 
-0x9a, 0x07, 0x92, 0x0f, 0x0d, 0xd0, 0xeb, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 
-0x1e, 0x2b, 0x08, 0xd3, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x2a, 0x04, 0xd1, 
-0x01, 0xe0, 0x02, 0x2a, 0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, 
-0x01, 0x43, 0x0a, 0x1c, 0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, 
-0x07, 0x9b, 0x01, 0xf0, 0x61, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, 
+0x71, 0x60, 0x03, 0x98, 0xfc, 0xf7, 0xa5, 0xfd, 0x21, 0x69, 0x49, 0x19, 
+0x21, 0x61, 0xa1, 0x68, 0x49, 0x1b, 0xa1, 0x60, 0x06, 0xd1, 0xb1, 0x89, 
+0xa2, 0x69, 0x11, 0x43, 0xb1, 0x81, 0xa1, 0x69, 0xfc, 0xf7, 0x97, 0xfd, 
+0x38, 0x82, 0x61, 0x6e, 0x38, 0x68, 0x09, 0x18, 0x0e, 0x31, 0xf9, 0x60, 
+0xe2, 0x68, 0x00, 0x99, 0x04, 0x38, 0x00, 0xf0, 0x4c, 0xf8, 0x02, 0x20, 
+0x78, 0x82, 0xe0, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, 
+0x78, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 
+0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0xc8, 0x81, 0x09, 0xe0, 0x78, 0x68, 
+0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 
+0x39, 0x68, 0xc0, 0x46, 0x48, 0x81, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, 
+0x0c, 0x2b, 0x00, 0x80, 0xf7, 0xb5, 0x03, 0x1c, 0x0f, 0x1c, 0x00, 0x20, 
+0x1c, 0x68, 0x26, 0x04, 0x31, 0x1c, 0x1d, 0x1d, 0xfc, 0xf7, 0x5b, 0xfd, 
+0x40, 0xc7, 0x02, 0x9a, 0xd1, 0x1c, 0x89, 0x08, 0x01, 0x39, 0x4a, 0x1e, 
+0x02, 0x92, 0x00, 0x29, 0x0d, 0xd0, 0x21, 0x0c, 0x10, 0xcd, 0x22, 0x04, 
+0x0a, 0x43, 0x11, 0x1c, 0x16, 0x1c, 0xfc, 0xf7, 0x4a, 0xfd, 0x40, 0xc7, 
+0x02, 0x99, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 0xf1, 0xd1, 0x03, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x08, 0x80, 0x00, 0x89, 0x08, 
+0x89, 0x00, 0x03, 0x32, 0x93, 0x08, 0x5a, 0x1e, 0x00, 0x2b, 0x05, 0xd0, 
+0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, 0x3a, 0x00, 0x2b, 0xf9, 0xd1, 
+0x70, 0x47, 0xff, 0xb5, 0x86, 0xb0, 0x17, 0x1c, 0x00, 0x26, 0x06, 0x98, 
+0x80, 0x6c, 0xc0, 0x1b, 0x06, 0x99, 0xc0, 0x46, 0x88, 0x64, 0x01, 0x20, 
+0xc0, 0x05, 0x06, 0x99, 0x89, 0x6b, 0xc0, 0x46, 0x01, 0x91, 0x06, 0x99, 
+0x4c, 0x6b, 0x67, 0xe0, 0x21, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x61, 0x68, 
+0xc0, 0x46, 0x03, 0x91, 0xa1, 0x68, 0xc0, 0x46, 0x04, 0x91, 0x02, 0xa9, 
+0x49, 0x88, 0xb9, 0x42, 0x08, 0xd2, 0x02, 0xad, 0x6d, 0x88, 0x02, 0xa9, 
+0x49, 0x88, 0x7f, 0x1a, 0x00, 0x21, 0x02, 0xab, 0x59, 0x80, 0x19, 0xe0, 
+0x02, 0xa9, 0x49, 0x88, 0xc9, 0x1b, 0x02, 0xab, 0x59, 0x80, 0x3d, 0x1c, 
+0x00, 0x27, 0x01, 0x21, 0x49, 0x06, 0x07, 0x9b, 0x9a, 0x07, 0x92, 0x0f, 
+0x0d, 0xd0, 0xeb, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, 0x08, 0xd3, 
+0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x2a, 0x04, 0xd1, 0x01, 0xe0, 0x02, 0x2a, 
+0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, 0x01, 0x43, 0x0a, 0x1c, 
+0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, 
+0x07, 0x9b, 0x01, 0xf0, 0x5b, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, 
 0x00, 0x2e, 0x0a, 0xd0, 0x1d, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x1d, 0x48, 
-0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x52, 0xff, 
+0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x4c, 0xff, 
 0x00, 0x26, 0x02, 0xa8, 0x40, 0x88, 0x00, 0x28, 0x0c, 0xd0, 0x03, 0x98, 
 0x40, 0x19, 0x03, 0x90, 0x02, 0x98, 0xc0, 0x46, 0x20, 0x60, 0x03, 0x98, 
 0xc0, 0x46, 0x60, 0x60, 0x04, 0x98, 0xc0, 0x46, 0xa0, 0x60, 0x03, 0xe0, 
@@ -1276,513 +1289,512 @@ const u8 typhoon_firmware_image[] = {
 0x44, 0x63, 0x01, 0x98, 0x06, 0x99, 0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 
 0x00, 0x2f, 0x02, 0xd0, 0x01, 0x99, 0x00, 0x29, 0x92, 0xd1, 0x09, 0x4a, 
 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 
-0x09, 0x9b, 0x01, 0xf0, 0x25, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 
-0xf8, 0x28, 0x00, 0x80, 0x04, 0x00, 0x53, 0x02, 0x90, 0xb5, 0x0c, 0x1c, 
-0x07, 0x1c, 0x38, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 
-0x01, 0x68, 0x38, 0x8a, 0xfc, 0xf7, 0xcb, 0xfc, 0xc0, 0x43, 0xf9, 0x68, 
-0xc0, 0x46, 0x08, 0x80, 0x78, 0x8a, 0x39, 0x68, 0x08, 0x1a, 0x38, 0x60, 
-0x38, 0x1c, 0x01, 0xf0, 0x8d, 0xf9, 0x38, 0x1c, 0xfc, 0xf7, 0xd2, 0xfb, 
-0x20, 0x1c, 0xff, 0xf7, 0x33, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x80, 0xb5, 0x01, 0x88, 0x8a, 0x09, 0x21, 0xd3, 0xca, 0x09, 0x1f, 0xd2, 
-0x8a, 0x08, 0x1d, 0xd3, 0x00, 0x21, 0x01, 0x80, 0x41, 0x80, 0x47, 0x6f, 
-0x40, 0x6d, 0xfa, 0x1d, 0x19, 0x32, 0x51, 0x71, 0xfa, 0x6d, 0xc0, 0x46, 
-0x10, 0x60, 0x3a, 0x6e, 0xc0, 0x46, 0x10, 0x60, 0x0c, 0x48, 0xc0, 0x46, 
-0x41, 0x63, 0x81, 0x6b, 0x49, 0x08, 0x49, 0x00, 0x81, 0x63, 0x01, 0x20, 
-0x00, 0xf0, 0xce, 0xff, 0x38, 0x1c, 0x00, 0xf0, 0x6d, 0xff, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 
-0x49, 0x09, 0xf6, 0xd2, 0x00, 0xf0, 0xb0, 0xf8, 0xf3, 0xe7, 0x00, 0x00, 
-0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 0x10, 0x1c, 0x0d, 0x1c, 
-0x00, 0x24, 0x5e, 0x1e, 0x00, 0x2b, 0x19, 0xd0, 0x01, 0x68, 0xc0, 0x46, 
-0x39, 0x60, 0x41, 0x88, 0x0c, 0x19, 0x41, 0x68, 0xc0, 0x46, 0x79, 0x60, 
-0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0xc1, 0x68, 0xc0, 0x46, 0xf9, 0x60, 
-0x10, 0x30, 0x10, 0x37, 0xe9, 0x6a, 0x81, 0x42, 0x02, 0xd8, 0x28, 0x1c, 
-0x00, 0xf0, 0xee, 0xff, 0x31, 0x1c, 0x01, 0x3e, 0x00, 0x29, 0xe5, 0xd1, 
-0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0xc1, 0x61, 
-0x05, 0x49, 0x0a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 0x08, 0x60, 0x02, 0xe0, 
-0x4a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, 
-0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x08, 0x68, 0x00, 0x28, 0x02, 0xd0, 
-0xc2, 0x69, 0xc0, 0x46, 0x0a, 0x60, 0x70, 0x47, 0x3c, 0x2c, 0x00, 0x80, 
-0x00, 0x21, 0x81, 0x67, 0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 
-0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, 0x90, 0x67, 0xc8, 0x60, 
-0x70, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68, 
-0x00, 0x28, 0x02, 0xd0, 0x82, 0x6f, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47, 
-0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, 
-0x08, 0x60, 0xff, 0xf7, 0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, 
+0x09, 0x9b, 0x01, 0xf0, 0x1f, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x7c, 0x29, 0x00, 0x80, 
+0x04, 0x00, 0x53, 0x02, 0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0x38, 0x68, 
+0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 0x01, 0x68, 0x38, 0x8a, 
+0xfc, 0xf7, 0x8f, 0xfc, 0xc0, 0x43, 0xf9, 0x68, 0xc0, 0x46, 0x08, 0x80, 
+0x78, 0x8a, 0x39, 0x68, 0x08, 0x1a, 0x38, 0x60, 0x38, 0x1c, 0x01, 0xf0, 
+0x8b, 0xf9, 0x38, 0x1c, 0xfc, 0xf7, 0x96, 0xfb, 0x20, 0x1c, 0xff, 0xf7, 
+0x33, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x01, 0x88, 
+0x8a, 0x09, 0x21, 0xd3, 0xca, 0x09, 0x1f, 0xd2, 0x8a, 0x08, 0x1d, 0xd3, 
+0x00, 0x21, 0x01, 0x80, 0x41, 0x80, 0x47, 0x6f, 0x40, 0x6d, 0xfa, 0x1d, 
+0x19, 0x32, 0x51, 0x71, 0xfa, 0x6d, 0xc0, 0x46, 0x10, 0x60, 0x3a, 0x6e, 
+0xc0, 0x46, 0x10, 0x60, 0x0c, 0x48, 0xc0, 0x46, 0x81, 0x63, 0xc1, 0x6b, 
+0x49, 0x08, 0x49, 0x00, 0xc1, 0x63, 0x01, 0x20, 0x00, 0xf0, 0xcc, 0xff, 
+0x38, 0x1c, 0x00, 0xf0, 0x6b, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x80, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 0x49, 0x09, 0xf6, 0xd2, 
+0x00, 0xf0, 0xb0, 0xf8, 0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x80, 
+0xf0, 0xb5, 0x07, 0x1c, 0x10, 0x1c, 0x0d, 0x1c, 0x00, 0x24, 0x5e, 0x1e, 
+0x00, 0x2b, 0x19, 0xd0, 0x01, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x41, 0x88, 
+0x0c, 0x19, 0x41, 0x68, 0xc0, 0x46, 0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, 
+0xb9, 0x60, 0xc1, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x10, 0x30, 0x10, 0x37, 
+0xe9, 0x6a, 0x81, 0x42, 0x02, 0xd8, 0x28, 0x1c, 0x00, 0xf0, 0xec, 0xff, 
+0x31, 0x1c, 0x01, 0x3e, 0x00, 0x29, 0xe5, 0xd1, 0x20, 0x1c, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x0a, 0x68, 
+0x00, 0x2a, 0x01, 0xd1, 0x08, 0x60, 0x02, 0xe0, 0x4a, 0x68, 0xc0, 0x46, 
+0xd0, 0x61, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80, 
+0x03, 0x49, 0x08, 0x68, 0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 
+0x0a, 0x60, 0x70, 0x47, 0xd0, 0x2c, 0x00, 0x80, 0x00, 0x21, 0x81, 0x67, 
+0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 0x88, 0x60, 0x02, 0xe0, 
+0xca, 0x68, 0xc0, 0x46, 0x90, 0x67, 0xc8, 0x60, 0x70, 0x47, 0x00, 0x00, 
+0xd0, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68, 0x00, 0x28, 0x02, 0xd0, 
+0x82, 0x6f, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47, 0xd0, 0x2c, 0x00, 0x80, 
+0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xff, 0xf7, 
+0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, 
 0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0a, 0x0f, 0x51, 0x01, 0x89, 0x1a, 
 0x89, 0x00, 0x0d, 0x4b, 0xc9, 0x18, 0x4b, 0x88, 0x00, 0x2b, 0x04, 0xd1, 
 0x11, 0x1c, 0xff, 0xf7, 0x3b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x2b, 
 0x02, 0xd1, 0xff, 0xf7, 0x05, 0xfc, 0xf8, 0xe7, 0x02, 0x2b, 0xf6, 0xd1, 
 0xff, 0xf7, 0x4e, 0xfb, 0xf3, 0xe7, 0x04, 0x48, 0x01, 0x6d, 0x01, 0x31, 
-0x01, 0x65, 0xee, 0xe7, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 
+0x01, 0x65, 0xee, 0xe7, 0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80, 
 0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x20, 0x20, 0x0d, 0x49, 0xc0, 0x46, 
 0x08, 0x60, 0xff, 0xf7, 0xbf, 0xff, 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x88, 
 0x20, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 0x10, 0x23, 0x99, 0x43, 
 0x01, 0x80, 0x01, 0x88, 0x09, 0x0a, 0x01, 0xd3, 0xff, 0xf7, 0x2e, 0xff, 
 0x08, 0xbc, 0x18, 0x47, 0x03, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 
-0xf8, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
-0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x07, 0x1c, 0x22, 0x48, 0xc0, 0x46, 
-0x00, 0x90, 0x22, 0x48, 0xc3, 0x1d, 0x41, 0x33, 0x41, 0x6d, 0x82, 0x6d, 
-0x80, 0x6c, 0x00, 0x03, 0x00, 0x0b, 0x9c, 0x68, 0x01, 0x23, 0x9b, 0x07, 
-0x23, 0x43, 0x1b, 0x68, 0x98, 0x42, 0x00, 0xd1, 0x0c, 0xe0, 0x98, 0x42, 
-0x03, 0xd9, 0x10, 0x1a, 0x59, 0x1a, 0x41, 0x18, 0x00, 0xe0, 0x19, 0x1a, 
-0x01, 0x20, 0x10, 0x29, 0x00, 0xd8, 0x00, 0x20, 0x00, 0x28, 0x1f, 0xd0, 
-0x78, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0xb8, 0x6a, 0xf9, 0x6a, 
-0xc0, 0x46, 0x48, 0x60, 0x10, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xfb, 0x6a, 
-0x0f, 0x48, 0x42, 0x6d, 0x03, 0x20, 0x39, 0x6a, 0x01, 0xf0, 0xe8, 0xfd, 
-0x38, 0x88, 0x10, 0x23, 0x18, 0x43, 0x38, 0x80, 0x38, 0x88, 0x40, 0x23, 
-0x98, 0x43, 0x38, 0x80, 0x38, 0x1c, 0xff, 0xf7, 0x55, 0xff, 0x98, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 
-0xf7, 0xe7, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, 
-0x08, 0x00, 0x11, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xb0, 0xb5, 0x40, 0x20, 
-0x2c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, 0xff, 0xfe, 0x07, 0x1c, 
-0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x05, 0x0f, 0x68, 0x01, 
-0x40, 0x1b, 0x80, 0x00, 0x26, 0x49, 0x44, 0x18, 0x20, 0x88, 0x02, 0x23, 
-0x18, 0x43, 0x20, 0x80, 0x20, 0x88, 0x41, 0x08, 0x34, 0xd3, 0x40, 0x08, 
-0x40, 0x00, 0x20, 0x80, 0xa0, 0x6c, 0xe1, 0x6c, 0x40, 0x18, 0xa0, 0x64, 
-0x00, 0x20, 0xe0, 0x64, 0xa1, 0x6b, 0x22, 0x6d, 0x89, 0x18, 0xa1, 0x63, 
-0x20, 0x65, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x03, 0x23, 0x1b, 0x07, 
-0x78, 0x68, 0x18, 0x40, 0x78, 0x60, 0x61, 0x68, 0x36, 0x31, 0x94, 0x29, 
-0x04, 0xd8, 0x38, 0x23, 0x18, 0x43, 0x78, 0x60, 0x38, 0x20, 0x03, 0xe0, 
-0x94, 0x23, 0x18, 0x43, 0x78, 0x60, 0x94, 0x20, 0xb8, 0x61, 0x39, 0x68, 
-0x78, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x20, 0x1c, 0xcb, 0x1f, 0x05, 0x3b, 
-0xff, 0xf7, 0xd7, 0xfd, 0x02, 0x20, 0x60, 0x80, 0x38, 0x1c, 0xff, 0xf7, 
-0xdf, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xfc, 0xf7, 
-0x4d, 0xfa, 0x28, 0x01, 0x06, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 
-0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xef, 0xe7, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, 
-0x90, 0xb5, 0x00, 0x27, 0x0f, 0x4c, 0x0d, 0xe0, 0x02, 0x6b, 0x01, 0x3a, 
-0x02, 0x63, 0x00, 0x2a, 0x05, 0xdc, 0xc2, 0x6a, 0xc0, 0x46, 0x02, 0x63, 
-0x80, 0x6a, 0x01, 0xf0, 0xcc, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, 
-0x38, 0x01, 0x00, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x41, 0x6a, 
+0xf8, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa0, 0x82, 0x20, 0x40, 
+0x98, 0xb5, 0x07, 0x1c, 0x22, 0x48, 0xc0, 0x46, 0x00, 0x90, 0x22, 0x48, 
+0xc3, 0x1d, 0x41, 0x33, 0x41, 0x6d, 0x82, 0x6d, 0x80, 0x6c, 0x00, 0x03, 
+0x00, 0x0b, 0x9c, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 
+0x98, 0x42, 0x00, 0xd1, 0x0c, 0xe0, 0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, 
+0x59, 0x1a, 0x41, 0x18, 0x00, 0xe0, 0x19, 0x1a, 0x01, 0x20, 0x10, 0x29, 
+0x00, 0xd8, 0x00, 0x20, 0x00, 0x28, 0x1f, 0xd0, 0x78, 0x6a, 0xf9, 0x6a, 
+0xc0, 0x46, 0x08, 0x60, 0xb8, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x48, 0x60, 
+0x10, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xfb, 0x6a, 0x0f, 0x48, 0x42, 0x6d, 
+0x03, 0x20, 0x39, 0x6a, 0x01, 0xf0, 0xe2, 0xfd, 0x38, 0x88, 0x10, 0x23, 
+0x18, 0x43, 0x38, 0x80, 0x38, 0x88, 0x40, 0x23, 0x98, 0x43, 0x38, 0x80, 
+0x38, 0x1c, 0xff, 0xf7, 0x55, 0xff, 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0xf7, 0xe7, 0x00, 0x00, 
+0x55, 0x55, 0x55, 0x55, 0xa8, 0x03, 0x00, 0x80, 0x08, 0x00, 0x11, 0x02, 
+0x7c, 0x29, 0x00, 0x80, 0xb0, 0xb5, 0x40, 0x20, 0x2c, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x00, 0xf0, 0xfd, 0xfe, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, 
+0x1b, 0x07, 0x18, 0x40, 0x05, 0x0f, 0x68, 0x01, 0x40, 0x1b, 0x80, 0x00, 
+0x26, 0x49, 0x44, 0x18, 0x20, 0x88, 0x02, 0x23, 0x18, 0x43, 0x20, 0x80, 
+0x20, 0x88, 0x41, 0x08, 0x34, 0xd3, 0x40, 0x08, 0x40, 0x00, 0x20, 0x80, 
+0xa0, 0x6c, 0xe1, 0x6c, 0x40, 0x18, 0xa0, 0x64, 0x00, 0x20, 0xe0, 0x64, 
+0xa1, 0x6b, 0x22, 0x6d, 0x89, 0x18, 0xa1, 0x63, 0x20, 0x65, 0xb8, 0x6a, 
+0xc0, 0x46, 0x60, 0x65, 0x03, 0x23, 0x1b, 0x07, 0x78, 0x68, 0x18, 0x40, 
+0x78, 0x60, 0x61, 0x68, 0x36, 0x31, 0x94, 0x29, 0x04, 0xd8, 0x38, 0x23, 
+0x18, 0x43, 0x78, 0x60, 0x38, 0x20, 0x03, 0xe0, 0x94, 0x23, 0x18, 0x43, 
+0x78, 0x60, 0x94, 0x20, 0xb8, 0x61, 0x39, 0x68, 0x78, 0x68, 0x02, 0x04, 
+0x12, 0x0c, 0x20, 0x1c, 0xcb, 0x1f, 0x05, 0x3b, 0xff, 0xf7, 0xd7, 0xfd, 
+0x02, 0x20, 0x60, 0x80, 0x38, 0x1c, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xfc, 0xf7, 0x11, 0xfa, 0x28, 0x01, 
+0x06, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 
+0x01, 0x39, 0x41, 0x63, 0xef, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
+0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 0x90, 0xb5, 0x00, 0x27, 
+0x0f, 0x4c, 0x0d, 0xe0, 0x42, 0x6b, 0x01, 0x3a, 
+0x42, 0x63, 0x00, 0x2a, 0x05, 0xdc, 0x02, 0x6b, 0xc0, 0x46, 0x42, 0x63, 
+0xc0, 0x6a, 0x01, 0xf0, 0xc6, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, 
+0x38, 0x01, 0x00, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x6a, 
 0x00, 0x29, 0xe9, 0xd1, 0x01, 0x20, 0x40, 0x06, 0x03, 0x49, 0xc0, 0x46, 
-0x08, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0x00, 0x00, 0xb0, 0x11, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 
-0x10, 0x49, 0xc8, 0x68, 0x01, 0x28, 0x19, 0xd1, 0xc8, 0x1d, 0x79, 0x30, 
-0x82, 0x88, 0x00, 0x2a, 0x14, 0xd0, 0x01, 0x3a, 0x82, 0x80, 0x82, 0x88, 
-0x00, 0x2a, 0x0f, 0xd1, 0xc2, 0x88, 0x00, 0x2a, 0x0a, 0xd1, 0x02, 0x23, 
-0xca, 0x6f, 0x1a, 0x43, 0xca, 0x67, 0x07, 0x49, 0xc0, 0x46, 0x0a, 0x60, 
-0x04, 0x21, 0x81, 0x80, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xc1, 0x80, 
-0x70, 0x47, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xb0, 0xb5, 0x07, 0x1c, 
-0x01, 0x23, 0xf8, 0x1d, 0x69, 0x30, 0x03, 0x73, 0x1d, 0x49, 0xca, 0x1d, 
-0x79, 0x32, 0xd4, 0x89, 0x60, 0x1c, 0xd0, 0x81, 0x55, 0x8a, 0x00, 0x20, 
-0xac, 0x42, 0x02, 0xdb, 0x53, 0x73, 0xd0, 0x81, 0x50, 0x83, 0x01, 0x23, 
-0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, 0xc0, 0x46, 0xba, 0x61, 
-0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, 0x12, 0x49, 0xc0, 0x46, 
-0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x61, 0x48, 0x69, 
-0xfa, 0x6c, 0x90, 0x43, 0x48, 0x61, 0x01, 0x21, 0x09, 0x05, 0xc8, 0x60, 
-0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, 0xf9, 0x69, 0x41, 0x1a, 
-0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 
-0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, 0x81, 0x42, 0xe2, 0xd3, 
-0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0xff, 0x23, 
-0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, 0x21, 0x37, 0xe1, 0x6e, 
-0x38, 0x1c, 0x01, 0xf0, 0xcf, 0xfc, 0x2d, 0x4d, 0x00, 0x28, 0x13, 0xd1, 
-0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, 0x19, 0x43, 0x01, 0x72, 
-0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, 0x01, 0x6d, 0x42, 0x6d, 
-0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb4, 0xfc, 0x00, 0x20, 0xf8, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, 0x20, 0x61, 0x23, 0x49, 
-0xc8, 0x1d, 0xb9, 0x30, 0xc2, 0x6a, 0x92, 0x00, 0x51, 0x18, 0xc0, 0x31, 
-0xcf, 0x60, 0xc1, 0x6a, 0x01, 0x31, 0x89, 0x07, 0x89, 0x0f, 0xc1, 0x62, 
-0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, 0x03, 0xd8, 0x23, 0x22, 
-0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, 0x7e, 0x1a, 0x07, 0xd1, 
-0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18, 
-0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x0a, 0x43, 0x00, 0x92, 
-0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, 0x2b, 0x1c, 0x01, 0xf0, 
-0x81, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, 0x00, 0x92, 0x61, 0x6e, 
-0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0x77, 0xfc, 0x20, 0x6b, 
-0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, 0x81, 0x42, 0x00, 0xd8, 
-0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7, 0x44, 0x80, 0x20, 0x40, 
-0x04, 0x00, 0x1b, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
-0x80, 0xb5, 0x01, 0x20, 0xc0, 0x03, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, 
-0x0c, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x27, 0x00, 0x2a, 
-0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x08, 0x49, 
-0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, 
-0x08, 0x1c, 0xff, 0xf7, 0x2f, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0x00, 0x00, 0xb0, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 
-0x90, 0xb5, 0x07, 0x1c, 0x10, 0x20, 0x18, 0x49, 0xc0, 0x46, 0x08, 0x60, 
-0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x16, 0x48, 0xc4, 0x1d, 0xb9, 0x34, 
-0x21, 0x6b, 0x89, 0x00, 0x09, 0x18, 0xc0, 0x31, 0xc9, 0x68, 0x7a, 0x68, 
-0x92, 0x00, 0xd2, 0x19, 0x51, 0x64, 0x21, 0x6b, 0x89, 0x00, 0x08, 0x18, 
-0xc0, 0x30, 0xc1, 0x68, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 
-0x01, 0xf0, 0xa6, 0xfa, 0x01, 0x23, 0x78, 0x68, 
-0x58, 0x40, 0x78, 0x60, 0x20, 0x6b, 0x01, 0x30, 0x80, 0x07, 0x80, 0x0f, 
-0x20, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, 0x00, 0x28, 0x02, 0xd1, 
-0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, 
-0x39, 0x48, 0x80, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xb8, 0x6a, 0xc0, 0x68, 
-0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, 0x78, 0x6f, 0xfc, 0xf7, 
-0x9d, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31, 
-0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x6c, 0x2f, 0x49, 
-0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 
-0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, 0x20, 0x1c, 0x00, 0xf0, 
-0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, 0x09, 0x18, 0x09, 0x09, 
-0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, 0x89, 0x1a, 0xa1, 0x62, 
-0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, 0x00, 0x2a, 0x07, 0xd0, 
-0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, 0x80, 0x00, 0xb9, 0x6a, 
-0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, 0x80, 0x00, 0xc0, 0x19, 
-0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, 0x41, 0x64, 0xb8, 0x6a, 
-0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, 0x40, 0x1a, 0xb8, 0x62, 
-0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, 0x40, 0x18, 0xb8, 0x62, 
-0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, 0x00, 0x29, 0xb8, 0xd1, 
-0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, 0x3a, 0x6c, 0x91, 0x42, 
-0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, 0x80, 0x00, 0xc0, 0x19, 
-0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x01, 0xd0, 
-0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, 0xa1, 0xd0, 0x01, 0x38, 
-0x38, 0x61, 0x9e, 0xe7, 0xe8, 0x18, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 
-0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x00, 0x20, 0x05, 0x90, 
-0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, 0x80, 0x6a, 0xc0, 0x46, 
-0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, 0x49, 0x6b, 0xc0, 0x46, 
-0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, 0xc0, 0x46, 0xa8, 0x60, 
-0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, 0xf0, 0x48, 0xc0, 0x46, 
-0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a, 0xc1, 0x1b, 0x09, 0x09, 
-0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46, 0x0f, 0x93, 0xeb, 0x4b, 
-0xc0, 0x46, 0x0e, 0x93, 0x91, 0x42, 0x01, 0xd3, 0xb8, 0x42, 0x21, 0xd8, 
-0xe1, 0x68, 0x02, 0x29, 0x1e, 0xd2, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 
-0x48, 0x71, 0x00, 0x20, 0x03, 0x99, 0x01, 0xf0, 0x5b, 0xfb, 0x00, 0x28, 
-0x03, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, 0x01, 0x30, 0x98, 0x63, 0x01, 0x20, 
-0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0xdd, 0x4a, 0xc0, 0x46, 
-0x00, 0x92, 0xdd, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0xdc, 0x4b, 0x00, 0x20, 
-0x01, 0xf0, 0x3e, 0xfb, 0x38, 0x1c, 0x5c, 0xe3, 0xb8, 0x42, 0x03, 0xd8, 
-0x20, 0x1c, 0x00, 0xf0, 0x7b, 0xfc, 0x07, 0x1c, 0xd7, 0x48, 0x80, 0x68, 
-0x00, 0x28, 0x64, 0xd0, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 
-0x60, 0xd1, 0x05, 0x98, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x05, 0x90, 
-0x38, 0x78, 0xf0, 0x23, 0x18, 0x40, 0x58, 0xd1, 0xe0, 0x6a, 0xc0, 0x1b, 
-0x00, 0x09, 0x0c, 0x99, 0x88, 0x42, 0x02, 0xd2, 
-0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, 0x88, 0x68, 0x00, 0xf0, 
-0x87, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, 0x28, 0x1c, 0x39, 0x1c, 
-0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, 0x2e, 0x62, 0xf8, 0x68, 
-0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, 0x03, 0xd0, 0xc1, 0x49, 
-0xc9, 0x68, 0x00, 0xf0, 0x74, 0xff, 0xf8, 0x89, 0x00, 0x28, 0x03, 0xd0, 
-0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x6d, 0xff, 0x7a, 0x68, 0xc0, 0x46, 
-0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, 0x30, 0x1c, 0xb8, 0x49, 
-0x09, 0x68, 0x00, 0xf0, 0x62, 0xff, 0x00, 0x28, 0x17, 0xd1, 0x30, 0x1c, 
-0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x5b, 0xff, 0x10, 0x37, 0xe0, 0x6a, 
-0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x27, 0xfc, 0x07, 0x1c, 
-0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 
-0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, 0xb0, 0xe0, 0xa8, 0x69, 
-0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a, 
-0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, 0xa4, 0xe0, 0x10, 0x28, 
-0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, 0x18, 0x40, 0x01, 0x0f, 
-0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, 0x82, 0x18, 0x01, 0x92, 
-0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, 0x2f, 0xd3, 0x9d, 0x48, 
-0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x80, 
-0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 
-0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 
-0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 
-0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x8f, 0x49, 0x40, 0x18, 
-0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, 0x50, 0x68, 0x36, 0x30, 
-0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, 0x94, 0x20, 0xa8, 0x61, 
-0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, 0x58, 0xe0, 0x7a, 0x88, 
-0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x23, 0xe0, 
-0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, 0x1d, 0xd0, 0x03, 0x93, 
-0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68, 
-0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46, 
-0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 
-0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49, 0x40, 0x18, 0x01, 0x9a, 
-0xc0, 0x46, 0x50, 0x63, 0x02, 0xe0, 0x33, 0xe0, 0x2a, 0xe0, 0x03, 0x93, 
-0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x12, 0x9a, 0x50, 0x78, 
-0x05, 0x99, 0x43, 0x1a, 0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 
-0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x92, 0xfb, 0x07, 0x1c, 0x01, 0x9a, 
-0x50, 0x6b, 0x91, 0x6b, 0x09, 0x01, 0x40, 0x18, 0x0b, 0x9b, 0x21, 0x1c, 
-0x3a, 0x1c, 0xff, 0xf7, 0x7b, 0xfb, 0x01, 0x9a, 0xc0, 0x46, 0xd0, 0x64, 
-0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x13, 0x65, 0x01, 0x23, 0x5b, 0x06, 
-0x68, 0x68, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 0x0d, 0xe0, 
+0x08, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0xb0, 0x10, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 
+0x0f, 0x49, 0xc8, 0x68, 0x01, 0x28, 0x17, 0xd1, 0xc8, 0x1d, 0x79, 0x30, 
+0x02, 0x89, 0x00, 0x2a, 0x12, 0xd0, 0x01, 0x3a, 0x02, 0x81, 0x02, 0x89, 
+0x00, 0x2a, 0x0d, 0xd1, 0x42, 0x89, 0x00, 0x2a, 0x08, 0xd1, 0xc9, 0x6f, 
+0x02, 0x23, 0x0a, 0x68, 0x1a, 0x43, 0x0a, 0x60, 0x04, 0x21, 0x01, 0x81, 
+0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x41, 0x81, 0x70, 0x47, 0x00, 0x00, 
+0x08, 0x83, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 
+0x01, 0x23, 0xf8, 0x1d, 0x69, 0x30, 0x03, 0x73, 0x1e, 0x48, 0xc2, 0x1d, 
+0x79, 0x32, 0x54, 0x8a, 0x61, 0x1c, 0x51, 0x82, 0xd5, 0x8a, 0x00, 0x21, 
+0xac, 0x42, 0x04, 0xdb, 0xc4, 0x1d, 0x89, 0x34, 0x63, 0x70, 0x51, 0x82, 
+0xd1, 0x83, 0x01, 0x23, 0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, 
+0xc0, 0x46, 0xba, 0x61, 0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, 
+0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x79, 0x61, 0x41, 0x69, 0xfa, 0x6c, 0x91, 0x43, 0x41, 0x61, 0x01, 0x20, 
+0x00, 0x05, 0xc1, 0x60, 0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, 
+0xf9, 0x69, 0x41, 0x1a, 0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, 
+0x00, 0xf0, 0x0e, 0xf8, 0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, 
+0x81, 0x42, 0xe2, 0xd3, 0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, 
+0x0f, 0x1c, 0xff, 0x23, 0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, 
+0x21, 0x37, 0xe1, 0x6e, 0x38, 0x1c, 0x01, 0xf0, 0xcb, 0xfc, 0x2d, 0x4d, 
+0x00, 0x28, 0x13, 0xd1, 0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, 
+0x19, 0x43, 0x01, 0x72, 0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, 
+0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb0, 0xfc, 
+0x00, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, 
+0x20, 0x61, 0x23, 0x49, 0xc8, 0x1d, 0xb9, 0x30, 0x02, 0x6b, 0x92, 0x00, 
+0x51, 0x18, 0xc0, 0x31, 0x0f, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x89, 0x07, 
+0x89, 0x0f, 0x01, 0x63, 0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, 
+0x03, 0xd8, 0x23, 0x22, 0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, 
+0x7e, 0x1a, 0x07, 0xd1, 0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, 
+0x61, 0x6e, 0x09, 0x18, 0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, 
+0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, 
+0x2b, 0x1c, 0x01, 0xf0, 0x7d, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, 
+0x00, 0x92, 0x61, 0x6e, 0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 
+0x73, 0xfc, 0x20, 0x6b, 0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, 
+0x81, 0x42, 0x00, 0xd8, 0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7, 
+0x44, 0x80, 0x20, 0x40, 0x04, 0x00, 0x1b, 0x02, 0x7c, 0x29, 0x00, 0x80, 
+0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x01, 0x20, 
+0xc0, 0x03, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0c, 0x49, 0xc8, 0x1d, 
+0x49, 0x30, 0x02, 0x7a, 0x00, 0x27, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, 
+0x08, 0x1c, 0xff, 0xf7, 0x37, 0xff, 0x08, 0x49, 0xc8, 0x1d, 0x49, 0x30, 
+0x02, 0x7a, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, 
+0x2d, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 
+0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, 
+0x10, 0x20, 0x18, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xf8, 0x68, 0x01, 0x30, 
+0xf8, 0x60, 0x16, 0x48, 0xc4, 0x1d, 0xb9, 0x34, 0x61, 0x6b, 0x89, 0x00, 
+0x09, 0x18, 0xc0, 0x31, 0x09, 0x69, 0x7a, 0x68, 0x92, 0x00, 0xd2, 0x19, 
+0x51, 0x64, 0x61, 0x6b, 0x89, 0x00, 0x08, 0x18, 0xc0, 0x30, 0x01, 0x69, 
+0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0x01, 0xf0, 0xa2, 0xfa, 
+0x01, 0x23, 0x78, 0x68, 0x58, 0x40, 0x78, 0x60, 0x60, 0x6b, 0x01, 0x30, 
+0x80, 0x07, 0x80, 0x0f, 0x60, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, 
+0x00, 0x28, 0x02, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 
+0x90, 0xb5, 0x07, 0x1c, 0x39, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x05, 0xd0, 
+0xb8, 0x6a, 0xc0, 0x68, 0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, 
+0x78, 0x6f, 0xfc, 0xf7, 0x63, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, 
+0xf9, 0x1d, 0x19, 0x31, 0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xf8, 0x6c, 0x2f, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, 
+0x21, 0x1c, 0x00, 0xf0, 0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, 
+0x20, 0x1c, 0x00, 0xf0, 0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, 
+0x09, 0x18, 0x09, 0x09, 0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, 
+0x89, 0x1a, 0xa1, 0x62, 0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, 
+0x00, 0x2a, 0x07, 0xd0, 0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, 
+0x80, 0x00, 0xb9, 0x6a, 0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, 
+0x80, 0x00, 0xc0, 0x19, 0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, 
+0x41, 0x64, 0xb8, 0x6a, 0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, 
+0x40, 0x1a, 0xb8, 0x62, 0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, 
+0x40, 0x18, 0xb8, 0x62, 0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, 
+0x00, 0x29, 0xb8, 0xd1, 0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, 
+0x3a, 0x6c, 0x91, 0x42, 0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, 
+0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, 
+0x00, 0x28, 0x01, 0xd0, 0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, 
+0xa1, 0xd0, 0x01, 0x38, 0x38, 0x61, 0x9e, 0xe7, 0x68, 0x19, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0xb0, 0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 
+0x00, 0x20, 0x05, 0x90, 0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, 
+0xc0, 0x6a, 0xc0, 0x46, 0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, 
+0x49, 0x6b, 0xc0, 0x46, 0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, 
+0xc0, 0x46, 0xa8, 0x60, 0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, 
+0xf0, 0x48, 0xc0, 0x46, 0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a, 
+0xc1, 0x1b, 0x09, 0x09, 0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46, 
+0x0f, 0x93, 0xeb, 0x4b, 0xc0, 0x46, 0x0e, 0x93, 
+0x91, 0x42, 0x01, 0xd3, 0xb8, 0x42, 0x21, 0xd8, 0xe1, 0x68, 0x02, 0x29, 
+0x1e, 0xd2, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x00, 0x20, 
+0x03, 0x99, 0x01, 0xf0, 0x57, 0xfb, 0x00, 0x28, 0x03, 0xd1, 0x0e, 0x9b, 
+0xd8, 0x6b, 0x01, 0x30, 0xd8, 0x63, 0x01, 0x20, 0x80, 0x06, 0x00, 0x27, 
+0x68, 0x60, 0xaf, 0x61, 0xdd, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xdd, 0x48, 
+0x01, 0x6d, 0x42, 0x6d, 0xdc, 0x4b, 0x00, 0x20, 0x01, 0xf0, 0x3a, 0xfb, 
+0x38, 0x1c, 0x5c, 0xe3, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 
+0x7b, 0xfc, 0x07, 0x1c, 0xd7, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x64, 0xd0, 
+0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 0x60, 0xd1, 0x05, 0x98, 
+0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x05, 0x90, 0x38, 0x78, 0xf0, 0x23, 
+0x18, 0x40, 0x58, 0xd1, 0xe0, 0x6a, 0xc0, 0x1b, 0x00, 0x09, 0x0c, 0x99, 
+0x88, 0x42, 0x02, 0xd2, 0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, 
+0x88, 0x68, 0x00, 0xf0, 0x83, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, 
+0x28, 0x1c, 0x39, 0x1c, 0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, 
+0x2e, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, 
+0x03, 0xd0, 0xc1, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x70, 0xff, 0xf8, 0x89, 
+0x00, 0x28, 0x03, 0xd0, 0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x69, 0xff, 
+0x7a, 0x68, 0xc0, 0x46, 0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, 
+0x30, 0x1c, 0xb8, 0x49, 0x09, 0x68, 0x00, 0xf0, 0x5e, 0xff, 0x00, 0x28, 
+0x17, 0xd1, 0x30, 0x1c, 0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x57, 0xff, 
 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 
-0x71, 0xfb, 0x07, 0x1c, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 
-0x00, 0xd1, 0xf8, 0xe6, 0xa8, 0x69, 0x03, 0x99, 0x01, 0xf0, 0x2a, 0xfa, 
-0x00, 0x28, 0x2a, 0xd1, 0x38, 0x1c, 0x21, 0x1c, 
-0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, 0x04, 0xd3, 0x30, 0x1c, 
-0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x85, 0xfe, 0x41, 0x49, 0x00, 0x20, 
-0x01, 0xf0, 0x18, 0xfa, 0x00, 0x28, 0x04, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, 
-0x01, 0x30, 0x98, 0x63, 0x11, 0xe0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 
-0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0x3a, 0x4a, 
-0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x39, 0x4b, 
-0x00, 0x20, 0x01, 0xf0, 0xf7, 0xf9, 0x00, 0x20, 0x15, 0xe2, 0x05, 0x98, 
-0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x0c, 0x90, 0x0b, 0x90, 
-0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 
-0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, 0x00, 0x26, 0x00, 0x20, 
-0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, 0x01, 0x38, 0x0d, 0x90, 
-0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, 0x12, 0x0c, 0x90, 0x42, 
-0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x90, 
-0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, 0x07, 0xd1, 0x0d, 0x98, 
-0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, 0x30, 0x18, 0x88, 0x42, 
-0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, 0x1c, 0xe0, 0x11, 0x20, 
-0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd1, 
-0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, 0x89, 0x0f, 0x0f, 0xd0, 
-0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, 0x1e, 0x28, 0x09, 0xdb, 
-0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29, 
-0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, 0x0a, 0x9a, 0x00, 0x2a, 
-0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 
-0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, 0x00, 0x90, 0x04, 0x98, 
-0x83, 0x19, 0x1d, 0xe0, 0x68, 0x0e, 0x00, 0x80, 0x79, 0x48, 0xff, 0xff, 
-0xa8, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, 
-0x44, 0x80, 0x20, 0x40, 0xe8, 0x18, 0x00, 0x80, 0xe0, 0x03, 0x00, 0x80, 
-0x00, 0x00, 0x00, 0x80, 0xc8, 0x2a, 0x00, 0x80, 0xc9, 0x31, 0xff, 0xff, 
-0x58, 0x5f, 0x21, 0x40, 0x81, 0x3c, 0xff, 0xff, 0x41, 0x31, 0xff, 0xff, 
-0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 
-0x6f, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98, 0x00, 0x28, 0x16, 0xd0, 
-0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1, 0x09, 0x23, 0x5b, 0x04, 
-0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 0x06, 0x98, 0xc2, 0x4a, 0x02, 0x43, 
-0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0xc1, 0x48, 0x01, 0x6d, 0x42, 0x6d, 
-0x00, 0x20, 0x01, 0xf0, 0x55, 0xf9, 0x00, 0x20, 0x02, 0x90, 0x08, 0x98, 
-0x00, 0x28, 0x0b, 0xd1, 0x0b, 0x9b, 0x01, 0x3b, 0x0b, 0x93, 0x10, 0x37, 
-0xe0, 0x6a, 0xb8, 0x42, 0x0c, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x8a, 0xfa, 
-0x07, 0x1c, 0x07, 0xe0, 0x78, 0x68, 0x07, 0x9a, 0x80, 0x18, 0x78, 0x60, 
-0x78, 0x88, 0x07, 0x9a, 0x80, 0x1a, 0x78, 0x80, 0x0a, 0x9a, 0x50, 0x1c, 
-0x02, 0x04, 0x12, 0x0c, 0x0a, 0x92, 0x0c, 0x98, 0x0a, 0x9a, 0x82, 0x42, 
-0x03, 0xda, 0xa9, 0x69, 0xb1, 0x42, 0x00, 0xd9, 0x53, 0xe7, 0xa8, 0x69, 
-0xb0, 0x42, 0x6b, 0xd1, 0xa8, 0x68, 0x01, 0x09, 0x69, 0xd2, 0x08, 0x9a, 
-0x00, 0x2a, 0x56, 0xd0, 0x0c, 0x99, 0x0a, 0x9a, 0x8a, 0x42, 0x3e, 0xdb, 
-0xb1, 0x07, 0x89, 0x0f, 0x0c, 0xd0, 0x08, 0x9a, 
-0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, 0x06, 0xdb, 0x1e, 0x2a, 
-0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd2, 
-0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92, 
-0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 
-0x05, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 
-0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x92, 0x48, 0x01, 0x22, 
-0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x8e, 0x48, 0x01, 0x6d, 
-0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xf0, 0xf8, 0x00, 0x20, 0x02, 0x90, 
-0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 
-0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, 0x00, 0xe0, 0x08, 0x9a, 
+0x27, 0xfc, 0x07, 0x1c, 0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, 
+0x00, 0x20, 0xa8, 0x61, 0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, 
+0xb0, 0xe0, 0xa8, 0x69, 0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, 
+0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, 
+0xa4, 0xe0, 0x10, 0x28, 0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, 
+0x18, 0x40, 0x01, 0x0f, 0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, 
+0x82, 0x18, 0x01, 0x92, 0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, 
+0x2f, 0xd3, 0x9d, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, 
+0xc0, 0x46, 0x10, 0x80, 0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 
+0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 
+0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 
+0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 
+0x8f, 0x49, 0x40, 0x18, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, 
+0x50, 0x68, 0x36, 0x30, 0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, 
+0x94, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, 
+0x58, 0xe0, 0x7a, 0x88, 0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, 
+0x03, 0x90, 0x23, 0xe0, 0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, 
+0x1d, 0xd0, 0x03, 0x93, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 
+0x50, 0x60, 0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 
+0x01, 0x9a, 0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 
+0x90, 0x64, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49, 
+0x40, 0x18, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 
+0x02, 0xe0, 0x33, 0xe0, 0x2a, 0xe0, 0x03, 0x93, 0x01, 0x20, 0x0f, 0x99, 
+0xc0, 0x46, 0x48, 0x71, 0x12, 0x9a, 0x50, 0x78, 0x05, 0x99, 0x43, 0x1a, 
+0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 
+0x00, 0xf0, 0x92, 0xfb, 0x07, 0x1c, 0x01, 0x9a, 0x50, 0x6b, 0x91, 0x6b, 
+0x09, 0x01, 0x40, 0x18, 0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, 
+0x7d, 0xfb, 0x01, 0x9a, 0xc0, 0x46, 0xd0, 0x64, 0x01, 0x9a, 0x0b, 0x9b, 
+0xc0, 0x46, 0x13, 0x65, 0x01, 0x23, 0x5b, 0x06, 0x68, 0x68, 0x18, 0x43, 
+0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 0x0d, 0xe0, 0x10, 0x37, 0xe0, 0x6a, 
+0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x71, 0xfb, 0x07, 0x1c, 
+0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 0x00, 0xd1, 0xf8, 0xe6, 
+0xa8, 0x69, 0x03, 0x99, 0x01, 0xf0, 0x26, 0xfa, 0x00, 0x28, 0x2a, 0xd1, 
+0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, 
+0x04, 0xd3, 0x30, 0x1c, 0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x81, 0xfe, 
+0x41, 0x49, 0x00, 0x20, 0x01, 0xf0, 0x14, 0xfa, 0x00, 0x28, 0x04, 0xd1, 
+0x0e, 0x9b, 0xd8, 0x6b, 0x01, 0x30, 0xd8, 0x63, 0x11, 0xe0, 0x01, 0x20, 
+0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 
+0xaf, 0x61, 0x3a, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, 
+0x42, 0x6d, 0x39, 0x4b, 0x00, 0x20, 0x01, 0xf0, 0xf3, 0xf9, 0x00, 0x20, 
+0x15, 0xe2, 0x05, 0x98, 0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 
+0x0c, 0x90, 0x0b, 0x90, 0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, 
+0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, 
+0x00, 0x26, 0x00, 0x20, 0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, 
+0x01, 0x38, 0x0d, 0x90, 0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, 
+0x12, 0x0c, 0x90, 0x42, 0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, 
+0x00, 0x0c, 0x08, 0x90, 0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, 
+0x07, 0xd1, 0x0d, 0x98, 0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, 
+0x30, 0x18, 0x88, 0x42, 0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, 
+0x1c, 0xe0, 0x11, 0x20, 0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, 
+0x18, 0x40, 0x02, 0xd1, 0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, 
+0x89, 0x0f, 0x0f, 0xd0, 0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, 
+0x1e, 0x28, 0x09, 0xdb, 0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 
+0x01, 0xe0, 0x02, 0x29, 0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, 
+0x0a, 0x9a, 0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, 
+0x18, 0x43, 0x06, 0x90, 0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, 
+0x00, 0x90, 0x04, 0x98, 0x83, 0x19, 0x1d, 0xe0, 0xe8, 0x0e, 0x00, 0x80, 
+0xed, 0x48, 0xff, 0xff, 0x28, 0x0f, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, 
+0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x68, 0x19, 0x00, 0x80, 
+0x60, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, 
+0x41, 0x32, 0xff, 0xff, 0x58, 0x5f, 0x21, 0x40, 0xf9, 0x3c, 0xff, 0xff, 
+0xb9, 0x31, 0xff, 0xff, 0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, 
+0x06, 0xca, 0x01, 0xf0, 0x6b, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98, 
+0x00, 0x28, 0x16, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1, 
+0x09, 0x23, 0x5b, 0x04, 0x06, 0x98, 0x18, 0x43, 
+0x06, 0x90, 0x06, 0x98, 0xc2, 0x4a, 0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 
+0x83, 0x19, 0xc1, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 
+0x51, 0xf9, 0x00, 0x20, 0x02, 0x90, 0x08, 0x98, 0x00, 0x28, 0x0b, 0xd1, 
+0x0b, 0x9b, 0x01, 0x3b, 0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 
+0x0c, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x8a, 0xfa, 0x07, 0x1c, 0x07, 0xe0, 
+0x78, 0x68, 0x07, 0x9a, 0x80, 0x18, 0x78, 0x60, 0x78, 0x88, 0x07, 0x9a, 
+0x80, 0x1a, 0x78, 0x80, 0x0a, 0x9a, 0x50, 0x1c, 0x02, 0x04, 0x12, 0x0c, 
+0x0a, 0x92, 0x0c, 0x98, 0x0a, 0x9a, 0x82, 0x42, 0x03, 0xda, 0xa9, 0x69, 
+0xb1, 0x42, 0x00, 0xd9, 0x53, 0xe7, 0xa8, 0x69, 0xb0, 0x42, 0x6b, 0xd1, 
+0xa8, 0x68, 0x01, 0x09, 0x69, 0xd2, 0x08, 0x9a, 0x00, 0x2a, 0x56, 0xd0, 
+0x0c, 0x99, 0x0a, 0x9a, 0x8a, 0x42, 0x3e, 0xdb, 0xb1, 0x07, 0x89, 0x0f, 
+0x0c, 0xd0, 0x08, 0x9a, 0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, 
+0x06, 0xdb, 0x1e, 0x2a, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, 
+0x02, 0x29, 0x02, 0xd2, 0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 
 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 
-0x06, 0xca, 0x01, 0xf0, 0xd9, 0xf8, 0x08, 0x98, 0x36, 0x18, 0x10, 0x37, 
-0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x14, 0xfa, 
-0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, 0x0a, 0x98, 0xc0, 0x46, 
-0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, 0x0d, 0x98, 0x09, 0x99, 
-0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, 0x5f, 0xe0, 0x5e, 0xe0, 
-0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, 0xa9, 0x68, 0x8c, 0x23, 
-0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, 0x1a, 0x43, 0xb1, 0x07, 
-0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, 
-0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 
-0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, 0x02, 0x1c, 0x09, 0x98, 
-0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x1a, 0x43, 0x00, 0x92, 
-0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 
-0x93, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, 0x02, 0x98, 0x00, 0x28, 
-0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 
-0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92, 
-0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 
-0x01, 0xf0, 0x7a, 0xf8, 0x00, 0x20, 0x02, 0x90, 0xe0, 0x6a, 0xb8, 0x42, 
-0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, 0x07, 0x1c, 0x09, 0x98, 
-0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 
-0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x68, 0x60, 
-0xe8, 0x6a, 0x00, 0xf0, 0x7b, 0xfa, 0x28, 0xe0, 0x27, 0xe0, 0xa8, 0x68, 
-0x00, 0x09, 0x14, 0xd3, 0x68, 0x68, 0x80, 0x0e, 0x15, 0xd2, 0x01, 0x9a, 
-0x00, 0x2a, 0x12, 0xd0, 0x01, 0x9a, 0x50, 0x6b, 0x0b, 0x9b, 0x21, 0x1c, 
-0x3a, 0x1c, 0xff, 0xf7, 0x87, 0xf9, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 
-0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x93, 0x63, 0x03, 0xe0, 0xe8, 0x6a, 
-0x31, 0x1c, 0x00, 0xf0, 0x5d, 0xfa, 0x68, 0x68, 0x30, 0x43, 0x68, 0x60, 
-0xa8, 0x69, 0xb0, 0x42, 0x05, 0xd9, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x1b, 
-0x00, 0xf0, 0xee, 0xf9, 0xae, 0x61, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 
-0x0b, 0xd0, 0x2f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0xc3, 0x1f, 
-0x05, 0x3b, 0x2a, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 
-0x27, 0xf8, 0x01, 0x23, 0x9b, 0x07, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 
-0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42, 
-0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, 0x41, 0x1a, 0x01, 0xd5, 
-0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, 0x3f, 0xfb, 0xe1, 0x69, 
-0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, 0x24, 0xd3, 0x40, 0x1a, 
-0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, 0x20, 0x69, 0x02, 0x28, 
-0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, 0x41, 0x69, 0xe2, 0x6c, 
-0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, 0x99, 0x43, 0x81, 0x61, 
-0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x08, 0x61, 
-0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, 
-0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0xce, 0xfa, 
-0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, 0x05, 0x99, 0x40, 0x18, 
-0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xf8, 0x28, 0x00, 0x80, 
-0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, 0xe8, 0x0d, 0x00, 0x80, 
-0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, 
-0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, 0xa0, 0x6f, 0x00, 0xf0, 
-0x49, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x79, 0x68, 
-0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, 0x24, 0x49, 0x40, 0x18, 
-0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, 0x01, 0x60, 0x36, 0xe0, 
-0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x20, 0x4e, 
-0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xa9, 0x6b, 0x19, 0x43, 0xa9, 0x63, 
-0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xb9, 0x6a, 0x22, 0x6e, 
-0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, 0x04, 0xd1, 0x69, 0x6b, 
-0x01, 0x31, 0x69, 0x63, 0x08, 0x29, 0x07, 0xd3, 0x68, 0x63, 0x01, 0x20, 
-0x00, 0xf0, 0x86, 0xf8, 0xa8, 0x6b, 0x40, 0x08, 0x40, 0x00, 0xa8, 0x63, 
-0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, 0x1b, 0x02, 0xf1, 0x18, 
-0x89, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, 0x04, 0xd2, 0x20, 0x1c, 
-0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 
-0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x4a, 0xfc, 0x20, 0x1c, 0x00, 0xf0, 
-0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 
-0x1c, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
-0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30, 0x01, 0x79, 0x00, 0x29, 
-0x04, 0xd0, 0x00, 0x21, 0x01, 0x71, 0x38, 0x1c, 0xff, 0xf7, 0x56, 0xfb, 
-0xf8, 0x68, 0x02, 0x28, 0x0d, 0xd0, 0xb8, 0x68, 0x80, 0x00, 0xc2, 0x19, 
-0x50, 0x6c, 0x00, 0x28, 0x11, 0xd0, 0xb8, 0x6a, 0x41, 0x78, 0x09, 0x01, 
-0x10, 0x31, 0x52, 0x6b, 0x10, 0x1a, 0x88, 0x42, 0x05, 0xd3, 0x38, 0x1c, 
-0xff, 0xf7, 0x42, 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 
-0xff, 0xf7, 0x2a, 0xfa, 0xf8, 0xe7, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 
-0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf1, 0xe7, 0xb0, 0xb5, 0x87, 0xb0, 
-0x0f, 0x1c, 0x80, 0x6f, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, 0x13, 0x4d, 
-0x0b, 0x23, 0x1b, 0x02, 0xe8, 0x18, 0x40, 0x69, 0x00, 0x28, 0x17, 0xd0, 
-0x69, 0x46, 0xa2, 0x00, 0x52, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xd2, 0x18, 
-0x52, 0x69, 0x38, 0x1c, 0x00, 0xf0, 0x96, 0xfb, 0x00, 0x28, 0x09, 0xd1, 
-0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x0b, 0x23, 
-0x1b, 0x02, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, 
-0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x9d, 0xf9, 0x07, 0xb0, 
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
-0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, 0x16, 0x49, 0x01, 0xd0, 
-0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, 0x0c, 0x22, 0xa4, 0x18, 
-0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, 0x1c, 0x22, 0x0b, 0x68, 
-0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x7b, 0x00, 0x2d, 0x13, 0xd0, 
-0x5b, 0x7b, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, 0x5b, 0x06, 0x1a, 0x43, 
-0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, 0x00, 0x92, 0x4a, 0x68, 
-0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0xe3, 0xfe, 0xb8, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, 0x1a, 0x43, 0xf1, 0xe7, 
-0x3c, 0xef, 0x20, 0x40, 0xf8, 0x28, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 
-0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x4a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 
-0x48, 0x60, 0x02, 0xe0, 0x8a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x88, 0x60, 
-0x70, 0x47, 0x00, 0x00, 0xa8, 0x0e, 0x00, 0x80, 0x03, 0x49, 0x48, 0x68, 
-0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x4a, 0x60, 0x70, 0x47, 
-0xa8, 0x0e, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 
-0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x3a, 
-0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, 0x53, 0x6b, 0xc0, 0x46, 
-0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, 0x49, 0x6c, 0x53, 0x6c, 
-0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, 0x92, 0x00, 0x52, 0x18, 
-0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, 0x3d, 0x30, 0x0a, 0x68, 
-0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, 0x9a, 0x1a, 0x02, 0x60, 
-0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x32, 
-0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, 0x40, 0x18, 0x0a, 0x61, 
-0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, 0xb8, 0xb5, 0x04, 0x1c, 
-0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xd9, 0xff, 
-0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x80, 0xfe, 0x01, 0x20, 0xf9, 0x1d, 
-0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, 0x00, 0x20, 0xa0, 0x61, 
-0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 
-0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x66, 0xfe, 0xb8, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, 
-0x44, 0x80, 0x20, 0x40, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 
+0x06, 0xca, 0x01, 0xf0, 0x01, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, 
+0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 
+0x92, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 
+0x8e, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xec, 0xf8, 
+0x00, 0x20, 0x02, 0x90, 0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 
+0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, 
+0x00, 0xe0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 
+0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 0xd5, 0xf8, 0x08, 0x98, 
+0x36, 0x18, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 
+0x00, 0xf0, 0x14, 0xfa, 0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, 
+0x0a, 0x98, 0xc0, 0x46, 0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, 
+0x0d, 0x98, 0x09, 0x99, 0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, 
+0x5f, 0xe0, 0x5e, 0xe0, 0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, 
+0xa9, 0x68, 0x8c, 0x23, 0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, 
+0x1a, 0x43, 0xb1, 0x07, 0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, 
+0x08, 0xd0, 0x1e, 0x2b, 0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, 
+0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, 
+0x02, 0x1c, 0x09, 0x98, 0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, 
+0x1a, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 
+0x06, 0xca, 0x01, 0xf0, 0x8f, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, 
+0x02, 0x98, 0x00, 0x28, 0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 
+0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, 
+0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, 
+0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x02, 0x90, 
+0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, 
+0x07, 0x1c, 0x09, 0x98, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90, 
+0x0c, 0x99, 0x88, 0x42, 0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04, 
+0x09, 0x0c, 0x68, 0x60, 0xe8, 0x6a, 0x00, 0xf0, 
+0x7b, 0xfa, 0x28, 0xe0, 0x27, 0xe0, 0xa8, 0x68, 0x00, 0x09, 0x14, 0xd3, 
+0x68, 0x68, 0x80, 0x0e, 0x15, 0xd2, 0x01, 0x9a, 0x00, 0x2a, 0x12, 0xd0, 
+0x01, 0x9a, 0x50, 0x6b, 0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, 
+0x89, 0xf9, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 0x0b, 0x9b, 
+0xc0, 0x46, 0x93, 0x63, 0x03, 0xe0, 0xe8, 0x6a, 0x31, 0x1c, 0x00, 0xf0, 
+0x5d, 0xfa, 0x68, 0x68, 0x30, 0x43, 0x68, 0x60, 0xa8, 0x69, 0xb0, 0x42, 
+0x05, 0xd9, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x1b, 0x00, 0xf0, 0xee, 0xf9, 
+0xae, 0x61, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x0b, 0xd0, 0x2f, 0x4a, 
+0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0xc3, 0x1f, 0x05, 0x3b, 0x2a, 0x48, 
+0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0x23, 0xf8, 0x01, 0x23, 
+0x9b, 0x07, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, 
+0xe1, 0x69, 0x81, 0x42, 0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, 
+0x41, 0x1a, 0x01, 0xd5, 0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, 
+0x3f, 0xfb, 0xe1, 0x69, 0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, 
+0x24, 0xd3, 0x40, 0x1a, 0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, 
+0x20, 0x69, 0x02, 0x28, 0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, 
+0x41, 0x69, 0xe2, 0x6c, 0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, 
+0x99, 0x43, 0x81, 0x61, 0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, 
+0xc0, 0x46, 0x08, 0x61, 0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 
+0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, 
+0xff, 0xf7, 0xcc, 0xfa, 0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, 
+0x05, 0x99, 0x40, 0x18, 0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 
+0x7c, 0x29, 0x00, 0x80, 0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, 
+0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x00, 0xf0, 0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, 
+0xa0, 0x6f, 0x00, 0xf0, 0x45, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, 
+0x48, 0x71, 0x79, 0x68, 0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, 
+0x24, 0x49, 0x40, 0x18, 0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, 
+0x01, 0x60, 0x36, 0xe0, 0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, 
+0x11, 0x60, 0x20, 0x4e, 0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xe9, 0x6b, 
+0x19, 0x43, 0xe9, 0x63, 0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 
+0xb9, 0x6a, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, 
+0x04, 0xd1, 0xa9, 0x6b, 0x01, 0x31, 0xa9, 0x63, 0x08, 0x29, 0x07, 0xd3, 
+0xa8, 0x63, 0x01, 0x20, 0x00, 0xf0, 0x86, 0xf8, 0xe8, 0x6b, 0x40, 0x08, 
+0x40, 0x00, 0xe8, 0x63, 0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, 
+0x1b, 0x02, 0xf1, 0x18, 0xc9, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, 
+0x04, 0xd2, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, 
+0x38, 0x1c, 0x00, 0xf0, 0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x10, 0xfc, 
+0x20, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x00, 0x00, 0xb0, 0xa0, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30, 
+0x01, 0x79, 0x00, 0x29, 0x04, 0xd0, 0x00, 0x21, 
+0x01, 0x71, 0x38, 0x1c, 0xff, 0xf7, 0x56, 0xfb, 0xf8, 0x68, 0x02, 0x28, 
+0x0d, 0xd0, 0xb8, 0x68, 0x80, 0x00, 0xc2, 0x19, 0x50, 0x6c, 0x00, 0x28, 
+0x11, 0xd0, 0xb8, 0x6a, 0x41, 0x78, 0x09, 0x01, 0x10, 0x31, 0x52, 0x6b, 
+0x10, 0x1a, 0x88, 0x42, 0x05, 0xd3, 0x38, 0x1c, 0xff, 0xf7, 0x42, 0xfb, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x28, 0xfa, 
+0xf8, 0xe7, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0xc0, 0x46, 
+0xb8, 0x62, 0xf1, 0xe7, 0xb0, 0xb5, 0x87, 0xb0, 0x0f, 0x1c, 0x80, 0x6f, 
+0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, 0x13, 0x4d, 0x0b, 0x23, 0x1b, 0x02, 
+0xe8, 0x18, 0x80, 0x69, 0x00, 0x28, 0x17, 0xd0, 0x69, 0x46, 0xa2, 0x00, 
+0x52, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xd2, 0x18, 0x92, 0x69, 0x38, 0x1c, 
+0x00, 0xf0, 0x92, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x01, 0x34, 0xa0, 0x00, 
+0x40, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xc0, 0x18, 0x80, 0x69, 0x00, 0x28, 
+0xea, 0xd1, 0x01, 0xe0, 0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 
+0x9d, 0xf9, 0x07, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, 
+0x16, 0x49, 0x01, 0xd0, 0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, 
+0x0c, 0x22, 0xa4, 0x18, 0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, 
+0x1c, 0x22, 0x0b, 0x68, 0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x78, 
+0x00, 0x2d, 0x13, 0xd0, 0x5b, 0x78, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, 
+0x5b, 0x06, 0x1a, 0x43, 0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, 
+0x00, 0x92, 0x4a, 0x68, 0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 
+0xdf, 0xfe, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, 
+0x1a, 0x43, 0xf1, 0xe7, 0x3c, 0xef, 0x20, 0x40, 0x7c, 0x29, 0x00, 0x80, 
+0xf8, 0x0e, 0x00, 0x80, 0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x8a, 0x68, 
+0x00, 0x2a, 0x01, 0xd1, 0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, 
+0xd0, 0x61, 0xc8, 0x60, 0x70, 0x47, 0x00, 0x00, 0x28, 0x0f, 0x00, 0x80, 
+0x03, 0x49, 0x88, 0x68, 0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 
+0x8a, 0x60, 0x70, 0x47, 0x28, 0x0f, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, 
+0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, 
+0x0a, 0x69, 0x01, 0x3a, 0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, 
+0x53, 0x6b, 0xc0, 0x46, 0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, 
+0x49, 0x6c, 0x53, 0x6c, 0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, 
+0x92, 0x00, 0x52, 0x18, 0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, 
+0x3d, 0x30, 0x0a, 0x68, 0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, 
+0x9a, 0x1a, 0x02, 0x60, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 
+0xca, 0x68, 0x01, 0x32, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, 
+0x40, 0x18, 0x0a, 0x61, 0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, 
+0xb8, 0xb5, 0x04, 0x1c, 0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, 
+0xff, 0xf7, 0xd9, 0xff, 0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x7c, 0xfe, 
+0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, 
+0x00, 0x20, 0xa0, 0x61, 0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 
+0x01, 0x6d, 0x42, 0x6d, 0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x62, 0xfe, 
+0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x04, 0x00, 0x12, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 
+0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 
+0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 
+0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 
 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 
-0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 0x50, 0x2d, 0x00, 0x80, 
-0xa0, 0x82, 0x20, 0x40, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 
-0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 
-0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 
-0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x03, 0x30, 0x80, 0x08, 
-0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 
-0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 
-0x0a, 0x71, 0x70, 0x47, 0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
-0x02, 0x48, 0x41, 0x79, 0x01, 0x31, 0x41, 0x71, 
-0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x82, 0x00, 
-0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, 0x89, 0x08, 0x0b, 0x1d, 
-0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, 0xd7, 0x68, 0x12, 0x4c, 
-0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, 0x03, 0xd1, 0x81, 0x42, 
-0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, 0xb9, 0x42, 0x09, 0xd9, 
-0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 
-0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, 0x81, 0x42, 0x05, 0xd8, 
-0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x02, 0xd8, 
-0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, 0x05, 0x30, 0xfa, 0xe7, 
-0xf0, 0x03, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, 0x0f, 0x4a, 0x17, 0x58, 
-0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, 0x01, 0xe0, 0x88, 0x08, 
-0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, 0x09, 0xd9, 0x39, 0x68, 
-0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9, 
-0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 0x38, 0x69, 0x00, 0xf0, 
-0xd5, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0xf0, 0x03, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x01, 0x40, 
-0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, 0x92, 0x07, 0x02, 0x40, 
-0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, 0x89, 0x0f, 0x00, 0x04, 
-0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, 0x01, 0x30, 0x00, 0x2a, 
-0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, 0xf9, 0x68, 0x7a, 0x68, 
+0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, 
+0xa0, 0x82, 0x20, 0x40, 0x03, 0x30, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 
+0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 
+0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 
+0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x02, 0x48, 0x41, 0x79, 
+0x01, 0x31, 0x41, 0x71, 0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, 
+0x90, 0xb4, 0x82, 0x00, 0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, 
+0x89, 0x08, 0x0b, 0x1d, 0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, 
+0xd7, 0x68, 0x12, 0x4c, 0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, 
+0x03, 0xd1, 0x81, 0x42, 0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, 
+0xb9, 0x42, 0x09, 0xd9, 0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, 
+0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, 
+0x81, 0x42, 0x05, 0xd8, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 
+0x98, 0x42, 0x02, 0xd8, 0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, 
+0x05, 0x30, 0xfa, 0xe7, 0x70, 0x04, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, 
+0x0f, 0x4a, 0x17, 0x58, 0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, 
+0x01, 0xe0, 0x88, 0x08, 0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, 
+0x09, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 
 0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 
-0xf8, 0x68, 0x00, 0xf0, 0xa9, 0xfd, 0xf8, 0x60, 0x0f, 0x48, 0x00, 0x69, 
-0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, 0x02, 0xd0, 0x20, 0x1c, 
-0xfe, 0xf7, 0xc8, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79, 
-0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, 0xc8, 0x1d, 0x19, 0x30, 
-0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, 0x08, 0x1c, 0xff, 0xf7, 
-0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0x03, 0x00, 0x80, 
-0x3c, 0x2c, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 
-0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x78, 0x00, 0x29, 0x03, 0xd1, 0x41, 0x68, 
-0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, 0x49, 0x08, 0x02, 0xd3, 
-0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21, 0x09, 0x04, 0x0c, 0xc8, 
-0x08, 0x38, 0x19, 0x43, 0x87, 0x68, 0xbb, 0x0a, 0x03, 0xd3, 0x43, 0x68, 
-0x5b, 0x08, 0x00, 0xd3, 0x01, 0x31, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 
-0x18, 0x40, 0x07, 0x0f, 0xf8, 0x00, 0x1d, 0x4c, 0x00, 0x19, 0x23, 0x68, 
-0xc0, 0x18, 0x50, 0x30, 0x00, 0x79, 0x01, 0x28, 0x10, 0xd1, 0x60, 0x68, 
-0x01, 0x28, 0x0d, 0xd0, 0x10, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x01, 
-0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 
-0x41, 0x63, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x01, 0x00, 0x19, 
-0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0x5d, 0x1c, 0x05, 0x63, 
-0xbd, 0x02, 0x2d, 0x19, 0xdb, 0x00, 0xeb, 0x18, 0x80, 0x33, 0x19, 0x63, 
-0xda, 0x62, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x01, 0x21, 0xb9, 0x40, 
-0x22, 0x68, 0x11, 0x43, 0x21, 0x60, 0x01, 0x6b, 0x80, 0x29, 0xe2, 0xd3, 
-0x00, 0x21, 0x01, 0x63, 0xdf, 0xe7, 0x00, 0x00, 
-0xa8, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, 
-0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, 0x36, 0xd1, 0x00, 0x24, 
-0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, 0xb0, 0x60, 0x32, 0x68, 
-0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, 0x00, 0xd3, 0xb4, 0x60, 
-0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x87, 0x6b, 
-0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, 0xaa, 0x02, 0x92, 0x19, 
-0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, 0xca, 0x6a, 0x09, 0x6b, 
-0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, 0xc4, 0x62, 0x00, 0x2f, 
-0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, 0xdb, 0x43, 0x37, 0x68, 
-0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, 0x43, 0x63, 0x10, 0x1c, 
-0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, 0x00, 0x28, 0xc9, 0xd0, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 
-0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, 0x00, 0x27, 0x2f, 0x4b, 
-0x2f, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, 0x01, 0x30, 0xd8, 0x62, 
-0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, 0x02, 0x69, 0x53, 0x1c, 
-0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, 0x41, 0x69, 0x01, 0x31, 
-0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, 0x07, 0x61, 0x0f, 0x29, 
-0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c, 
-0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, 0x6e, 0x1c, 0xad, 0x00, 
-0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, 0x01, 0x35, 0x55, 0x61, 
-0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, 0x0f, 0x2d, 0x00, 0xd3, 
-0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x17, 0x4f, 0x3a, 0x6f, 0xfd, 0x68, 
-0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0e, 0xd1, 0xdb, 0x6d, 0x5b, 0x08, 
-0x0b, 0xd3, 0x8b, 0x88, 0x00, 0x2b, 0x08, 0xd1, 0x03, 0x3b, 0xfd, 0x6f, 
-0x2b, 0x40, 0xfb, 0x67, 0x0f, 0x4d, 0xc0, 0x46, 0x2b, 0x60, 0x14, 0x23, 
-0x8b, 0x80, 0x10, 0x60, 0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, 
-0x00, 0xd0, 0x01, 0x38, 0x50, 0x60, 0xc9, 0x69, 0x08, 0x32, 0x91, 0x42, 
-0x00, 0xd8, 0x08, 0x4a, 0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, 
-0x82, 0x61, 0x3a, 0x67, 0xbc, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 
-0x1c, 0x1c, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
-0x24, 0xa7, 0x20, 0x40, 0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, 
-0xc0, 0x05, 0x16, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, 
+0x38, 0x69, 0x00, 0xf0, 0xd1, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x70, 0x04, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, 
+0x09, 0x07, 0x01, 0x40, 0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, 
+0x92, 0x07, 0x02, 0x40, 0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, 
+0x89, 0x0f, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, 
+0x01, 0x30, 0x00, 0x2a, 0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, 
+0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, 
+0xf9, 0x60, 0x81, 0x00, 0xf8, 0x68, 0x00, 0xf0, 0xa5, 0xfd, 0xf8, 0x60, 
+0x0f, 0x48, 0x00, 0x69, 0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, 
+0x02, 0xd0, 0x20, 0x1c, 0xfe, 0xf7, 0xca, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, 
+0x19, 0x30, 0x03, 0x79, 0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, 
+0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, 
+0x08, 0x1c, 0xff, 0xf7, 0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x70, 0x04, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, 0x64, 0x2d, 0x00, 0x80, 
+0xe4, 0x2c, 0x00, 0x80, 0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x79, 0x00, 0x29, 
+0x03, 0xd1, 0x41, 0x68, 0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, 
+0x49, 0x08, 0x02, 0xd3, 0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21, 
+0x09, 0x04, 0x0c, 0xc8, 0x08, 0x38, 0x19, 0x43, 
+0x87, 0x68, 0xbb, 0x0a, 0x03, 0xd3, 0x43, 0x68, 0x5b, 0x08, 0x00, 0xd3, 
+0x01, 0x31, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x07, 0x0f, 
+0xf8, 0x00, 0x1d, 0x4c, 0x00, 0x19, 0x23, 0x68, 0xc0, 0x18, 0x50, 0x30, 
+0x00, 0x79, 0x01, 0x28, 0x10, 0xd1, 0x60, 0x68, 0x01, 0x28, 0x0d, 0xd0, 
+0x10, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x01, 0x00, 0x19, 0x19, 0x23, 
+0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xb0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x38, 0x01, 0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 
+0xc0, 0x18, 0x03, 0x6b, 0x5d, 0x1c, 0x05, 0x63, 0xbd, 0x02, 0x2d, 0x19, 
+0xdb, 0x00, 0xeb, 0x18, 0x80, 0x33, 0x19, 0x63, 0xda, 0x62, 0x81, 0x6b, 
+0x01, 0x31, 0x81, 0x63, 0x01, 0x21, 0xb9, 0x40, 0x22, 0x68, 0x11, 0x43, 
+0x21, 0x60, 0x01, 0x6b, 0x80, 0x29, 0xe2, 0xd3, 0x00, 0x21, 0x01, 0x63, 
+0xdf, 0xe7, 0x00, 0x00, 0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
+0xa0, 0x1c, 0x00, 0x80, 0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, 
+0x36, 0xd1, 0x00, 0x24, 0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, 
+0xb0, 0x60, 0x32, 0x68, 0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, 
+0x00, 0xd3, 0xb4, 0x60, 0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, 
+0xc0, 0x18, 0x87, 0x6b, 0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, 
+0xaa, 0x02, 0x92, 0x19, 0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, 
+0xca, 0x6a, 0x09, 0x6b, 0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, 
+0xc4, 0x62, 0x00, 0x2f, 0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, 
+0xdb, 0x43, 0x37, 0x68, 0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, 
+0x43, 0x63, 0x10, 0x1c, 0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, 
+0x00, 0x28, 0xc9, 0xd0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xa0, 0x1c, 0x00, 0x80, 0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, 
+0x00, 0x27, 0x2e, 0x4b, 0x2e, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, 
+0x01, 0x30, 0xd8, 0x62, 0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, 
+0x02, 0x69, 0x53, 0x1c, 0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, 
+0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, 
+0x07, 0x61, 0x0f, 0x29, 0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x08, 0x1c, 0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, 
+0x6e, 0x1c, 0xad, 0x00, 0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, 
+0x01, 0x35, 0x55, 0x61, 0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, 
+0x0f, 0x2d, 0x00, 0xd3, 0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x16, 0x4f, 
+0x3a, 0x6f, 0xfd, 0x68, 0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0c, 0xd1, 
+0xdb, 0x6d, 0x5b, 0x08, 0x09, 0xd3, 0x0b, 0x89, 0x00, 0x2b, 0x06, 0xd1, 
+0xfd, 0x6f, 0x03, 0x3b, 0x2e, 0x68, 0x33, 0x40, 0x2b, 0x60, 0x14, 0x23, 
+0x0b, 0x81, 0x10, 0x60, 0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, 
+0x00, 0xd0, 0x01, 0x38, 0x50, 0x60, 0x09, 0x6a, 0x08, 0x32, 0x91, 0x42, 
+0x00, 0xd8, 0x07, 0x4a, 0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, 
+0x82, 0x61, 0x3a, 0x67, 0xbe, 0xe7, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 
+0xa0, 0x1c, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, 
+0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, 0xc0, 0x05, 0x16, 0x49, 
+0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, 
 0x67, 0x69, 0x00, 0x2f, 0x16, 0xd0, 0xe0, 0x68, 0x41, 0x1c, 0x80, 0x00, 
-0x00, 0x19, 0xe1, 0x60, 0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x90, 0xfe, 
+0x00, 0x19, 0xe1, 0x60, 0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x94, 0xfe, 
 0xe0, 0x68, 0x0f, 0x28, 0x00, 0xd3, 0xe5, 0x60, 0xe0, 0x68, 0x80, 0x00, 
 0x00, 0x19, 0x80, 0x69, 0x00, 0x08, 0x01, 0xd3, 0x00, 0x2f, 0xea, 0xd1, 
 0x67, 0x61, 0x03, 0xe0, 0x08, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 
-0x65, 0x60, 0x20, 0x68, 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x22, 0xff, 
+0x65, 0x60, 0x20, 0x68, 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x26, 0xff, 
 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
-0x1c, 0x1c, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, 
+0xa0, 0x1c, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, 
 0xb0, 0xb4, 0x10, 0x23, 0x82, 0x68, 0x13, 0x40, 0x00, 0x21, 0x00, 0x2b, 
 0x15, 0xd0, 0x0c, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x24, 0x14, 0x43, 
-0x02, 0x68, 0x15, 0x68, 0x13, 0x1d, 0x80, 0xcb, 
-0x1b, 0x68, 0x04, 0x3a, 0x02, 0x60, 0x20, 0xc2, 0x80, 0xc2, 0x08, 0xc2, 
-0x14, 0x60, 0x42, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x32, 0x1a, 0x43, 
-0x42, 0x60, 0x08, 0x1c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, 
-0xf0, 0xb4, 0x82, 0x68, 0x53, 0x09, 0x34, 0xd3, 0x1b, 0x4b, 0x1a, 0x40, 
-0x12, 0x01, 0x81, 0x26, 0x16, 0x43, 0x03, 0x68, 0x1d, 0x68, 0x1f, 0x1d, 
-0x10, 0xcf, 0x3f, 0x68, 0x04, 0x3b, 0x03, 0x60, 0x20, 0xc3, 0x10, 0xc3, 
-0x80, 0xc3, 0x1e, 0x60, 0x43, 0x68, 0x1f, 0x1d, 0x01, 0x23, 0x9b, 0x07, 
-0x3b, 0x43, 0x43, 0x60, 0xcb, 0x6b, 0x18, 0x1f, 0xc8, 0x63, 0x80, 0xcb, 
-0x80, 0xc0, 0x1c, 0x68, 0x1f, 0x1d, 0x03, 0x1d, 0x04, 0x60, 0x38, 0x1c, 
-0x3f, 0x68, 0xc0, 0x46, 0x1f, 0x60, 0x1f, 0x1d, 0x43, 0x68, 0x1c, 0x04, 
-0x24, 0x0c, 0x81, 0x23, 0x23, 0x43, 0x3b, 0x60, 0x40, 0x68, 0x00, 0x0c, 
-0x00, 0x04, 0x10, 0x43, 0x78, 0x60, 0x08, 0x6e, 0x04, 0x30, 0x08, 0x66, 
-0x48, 0x6e, 0x04, 0x30, 0x48, 0x66, 0x00, 0x20, 0xf0, 0xbc, 0x70, 0x47, 
-0x00, 0xf0, 0xff, 0x0f, 0x80, 0xb4, 0x81, 0x6a, 0x01, 0x23, 0x9b, 0x07, 
-0xca, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0xcf, 0x1d, 0x01, 0x37, 
-0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x60, 0x01, 0x23, 0x9b, 0x07, 
-0x0f, 0x1d, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x60, 0x01, 0x23, 
-0x9b, 0x07, 0x0b, 0x43, 0x1b, 0x68, 0x0c, 0xc1, 0x02, 0x62, 0x01, 0x6b, 
-0xc0, 0x46, 0x0a, 0x62, 0x04, 0x23, 0x81, 0x69, 0x19, 0x43, 0x81, 0x61, 
-0x02, 0x6b, 0xc0, 0x46, 0x91, 0x61, 0x81, 0x6a, 0x04, 0x31, 0x81, 0x62, 
-0x02, 0x6b, 0xc0, 0x46, 0x91, 0x62, 0xc1, 0x1d, 0x39, 0x31, 0x4a, 0x8b, 
-0x04, 0x3a, 0x4a, 0x83, 0x49, 0x8b, 0x02, 0x6b, 0x40, 0x32, 0x51, 0x83, 
-0xc1, 0x89, 0x04, 0x39, 0xc1, 0x81, 0xc1, 0x68, 0x00, 0x6b, 0xc0, 0x46, 
-0xc1, 0x60, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x47, 0x08, 0x47, 
-0x10, 0x47, 0x18, 0x47, 0x20, 0x47, 0x28, 0x47, 0x30, 0x47, 0x38, 0x47, 
-0x30, 0x40, 0x2d, 0xe9, 0x0c, 0xc0, 0x9d, 0xe5, 0x0c, 0x48, 0xa0, 0xe1, 
-0x24, 0x48, 0xb0, 0xe1, 0x1e, 0x00, 0x00, 0x0a, 0x01, 0xc0, 0x4c, 0xe2, 
-0x18, 0x40, 0xa0, 0xe3, 0x64, 0x51, 0x9f, 0xe5, 0x94, 0x50, 0x20, 0xe0, 
-0x00, 0x50, 0x90, 0xe5, 0x14, 0x40, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 
-0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 
-0x10, 0x10, 0x90, 0xe5, 0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, 
-0x0c, 0x50, 0x90, 0x55, 0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, 
+0x02, 0x68, 0x15, 0x68, 0x13, 0x1d, 0x80, 0xcb, 0x1b, 0x68, 0x04, 0x3a, 
+0x02, 0x60, 0x20, 0xc2, 0x80, 0xc2, 0x08, 0xc2, 0x14, 0x60, 0x42, 0x68, 
+0x01, 0x23, 0x9b, 0x07, 0x04, 0x32, 0x1a, 0x43, 0x42, 0x60, 0x08, 0x1c, 
+0xb0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, 0xf0, 0xb4, 0x82, 0x68, 
+0x53, 0x09, 0x34, 0xd3, 0x1b, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x26, 
+0x16, 0x43, 0x03, 0x68, 0x1d, 0x68, 0x1f, 0x1d, 0x10, 0xcf, 0x3f, 0x68, 
+0x04, 0x3b, 0x03, 0x60, 0x20, 0xc3, 0x10, 0xc3, 0x80, 0xc3, 0x1e, 0x60, 
+0x43, 0x68, 0x1f, 0x1d, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x43, 0x60, 
+0xcb, 0x6b, 0x18, 0x1f, 0xc8, 0x63, 0x80, 0xcb, 0x80, 0xc0, 0x1c, 0x68, 
+0x1f, 0x1d, 0x03, 0x1d, 0x04, 0x60, 0x38, 0x1c, 0x3f, 0x68, 0xc0, 0x46, 
+0x1f, 0x60, 0x1f, 0x1d, 0x43, 0x68, 0x1c, 0x04, 0x24, 0x0c, 0x81, 0x23, 
+0x23, 0x43, 0x3b, 0x60, 0x40, 0x68, 0x00, 0x0c, 0x00, 0x04, 0x10, 0x43, 
+0x78, 0x60, 0x08, 0x6e, 0x04, 0x30, 0x08, 0x66, 0x48, 0x6e, 0x04, 0x30, 
+0x48, 0x66, 0x00, 0x20, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, 
+0x80, 0xb4, 0x81, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xca, 0x1d, 0x05, 0x32, 
+0x1a, 0x43, 0x12, 0x68, 0xcf, 0x1d, 0x01, 0x37, 0x3b, 0x43, 0x1b, 0x68, 
+0xc0, 0x46, 0xcb, 0x60, 0x01, 0x23, 0x9b, 0x07, 0x0f, 0x1d, 0x3b, 0x43, 
+0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x60, 0x01, 0x23, 0x9b, 0x07, 0x0b, 0x43, 
+0x1b, 0x68, 0x0c, 0xc1, 0x02, 0x62, 0x01, 0x6b, 0xc0, 0x46, 0x0a, 0x62, 
+0x04, 0x23, 0x81, 0x69, 0x19, 0x43, 0x81, 0x61, 0x02, 0x6b, 0xc0, 0x46, 
+0x91, 0x61, 0x81, 0x6a, 0x04, 0x31, 0x81, 0x62, 0x02, 0x6b, 0xc0, 0x46, 
+0x91, 0x62, 0xc1, 0x1d, 0x39, 0x31, 0x4a, 0x8b, 0x04, 0x3a, 0x4a, 0x83, 
+0x49, 0x8b, 0x02, 0x6b, 0x40, 0x32, 0x51, 0x83, 0xc1, 0x89, 0x04, 0x39, 
+0xc1, 0x81, 0xc1, 0x68, 0x00, 0x6b, 0xc0, 0x46, 0xc1, 0x60, 0x00, 0x20, 
+0x80, 0xbc, 0x70, 0x47, 0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, 
+0x20, 0x47, 0x28, 0x47, 0x30, 0x47, 0x38, 0x47, 0x30, 0x40, 0x2d, 0xe9, 
+0x0c, 0xc0, 0x9d, 0xe5, 0x0c, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xb0, 0xe1, 
+0x1e, 0x00, 0x00, 0x0a, 0x01, 0xc0, 0x4c, 0xe2, 0x18, 0x40, 0xa0, 0xe3, 
+0x64, 0x51, 0x9f, 0xe5, 0x94, 0x50, 0x20, 0xe0, 0x00, 0x50, 0x90, 0xe5, 
+0x14, 0x40, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, 
+0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 0x10, 0x10, 0x90, 0xe5, 
+0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, 
+0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, 
 0x04, 0x10, 0x90, 0xe5, 0x00, 0x50, 0x80, 0xe5, 0x00, 0x50, 0x81, 0xe5, 
 0x00, 0x00, 0xa0, 0xe3, 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 
 0x00, 0x30, 0x93, 0xe5, 0x08, 0x20, 0x90, 0xe5, 0x01, 0x31, 0x83, 0xe3, 
@@ -1793,39 +1805,39 @@ const u8 typhoon_firmware_image[] = {
 0x50, 0x10, 0x91, 0xe5, 0xd9, 0xff, 0xff, 0xea, 0xf0, 0x47, 0x2d, 0xe9, 
 0x20, 0xc0, 0x9d, 0xe5, 0x0c, 0x68, 0xa0, 0xe1, 0x26, 0x68, 0xb0, 0xe1, 
 0x25, 0x00, 0x00, 0x0a, 0x18, 0x40, 0xa0, 0xe3, 0xb8, 0x50, 0x9f, 0xe5, 
-0x94, 0x00, 0x00, 0xe0, 0x05, 0x00, 0x80, 0xe0, 
-0x08, 0x40, 0x90, 0xe5, 0x04, 0x80, 0x90, 0xe5, 0x00, 0x70, 0xa0, 0xe3, 
-0x1f, 0xc0, 0xa0, 0xe3, 0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x50, 0x90, 0xe5, 
-0x10, 0x90, 0x90, 0xe5, 0x14, 0xa0, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 
-0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 
-0x10, 0x50, 0x85, 0xe2, 0x09, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, 
-0x0a, 0x00, 0x55, 0xe1, 0x15, 0x00, 0x00, 0x0a, 0x03, 0x70, 0x17, 0xe2, 
-0x20, 0x10, 0x81, 0xe2, 0x20, 0x30, 0x83, 0xe2, 0x0a, 0x00, 0x00, 0x0a, 
-0x00, 0x60, 0x96, 0xe2, 0x01, 0x70, 0x87, 0xe2, 0x09, 0x00, 0x00, 0x0a, 
-0x20, 0x60, 0x46, 0xe2, 0x20, 0x00, 0x56, 0xe3, 0xec, 0xff, 0xff, 0xca, 
-0x00, 0x70, 0xa0, 0xe3, 0x01, 0xc0, 0x46, 0xe2, 0x02, 0xc4, 0x8c, 0xe3, 
-0x00, 0x60, 0xa0, 0xe3, 0xe7, 0xff, 0xff, 0xea, 0x00, 0x50, 0x88, 0xe5, 
-0xf2, 0xff, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x50, 0x80, 0xe5, 
-0x01, 0x00, 0xa0, 0xe1, 0xf0, 0x47, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 
-0x00, 0xa0, 0x94, 0xe5, 0x0a, 0x00, 0x55, 0xe1, 0x14, 0xa0, 0x80, 0xe5, 
-0xe5, 0xff, 0xff, 0x1a, 0x01, 0x10, 0xa0, 0xe3, 0xf5, 0xff, 0xff, 0xea, 
-0x28, 0x03, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x00, 0x80, 0x20, 0x40, 
-0x68, 0x82, 0x9f, 0xe5, 0x0b, 0x92, 0xa0, 0xe3, 0x64, 0xa2, 0x9f, 0xe5, 
-0x58, 0xb0, 0x9a, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 
-0x1e, 0xff, 0x2f, 0xe1, 0x3f, 0x40, 0x2d, 0xe9, 0x00, 0x00, 0x4f, 0xe1, 
-0x1f, 0x00, 0x00, 0xe2, 0x12, 0x00, 0x50, 0xe3, 0x54, 0x00, 0x00, 0x0a, 
-0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
-0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x99, 0xe5, 0x09, 0x00, 0x00, 0xea, 
-0x02, 0x00, 0x14, 0xe3, 0x53, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x14, 0xe3, 
-0x59, 0x00, 0x00, 0x1b, 0x20, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 
-0x02, 0x07, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x01, 0x06, 0x14, 0xe3, 
-0x59, 0x00, 0x00, 0x1b, 0x08, 0x00, 0x14, 0xe3, 0x45, 0x00, 0x00, 0x1b, 
-0x02, 0x05, 0x14, 0xe3, 0x4a, 0x00, 0x00, 0x1b, 0x02, 0x08, 0x14, 0xe3, 
-0x4b, 0x00, 0x00, 0x1b, 0xe5, 0x0e, 0x14, 0xe3, 0x07, 0x00, 0x00, 0x0a, 
-0x04, 0x20, 0x98, 0xe5, 0x0c, 0x10, 0x98, 0xe5, 0x04, 0x30, 0x52, 0xe2, 
-0x3c, 0x30, 0xa0, 0xb3, 0x04, 0x30, 0x88, 0xe5, 0x02, 0x00, 0x91, 0xe7, 
-0x0f, 0xe0, 0xa0, 0xe1, 0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, 
-0x03, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, 
+0x94, 0x00, 0x00, 0xe0, 0x05, 0x00, 0x80, 0xe0, 0x08, 0x40, 0x90, 0xe5, 
+0x04, 0x80, 0x90, 0xe5, 0x00, 0x70, 0xa0, 0xe3, 0x1f, 0xc0, 0xa0, 0xe3, 
+0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x50, 0x90, 0xe5, 0x10, 0x90, 0x90, 0xe5, 
+0x14, 0xa0, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, 
+0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 0x10, 0x50, 0x85, 0xe2, 
+0x09, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, 0x0a, 0x00, 0x55, 0xe1, 
+0x15, 0x00, 0x00, 0x0a, 0x03, 0x70, 0x17, 0xe2, 0x20, 0x10, 0x81, 0xe2, 
+0x20, 0x30, 0x83, 0xe2, 0x0a, 0x00, 0x00, 0x0a, 0x00, 0x60, 0x96, 0xe2, 
+0x01, 0x70, 0x87, 0xe2, 0x09, 0x00, 0x00, 0x0a, 0x20, 0x60, 0x46, 0xe2, 
+0x20, 0x00, 0x56, 0xe3, 0xec, 0xff, 0xff, 0xca, 0x00, 0x70, 0xa0, 0xe3, 
+0x01, 0xc0, 0x46, 0xe2, 0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x60, 0xa0, 0xe3, 
+0xe7, 0xff, 0xff, 0xea, 0x00, 0x50, 0x88, 0xe5, 0xf2, 0xff, 0xff, 0xea, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x50, 0x80, 0xe5, 0x01, 0x00, 0xa0, 0xe1, 
+0xf0, 0x47, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xa0, 0x94, 0xe5, 
+0x0a, 0x00, 0x55, 0xe1, 0x14, 0xa0, 0x80, 0xe5, 0xe5, 0xff, 0xff, 0x1a, 
+0x01, 0x10, 0xa0, 0xe3, 0xf5, 0xff, 0xff, 0xea, 0xa8, 0x03, 0x00, 0x80, 
+0x7c, 0x29, 0x00, 0x80, 0x00, 0x80, 0x20, 0x40, 0x68, 0x82, 0x9f, 0xe5, 
+0x0b, 0x92, 0xa0, 0xe3, 0x64, 0xa2, 0x9f, 0xe5, 0x58, 0xb0, 0x9a, 0xe5, 
+0x0e, 0xf0, 0xa0, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0x3f, 0x40, 0x2d, 0xe9, 0x00, 0x00, 0x4f, 0xe1, 0x1f, 0x00, 0x00, 0xe2, 
+0x12, 0x00, 0x50, 0xe3, 0x54, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0f, 0xe1, 
+0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x04, 0x50, 0xa0, 0xe3, 
+0x00, 0x40, 0x99, 0xe5, 0x09, 0x00, 0x00, 0xea, 0x02, 0x00, 0x14, 0xe3, 
+0x53, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 
+0x20, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x02, 0x07, 0x14, 0xe3, 
+0x59, 0x00, 0x00, 0x1b, 0x01, 0x06, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 
+0x08, 0x00, 0x14, 0xe3, 0x45, 0x00, 0x00, 0x1b, 0x02, 0x05, 0x14, 0xe3, 
+0x4a, 0x00, 0x00, 0x1b, 0x02, 0x08, 0x14, 0xe3, 0x4b, 0x00, 0x00, 0x1b, 
+0xe5, 0x0e, 0x14, 0xe3, 0x07, 0x00, 0x00, 0x0a, 0x04, 0x20, 0x98, 0xe5, 
+0x0c, 0x10, 0x98, 0xe5, 0x04, 0x30, 0x52, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, 
+0x04, 0x30, 0x88, 0xe5, 0x02, 0x00, 0x91, 0xe7, 0x0f, 0xe0, 0xa0, 0xe1, 
+0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, 0x03, 0x00, 0x00, 0x0a, 
+0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, 
 0x00, 0x00, 0x14, 0xe1, 0x1b, 0xff, 0x2f, 0x11, 0x08, 0x00, 0x9a, 0xe5, 
 0x00, 0x00, 0x14, 0xe1, 0x0b, 0x00, 0x00, 0x0a, 0x01, 0x0c, 0x14, 0xe3, 
 0x98, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, 
@@ -1836,38 +1848,39 @@ const u8 typhoon_firmware_image[] = {
 0x04, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
 0x02, 0x0a, 0x14, 0xe3, 0x44, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
 0x02, 0x09, 0x14, 0xe3, 0x48, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
-0x01, 0x02, 0x14, 0xe3, 0x4c, 0x00, 0x9a, 0x15, 
-0x10, 0xff, 0x2f, 0x11, 0x01, 0x04, 0x14, 0xe3, 0x50, 0x00, 0x9a, 0x15, 
-0x10, 0xff, 0x2f, 0x11, 0x01, 0x0a, 0x14, 0xe3, 0x21, 0x00, 0x00, 0x1b, 
-0x02, 0x00, 0x14, 0xe3, 0x0e, 0x00, 0x00, 0x1b, 0x10, 0x00, 0x9a, 0xe5, 
-0x00, 0x00, 0x14, 0xe1, 0x1c, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x99, 0xe5, 
-0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x94, 0xe2, 0x1b, 0xff, 0x2f, 0x11, 
-0x3f, 0x40, 0xbd, 0xe8, 0x04, 0xf0, 0x5e, 0xe2, 0xc0, 0x00, 0x80, 0xe3, 
-0x00, 0xf0, 0x61, 0xe1, 0xfa, 0xff, 0xff, 0xea, 0x18, 0x00, 0x9a, 0xe5, 
-0x1c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 
-0x1c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
-0x20, 0x10, 0x9a, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x11, 0xff, 0x2f, 0xe1, 
-0x24, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x28, 0x10, 0x9a, 0xe5, 
-0x11, 0xff, 0x2f, 0xe1, 0x2c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
-0x30, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x34, 0x10, 0x9a, 0xe5, 
-0x11, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea, 0x38, 0xe0, 0x9a, 0xe5, 
-0x3c, 0x10, 0x9a, 0xe5, 0x18, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
-0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 
-0x11, 0xff, 0x2f, 0xe1, 0x64, 0x20, 0x9f, 0xe5, 0x00, 0x30, 0x92, 0xe5, 
-0x00, 0x30, 0x53, 0xe0, 0x0a, 0x00, 0x00, 0xba, 0x00, 0x30, 0x82, 0xe5, 
-0x0c, 0x00, 0x92, 0xe5, 0x08, 0x30, 0x92, 0xe5, 0x00, 0x10, 0x91, 0xe2, 
-0x03, 0x00, 0x00, 0x0a, 0x03, 0x10, 0x80, 0xe7, 0x04, 0x30, 0x53, 0xe2, 
-0x3c, 0x30, 0xa0, 0xb3, 0x08, 0x30, 0x82, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 
-0x1e, 0xff, 0x2f, 0xe1, 0x3c, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 
-0x01, 0x00, 0x80, 0xe2, 0x00, 0x00, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 
-0xf8, 0xff, 0xff, 0xea, 0x10, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0x90, 0xe5, 
-0x04, 0x10, 0x51, 0xe2, 0x3c, 0x10, 0xa0, 0xb3, 0x08, 0x10, 0x80, 0xe5, 
-0x1e, 0xff, 0x2f, 0xe1, 0x50, 0x2d, 0x00, 0x80, 0x4c, 0x04, 0x00, 0x80, 
-0xe5, 0x2a, 0xff, 0xff, 0x45, 0x3d, 0xff, 0xff, 0x3d, 0x2b, 0xff, 0xff, 
-0xa0, 0x82, 0x20, 0x40, 0xc9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0x01, 0x23, 
-0x85, 0x4a, 0x5b, 0x07, 0x18, 0x43, 0x13, 0x68, 0x5b, 0x18, 0x13, 0x60, 
-0x00, 0x1f, 0x81, 0xa3, 0x5b, 0x1a, 0x18, 0x47, 0x04, 0x20, 0xa0, 0xe5, 
+0x01, 0x02, 0x14, 0xe3, 0x4c, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
+0x01, 0x04, 0x14, 0xe3, 0x50, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
+0x01, 0x0a, 0x14, 0xe3, 0x21, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x14, 0xe3, 
+0x0e, 0x00, 0x00, 0x1b, 0x10, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1, 
+0x1c, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x99, 0xe5, 0x04, 0x50, 0xa0, 0xe3, 
+0x00, 0x40, 0x94, 0xe2, 0x1b, 0xff, 0x2f, 0x11, 0x3f, 0x40, 0xbd, 0xe8, 
+0x04, 0xf0, 0x5e, 0xe2, 0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x61, 0xe1, 
+0xfa, 0xff, 0xff, 0xea, 0x18, 0x00, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, 
+0x11, 0xff, 0x2f, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, 
+0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x20, 0x10, 0x9a, 0xe5, 
+0x00, 0x00, 0xa0, 0xe3, 0x11, 0xff, 0x2f, 0xe1, 0x24, 0x10, 0x9a, 0xe5, 
+0x11, 0xff, 0x2f, 0xe1, 0x28, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
+0x2c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x30, 0x10, 0x9a, 0xe5, 
+0x11, 0xff, 0x2f, 0xe1, 0x34, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
+0xfe, 0xff, 0xff, 0xea, 0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, 
+0x18, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x38, 0xe0, 0x9a, 0xe5, 
+0x3c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
+0x64, 0x20, 0x9f, 0xe5, 0x00, 0x30, 0x92, 0xe5, 0x00, 0x30, 0x53, 0xe0, 
+0x0a, 0x00, 0x00, 0xba, 0x00, 0x30, 0x82, 0xe5, 0x0c, 0x00, 0x92, 0xe5, 
+0x08, 0x30, 0x92, 0xe5, 0x00, 0x10, 0x91, 0xe2, 0x03, 0x00, 0x00, 0x0a, 
+0x03, 0x10, 0x80, 0xe7, 0x04, 0x30, 0x53, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, 
+0x08, 0x30, 0x82, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 
+0x3c, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe2, 
+0x00, 0x00, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0xf8, 0xff, 0xff, 0xea, 
+0x10, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0x90, 0xe5, 0x04, 0x10, 0x51, 0xe2, 
+0x3c, 0x10, 0xa0, 0xb3, 0x08, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0xe4, 0x2d, 0x00, 0x80, 0xcc, 0x04, 0x00, 0x80, 0x5d, 0x2b, 0xff, 0xff, 
+0xbd, 0x3d, 0xff, 0xff, 0xb5, 0x2b, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40, 
+0xc9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0x01, 0x23, 0x85, 0x4a, 0x5b, 0x07, 
+0x18, 0x43, 0x13, 0x68, 0x5b, 0x18, 0x13, 0x60, 0x00, 0x1f, 0x81, 0xa3, 
+0x5b, 0x1a, 0x18, 0x47, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
@@ -1879,7 +1892,6 @@ const u8 typhoon_firmware_image[] = {
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
@@ -1909,9 +1921,9 @@ const u8 typhoon_firmware_image[] = {
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
-0x50, 0x2d, 0x00, 0x80, 0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, 
-0x01, 0x20, 0x40, 0xe0, 0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xe4, 0x2d, 0x00, 0x80, 
+0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 
+0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 
 0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 
 0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 
 0x78, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x74, 0x00, 0x9f, 0xe5, 
@@ -1922,125 +1934,125 @@ const u8 typhoon_firmware_image[] = {
 0x4c, 0x00, 0x9f, 0xe5, 0x4c, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 
 0x2c, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 
 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, 
-0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 
-0x28, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
-0x7c, 0x34, 0x00, 0x80, 0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 
-0x40, 0x04, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0x80, 0x34, 0x00, 0x80, 
-0x44, 0x04, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80, 0x40, 0x38, 0x00, 0x80, 
-0x48, 0x04, 0x00, 0x80, 0x78, 0x47, 0x00, 0x00, 0x91, 0xea, 0xff, 0xea, 
-0x78, 0x47, 0x00, 0x00, 0x39, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 
-0x63, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xea, 
-0x78, 0x47, 0x00, 0x00, 0x8b, 0xea, 0xff, 0xea, 0x00, 0x00, 0x00, 0x00, 
-0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, 
-0x61, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0xff, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xb9, 0x0b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
-0xd5, 0x0b, 0xff, 0xff, 0x03, 0xff, 0x06, 0x54, 0x03, 0x00, 0x00, 0x00, 
-0x75, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x05, 0xff, 0xff, 
-0x04, 0xff, 0x07, 0x54, 0x03, 0x00, 0x00, 0x00, 0xb5, 0x04, 0xff, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0xf1, 0x05, 0xff, 0xff, 0x05, 0xff, 0x05, 0x54, 
-0x03, 0x00, 0x00, 0x00, 0x39, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
-0x55, 0x05, 0xff, 0xff, 0x00, 0xff, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 
-0xf5, 0x17, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0e, 0xff, 0xff, 
-0x01, 0xff, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x02, 0xff, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0xf1, 0x02, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, 
-0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x65, 0x0d, 0xff, 0xff, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0xbd, 0x4f, 0xff, 0xff, 0x01, 0x50, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
-0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 
+0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 0x28, 0x00, 0x9f, 0xe5, 
+0x00, 0x20, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x7c, 0x34, 0x00, 0x80, 
+0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 0xc0, 0x04, 0x00, 0x80, 
+0xfc, 0x37, 0x00, 0x80, 0x80, 0x34, 0x00, 0x80, 0xc4, 0x04, 0x00, 0x80, 
+0xfc, 0x3f, 0x00, 0x80, 0x40, 0x38, 0x00, 0x80, 0xc8, 0x04, 0x00, 0x80, 
+0x78, 0x47, 0x00, 0x00, 0x76, 0xea, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 
+0x39, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x63, 0xfe, 0xff, 0xea, 
+0x78, 0x47, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 
+0x70, 0xea, 0xff, 0xea, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, 0x95, 0x22, 0x00, 0x00, 
+0x00, 0x01, 0x00, 0x80, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xb9, 0x0b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x0b, 0xff, 0xff, 
+0x03, 0xff, 0x06, 0x54, 0x03, 0x00, 0x00, 0x00, 0x75, 0x04, 0xff, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0xa1, 0x05, 0xff, 0xff, 0x04, 0xff, 0x07, 0x54, 
+0x03, 0x00, 0x00, 0x00, 0xb5, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0xf1, 0x05, 0xff, 0xff, 0x05, 0xff, 0x05, 0x54, 0x03, 0x00, 0x00, 0x00, 
+0x39, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x55, 0x05, 0xff, 0xff, 
+0x01, 0xff, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x41, 0x18, 0xff, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x61, 0x0e, 0xff, 0xff, 0x02, 0xff, 0x02, 0x08, 
+0x00, 0x00, 0x00, 0x00, 0xa1, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0xf1, 0x02, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, 0x03, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x0d, 0xff, 0xff, 
+0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x50, 0xff, 0xff, 
+0x6d, 0x50, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x04, 0x00, 0x80, 
-0x19, 0x78, 0x21, 0x40, 0x23, 0x78, 0x21, 0x40, 0x39, 0x78, 0x21, 0x40, 
-0x51, 0x78, 0x21, 0x40, 0x5d, 0x78, 0x21, 0x40, 0x6b, 0x78, 0x21, 0x40, 
-0x85, 0x78, 0x21, 0x40, 0xb1, 0x78, 0x21, 0x40, 0x75, 0x79, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x48, 0x05, 0x00, 0x80, 0x19, 0x78, 0x21, 0x40, 
+0x23, 0x78, 0x21, 0x40, 0x39, 0x78, 0x21, 0x40, 0x51, 0x78, 0x21, 0x40, 
+0x5d, 0x78, 0x21, 0x40, 0x6b, 0x78, 0x21, 0x40, 0x85, 0x78, 0x21, 0x40, 
+0xb1, 0x78, 0x21, 0x40, 0x75, 0x79, 0x21, 0x40, 
 0xcd, 0x79, 0x21, 0x40, 0xdb, 0x79, 0x21, 0x40, 0xe5, 0x79, 0x21, 0x40, 
-0xef, 0x79, 0x21, 0x40, 0x81, 0x7a, 0x21, 0x40, 0x8f, 0x7a, 0x21, 0x40, 
-0x9d, 0x7a, 0x21, 0x40, 0x35, 0x7b, 0x21, 0x40, 0x03, 0x7f, 0x21, 0x40, 
-0x71, 0x7f, 0x21, 0x40, 0x19, 0x80, 0x21, 0x40, 0x4d, 0x81, 0x21, 0x40, 
-0x59, 0x81, 0x21, 0x40, 0xb9, 0x81, 0x21, 0x40, 0x1d, 0x82, 0x21, 0x40, 
-0x49, 0x82, 0x21, 0x40, 0x6d, 0x82, 0x21, 0x40, 0xad, 0x82, 0x21, 0x40, 
-0xd5, 0x82, 0x21, 0x40, 0x1d, 0x83, 0x21, 0x40, 0x2d, 0x83, 0x21, 0x40, 
-0x55, 0x83, 0x21, 0x40, 0x65, 0x83, 0x21, 0x40, 0xad, 0x83, 0x21, 0x40, 
-0xeb, 0x83, 0x21, 0x40, 0x41, 0x84, 0x21, 0x40, 0xa1, 0x84, 0x21, 0x40, 
-0xab, 0x84, 0x21, 0x40, 0xaf, 0x84, 0x21, 0x40, 0x1d, 0x85, 0x21, 0x40, 
-0x75, 0x85, 0x21, 0x40, 0xcd, 0x85, 0x21, 0x40, 
-0x09, 0x86, 0x21, 0x40, 0x6d, 0x86, 0x21, 0x40, 0xa5, 0x86, 0x21, 0x40, 
-0xb5, 0x86, 0x21, 0x40, 0xed, 0x86, 0x21, 0x40, 0xfd, 0x86, 0x21, 0x40, 
-0x11, 0x87, 0x21, 0x40, 0x39, 0x87, 0x21, 0x40, 0x43, 0x87, 0x21, 0x40, 
-0x4d, 0x87, 0x21, 0x40, 0x57, 0x87, 0x21, 0x40, 0xc1, 0x87, 0x21, 0x40, 
-0xcd, 0x87, 0x21, 0x40, 0x41, 0x88, 0x21, 0x40, 0x4b, 0x88, 0x21, 0x40, 
-0x55, 0x88, 0x21, 0x40, 0x5f, 0x88, 0x21, 0x40, 0x69, 0x88, 0x21, 0x40, 
-0x73, 0x88, 0x21, 0x40, 0x7d, 0x88, 0x21, 0x40, 0x87, 0x88, 0x21, 0x40, 
-0x91, 0x88, 0x21, 0x40, 0x9b, 0x88, 0x21, 0x40, 0xa5, 0x88, 0x21, 0x40, 
-0xaf, 0x88, 0x21, 0x40, 0xb9, 0x88, 0x21, 0x40, 0xc3, 0x88, 0x21, 0x40, 
-0xeb, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40, 0x51, 0x89, 0x21, 0x40, 
-0x5b, 0x89, 0x21, 0x40, 0x65, 0x89, 0x21, 0x40, 0x6f, 0x89, 0x21, 0x40, 
-0x79, 0x89, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0x83, 0x89, 0x21, 0x40, 
-0xe9, 0x89, 0x21, 0x40, 0x35, 0x8a, 0x21, 0x40, 0x81, 0x8a, 0x21, 0x40, 
-0x91, 0x8a, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xdd, 0x8a, 0x21, 0x40, 
-0xe1, 0x8a, 0x21, 0x40, 0xe5, 0x8a, 0x21, 0x40, 0x3d, 0x8b, 0x21, 0x40, 
-0x65, 0x8b, 0x21, 0x40, 0x71, 0x8b, 0x21, 0x40, 0x75, 0x8b, 0x21, 0x40, 
-0x79, 0x8b, 0x21, 0x40, 0xe9, 0x8b, 0x21, 0x40, 0xed, 0x8b, 0x21, 0x40, 
-0xf1, 0x8b, 0x21, 0x40, 0x7d, 0x8b, 0x21, 0x40, 0x05, 0x88, 0x21, 0x40, 
-0xa5, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xf5, 0x8b, 0x21, 0x40, 
-0xe9, 0xc1, 0x21, 0x40, 0xe9, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 
-0xa5, 0x77, 0x21, 0x40, 0xcd, 0xc2, 0x21, 0x40, 0x03, 0xc3, 0x21, 0x40, 
-0x35, 0xc3, 0x21, 0x40, 0x4d, 0x8c, 0x21, 0x40, 0x3f, 0x7b, 0x21, 0x40, 
-0x99, 0x7e, 0x21, 0x40, 0xd5, 0x7e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x5c, 0x01, 0x18, 0x40, 0x58, 0x01, 0x18, 0x40, 0x24, 0xa3, 0x20, 0x40, 
-0x24, 0xa7, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x6c, 0x01, 0x18, 0x40, 0x68, 0x01, 0x18, 0x40, 0x24, 0x83, 0x20, 0x40, 
-0x24, 0xa3, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x7c, 0x01, 0x18, 0x40, 0x78, 0x01, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x8c, 0x01, 0x18, 0x40, 0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, 
-0x24, 0xab, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xef, 0x79, 0x21, 0x40, 0x8d, 0x7a, 0x21, 0x40, 0x9b, 0x7a, 0x21, 0x40, 
+0xa9, 0x7a, 0x21, 0x40, 0x51, 0x7b, 0x21, 0x40, 0x4f, 0x7f, 0x21, 0x40, 
+0xc9, 0x7f, 0x21, 0x40, 0x69, 0x80, 0x21, 0x40, 0x9d, 0x81, 0x21, 0x40, 
+0xa9, 0x81, 0x21, 0x40, 0x09, 0x82, 0x21, 0x40, 0x6d, 0x82, 0x21, 0x40, 
+0x99, 0x82, 0x21, 0x40, 0xbd, 0x82, 0x21, 0x40, 0xfd, 0x82, 0x21, 0x40, 
+0x25, 0x83, 0x21, 0x40, 0x6d, 0x83, 0x21, 0x40, 0x7d, 0x83, 0x21, 0x40, 
+0xa5, 0x83, 0x21, 0x40, 0xb5, 0x83, 0x21, 0x40, 0xfd, 0x83, 0x21, 0x40, 
+0x3b, 0x84, 0x21, 0x40, 0x91, 0x84, 0x21, 0x40, 0xf1, 0x84, 0x21, 0x40, 
+0xfb, 0x84, 0x21, 0x40, 0xff, 0x84, 0x21, 0x40, 0x6d, 0x85, 0x21, 0x40, 
+0xb9, 0x85, 0x21, 0x40, 0x11, 0x86, 0x21, 0x40, 0x4d, 0x86, 0x21, 0x40, 
+0xb1, 0x86, 0x21, 0x40, 0xe9, 0x86, 0x21, 0x40, 0xf9, 0x86, 0x21, 0x40, 
+0x31, 0x87, 0x21, 0x40, 0x41, 0x87, 0x21, 0x40, 0x55, 0x87, 0x21, 0x40, 
+0x7d, 0x87, 0x21, 0x40, 0x87, 0x87, 0x21, 0x40, 0x91, 0x87, 0x21, 0x40, 
+0xf5, 0x87, 0x21, 0x40, 0x25, 0x88, 0x21, 0x40, 0x31, 0x88, 0x21, 0x40, 
+0xa5, 0x88, 0x21, 0x40, 0xaf, 0x88, 0x21, 0x40, 0xb9, 0x88, 0x21, 0x40, 
+0xc3, 0x88, 0x21, 0x40, 0xcd, 0x88, 0x21, 0x40, 0xd7, 0x88, 0x21, 0x40, 
+0xe1, 0x88, 0x21, 0x40, 0xeb, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40, 
+0xe9, 0x8b, 0x21, 0x40, 0xff, 0x88, 0x21, 0x40, 0x09, 0x89, 0x21, 0x40, 
+0x13, 0x89, 0x21, 0x40, 0x1d, 0x89, 0x21, 0x40, 0x45, 0x89, 0x21, 0x40, 
+0x4f, 0x89, 0x21, 0x40, 0xb1, 0x89, 0x21, 0x40, 0xbb, 0x89, 0x21, 0x40, 
+0xc5, 0x89, 0x21, 0x40, 0xcf, 0x89, 0x21, 0x40, 0xd9, 0x89, 0x21, 0x40, 
+0xa5, 0x77, 0x21, 0x40, 0xe3, 0x89, 0x21, 0x40, 0x49, 0x8a, 0x21, 0x40, 
+0x95, 0x8a, 0x21, 0x40, 0xe1, 0x8a, 0x21, 0x40, 0xf1, 0x8a, 0x21, 0x40, 
+0xa5, 0x77, 0x21, 0x40, 0x3d, 0x8b, 0x21, 0x40, 0x41, 0x8b, 0x21, 0x40, 
+0x45, 0x8b, 0x21, 0x40, 0x9d, 0x8b, 0x21, 0x40, 0xc5, 0x8b, 0x21, 0x40, 
+0xd1, 0x8b, 0x21, 0x40, 0xd5, 0x8b, 0x21, 0x40, 0xd9, 0x8b, 0x21, 0x40, 
+0xdd, 0x8b, 0x21, 0x40, 0xe1, 0x8b, 0x21, 0x40, 0xe5, 0x8b, 0x21, 0x40, 
+0x0d, 0x88, 0x21, 0x40, 0x69, 0x88, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 
+0xa5, 0x77, 0x21, 0x40, 0xf5, 0x8b, 0x21, 0x40, 0xe1, 0xc9, 0x21, 0x40, 
+0xe9, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 
+0xdd, 0xca, 0x21, 0x40, 0x13, 0xcb, 0x21, 0x40, 0x45, 0xcb, 0x21, 0x40, 
+0x4d, 0x8c, 0x21, 0x40, 0x5b, 0x7b, 0x21, 0x40, 0xe5, 0x7e, 0x21, 0x40, 
+0x21, 0x7f, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x18, 0x40, 
+0x58, 0x01, 0x18, 0x40, 0x24, 0xa3, 0x20, 0x40, 0x24, 0xa7, 0x20, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x18, 0x40, 
+0x68, 0x01, 0x18, 0x40, 0x24, 0x83, 0x20, 0x40, 0x24, 0xa3, 0x20, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x18, 0x40, 
+0x78, 0x01, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x18, 0x40, 
+0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x24, 0xab, 0x20, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x12, 0x00, 0x18, 0x00, 0x12, 0x00, 
 0x0c, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x24, 0xa8, 0x20, 0x40, 
 0xa4, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, 
-0x00, 0x00, 0x00, 0x00, 0x11, 0xb2, 0x21, 0x40, 0x6d, 0xb3, 0x21, 0x40, 
-0x00, 0x00, 0x00, 0x00, 0x91, 0x73, 0x21, 0x40, 0x89, 0xaa, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0xa5, 0xb9, 0x21, 0x40, 0x01, 0xbb, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x91, 0x73, 0x21, 0x40, 0x19, 0xb2, 0x21, 0x40, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x67, 0x92, 0x21, 0x40, 0x11, 0xb2, 0x21, 0x40, 
-0x39, 0x2f, 0xff, 0xff, 0xad, 0x20, 0xff, 0xff, 0x97, 0x20, 0xff, 0xff, 
-0xe9, 0xb0, 0x21, 0x40, 0xa0, 0x2d, 0x00, 0x80, 0xb4, 0x2d, 0x00, 0x80, 
-0xc8, 0x2d, 0x00, 0x80, 0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, 
-0x00, 0x30, 0x37, 0x2f, 0x32, 0x33, 0x2f, 0x30, 
-0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x31, 0x35, 0x36, 0x39, 0x00, 0x43, 
-0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 
-0x20, 0x32, 0x30, 0x30, 0x31, 0x20, 0x33, 0x43, 0x6f, 0x6d, 0x20, 0x43, 
-0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x00, 
-0x17, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x0c, 0x53, 0xff, 0xff, 0x27, 0xf0, 0x7d, 0xfd, 
-0x00, 0x01, 0x00, 0x02, 0xda, 0x0e, 0x82, 0x00, 0x01, 0x40, 0x64, 0x04, 
-0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 0xe5, 0x3d, 0xff, 0xff, 
-0x49, 0x4f, 0xff, 0xff, 0x79, 0x24, 0xff, 0xff, 0x3d, 0x3b, 0xff, 0xff, 
-0x9d, 0x3b, 0xff, 0xff, 0xa1, 0x19, 0xff, 0xff, 0x19, 0x11, 0xff, 0xff, 
-0x4c, 0x53, 0xff, 0xff, 0x99, 0x3f, 0xff, 0xff, 0x91, 0x73, 0x21, 0x40, 
-0x51, 0x75, 0x21, 0x40, 0x51, 0x3f, 0xff, 0xff, 0x11, 0xa3, 0x21, 0x40, 
-0x29, 0x24, 0xff, 0xff, 0xe4, 0x52, 0xff, 0xff, 0x0c, 0x53, 0xff, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, 
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 
-0xb8, 0x60, 0x00, 0x00, 0x74, 0x6c, 0x00, 0x00, 0x00, 0x6e, 0x21, 0x40, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
-0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
-0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
-0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
-0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 
-0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
-0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
-0xfd, 0x92, 0x21, 0x40, 0x9b, 0x92, 0x21, 0x40, 0xc1, 0x95, 0x21, 0x40, 
-0x21, 0x96, 0x21, 0x40, 0xe9, 0x96, 0x21, 0x40, 0xa7, 0x94, 0x21, 0x40, 
-0xc5, 0x97, 0x21, 0x40, 0x31, 0x98, 0x21, 0x40, 0x85, 0x94, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0xa7, 0x99, 0x21, 0x40, 0xa5, 0xb9, 0x21, 0x40, 
+0xb1, 0x2f, 0xff, 0xff, 0xf1, 0x20, 0xff, 0xff, 0xdb, 0x20, 0xff, 0xff, 
+0x2d, 0xb8, 0x21, 0x40, 0x34, 0x2e, 0x00, 0x80, 0x48, 0x2e, 0x00, 0x80, 
+0x5c, 0x2e, 0x00, 0x80, 0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, 
+0x00, 0x30, 0x37, 0x2f, 0x32, 0x33, 0x2f, 0x30, 0x31, 0x00, 0x30, 0x30, 
+0x30, 0x30, 0x31, 0x35, 0x36, 0x39, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 
+0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 
+0x31, 0x20, 0x33, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 
+0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x00, 0x02, 0x10, 0x00, 0x03, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x78, 0x53, 0xff, 0xff, 0x27, 0xf0, 0x7d, 0xfd, 0x00, 0x01, 0x00, 0x02, 
+0xda, 0x0e, 0x82, 0x00, 0x01, 0x40, 0x64, 0x04, 0x64, 0x2d, 0x00, 0x80, 
+0xe4, 0x2c, 0x00, 0x80, 0x55, 0x3e, 0xff, 0xff, 0xb5, 0x4f, 0xff, 0xff, 
+0xc1, 0x24, 0xff, 0xff, 0xb5, 0x3b, 0xff, 0xff, 0x15, 0x3c, 0xff, 0xff, 
+0x05, 0x1a, 0xff, 0xff, 0x65, 0x11, 0xff, 0xff, 0xb8, 0x53, 0xff, 0xff, 
+0x0d, 0x40, 0xff, 0xff, 0x91, 0x73, 0x21, 0x40, 0x51, 0x75, 0x21, 0x40, 
+0xc5, 0x3f, 0xff, 0xff, 0x71, 0xaa, 0x21, 0x40, 0x71, 0x24, 0xff, 0xff, 
+0x50, 0x53, 0xff, 0xff, 0x78, 0x53, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0xff, 0xff, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0xec, 0x68, 0x00, 0x00, 
+0x10, 0x5c, 0x00, 0x00, 0x00, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 
+0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 
+0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 
+0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 
+0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3d, 0x9a, 0x21, 0x40, 
+0xdb, 0x99, 0x21, 0x40, 0xf5, 0x9c, 0x21, 0x40, 0x55, 0x9d, 0x21, 0x40, 
+0x1d, 0x9e, 0x21, 0x40, 0xdb, 0x9b, 0x21, 0x40, 0xf9, 0x9e, 0x21, 0x40, 
+0x65, 0x9f, 0x21, 0x40, 0xb9, 0x9b, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
@@ -2051,7 +2063,6 @@ const u8 typhoon_firmware_image[] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
@@ -2084,92 +2095,93 @@ const u8 typhoon_firmware_image[] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
-0xb5, 0xce, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xc3, 0x21, 0x40, 
-0x45, 0xc5, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcc, 0x21, 0x40, 
-0x59, 0xcd, 0x21, 0x40, 0xc5, 0xcd, 0x21, 0x40, 0x09, 0x29, 0x09, 0xd1, 
+0xe9, 0xd6, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xcb, 0x21, 0x40, 
+0x55, 0xcd, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x25, 0xd5, 0x21, 0x40, 
+0x8d, 0xd5, 0x21, 0x40, 0xf9, 0xd5, 0x21, 0x40, 0x09, 0x29, 0x09, 0xd1, 
 0x20, 0x28, 0x07, 0xd2, 0x04, 0x48, 0x01, 0x78, 0x00, 0x29, 0x03, 0xd1, 
 0x01, 0x21, 0x01, 0x70, 0x02, 0x48, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 
 0x00, 0x6e, 0x21, 0x40, 0x24, 0xab, 0x20, 0x40, 0x03, 0x49, 0x88, 0x42, 
 0x03, 0xd1, 0x00, 0x20, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x70, 0x70, 0x47, 
-0x24, 0xab, 0x20, 0x40, 0x00, 0x6e, 0x21, 0x40, 
-0x00, 0xb5, 0x00, 0x20, 0x0b, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, 
-0x2d, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x48, 0x61, 0x98, 0x60, 0x98, 0x63, 
-0x80, 0x32, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0x62, 0x05, 0x48, 
-0xc0, 0x46, 0x08, 0x60, 0x48, 0x60, 0x05, 0xf0, 0xc3, 0xf9, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xfe, 0x03, 0x00, 0x00, 
-0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, 0x05, 0x1c, 0x00, 0x23, 0x00, 0x93, 
-0xff, 0xf7, 0xda, 0xff, 0x68, 0x49, 0x0b, 0x23, 0x1b, 0x02, 0xcf, 0x18, 
-0x38, 0x68, 0x28, 0x40, 0x00, 0x22, 0xb8, 0x60, 0xfa, 0x60, 0x7a, 0x68, 
-0x22, 0x40, 0x3a, 0x61, 0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, 
-0x01, 0xd2, 0x80, 0x0a, 0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, 
-0x01, 0x20, 0xb9, 0x68, 0x49, 0x09, 0x03, 0xd2, 0x39, 0x69, 0x49, 0x09, 
-0x00, 0xd2, 0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x03, 0xf0, 0xf8, 0xfd, 
-0xb8, 0x68, 0x00, 0x28, 0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, 
-0x54, 0x4a, 0x01, 0x23, 0x18, 0x43, 0xb8, 0x60, 0x00, 0x20, 0xd5, 0x1d, 
-0x79, 0x35, 0x03, 0x95, 0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xba, 0x68, 
-0x22, 0x40, 0x39, 0xd0, 0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, 
-0x9b, 0x5c, 0x1e, 0x1c, 0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, 
-0x5b, 0x78, 0x83, 0x42, 0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, 
-0x03, 0x9d, 0xad, 0x6a, 0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, 
-0xab, 0x62, 0x53, 0x68, 0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, 
-0x86, 0x42, 0x0a, 0xd1, 0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, 
-0x9b, 0x00, 0x3c, 0x4e, 0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, 
-0x5d, 0x61, 0x53, 0x78, 0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, 
-0x5d, 0x1c, 0x01, 0x95, 0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, 
-0x9b, 0x01, 0xeb, 0x18, 0x9a, 0x60, 0xfa, 0x68, 0x01, 0x32, 0xfa, 0x60, 
-0x64, 0x00, 0x01, 0x31, 0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, 
-0xb8, 0xd3, 0x00, 0x20, 0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, 
-0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0x48, 0x61, 0x01, 0x9b, 0x99, 0x00, 
-0x89, 0x18, 0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x60, 0x00, 0x9b, 
-0x00, 0x2b, 0x0c, 0xd1, 0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, 
-0xc9, 0x18, 0x8b, 0x69, 0xc0, 0x46, 0x4b, 0x61, 0x01, 0x30, 0x0b, 0x28, 
-0xf4, 0xd3, 0x08, 0xe0, 0x07, 0xe0, 0x03, 0x9d, 0xa8, 0x6a, 0x30, 0x28, 
-0x03, 0xd2, 0x30, 0x20, 0x03, 0x9d, 0xc0, 0x46, 0xa8, 0x62, 0x19, 0x4a, 
-0x38, 0x69, 0x00, 0x28, 0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, 
-0x38, 0x61, 0x00, 0x20, 0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x3b, 0x69, 
+0x24, 0xab, 0x20, 0x40, 0x00, 0x6e, 0x21, 0x40, 0x00, 0xb5, 0x00, 0x20, 
+0x0b, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, 0x2d, 0x23, 0x9b, 0x01, 
+0xd3, 0x18, 0x88, 0x61, 0xd8, 0x60, 0xd8, 0x63, 0x80, 0x32, 0xc8, 0x60, 
+0x08, 0x61, 0x48, 0x61, 0xd0, 0x62, 0x05, 0x48, 0xc0, 0x46, 0x48, 0x60, 
+0x88, 0x60, 0x05, 0xf0, 0xcb, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0xfe, 0x03, 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, 
+0x0c, 0x1c, 0x05, 0x1c, 0x00, 0x23, 0x00, 0x93, 0xff, 0xf7, 0xda, 0xff, 
+0x68, 0x49, 0x0b, 0x23, 0x1b, 0x02, 0xcf, 0x18, 0x78, 0x68, 0x28, 0x40, 
+0x00, 0x22, 0xf8, 0x60, 0x3a, 0x61, 0xba, 0x68, 0x22, 0x40, 0x7a, 0x61, 
+0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, 0x01, 0xd2, 0x80, 0x0a, 
+0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, 0x01, 0x20, 0xf9, 0x68, 
+0x49, 0x09, 0x03, 0xd2, 0x79, 0x69, 0x49, 0x09, 0x00, 0xd2, 0x00, 0x20, 
+0x00, 0x06, 0x00, 0x0e, 0x04, 0xf0, 0xc8, 0xf9, 0xf8, 0x68, 0x00, 0x28, 
+0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, 0x54, 0x4a, 0x01, 0x23, 
+0x18, 0x43, 0xf8, 0x60, 0x00, 0x20, 0xd5, 0x1d, 0x79, 0x35, 0x03, 0x95, 
+0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xfa, 0x68, 0x22, 0x40, 0x39, 0xd0, 
+0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, 0x9b, 0x5c, 0x1e, 0x1c, 
+0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, 0x5b, 0x78, 0x83, 0x42, 
+0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, 0x03, 0x9d, 0xed, 0x6a, 
+0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, 0xeb, 0x62, 0x53, 0x68, 
+0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, 0x86, 0x42, 0x0a, 0xd1, 
+0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, 0x9b, 0x00, 0x3c, 0x4e, 
+0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, 0x9d, 0x61, 0x53, 0x78, 
+0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, 0x5d, 0x1c, 0x01, 0x95, 
+0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xeb, 0x18, 
+0xda, 0x60, 0x3a, 0x69, 0x01, 0x32, 0x3a, 0x61, 0x64, 0x00, 0x01, 0x31, 
+0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, 0xb8, 0xd3, 0x00, 0x20, 
+0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, 
+0xc9, 0x18, 0x88, 0x61, 0x01, 0x9b, 0x99, 0x00, 0x89, 0x18, 0x2d, 0x23, 
+0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x60, 0x00, 0x9b, 0x00, 0x2b, 0x0c, 0xd1, 
+0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0xcb, 0x69, 
+0xc0, 0x46, 0x8b, 0x61, 0x01, 0x30, 0x0b, 0x28, 0xf4, 0xd3, 0x08, 0xe0, 
+0x07, 0xe0, 0x03, 0x9d, 0xe8, 0x6a, 0x30, 0x28, 
+0x03, 0xd2, 0x30, 0x20, 0x03, 0x9d, 0xc0, 0x46, 0xe8, 0x62, 0x19, 0x4a, 
+0x78, 0x69, 0x00, 0x28, 0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, 
+0x78, 0x61, 0x00, 0x20, 0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x7b, 0x69, 
 0x23, 0x40, 0x10, 0xd0, 0x93, 0x00, 0x9b, 0x18, 0x9b, 0x00, 0x12, 0x4d, 
 0x5b, 0x19, 0x9d, 0x78, 0x85, 0x42, 0x08, 0xd1, 0x1d, 0x69, 0x0b, 0x1c, 
-0x9b, 0x00, 0x9e, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x9d, 0x63, 
+0x9b, 0x00, 0x9e, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0xdd, 0x63, 
 0x01, 0x31, 0x64, 0x00, 0x01, 0x32, 0x0b, 0x2a, 0xe6, 0xd3, 0x01, 0x30, 
 0x09, 0x28, 0xe1, 0xd3, 0x00, 0x20, 0x89, 0x00, 0x04, 0x4a, 0x89, 0x18, 
-0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x63, 0x04, 0xb0, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xb0, 0x52, 0xff, 0xff, 
-0x80, 0x00, 0x00, 0x80, 0x00, 0x47, 0x08, 0x47, 
-0x10, 0x47, 0x18, 0x47, 0x78, 0x47, 0xc0, 0x46, 0x34, 0xc0, 0x9f, 0xe5, 
-0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x2c, 0xc0, 0x9f, 0xe5, 
-0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x24, 0xc0, 0x9f, 0xe5, 
-0x1c, 0xff, 0x2f, 0xe1, 0xc0, 0x46, 0xff, 0xb4, 0x75, 0x46, 0x20, 0xb4, 
-0x01, 0x21, 0x08, 0x43, 0x01, 0xa4, 0xa6, 0x46, 0x00, 0x47, 0xc0, 0x46, 
-0x20, 0xbc, 0xae, 0x46, 0xff, 0xbc, 0xf7, 0x46, 0xb8, 0x51, 0xff, 0xff, 
-0x08, 0x51, 0xff, 0xff, 0xd7, 0xb7, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20, 
-0x1a, 0x49, 0x01, 0x25, 0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01, 
-0xf8, 0x18, 0x05, 0x72, 0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20, 
-0x7a, 0x6e, 0x17, 0x4b, 0x8a, 0x42, 0x1d, 0xd0, 0x19, 0x7b, 0x00, 0x29, 
-0x17, 0xd1, 0xd9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x1e, 0x1c, 
-0x00, 0x29, 0x10, 0xd1, 0xb0, 0x60, 0x10, 0x20, 0x70, 0x60, 0x10, 0x4a, 
-0x10, 0x49, 0xff, 0xf7, 0xb5, 0xff, 0x00, 0x28, 0x07, 0xd0, 0x35, 0x73, 
-0x04, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x20, 0x61, 0x00, 0xf0, 
-0x17, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x18, 0x73, 0x04, 0x23, 
-0xb8, 0x69, 0x98, 0x43, 0xb8, 0x61, 0x20, 0x61, 0xf5, 0xe7, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, 
-0xa8, 0x04, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, 
-0xf8, 0xb5, 0x15, 0x4f, 0x39, 0x6c, 0x15, 0x48, 0x40, 0x6e, 0x0c, 0x1a, 
-0x14, 0x4e, 0x71, 0x68, 0x14, 0x4d, 0xa1, 0x42, 0x06, 0xd8, 0x14, 0x4a, 
-0x0a, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 0xfa, 0x6b, 0x11, 0xe0, 
-0x11, 0x22, 0x52, 0x05, 0x22, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 
-0x00, 0x20, 0xfa, 0x6b, 0x2b, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x70, 0x68, 
-0x00, 0x1b, 0x0a, 0x4a, 0x02, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0xfa, 0x6b, 
-0x00, 0x20, 0x2b, 0x1c, 0xff, 0xf7, 0x74, 0xff, 0xf8, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
-0xa8, 0x04, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x37, 0x02, 
-0xf0, 0xb5, 0x2b, 0x4f, 0xb8, 0x68, 0x79, 0x68, 0xc0, 0x19, 0x20, 0x30, 
-0x29, 0x4a, 0xff, 0xf7, 0x55, 0xff, 0x01, 0x20, 0xc0, 0x02, 0x28, 0x49, 
-0xc0, 0x46, 0x08, 0x60, 0xb9, 0x68, 0x38, 0x1c, 0x26, 0x4d, 0x00, 0x24, 
-0x26, 0x4e, 0xef, 0x1d, 0x79, 0x37, 0x00, 0x29, 0x31, 0xd1, 0x31, 0x68, 
-0x0a, 0x78, 0x12, 0x0a, 0x03, 0xd2, 0x04, 0x73, 0xf0, 0xbc, 0x08, 0xbc, 
+0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x63, 0x04, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x1c, 0x53, 0xff, 0xff, 
+0x00, 0x01, 0x00, 0x80, 0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, 
+0x78, 0x47, 0xc0, 0x46, 0x34, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 
+0x78, 0x47, 0xc0, 0x46, 0x2c, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 
+0x78, 0x47, 0xc0, 0x46, 0x24, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 
+0xc0, 0x46, 0xff, 0xb4, 0x75, 0x46, 0x20, 0xb4, 0x01, 0x21, 0x08, 0x43, 
+0x01, 0xa4, 0xa6, 0x46, 0x00, 0x47, 0xc0, 0x46, 0x20, 0xbc, 0xae, 0x46, 
+0xff, 0xbc, 0xf7, 0x46, 0x24, 0x52, 0xff, 0xff, 0x74, 0x51, 0xff, 0xff, 
+0x51, 0xc0, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20, 0x1a, 0x49, 0x01, 0x25, 
+0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01, 0xf8, 0x18, 0x05, 0x73, 
+0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20, 0x7a, 0x6e, 0x17, 0x4b, 
+0x8a, 0x42, 0x1d, 0xd0, 0x19, 0x7b, 0x00, 0x29, 0x17, 0xd1, 0xd9, 0x1d, 
+0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x1e, 0x1c, 0x00, 0x29, 0x10, 0xd1, 
+0xb0, 0x60, 0x10, 0x20, 0x70, 0x60, 0x10, 0x4a, 0x10, 0x49, 0xff, 0xf7, 
+0xb5, 0xff, 0x00, 0x28, 0x07, 0xd0, 0x35, 0x73, 0x04, 0x23, 0xb8, 0x69, 
+0x18, 0x43, 0xb8, 0x61, 0x20, 0x61, 0x00, 0xf0, 0x17, 0xf8, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x18, 0x73, 0x04, 0x23, 0xb8, 0x69, 0x98, 0x43, 
+0xb8, 0x61, 0x20, 0x61, 0xf5, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
+0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, 0x28, 0x05, 0x00, 0x80, 
+0x0c, 0x55, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, 0xf8, 0xb5, 0x15, 0x4f, 
+0x39, 0x6c, 0x15, 0x48, 0x40, 0x6e, 0x0c, 0x1a, 0x14, 0x4e, 0x71, 0x68, 
+0x14, 0x4d, 0xa1, 0x42, 0x06, 0xd8, 0x14, 0x4a, 0x0a, 0x43, 0x00, 0x92, 
+0xb9, 0x6b, 0x09, 0x18, 0xfa, 0x6b, 0x11, 0xe0, 0x11, 0x22, 0x52, 0x05, 
+0x22, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 0x00, 0x20, 0xfa, 0x6b, 
+0x2b, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x70, 0x68, 0x00, 0x1b, 0x0a, 0x4a, 
+0x02, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0xfa, 0x6b, 0x00, 0x20, 0x2b, 0x1c, 
+0xff, 0xf7, 0x74, 0xff, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x7c, 0x29, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 
+0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x37, 0x02, 0xf0, 0xb5, 0x2b, 0x4f, 
+0xb8, 0x68, 0x79, 0x68, 0xc0, 0x19, 0x20, 0x30, 0x29, 0x4a, 0xff, 0xf7, 
+0x55, 0xff, 0x01, 0x20, 0xc0, 0x02, 0x28, 0x49, 0xc0, 0x46, 0x08, 0x60, 
+0xb9, 0x68, 0x38, 0x1c, 0x26, 0x4d, 0x00, 0x24, 0x26, 0x4e, 0xef, 0x1d, 
+0x79, 0x37, 0x00, 0x29, 0x31, 0xd1, 0x31, 0x68, 0x0a, 0x78, 0x12, 0x0a, 
+0x03, 0xd2, 0x04, 0x73, 0xf0, 0xbc, 0x08, 0xbc, 
 0x18, 0x47, 0x49, 0x78, 0x00, 0x29, 0x0c, 0xd1, 0x05, 0x1c, 0x40, 0x68, 
 0x00, 0xf0, 0x3e, 0xf9, 0x30, 0x68, 0x00, 0xf0, 0x67, 0xf8, 0x00, 0x28, 
 0x26, 0xd1, 0x2c, 0x73, 0xff, 0xf7, 0x58, 0xff, 0x22, 0xe0, 0x09, 0x01, 
@@ -2178,85 +2190,85 @@ const u8 typhoon_firmware_image[] = {
 0x98, 0x43, 0x99, 0x04, 0xa8, 0x61, 0x08, 0x61, 0xda, 0xe7, 0x10, 0x20, 
 0x00, 0xf0, 0x20, 0xf9, 0x10, 0x20, 0xb8, 0x60, 0xff, 0xf7, 0x82, 0xff, 
 0xd2, 0xe7, 0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0, 0x17, 0xf9, 0x30, 0x68, 
-0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0, 0x02, 0x23, 0xb8, 0x6b, 
-0x18, 0x43, 0xb8, 0x63, 0xc4, 0xe7, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, 
-0x25, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0, 
-0xe8, 0x0d, 0x00, 0x80, 0x64, 0x01, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, 
-0x85, 0x74, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49, 
-0x00, 0x27, 0x08, 0x60, 0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, 
-0x47, 0x70, 0xe0, 0x69, 0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0, 
-0xd7, 0xf8, 0xe0, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0, 
-0x01, 0x20, 0xe0, 0x61, 0x07, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 
-0x81, 0x63, 0x27, 0x73, 0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa8, 0x04, 0x00, 0x80, 
-0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88, 
-0x6d, 0x28, 0x03, 0xdb, 0x38, 0x1c, 0x00, 0xf0, 0xf7, 0xf8, 0x17, 0xe0, 
-0x80, 0x00, 0x0d, 0x49, 0x09, 0x58, 0x38, 0x1c, 0xff, 0xf7, 0xbd, 0xfe, 
-0x00, 0x28, 0x0f, 0xd1, 0x39, 0x78, 0xc9, 0x09, 0x0c, 0xd3, 0x69, 0x46, 
-0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xf8, 0x68, 0x46, 0x00, 0x21, 0x00, 0xf0, 
-0x0b, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 
-0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x01, 0x00, 0x80, 
-0xf0, 0xb5, 0x82, 0xb0, 0x02, 0x1c, 0x41, 0x4b, 0xdd, 0x1d, 0xff, 0x35, 
-0x3a, 0x35, 0x2f, 0x78, 0x00, 0x2f, 0x01, 0xd0, 0x00, 0x27, 0x00, 0xe0, 
-0x01, 0x27, 0x2f, 0x70, 0x2f, 0x78, 0xfb, 0x00, 0xdb, 0x19, 0x5b, 0x01, 
-0x3a, 0x4f, 0xdc, 0x19, 0x40, 0x78, 0x00, 0x01, 0xc7, 0x1d, 0x09, 0x37, 
-0x00, 0x20, 0x83, 0x00, 0xd6, 0x58, 0xc0, 0x46, 0xe6, 0x50, 0x01, 0x30, 
-0x04, 0x28, 0xf8, 0xd3, 0x00, 0x29, 0x0f, 0xd0, 0x00, 0x22, 0xbb, 0x08, 
-0x01, 0x93, 0x83, 0x42, 0x0b, 0xd9, 0x13, 0x1c, 0x9b, 0x00, 0xcb, 0x58, 
-0x86, 0x00, 0xa3, 0x51, 0x01, 0x9b, 0x01, 0x30, 0x01, 0x32, 0x83, 0x42, 
-0xf5, 0xd8, 0x00, 0xe0, 0x10, 0x27, 0x2b, 0x48, 0x02, 0x6d, 0x80, 0x6e, 
-0x2a, 0x49, 0x82, 0x42, 0x03, 0xd8, 0x82, 0x1a, 0xcb, 0x6c, 0x9a, 0x1a, 
-0x00, 0xe0, 0x12, 0x1a, 0xba, 0x42, 0x05, 0xd8, 0x26, 0x48, 0x81, 0x6b, 
-0x01, 0x31, 0x81, 0x63, 0x01, 0x20, 0x37, 0xe0, 0xc3, 0x19, 0xca, 0x6c, 
-0x93, 0x42, 0x08, 0xd8, 0x22, 0x4a, 0x3a, 0x43, 0x00, 0x92, 0x0a, 0x1c, 
-0x49, 0x6c, 0x09, 0x18, 0x92, 0x6c, 0x23, 0x1c, 0x12, 0xe0, 0x16, 0x1a, 
-0x00, 0x96, 0x1b, 0x49, 0x49, 0x6c, 0x09, 0x18, 0x19, 0x48, 0x82, 0x6c, 
-0x03, 0x20, 0x23, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0xb8, 0x1b, 0x18, 0x4a, 
-0x02, 0x43, 0x00, 0x92, 0xa3, 0x19, 0x14, 0x48, 0x82, 0x6c, 0x41, 0x6c, 
+0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0, 0x02, 0x23, 0xf8, 0x6b, 
+0x18, 0x43, 0xf8, 0x63, 0xc4, 0xe7, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, 
+0x91, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 
+0xe4, 0x01, 0x00, 0x80, 0x0c, 0x55, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, 
+0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49, 0x00, 0x27, 0x08, 0x60, 
+0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x47, 0x70, 0xe0, 0x69, 
+0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0, 0xd7, 0xf8, 0xe0, 0x69, 
+0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0, 0x01, 0x20, 0xe0, 0x61, 
+0x07, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x27, 0x73, 
+0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0x28, 0x05, 0x00, 0x80, 0xe8, 0x0e, 0x00, 0x80, 
+0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88, 0x6d, 0x28, 0x03, 0xdb, 
+0x38, 0x1c, 0x00, 0xf0, 0xf7, 0xf8, 0x17, 0xe0, 0x80, 0x00, 0x0d, 0x49, 
+0x09, 0x58, 0x38, 0x1c, 0xff, 0xf7, 0xbd, 0xfe, 0x00, 0x28, 0x0f, 0xd1, 
+0x39, 0x78, 0xc9, 0x09, 0x0c, 0xd3, 0x69, 0x46, 0x38, 0x1c, 0x00, 0xf0, 
+0xcf, 0xf8, 0x68, 0x46, 0x00, 0x21, 0x00, 0xf0, 0x0b, 0xf8, 0x00, 0x28, 
+0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xe8, 0x01, 0x00, 0x80, 0xf0, 0xb5, 0x82, 0xb0, 
+0x02, 0x1c, 0x41, 0x4b, 0xdd, 0x1d, 0xff, 0x35, 0x3a, 0x35, 0x2f, 0x78, 
+0x00, 0x2f, 0x01, 0xd0, 0x00, 0x27, 0x00, 0xe0, 0x01, 0x27, 0x2f, 0x70, 
+0x2f, 0x78, 0xfb, 0x00, 0xdb, 0x19, 0x5b, 0x01, 0x3a, 0x4f, 0xdc, 0x19, 
+0x40, 0x78, 0x00, 0x01, 0xc7, 0x1d, 0x09, 0x37, 0x00, 0x20, 0x83, 0x00, 
+0xd6, 0x58, 0xc0, 0x46, 0xe6, 0x50, 0x01, 0x30, 0x04, 0x28, 0xf8, 0xd3, 
+0x00, 0x29, 0x0f, 0xd0, 0x00, 0x22, 0xbb, 0x08, 0x01, 0x93, 0x83, 0x42, 
+0x0b, 0xd9, 0x13, 0x1c, 0x9b, 0x00, 0xcb, 0x58, 0x86, 0x00, 0xa3, 0x51, 
+0x01, 0x9b, 0x01, 0x30, 0x01, 0x32, 0x83, 0x42, 0xf5, 0xd8, 0x00, 0xe0, 
+0x10, 0x27, 0x2b, 0x48, 0x02, 0x6d, 0x80, 0x6e, 0x2a, 0x49, 0x82, 0x42, 
+0x03, 0xd8, 0x82, 0x1a, 0xcb, 0x6c, 0x9a, 0x1a, 0x00, 0xe0, 0x12, 0x1a, 
+0xba, 0x42, 0x05, 0xd8, 0x26, 0x48, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 
+0x01, 0x20, 0x37, 0xe0, 0xc3, 0x19, 0xca, 0x6c, 0x93, 0x42, 0x08, 0xd8, 
+0x22, 0x4a, 0x3a, 0x43, 0x00, 0x92, 0x0a, 0x1c, 0x49, 0x6c, 0x09, 0x18, 
+0x92, 0x6c, 0x23, 0x1c, 0x12, 0xe0, 0x16, 0x1a, 0x00, 0x96, 0x1b, 0x49, 
+0x49, 0x6c, 0x09, 0x18, 0x19, 0x48, 0x82, 0x6c, 0x03, 0x20, 0x23, 0x1c, 
+0xff, 0xf7, 0x50, 0xfe, 0xb8, 0x1b, 0x18, 0x4a, 0x02, 0x43, 0x00, 0x92, 
+0xa3, 0x19, 0x14, 0x48, 0x82, 0x6c, 0x41, 0x6c, 
 0x03, 0x20, 0xff, 0xf7, 0x45, 0xfe, 0x01, 0x20, 0x0d, 0x49, 0xc0, 0x46, 
 0x68, 0x70, 0x8a, 0x69, 0x92, 0x00, 0x52, 0x18, 0x17, 0x61, 0x8a, 0x69, 
 0x00, 0x2a, 0x02, 0xd0, 0x00, 0x27, 0x8f, 0x61, 0x00, 0xe0, 0x88, 0x61, 
-0x0c, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x00, 0x20, 
-0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x72, 0x02, 0xb0, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xa8, 0x04, 0x00, 0x80, 0xfc, 0xba, 0x20, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
-0x00, 0x00, 0x19, 0x02, 0x68, 0x0e, 0x00, 0x80, 0x98, 0x19, 0x00, 0x80, 
+0x0c, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x00, 0x20, 
+0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x73, 0x02, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x28, 0x05, 0x00, 0x80, 0xfc, 0xba, 0x20, 0x40, 
+0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x00, 0x00, 0x19, 0x02, 0xe8, 0x0e, 0x00, 0x80, 0x18, 0x1a, 0x00, 0x80, 
 0x07, 0x49, 0x8a, 0x6e, 0x10, 0x18, 0x07, 0x4a, 0xd2, 0x6c, 0x13, 0x04, 
 0x1b, 0x0c, 0x83, 0x42, 0x00, 0xd8, 0x80, 0x1a, 0x88, 0x66, 0x88, 0x6e, 
-0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47, 
-0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 
-0x06, 0x49, 0x4a, 0x6e, 0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42, 
-0x00, 0xd8, 0x80, 0x1a, 0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46, 
-0x08, 0x61, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 
-0x3c, 0xef, 0x20, 0x40, 0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46, 
-0x8a, 0x80, 0x00, 0x22, 0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80, 
-0xca, 0x80, 0x8a, 0x60, 0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60, 
-0x00, 0x22, 0x82, 0x80, 0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60, 
-0xc2, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48, 
-0x41, 0x6b, 0x01, 0x31, 0x41, 0x63, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 
-0xdd, 0xff, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x45, 0x20, 0x00, 0xab, 
-0x18, 0x70, 0x01, 0x27, 0xdf, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
-0x11, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x38, 0x1c, 0x00, 0xe0, 0x00, 0x20, 
-0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xa0, 0x82, 0x20, 0x40, 
-0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x09, 0x4a, 0xc0, 0x46, 0x11, 0x81, 
-0x69, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x01, 0x20, 0x40, 0x02, 0x01, 0xab, 
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xf5, 0xfe, 0x01, 0x20, 
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
-0x00, 0xb5, 0xff, 0xf7, 0xc3, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 
-0x03, 0x49, 0xc0, 0x46, 0x08, 0x70, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 
-0x00, 0x20, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x00, 0x20, 0x04, 0x49, 
-0xc0, 0x46, 0x08, 0x70, 0xff, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x01, 0x31, 
-0x91, 0x60, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x02, 0x20, 0xa1, 0x21, 
-0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x40, 0x02, 
-0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x88, 
-0xc0, 0x06, 0xc0, 0x0e, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x61, 0x02, 0x49, 
-0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 0x70, 0x47, 0x68, 0x1a, 0x00, 0x80, 
-0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0x0f, 0x6b, 0x69, 0x46, 0xff, 0xf7, 
-0x71, 0xff, 0xf8, 0x06, 0xc0, 0x0e, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
-0x00, 0x21, 0xff, 0xf7, 0xa9, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x80, 0x00, 0x14, 0x40, 0x80, 0xb5, 0x85, 0xb0, 
-0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x5b, 0xff, 0xf8, 0x88, 
-0x04, 0xa9, 0x04, 0xf0, 0xef, 0xfd, 0x01, 0xab, 0x58, 0x80, 0x01, 0xa8, 
+0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 
+0x7c, 0x29, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x06, 0x49, 0x4a, 0x6e, 
+0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42, 0x00, 0xd8, 0x80, 0x1a, 
+0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46, 0x08, 0x61, 0x70, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 
+0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46, 0x8a, 0x80, 0x00, 0x22, 
+0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80, 0xca, 0x80, 0x8a, 0x60, 
+0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60, 0x00, 0x22, 0x82, 0x80, 
+0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60, 0xc2, 0x60, 0x70, 0x47, 
+0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48, 0x41, 0x6b, 0x01, 0x31, 
+0x41, 0x63, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0xdd, 0xff, 0x38, 0x68, 
+0xc0, 0x46, 0x00, 0x90, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x01, 0x27, 
+0xdf, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x11, 0xff, 0x00, 0x28, 
+0x01, 0xd1, 0x38, 0x1c, 0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x84, 0xb0, 
+0xc1, 0x88, 0x09, 0x4a, 0xc0, 0x46, 0x91, 0x81, 0x69, 0x46, 0xff, 0xf7, 
+0xbd, 0xff, 0x01, 0x20, 0x40, 0x02, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xff, 0xf7, 0xf5, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xff, 0xf7, 
+0xc3, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0x03, 0x49, 0xc0, 0x46, 
+0x08, 0x71, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 
+0x28, 0x0f, 0x00, 0x80, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 0x08, 0x71, 
+0xff, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x01, 0x31, 0x91, 0x60, 0x70, 0x47, 
+0x28, 0x0f, 0x00, 0x80, 0x02, 0x20, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 
+0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, 
+0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x88, 0xc0, 0x06, 0xc0, 0x0e, 
+0xa1, 0x21, 0x49, 0x03, 0x48, 0x61, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x63, 
+0x00, 0x20, 0x70, 0x47, 0xe8, 0x1a, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 
+0x08, 0x49, 0x0f, 0x6b, 0x69, 0x46, 0xff, 0xf7, 0x71, 0xff, 0xf8, 0x06, 
+0xc0, 0x0e, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0xa9, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x80, 0x00, 0x14, 0x40, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x69, 0x46, 
+0x38, 0x1c, 0xff, 0xf7, 0x5b, 0xff, 0xf8, 0x88, 
+0x04, 0xa9, 0x05, 0xf0, 0xf7, 0xf9, 0x01, 0xab, 0x58, 0x80, 0x01, 0xa8, 
 0x40, 0x88, 0x00, 0x28, 0x0f, 0xd0, 0x01, 0xa8, 0x40, 0x88, 0x80, 0x08, 
 0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x04, 0x3b, 0x58, 0x70, 0x04, 0x98, 
 0x01, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x40, 0x68, 0xc0, 0x46, 0x03, 0x90, 
@@ -2266,52 +2278,54 @@ const u8 typhoon_firmware_image[] = {
 0x90, 0xb5, 0x84, 0xb0, 0x14, 0x4f, 0x39, 0x7b, 0x00, 0x29, 0x20, 0xd1, 
 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x00, 0x29, 0x1a, 0xd1, 
 0x10, 0x49, 0x05, 0x22, 0x00, 0x92, 0x08, 0x22, 0x00, 0xab, 0x5a, 0x80, 
-0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70, 
-0x00, 0x24, 0xdc, 0x80, 0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68, 
-0xc0, 0x46, 0x03, 0x90, 0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31, 
-0xff, 0xf7, 0x4c, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0, 
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, 
-0x10, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 
-0x38, 0x1c, 0xff, 0xf7, 0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48, 
-0x00, 0x2a, 0x05, 0xd1, 0x0d, 0x49, 0xff, 0xf7, 0xd6, 0xfc, 0x00, 0x28, 
-0x0c, 0xda, 0x05, 0xe0, 0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xd1, 0xfc, 
-0x00, 0x28, 0x05, 0xda, 0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21, 
-0xff, 0xf7, 0x22, 0xfe, 0x00, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x15, 0x79, 0x21, 0x40, 
-0x59, 0xcd, 0x21, 0x40, 0xf1, 0xcc, 0x21, 0x40, 0x00, 0xb5, 0xc0, 0x88, 
-0x04, 0xf0, 0x54, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
-0xff, 0xf7, 0xe2, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 
-0xdd, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, 
-0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 
-0x04, 0x1c, 0x08, 0x1c, 0x69, 0x46, 0xff, 0xf7, 0xb5, 0xfe, 0x1b, 0x48, 
-0xff, 0xf7, 0x96, 0xfc, 0x07, 0x1c, 0x00, 0x21, 0x20, 0x1c, 0x03, 0xf0, 
-0x4f, 0xff, 0x00, 0x28, 0x1c, 0xd0, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, 
-0x2d, 0xfe, 0x04, 0x98, 0x04, 0x28, 0x05, 0xd9, 0x04, 0x98, 0x80, 0x08, 
+0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70, 0x00, 0x24, 0xdc, 0x80, 
+0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68, 0xc0, 0x46, 0x03, 0x90, 
+0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31, 0xff, 0xf7, 0x4c, 0xfe, 
+0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, 
+0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 
+0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48, 0x00, 0x2a, 0x05, 0xd1, 
+0x0d, 0x49, 0xff, 0xf7, 0xd6, 0xfc, 0x00, 0x28, 0x0c, 0xda, 0x05, 0xe0, 
+0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xd1, 0xfc, 0x00, 0x28, 0x05, 0xda, 
+0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x22, 0xfe, 
+0x00, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xff, 0xff, 0x00, 0x00, 0x15, 0x79, 0x21, 0x40, 0x8d, 0xd5, 0x21, 0x40, 
+0x25, 0xd5, 0x21, 0x40, 0x00, 0xb5, 0xc0, 0x88, 0x05, 0xf0, 0x5c, 0xf9, 
+0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xe2, 0xfe, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xdd, 0xfe, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, 0x00, 0xf0, 0x02, 0xf8, 
+0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0x04, 0x1c, 0x08, 0x1c, 
+0x69, 0x46, 0xff, 0xf7, 0xb5, 0xfe, 0x1c, 0x48, 0xff, 0xf7, 0x96, 0xfc, 
+0x07, 0x1c, 0x1b, 0x4a, 0x00, 0x21, 0x20, 0x1c, 0xff, 0xf7, 0x92, 0xfc, 
+0x00, 0x28, 0x1d, 0xd0, 0x04, 0xa9, 0x18, 0x4a, 0x20, 0x1c, 0xff, 0xf7, 
+0x8b, 0xfc, 0x04, 0x98, 0x04, 0x28, 0x05, 0xd9, 0x04, 0x98, 0x80, 0x08, 
 0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x00, 0xe0, 0x00, 0x20, 0x00, 0xab, 
 0x58, 0x70, 0x06, 0xa8, 0x00, 0x78, 0xc0, 0x46, 0xd8, 0x80, 0x04, 0x98, 
 0xc0, 0x46, 0x02, 0x90, 0x07, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x04, 0x33, 
-0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 
-0x38, 0x1c, 0xff, 0xf7, 0x6c, 0xfc, 0x68, 0x46, 0x29, 0x1c, 0xff, 0xf7, 
-0xc3, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c, 
-0x02, 0x20, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
-0x01, 0x1c, 0x01, 0x20, 0xff, 0xf7, 0xb2, 0xff, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 
-0x18, 0x47, 0xf3, 0xb5, 0xc6, 0xb0, 0x0f, 0x1c, 0x69, 0x46, 0x38, 0x1c, 
-0xff, 0xf7, 0x5e, 0xfe, 0x1c, 0x48, 0xff, 0xf7, 0x3f, 0xfc, 0xba, 0x68, 
-0x04, 0x1c, 0xfc, 0x2a, 0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, 0xc0, 0x46, 
-0x04, 0x90, 0xf9, 0x1d, 0x09, 0x31, 0x05, 0xab, 0x00, 0x20, 0x7e, 0x78, 
-0x00, 0x2e, 0x0d, 0xdd, 0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 
-0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 0x01, 0x30, 0x00, 0x04, 
-0x00, 0x0c, 0x7e, 0x78, 0x86, 0x42, 0xf1, 0xdc, 0x46, 0x98, 0x04, 0xa9, 
-0x2b, 0x1c, 0xff, 0xf7, 0x2d, 0xfc, 0x00, 0x28, 0x05, 0xd0, 0x00, 0xa8, 
-0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 
-0x20, 0x1c, 0xff, 0xf7, 0x12, 0xfc, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
-0x69, 0xfd, 0x01, 0x20, 0x48, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 
-0x35, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
+0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, 
+0x38, 0x1c, 0xff, 0xf7, 0x6a, 0xfc, 0x68, 0x46, 0x29, 0x1c, 0xff, 0xf7, 
+0xc1, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x24, 0x02, 0xff, 0xff, 0xcd, 0xc0, 0x21, 0x40, 0x29, 0xbf, 0x21, 0x40, 
+0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, 0x00, 0xf0, 
+0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, 
+0xff, 0xf7, 0xac, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 
+0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 
+0xc6, 0xb0, 0x0f, 0x1c, 0x69, 0x46, 0x38, 0x1c, 
+0xff, 0xf7, 0x58, 0xfe, 0x20, 0x48, 0xff, 0xf7, 0x39, 0xfc, 0x04, 0x1c, 
+0x78, 0x78, 0x00, 0x01, 0xba, 0x68, 0x04, 0x30, 0xfc, 0x2a, 0x23, 0xd8, 
+0xff, 0x23, 0x09, 0x33, 0x98, 0x42, 0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, 
+0xc0, 0x46, 0x04, 0x90, 0x05, 0xa9, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, 
+0x7e, 0x78, 0x00, 0x2e, 0x0d, 0xdd, 0x40, 0xcb, 0x40, 0xc1, 0x40, 0xcb, 
+0x40, 0xc1, 0x40, 0xcb, 0x40, 0xc1, 0x40, 0xcb, 0x40, 0xc1, 0x01, 0x30, 
+0x00, 0x04, 0x00, 0x0c, 0x7e, 0x78, 0x86, 0x42, 0xf1, 0xdc, 0x46, 0x98, 
+0x04, 0xa9, 0x2b, 0x1c, 0xff, 0xf7, 0x20, 0xfc, 0x00, 0x28, 0x05, 0xd0, 
+0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 
+0x07, 0x49, 0x20, 0x1c, 0xff, 0xf7, 0x05, 0xfc, 0x68, 0x46, 0x00, 0x21, 
+0xff, 0xf7, 0x5c, 0xfd, 0x01, 0x20, 0x48, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 
+0x00, 0xb5, 0xff, 0xf7, 0x27, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
 0xc6, 0xb0, 0x07, 0x1c, 0xfc, 0x88, 0x25, 0x4d, 0x68, 0x68, 0x01, 0x30, 
-0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7, 0x0f, 0xfe, 0x10, 0x2c, 
+0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7, 0x01, 0xfe, 0x10, 0x2c, 
 0x08, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 
 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x17, 0xe0, 0x78, 0x78, 0x82, 0x00, 
 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, 0xb9, 0x68, 0x00, 0x2a, 0x15, 0xd9, 
@@ -2322,1121 +2336,1275 @@ const u8 typhoon_firmware_image[] = {
 0x02, 0x94, 0x69, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa2, 0x00, 0x00, 0x20, 
 0x10, 0x33, 0x00, 0x2a, 0x05, 0xd9, 0x0f, 0x1c, 0x80, 0xc3, 0x01, 0x30, 
 0x01, 0x31, 0x90, 0x42, 0xf9, 0xd3, 0x68, 0x46, 0x04, 0xa9, 0xff, 0xf7, 
-0x11, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x1c, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x22, 0x48, 0x00, 0x68, 0x01, 0x21, 
+0x03, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x9c, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x23, 0x48, 0x00, 0x68, 0x01, 0x21, 
 0x42, 0x09, 0x00, 0xd3, 0x00, 0x21, 0x00, 0x27, 0x3a, 0x1c, 0x43, 0x0b, 
-0x00, 0xd2, 0x02, 0x22, 0x11, 0x43, 0x1d, 0x4a, 0x20, 0x24, 0xd3, 0x68, 
-0x01, 0x2b, 0x2c, 0xd1, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 
-0x20, 0x1c, 0x1b, 0x23, 0xdb, 0x01, 0xd1, 0x18, 0x09, 0x8b, 0x09, 0x0b, 
-0x00, 0xd2, 0x04, 0x27, 0x38, 0x43, 0xd1, 0x6f, 0x09, 0x0a, 0x06, 0xd2, 
-0xd1, 0x1d, 0x79, 0x31, 0x09, 0x68, 0x09, 0x0a, 0x01, 0xd3, 0x08, 0x23, 
-0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x89, 0x78, 0x03, 0x29, 
-0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 0x0b, 0x49, 0x09, 0x6a, 
-0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, 0x10, 0x43, 0x89, 0x07, 
-0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, 0x70, 0x47, 0x40, 0x0c, 
-0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0xec, 0xe7, 0x00, 0x00, 
-0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, 
-0xf0, 0xb5, 0x33, 0x4d, 0x28, 0x1c, 0x05, 0xf0, 0x6b, 0xf8, 0x32, 0x49, 
-0xe3, 0x23, 0x1b, 0x01, 0xcf, 0x18, 0xba, 0x78, 0x30, 0x4e, 0x00, 0x20, 
-0xcc, 0x1d, 0x79, 0x34, 0x05, 0x2a, 0x53, 0xd2, 0x01, 0xa3, 0x9b, 0x5c, 
-0x5b, 0x00, 0x9f, 0x44, 0x02, 0x0e, 0x23, 0x3c, 0x3e, 0x00, 0x01, 0x21, 
-0xb9, 0x70, 0xb0, 0x60, 0xff, 0xf7, 0x98, 0xff, 0x04, 0x23, 0x98, 0x43, 
-0x00, 0xf0, 0x62, 0xf8, 0x14, 0x22, 0x28, 0x1c, 0x0e, 0xe0, 0xff, 0xf7, 
-0x8f, 0xff, 0xc0, 0x08, 0x06, 0xd3, 0xb1, 0x68, 0x48, 0x1c, 0xb0, 0x60, 
-0x0a, 0x29, 0x03, 0xd9, 0x04, 0x20, 0x00, 0xe0, 0x02, 0x20, 0xb8, 0x70, 
-0x02, 0x22, 0x28, 0x1c, 0x00, 0x21, 0x05, 0xf0, 0x07, 0xf8, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0xc8, 0x6f, 0x18, 0x43, 0xc8, 0x67, 
-0x18, 0x4e, 0xc0, 0x46, 0x30, 0x60, 0x03, 0x20, 0xb8, 0x70, 0x28, 0x1c, 
-0x16, 0x4a, 0x00, 0x21, 0x04, 0xf0, 0xf6, 0xff, 0x11, 0x48, 0x04, 0x23, 
-0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x31, 0x60, 0x20, 0x68, 0x18, 0x43, 
-0x20, 0x60, 0x70, 0x60, 0xe3, 0xe7, 0x05, 0x21, 0xb9, 0x70, 0x51, 0x21, 
-0x89, 0x03, 0x08, 0x62, 0x04, 0x23, 0x20, 0x68, 0x98, 0x43, 0x20, 0x60, 
-0x09, 0x4e, 0xc0, 0x46, 0x70, 0x60, 0xff, 0xf7, 0x55, 0xff, 0x04, 0x23, 
-0x18, 0x43, 0x00, 0xf0, 0x1f, 0xf8, 0xd0, 0xe7, 
-0x06, 0x20, 0xb8, 0x70, 0xcd, 0xe7, 0x00, 0x00, 0x79, 0x7c, 0x21, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0x1c, 0x03, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
-0x88, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 
-0x88, 0x70, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21, 0x04, 0xf0, 0xc0, 0xff, 
-0x08, 0xbc, 0x18, 0x47, 0x18, 0x1c, 0x00, 0x80, 0x79, 0x7c, 0x21, 0x40, 
-0x90, 0xb5, 0x07, 0x1c, 0x30, 0x48, 0x00, 0x68, 0x01, 0x1c, 0x7a, 0x08, 
-0x02, 0xd3, 0x10, 0x23, 0x98, 0x43, 0x01, 0xe0, 0x10, 0x23, 0x18, 0x43, 
-0xba, 0x08, 0x03, 0xd3, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, 0x02, 0xe0, 
-0x01, 0x23, 0x1b, 0x03, 0x18, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x01, 0x21, 
-0x09, 0x05, 0x08, 0x60, 0x25, 0x4c, 0xe0, 0x68, 0x01, 0x28, 0x1e, 0xd1, 
-0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0x00, 0x8b, 0xf9, 0x08, 0x04, 0xd3, 
-0x01, 0x23, 0xdb, 0x02, 0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0, 0x01, 0x21, 
-0xc9, 0x02, 0x81, 0x42, 0x02, 0xd0, 0x00, 0x20, 0x02, 0xf0, 0x20, 0xfe, 
-0x08, 0x21, 0x39, 0x40, 0x1a, 0x48, 0x03, 0xd0, 0x80, 0x23, 0xe1, 0x6f, 
-0x99, 0x43, 0x02, 0xe0, 0x80, 0x23, 0xe1, 0x6f, 0x19, 0x43, 0xe1, 0x67, 
-0x01, 0x60, 0x16, 0x48, 0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, 
+0x00, 0xd2, 0x02, 0x22, 0x11, 0x43, 0x1e, 0x4a, 0x20, 0x24, 0xd3, 0x68, 
+0x01, 0x2b, 0x2e, 0xd1, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 
+0x20, 0x1c, 0x1b, 0x23, 0xdb, 0x01, 0xd1, 0x18, 0x89, 0x8b, 0x09, 0x0b, 
+0x00, 0xd2, 0x04, 0x27, 0x38, 0x43, 0xd1, 0x6f, 0x09, 0x68, 0x09, 0x0a, 
+0x07, 0xd2, 0xd1, 0x1d, 0x79, 0x31, 0x09, 0x68, 0x09, 0x68, 0x09, 0x0a, 
+0x01, 0xd3, 0x08, 0x23, 0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, 
+0x89, 0x79, 0x03, 0x29, 0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 
+0x0b, 0x49, 0x09, 0x6a, 0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, 
+0x10, 0x43, 0x89, 0x07, 0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, 
+0x70, 0x47, 0x40, 0x0c, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 
+0xec, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80, 
+0xc0, 0x00, 0x18, 0x40, 0xf0, 0xb5, 0x3a, 0x4c, 0x20, 0x1c, 0x05, 0xf0, 
+0x75, 0xfc, 0x39, 0x48, 0xe3, 0x23, 0x1b, 0x01, 0xc7, 0x18, 0xb9, 0x79, 
+0x37, 0x4e, 0xc5, 0x1d, 0x79, 0x35, 0x06, 0x29, 0x62, 0xd2, 0x02, 0xa3, 
+0x5b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 
+0x03, 0x0e, 0x1e, 0x37, 0x4e, 0x55, 0x01, 0x20, 0xb8, 0x71, 0x00, 0x20, 
+0xb0, 0x60, 0xff, 0xf7, 0x95, 0xff, 0x05, 0x23, 0x98, 0x43, 0x00, 0xf0, 
+0x6f, 0xf8, 0x0c, 0xe0, 0xff, 0xf7, 0x8e, 0xff, 0xc0, 0x08, 0x06, 0xd3, 
+0xb0, 0x68, 0x41, 0x1c, 0xb1, 0x60, 0x0a, 0x28, 0x03, 0xd9, 0x04, 0x20, 
+0x00, 0xe0, 0x02, 0x20, 0xb8, 0x71, 0x64, 0x22, 0x20, 0x1c, 0x2b, 0xe0, 
+0x06, 0x1c, 0xc0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 
+0x03, 0x20, 0xb8, 0x71, 0x20, 0x1c, 0x20, 0x4a, 0x00, 0x21, 0x05, 0xf0, 
+0x07, 0xfc, 0xf0, 0x6f, 0x04, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 
+0x28, 0x68, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x05, 0x21, 0xb9, 0x71, 0x29, 0x68, 0x04, 0x23, 0x0a, 0x68, 
+0x9a, 0x43, 0x0a, 0x60, 0xc0, 0x6f, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 
+0xff, 0xf7, 0x5a, 0xff, 0x08, 0x23, 0x18, 0x43, 0x00, 0xf0, 0x34, 0xf8, 
+0x20, 0x1c, 0x10, 0x4a, 0x00, 0x21, 0x05, 0xf0, 0xe5, 0xfb, 0xe5, 0xe7, 
+0xff, 0xf7, 0x4e, 0xff, 0x04, 0x23, 0x18, 0x43, 0x00, 0xf0, 0x28, 0xf8, 
+0xde, 0xe7, 0x00, 0x20, 0x29, 0x68, 0x60, 0x23, 0x0a, 0x68, 0x9a, 0x43, 
+0x0a, 0x60, 0xff, 0xf7, 0xe1, 0xfa, 0xd5, 0xe7, 0x06, 0x20, 0xb8, 0x71, 
+0xd2, 0xe7, 0x00, 0x00, 0x99, 0x7c, 0x21, 0x40, 0x68, 0x0e, 0x00, 0x80, 
+0x9c, 0x03, 0x00, 0x80, 0x30, 0x75, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 
+0x00, 0xb5, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 0x88, 0x71, 0x04, 0x48, 
+0x01, 0x22, 0x00, 0x21, 0x05, 0xf0, 0xbc, 0xfb, 0x08, 0xbc, 0x18, 0x47, 
+0x98, 0x1c, 0x00, 0x80, 0x99, 0x7c, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, 
+0x31, 0x48, 0x00, 0x68, 0x79, 0x08, 0x03, 0xd3, 0x10, 0x23, 0x01, 0x1c, 
+0x99, 0x43, 0x01, 0xe0, 0x10, 0x21, 0x01, 0x43, 0x2d, 0x4c, 0xe2, 0x68, 
+0x01, 0x2a, 0x05, 0xd1, 0x22, 0x79, 0x00, 0x2a, 0x02, 0xd0, 0x01, 0x23, 
+0x9b, 0x02, 0x19, 0x43, 0x81, 0x42, 0x02, 0xd0, 0x01, 0x20, 0x00, 0x05, 
+0x01, 0x60, 0xe0, 0x68, 0x01, 0x28, 0x20, 0xd1, 0x1b, 0x23, 0xdb, 0x01, 
+0xe0, 0x18, 0x80, 0x8b, 0xf9, 0x08, 0x04, 0xd3, 0x01, 0x23, 0xdb, 0x02, 
+0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0, 0x01, 0x21, 0xc9, 0x02, 0x81, 0x42, 
+0x02, 0xd0, 0x00, 0x20, 0x03, 0xf0, 0xca, 0xf9, 0x38, 0x09, 0x07, 0xd3, 
+0xe0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xe0, 0x18, 
+0x00, 0x68, 0x00, 0xe0, 0xe0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 
+0x01, 0x60, 0x15, 0x48, 0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, 
 0x01, 0x30, 0x08, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x08, 0x1c, 0x01, 0x33, 
 0x98, 0x43, 0x80, 0x08, 0x80, 0x00, 0xba, 0x09, 0x92, 0x07, 0x92, 0x0f, 
-0x10, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x62, 
+0x10, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x0c, 0x49, 0xc0, 0x46, 0x08, 0x62, 
 0xe1, 0x68, 0x01, 0x29, 0x08, 0xd1, 0x79, 0x0a, 0x06, 0xd3, 0xff, 0x23, 
-0x04, 0x33, 0x18, 0x40, 0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x90, 0xff, 
+0x04, 0x33, 0x18, 0x40, 0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x8e, 0xff, 
 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x40, 
-0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xff, 0xf7, 0xc1, 0xfe, 0x80, 0x09, 
-0x12, 0xd2, 0x0b, 0x48, 0x41, 0x78, 0x00, 0x29, 0x0e, 0xd1, 0x01, 0x21, 
-0x41, 0x70, 0x00, 0x27, 0x08, 0x48, 0x06, 0xe0, 0x02, 0x20, 0x03, 0xf0, 
-0x03, 0xf8, 0x07, 0x20, 0x02, 0xf0, 0xd2, 0xff, 0x38, 0x1c, 0xff, 0xf7, 
-0x5b, 0xfa, 0xf5, 0xe7, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x18, 0x1c, 0x00, 0x80, 0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 
-0x69, 0x46, 0xff, 0xf7, 0x69, 0xfc, 0xff, 0xf7, 0x9d, 0xfe, 0x01, 0xab, 
-0x58, 0x80, 0x08, 0x48, 0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x48, 
-0x00, 0x6a, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
-0x99, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, 0x80, 0xb5, 0x84, 0xb0, 
-0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x49, 0xfc, 0xf8, 0x88, 
-0xff, 0xf7, 0x4a, 0xff, 0xff, 0xf7, 0x7a, 0xfe, 0x01, 0xab, 0x58, 0x80, 
-0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7e, 0xfb, 0x01, 0x20, 0x04, 0xb0, 
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0xc7, 0x88, 
-0x69, 0x46, 0xff, 0xf7, 0x33, 0xfc, 0x01, 0x24, 0x63, 0x02, 0x9f, 0x42, 
-0x0a, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 
-0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x16, 0xe0, 
-0x0e, 0x48, 0xff, 0xf7, 0x05, 0xfa, 0x05, 0x1c, 0x38, 0x1c, 0x04, 0xa9, 
-0x03, 0xf0, 0xa2, 0xfb, 0x0b, 0x49, 0x28, 0x1c, 
-0xff, 0xf7, 0xfd, 0xf9, 0x10, 0x20, 0x00, 0xab, 0x58, 0x70, 0x04, 0x98, 
-0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 
-0x06, 0xa9, 0xff, 0xf7, 0x4b, 0xfb, 0x20, 0x1c, 0x46, 0xb0, 0xb0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 
+0x68, 0x0e, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 
+0x80, 0xb5, 0xff, 0xf7, 0xb1, 0xfe, 0x80, 0x09, 0x1b, 0xd2, 0x0f, 0x48, 
+0xe3, 0x23, 0x1b, 0x01, 0xc1, 0x18, 0x4a, 0x79, 0x00, 0x2a, 0x14, 0xd1, 
+0x01, 0x22, 0x4a, 0x71, 0x00, 0x27, 0x80, 0x30, 0x00, 0x68, 0x60, 0x23, 
+0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0x08, 0x48, 
+0x06, 0xe0, 0x02, 0x20, 0x03, 0xf0, 0x7e, 0xfb, 0x07, 0x20, 0x03, 0xf0, 
+0x4d, 0xfb, 0x38, 0x1c, 0xff, 0xf7, 0x34, 0xfa, 0xf5, 0xe7, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xf4, 0x01, 0xff, 0xff, 
+0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, 0x43, 0xfc, 0xff, 0xf7, 
+0x85, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x08, 0x48, 0x00, 0x68, 0xc0, 0x46, 
+0x02, 0x90, 0x07, 0x48, 0x00, 0x6a, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 
+0x00, 0x21, 0xff, 0xf7, 0x73, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, 
+0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 
+0x23, 0xfc, 0xf8, 0x88, 0xff, 0xf7, 0x42, 0xff, 0xff, 0xf7, 0x62, 0xfe, 
+0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x58, 0xfb, 
+0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 
+0xc6, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7, 0x0d, 0xfc, 0x01, 0x24, 
+0x16, 0x4b, 0x9f, 0x42, 0x0a, 0xd9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 
+0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0x17, 0xe0, 0x10, 0x48, 0xff, 0xf7, 0xdf, 0xf9, 0x05, 0x1c, 
+0x0f, 0x4a, 0x38, 0x1c, 0x04, 0xa9, 0xff, 0xf7, 0xdb, 0xf9, 0x0e, 0x49, 
+0x28, 0x1c, 0xff, 0xf7, 0xd6, 0xf9, 0x10, 0x20, 0x00, 0xab, 0x58, 0x70, 
+0x04, 0x98, 0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46, 0x03, 0x90, 
+0x68, 0x46, 0x06, 0xa9, 0xff, 0xf7, 0x24, 0xfb, 0x20, 0x1c, 0x46, 0xb0, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 
+0x24, 0x02, 0xff, 0xff, 0x29, 0xbf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, 
 0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 
-0xfb, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x02, 0xd1, 
+0xcf, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x02, 0xd1, 
 0x43, 0x01, 0x9c, 0x42, 0x09, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 
 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x04, 0x33, 
-0x2c, 0xe0, 0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, 
+0x27, 0xe0, 0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, 
 0x05, 0x90, 0x06, 0xaa, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x21, 0x78, 0x78, 
 0x00, 0x28, 0x0d, 0xdd, 0x00, 0x20, 0x40, 0xcb, 0x40, 0xc2, 0x01, 0x30, 
 0x00, 0x04, 0x00, 0x0c, 0x04, 0x28, 0xf8, 0xdb, 0x48, 0x1c, 0x01, 0x04, 
-0x09, 0x0c, 0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0d, 0x48, 0xff, 0xf7, 
-0xaf, 0xf9, 0x06, 0x1c, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, 0x76, 0xfb, 
-0x0a, 0x49, 0x30, 0x1c, 0xff, 0xf7, 0xa7, 0xf9, 0x38, 0x68, 0xc0, 0x46, 
-0x00, 0x90, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 0x68, 0x46, 0x00, 0x21, 
-0xff, 0xf7, 0xf8, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 
-0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27, 0xe6, 0x88, 0xa2, 0x68, 
-0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x2e, 0x01, 0xd0, 
-0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0, 0x04, 0x2e, 0x00, 0xd1, 
-0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e, 0x66, 0xd2, 0x02, 0xa3, 
-0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x03, 0x06, 0x08, 0x0c, 
-0x10, 0x00, 0x85, 0x83, 0x00, 0x23, 0x03, 0xe0, 0x85, 0x83, 0x05, 0xe0, 
-0x00, 0x23, 0x83, 0x83, 0xc3, 0x83, 0x06, 0xe0, 0x00, 0x23, 0x83, 0x83, 
-0xc5, 0x83, 0x02, 0xe0, 0xff, 0x23, 0x01, 0x33, 0x83, 0x83, 0xcb, 0x1d, 
-0x79, 0x33, 0x1e, 0x89, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x02, 0xdb, 
-0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xe0, 0x01, 0x22, 0x6d, 0x23, 0x5b, 0x01, 
-0xc9, 0x18, 0x09, 0x88, 0xff, 0x23, 0xe1, 0x33, 0x99, 0x43, 0x01, 0x23, 
-0x19, 0x43, 0x86, 0x8b, 0xff, 0x33, 0x9e, 0x42, 0x0d, 0xd1, 0xff, 0x20, 
-0xe1, 0x30, 0x08, 0x43, 0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0x9b, 0x02, 
-0x98, 0x43, 0x01, 0x1c, 0x20, 0xe0, 0x01, 0x21, 0x89, 0x02, 0x01, 0x43, 
-0x1c, 0xe0, 0x01, 0x2e, 0x0a, 0xd1, 0xc0, 0x8b, 0x01, 0x28, 0x04, 0xd1, 
-0x60, 0x23, 0x19, 0x43, 0x00, 0x2a, 0x13, 0xd0, 0x0c, 0xe0, 0x20, 0x23, 
-0x19, 0x43, 0x0f, 0xe0, 0x00, 0x2e, 0x0d, 0xd1, 0xc0, 0x8b, 0x01, 0x28, 
-0x08, 0xd1, 0xff, 0x23, 0x81, 0x33, 0x19, 0x43, 0x00, 0x2a, 0x05, 0xd0, 
-0x01, 0x23, 0x9b, 0x02, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, 
-0x04, 0x20, 0x02, 0xf0, 0x8d, 0xfc, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 
-0x02, 0xf0, 0x88, 0xfc, 0x00, 0x2f, 0x02, 0xd1, 0x00, 0x20, 0x12, 0xe0, 
-0xff, 0xe7, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x2b, 0xfb, 0x00, 0xa8, 
-0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 
-0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0x5e, 0xfa, 
-0x28, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 
-0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, 
-0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x07, 0xd1, 0x37, 0x23, 
-0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x21, 0x01, 0x43, 0x1b, 0x20, 
-0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x21, 
-0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0, 0x4b, 0xfc, 0x01, 0x20, 
-0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x88, 0x83, 0xc8, 0x83, 0x1b, 0x23, 
-0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, 
-0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0x38, 0xfc, 
-0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
-0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x37, 0x23, 
-0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x23, 0x98, 0x43, 0x01, 0x1c, 
-0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, 
-0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c, 0x10, 0x20, 0x02, 0xf0, 
-0x19, 0xfc, 0xff, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x01, 0x30, 
-0x88, 0x83, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x41, 0x23, 
-0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02, 0x01, 0x43, 0x00, 0x20, 
-0x02, 0xf0, 0x06, 0xfc, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0xcf, 0x6a, 
-0x69, 0x46, 0xff, 0xf7, 0xa5, 0xfa, 0xb8, 0x05, 0x80, 0x0d, 0x01, 0xab, 
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xdd, 0xf9, 0x01, 0x20, 
-0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 
-0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49, 0xc9, 0x6a, 0x1b, 0x23, 
-0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49, 0xc0, 0x46, 0xc8, 0x62, 
-0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x00, 
-0x80, 0xb5, 0x84, 0xb0, 0x0d, 0x49, 0x0f, 0x6a, 0x01, 0x2f, 0x01, 0xd1, 
-0xff, 0x03, 0x07, 0xe0, 0x02, 0x2f, 0x01, 0xd1, 0x3f, 0x03, 0x03, 0xe0, 
-0x00, 0x2f, 0x01, 0xd1, 0x01, 0x27, 0xff, 0x02, 0x69, 0x46, 0xff, 0xf7, 
-0x71, 0xfa, 0x01, 0xab, 0x5f, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
-0xab, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0x20, 0x14, 0x40, 0xc2, 0x88, 0xa1, 0x20, 0x40, 0x03, 0x00, 0x21, 
-0x01, 0x23, 0x5b, 0x03, 0x9a, 0x42, 0x01, 0xd1, 0x02, 0x22, 0x04, 0xe0, 
-0x01, 0x23, 0xdb, 0x03, 0x9a, 0x42, 0x02, 0xd1, 0x01, 0x22, 0x02, 0x62, 
-0x00, 0xe0, 0x01, 0x62, 0x08, 0x1c, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 
-0x07, 0x1c, 0x02, 0xf0, 0xb7, 0xfb, 0x69, 0x46, 0x04, 0x1c, 0x38, 0x1c, 
-0xff, 0xf7, 0x46, 0xfa, 0x01, 0xab, 0x5c, 0x80, 0x09, 0x4f, 0xf8, 0x6d, 
-0xc0, 0x46, 0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7c, 0xf9, 
-0xf8, 0x6d, 0xc0, 0x07, 0xc0, 0x0f, 0x05, 0x49, 0xc0, 0x46, 0x88, 0x62, 
+0x09, 0x0c, 0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0a, 0x48, 0xff, 0xf7, 
+0x83, 0xf9, 0x07, 0x1c, 0x09, 0x4a, 0x20, 0x1c, 0x04, 0xa9, 0xff, 0xf7, 
+0x7f, 0xf9, 0x08, 0x49, 0x38, 0x1c, 0xff, 0xf7, 0x7a, 0xf9, 0x68, 0x46, 
+0x00, 0x21, 0xff, 0xf7, 0xd1, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x51, 0xbf, 0x21, 0x40, 
+0x3c, 0x02, 0xff, 0xff, 0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27, 
+0xe6, 0x88, 0xa2, 0x68, 0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0, 
+0x00, 0x2e, 0x01, 0xd0, 0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0, 
+0x04, 0x2e, 0x00, 0xd1, 0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e, 
+0x66, 0xd2, 0x02, 0xa3, 0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 
+0x03, 0x06, 0x08, 0x0c, 0x10, 0x00, 0x05, 0x80, 0x00, 0x23, 0x03, 0xe0, 
+0x05, 0x80, 0x05, 0xe0, 0x00, 0x23, 0x03, 0x80, 0x43, 0x80, 0x06, 0xe0, 
+0x00, 0x23, 0x03, 0x80, 0x45, 0x80, 0x02, 0xe0, 
+0xff, 0x23, 0x01, 0x33, 0x03, 0x80, 0xcb, 0x1d, 0x79, 0x33, 0x9e, 0x89, 
+0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x02, 0xdb, 0xd2, 0x07, 0xd2, 0x0f, 
+0x00, 0xe0, 0x01, 0x22, 0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x89, 0x88, 
+0xff, 0x23, 0xe1, 0x33, 0x99, 0x43, 0x01, 0x23, 0x19, 0x43, 0x06, 0x88, 
+0xff, 0x33, 0x9e, 0x42, 0x0d, 0xd1, 0xff, 0x20, 0xe1, 0x30, 0x08, 0x43, 
+0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0x9b, 0x02, 0x98, 0x43, 0x01, 0x1c, 
+0x20, 0xe0, 0x01, 0x21, 0x89, 0x02, 0x01, 0x43, 0x1c, 0xe0, 0x01, 0x2e, 
+0x0a, 0xd1, 0x40, 0x88, 0x01, 0x28, 0x04, 0xd1, 0x60, 0x23, 0x19, 0x43, 
+0x00, 0x2a, 0x13, 0xd0, 0x0c, 0xe0, 0x20, 0x23, 0x19, 0x43, 0x0f, 0xe0, 
+0x00, 0x2e, 0x0d, 0xd1, 0x40, 0x88, 0x01, 0x28, 0x08, 0xd1, 0xff, 0x23, 
+0x81, 0x33, 0x19, 0x43, 0x00, 0x2a, 0x05, 0xd0, 0x01, 0x23, 0x9b, 0x02, 
+0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, 0x04, 0x20, 0x03, 0xf0, 
+0x2d, 0xf8, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0x03, 0xf0, 0x28, 0xf8, 
+0x00, 0x2f, 0x02, 0xd1, 0x00, 0x20, 0x12, 0xe0, 0xff, 0xe7, 0x69, 0x46, 
+0x20, 0x1c, 0xff, 0xf7, 0x03, 0xfb, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 
+0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0x36, 0xfa, 0x28, 0x1c, 0x04, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
+0x88, 0x1c, 0x00, 0x80, 0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62, 
+0x00, 0x20, 0x70, 0x47, 0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28, 
+0x07, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x21, 
+0x01, 0x43, 0x1b, 0x20, 0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 
+0x80, 0x8b, 0x01, 0x21, 0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0, 
+0xeb, 0xff, 0x01, 0x20, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x80, 
+0x48, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23, 
+0x1b, 0x03, 0x98, 0x43, 0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20, 
+0x02, 0xf0, 0xd8, 0xff, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28, 
+0x08, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x23, 
+0x98, 0x43, 0x01, 0x1c, 0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 
+0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c, 
+0x10, 0x20, 0x02, 0xf0, 0xb9, 0xff, 0xff, 0x20, 0x71, 0x23, 0x5b, 0x01, 
+0xf9, 0x18, 0x01, 0x30, 0x08, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 
+0x80, 0x8b, 0x41, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02, 
+0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0xa6, 0xff, 0x00, 0x20, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 
+0x08, 0x49, 0xcf, 0x6a, 0x69, 0x46, 0xff, 0xf7, 0x7d, 0xfa, 0xb8, 0x05, 
+0x80, 0x0d, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0xb5, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x40, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49, 
+0xc9, 0x6a, 0x1b, 0x23, 0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49, 
+0xc0, 0x46, 0xc8, 0x62, 0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40, 
+0x40, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, 
+0x0d, 0x49, 0x0f, 0x6a, 0x01, 0x2f, 0x01, 0xd1, 0xff, 0x03, 0x07, 0xe0, 
+0x02, 0x2f, 0x01, 0xd1, 0x3f, 0x03, 0x03, 0xe0, 0x00, 0x2f, 0x01, 0xd1, 
+0x01, 0x27, 0xff, 0x02, 0x69, 0x46, 0xff, 0xf7, 0x49, 0xfa, 0x01, 0xab, 
+0x5f, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x83, 0xf9, 0x01, 0x20, 
+0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x14, 0x40, 
+0xc2, 0x88, 0xa1, 0x20, 0x40, 0x03, 0x00, 0x21, 0x01, 0x23, 0x5b, 0x03, 
+0x9a, 0x42, 0x01, 0xd1, 0x02, 0x22, 0x04, 0xe0, 0x01, 0x23, 0xdb, 0x03, 
+0x9a, 0x42, 0x02, 0xd1, 0x01, 0x22, 0x02, 0x62, 0x00, 0xe0, 0x01, 0x62, 
+0x08, 0x1c, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x02, 0xf0, 
+0x57, 0xff, 0x69, 0x46, 0x04, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x1e, 0xfa, 
+0x01, 0xab, 0x5c, 0x80, 0x09, 0x4f, 0xf8, 0x6d, 0xc0, 0x46, 0x02, 0x90, 
+0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x54, 0xf9, 0xf8, 0x6d, 0xc0, 0x07, 
+0xc0, 0x0f, 0x05, 0x49, 0xc0, 0x46, 0xc8, 0x62, 0x01, 0x20, 0x04, 0xb0, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 
+0x68, 0x1c, 0x00, 0x80, 0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x48, 0x61, 
+0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, 
+0x69, 0x46, 0xff, 0xf7, 0xf7, 0xf9, 0x06, 0x48, 0xc0, 0x68, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x2f, 0xf9, 0x01, 0x20, 
+0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 
+0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47, 
+0x80, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68, 
+0xff, 0xf7, 0xda, 0xf9, 0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49, 
+0x40, 0x18, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x80, 0x8b, 0x06, 0xe0, 
+0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 
+0x02, 0x20, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0x03, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68, 
+0x20, 0x2a, 0x04, 0xd2, 0x10, 0x1c, 0x02, 0xf0, 0xcf, 0xfe, 0x00, 0x20, 
+0x10, 0xe0, 0x69, 0x46, 0xff, 0xf7, 0xae, 0xf9, 0x00, 0xa8, 0x00, 0x78, 
+0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 
+0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0xe1, 0xf8, 0x01, 0x20, 
+0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 
+0x69, 0x46, 0xff, 0xf7, 0x97, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x78, 0xff, 
+0x02, 0x20, 0x39, 0x1c, 0x03, 0xf0, 0x3c, 0xfe, 0x00, 0x28, 0x06, 0xd0, 
+0x02, 0x20, 0x39, 0x1c, 0x03, 0xf0, 0x8c, 0xfd, 0x01, 0xab, 0x58, 0x80, 
+0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c, 
+0xfe, 0xf7, 0x65, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xbc, 0xf8, 
 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x10, 0x2a, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 0xc0, 0x88, 0x02, 0x49, 
-0xc0, 0x46, 0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 
-0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, 0x1f, 0xfa, 0x06, 0x48, 
-0xc0, 0x68, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
-0x00, 0x21, 0xff, 0xf7, 0x57, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 
-0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 
-0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68, 0xff, 0xf7, 0x02, 0xfa, 
-0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49, 0x40, 0x18, 0x1b, 0x23, 
-0xdb, 0x01, 0xc0, 0x18, 0x00, 0x8b, 0x06, 0xe0, 0x00, 0xa8, 0x00, 0x78, 
-0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0x01, 0xab, 
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x2b, 0xf9, 0x01, 0x20, 
-0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68, 0x20, 0x2a, 0x04, 0xd2, 
-0x10, 0x1c, 0x02, 0xf0, 0x2f, 0xfb, 0x00, 0x20, 0x10, 0xe0, 0x69, 0x46, 
-0xff, 0xf7, 0xd6, 0xf9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 
-0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 
-0x04, 0x33, 0xff, 0xf7, 0x09, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
-0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7, 
-0xbf, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0xa0, 0xff, 0x02, 0x20, 0x39, 0x1c, 
-0x03, 0xf0, 0x5a, 0xfa, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x20, 0x39, 0x1c, 
-0x03, 0xf0, 0x94, 0xf9, 0x01, 0xab, 0x58, 0x80, 0x02, 0xe0, 0x45, 0x20, 
-0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c, 0xfe, 0xf7, 0x8d, 0xff, 
-0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xe4, 0xf8, 0x01, 0x20, 0x04, 0xb0, 
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 
-0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, 
-0x84, 0x68, 0xff, 0xf7, 0x93, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x74, 0xff, 
-0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7, 0x71, 0xff, 0x00, 0x28, 
-0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c, 0x22, 0x1c, 0xfe, 0xf7, 
-0x6a, 0xff, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, 
-0x28, 0x1c, 0xfe, 0xf7, 0x60, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
-0xb7, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x24, 0x02, 0xff, 0xff, 0xb9, 0xb8, 0x21, 0x40, 0x7b, 0xb7, 0x21, 0x40, 
-0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0x7f, 0xf9, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x80, 0xb4, 0xc2, 0x88, 0x19, 0x4b, 
-0xa1, 0x21, 0x49, 0x03, 0x00, 0x2a, 0x03, 0xd1, 0x18, 0x6b, 0x10, 0x23, 
-0x98, 0x43, 0x04, 0xe0, 0x01, 0x2a, 0x04, 0xd1, 0x18, 0x6b, 0x10, 0x23, 
-0x18, 0x43, 0x48, 0x61, 0x1f, 0xe0, 0x02, 0x2a, 0x1d, 0xd1, 0xc2, 0x68, 
-0x87, 0x68, 0x00, 0x20, 0x3b, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 
-0x9b, 0x02, 0x03, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 
-0x20, 0x28, 0xf3, 0xdb, 0x00, 0x20, 0x13, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 
-0xdb, 0x0f, 0x9b, 0x02, 0xc7, 0x1d, 0x19, 0x37, 0x3b, 0x43, 0x0b, 0x61, 
-0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf1, 0xdb, 0x00, 0x20, 
-0x80, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x40, 0x90, 0xb4, 0xc2, 0x88, 
-0x81, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x10, 0x43, 0x02, 0x04, 0x12, 0x0c, 
-0x0f, 0x48, 0xc0, 0x46, 0x02, 0x60, 0x0f, 0x4f, 0x65, 0x23, 0x5b, 0x01, 
-0xfb, 0x18, 0x9a, 0x83, 0x0a, 0x0c, 0x14, 0x02, 
-0x12, 0x12, 0x22, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0xda, 0x83, 
+0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0, 
+0xc7, 0x88, 0x69, 0x46, 0x84, 0x68, 0xff, 0xf7, 0x6b, 0xf9, 0x10, 0x48, 
+0xfe, 0xf7, 0x4c, 0xff, 0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7, 
+0x49, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c, 
+0x22, 0x1c, 0xfe, 0xf7, 0x42, 0xff, 0x02, 0xe0, 
+0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, 0x28, 0x1c, 0xfe, 0xf7, 
+0x38, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x8f, 0xf8, 0x01, 0x20, 
+0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 
+0xcd, 0xc0, 0x21, 0x40, 0xd9, 0xbf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, 
+0x00, 0xb5, 0xff, 0xf7, 0x57, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 
+0x70, 0x47, 0x80, 0xb4, 0xc2, 0x88, 0x19, 0x4b, 0xa1, 0x21, 0x49, 0x03, 
+0x00, 0x2a, 0x03, 0xd1, 0x18, 0x6b, 0x10, 0x23, 0x98, 0x43, 0x04, 0xe0, 
+0x01, 0x2a, 0x04, 0xd1, 0x18, 0x6b, 0x10, 0x23, 0x18, 0x43, 0x48, 0x61, 
+0x1f, 0xe0, 0x02, 0x2a, 0x1d, 0xd1, 0xc2, 0x68, 0x87, 0x68, 0x00, 0x20, 
+0x3b, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, 0x03, 0x43, 
+0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf3, 0xdb, 
+0x00, 0x20, 0x13, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, 
+0xc7, 0x1d, 0x19, 0x37, 0x3b, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 
+0x00, 0x0c, 0x20, 0x28, 0xf1, 0xdb, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 
+0x80, 0x00, 0x14, 0x40, 0x80, 0xb4, 0xc2, 0x88, 0x81, 0x68, 0x10, 0x02, 
+0x12, 0x0a, 0x10, 0x43, 0x02, 0x04, 0x12, 0x0c, 0x0c, 0x48, 0xc0, 0x46, 
+0x02, 0x60, 0x0c, 0x4b, 0xc0, 0x46, 0x1a, 0x80, 0x0a, 0x0c, 0x17, 0x02, 
+0x12, 0x12, 0x3a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0x5a, 0x80, 
 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x0a, 0x11, 0x43, 0x09, 0x04, 
-0x09, 0x0c, 0x81, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x01, 0x80, 
-0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 
-0xe8, 0x0d, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0, 0x13, 0x49, 0x0a, 0x68, 
-0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, 0x4a, 0x68, 
-0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, 
-0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, 
-0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c, 0xff, 0xf7, 0xe4, 0xf8, 
-0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43, 0x02, 0x90, 0x68, 0x46, 
-0x00, 0x21, 0xff, 0xf7, 0x1b, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 0xc1, 0x88, 0x82, 0x68, 
-0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x0a, 0x49, 
-0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02, 0x00, 0x12, 0x18, 0x43, 
-0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04, 0x00, 0x0c, 0x02, 0x02, 
-0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x48, 0x61, 0x00, 0x20, 
-0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb5, 0x84, 0xb0, 
-0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, 
-0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c, 0x17, 0x02, 0x12, 0x12, 
-0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c, 0x1f, 0x02, 0x1b, 0x12, 
-0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23, 0x00, 0x93, 0x84, 0x88, 
-0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b, 0x5c, 0x70, 0x40, 0x88, 
-0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04, 0x38, 0x43, 0x02, 0x90, 
-0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xcb, 0xff, 0x01, 0x20, 
-0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 
-0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a, 0x05, 0x21, 0x00, 0x91, 
-0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 
-0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 
-0x68, 0x46, 0xfe, 0xf7, 0xaf, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 
-0xc0, 0x46, 0x88, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 
-0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x0a, 0x6a, 0x05, 0x21, 0x00, 0x91, 
-0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 
-0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 
-0x68, 0x46, 0xfe, 0xf7, 0x8b, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 
-0xc0, 0x46, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 
-0x00, 0xb5, 0xc0, 0x88, 0x02, 0x49, 0xfe, 0xf7, 0x1c, 0xfe, 0x00, 0x20, 
-0x08, 0xbc, 0x18, 0x47, 0x75, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 
-0x69, 0x46, 0xff, 0xf7, 0x2d, 0xf8, 0x06, 0x48, 0x00, 0x6b, 0x01, 0xab, 
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x65, 0xff, 0x01, 0x20, 
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0xb5, 0xff, 0xf7, 0x33, 0xf8, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x2e, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0xb5, 0xff, 0xf7, 0x29, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 
-0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x71, 
-0x12, 0x48, 0xfe, 0xf7, 0xe9, 0xfd, 0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 
-0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, 0x08, 0x70, 
-0x0d, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, 0x12, 0x21, 
-0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 0x12, 0x68, 
-0x92, 0x0a, 0x05, 0xd3, 0x07, 0x4a, 0xc0, 0x46, 0xd1, 0x60, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x05, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0xf8, 0xe7, 
-0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, 0x00, 0x00, 0x10, 0x40, 
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x02, 0xf0, 
-0x83, 0xfb, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 
-0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0x88, 0xfc, 0x00, 0x28, 0x0c, 0xd1, 
-0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xc8, 0xff, 0x06, 0x48, 0x01, 0xab, 
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x01, 0xff, 0x01, 0x20, 
+0x09, 0x0c, 0x81, 0x60, 0x99, 0x80, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 
+0x40, 0x00, 0x14, 0x00, 0x28, 0x1b, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0, 
+0x13, 0x49, 0x0a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12, 
+0x13, 0x43, 0x4a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02, 
+0x12, 0x12, 0x13, 0x43, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 
+0x09, 0x12, 0x11, 0x43, 0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c, 
+0xff, 0xf7, 0xc2, 0xf8, 0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43, 
+0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xf9, 0xff, 0x01, 0x20, 
+0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 
+0xc1, 0x88, 0x82, 0x68, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04, 
+0x00, 0x0c, 0x0a, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02, 
+0x00, 0x12, 0x18, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04, 
+0x00, 0x0c, 0x02, 0x02, 0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c, 
+0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 
+0x90, 0xb5, 0x84, 0xb0, 0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c, 
+0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c, 
+0x17, 0x02, 0x12, 0x12, 0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c, 
+0x1f, 0x02, 0x1b, 0x12, 0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23, 
+0x00, 0x93, 0x84, 0x88, 0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b, 
+0x5c, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04, 
+0x38, 0x43, 0x02, 0x90, 0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 
+0xa9, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x40, 0x00, 0x14, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a, 
+0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, 
+0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, 
+0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, 
+0x8d, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x88, 0x62, 
+0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, 
+0x0b, 0x49, 0x0a, 0x6a, 0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, 
+0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, 
+0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, 
+0x69, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x62, 
+0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0xc0, 0x88, 
+0x02, 0x49, 0xfe, 0xf7, 0xfa, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 
+0x75, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, 
+0x0b, 0xf8, 0x06, 0x48, 0x00, 0x6b, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xfe, 0xf7, 0x43, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xff, 0xf7, 
+0x11, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x0c, 0xf8, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x07, 0xf8, 0x08, 0xbc, 
+0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0x10, 0x48, 0xfe, 0xf7, 0xcc, 0xfd, 
+0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x21, 
+0x0c, 0x48, 0xc0, 0x46, 0x01, 0x71, 0x0c, 0x48, 0x02, 0x68, 0x52, 0x0c, 
+0x05, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 
+0x03, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc7, 0x60, 0x02, 0xe0, 0x07, 0x48, 
+0xc0, 0x46, 0x07, 0x64, 0x08, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x21, 0xa5, 0x21, 0x40, 0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 
+0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20, 
+0x03, 0x49, 0xc0, 0x46, 0x08, 0x72, 0x12, 0x20, 0xff, 0xf7, 0xcb, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20, 
+0x03, 0x49, 0xc0, 0x46, 0x48, 0x72, 0x15, 0x20, 0xff, 0xf7, 0xbf, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x02, 0xf0, 
+0xf3, 0xfe, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 
+0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0xf8, 0xff, 0x00, 0x28, 0x0c, 0xd1, 
+0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x96, 0xff, 0x06, 0x48, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xcf, 0xfe, 0x01, 0x20, 
 0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
 0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, 
-0xb3, 0xff, 0x03, 0xf0, 0x71, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x09, 0x48, 
+0x81, 0xff, 0x04, 0xf0, 0x47, 0xfa, 0x01, 0xab, 0x58, 0x80, 0x09, 0x48, 
 0x81, 0x89, 0x09, 0x04, 0xc2, 0x89, 0x11, 0x43, 0x02, 0x91, 0x81, 0x88, 
 0x09, 0x04, 0xc0, 0x88, 0x08, 0x43, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 
-0xfe, 0xf7, 0xe0, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 
-0xc8, 0x29, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0xaf, 0xff, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xaa, 0xff, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0xb5, 0xfe, 0xf7, 0xa5, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
-0xfe, 0xf7, 0xa0, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
-0x9b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x96, 0xff, 
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x91, 0xff, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x8c, 0xff, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0xb5, 0xfe, 0xf7, 0x87, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
-0xfe, 0xf7, 0x82, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
-0x7d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x78, 0xff, 
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x73, 0xff, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, 0x08, 0xa9, 0xfe, 0xf7, 0x54, 0xff, 
-0x69, 0x46, 0x08, 0xa8, 0x03, 0xf0, 0xba, 0xfe, 0x02, 0x20, 0x08, 0xab, 
-0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, 0xfe, 0xf7, 0x89, 0xfe, 0x01, 0x20, 
-0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x5a, 0xff, 
-0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 
-0x38, 0x1c, 0xfe, 0xf7, 0x39, 0xff, 0xf9, 0x88, 0x10, 0x48, 0x01, 0x24, 
-0x00, 0x29, 0x0e, 0xd0, 0x04, 0x73, 0x44, 0x73, 0xb9, 0x68, 0x09, 0x0c, 
-0x41, 0x82, 0xb9, 0x68, 0xc0, 0x46, 0x81, 0x82, 0xf9, 0x68, 0x09, 0x0c, 
-0xc1, 0x82, 0xf9, 0x68, 0xc0, 0x46, 0x01, 0x83, 0x02, 0xe0, 0x00, 0x21, 
-0x01, 0x73, 0x41, 0x73, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
-0x00, 0x21, 0xfe, 0xf7, 0x5b, 0xfe, 0x20, 0x1c, 
-0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 
-0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0xfe, 0xf7, 0x27, 0xff, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x22, 0xff, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
-0xfe, 0xf7, 0x18, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
-0x13, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 
-0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xf2, 0xfe, 0xf8, 0x88, 0x03, 0x24, 
-0xe4, 0x04, 0x04, 0x43, 0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, 
-0x0f, 0x4b, 0x9c, 0x42, 0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, 
-0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x20, 0xfe, 0x01, 0x20, 0x80, 0x07, 
-0x20, 0x43, 0x00, 0x68, 0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, 
-0xc0, 0x46, 0xda, 0x80, 0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, 
-0xfe, 0xf7, 0x10, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 
+0xfe, 0xf7, 0xae, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 
+0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0x7d, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x78, 0xff, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xfe, 0xf7, 0x73, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x6e, 0xff, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xfe, 0xf7, 0x69, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0xfe, 0xf7, 0x64, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
+0x5f, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x5a, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x55, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x50, 0xff, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xfe, 0xf7, 0x4b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0xfe, 0xf7, 0x46, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, 
+0x08, 0xa9, 0xfe, 0xf7, 0x27, 0xff, 0x69, 0x46, 0x08, 0xa8, 0x04, 0xf0, 
+0x75, 0xfa, 0x02, 0x20, 0x08, 0xab, 0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, 
+0xfe, 0xf7, 0x5c, 0xfe, 0x01, 0x20, 0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xfe, 0xf7, 0x2d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 
+0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x0c, 0xff, 
+0xfa, 0x88, 0x12, 0x49, 0x01, 0x24, 0xc8, 0x1d, 0x89, 0x30, 0x00, 0x2a, 
+0x0f, 0xd0, 0x04, 0x70, 0x44, 0x70, 0xb8, 0x68, 0x00, 0x0c, 0x80, 0x31, 
+0xc8, 0x82, 0xb8, 0x68, 0xc0, 0x46, 0x08, 0x83, 0xf8, 0x68, 0x00, 0x0c, 
+0x48, 0x83, 0xf8, 0x68, 0xc0, 0x46, 0x88, 0x83, 0x02, 0xe0, 0x00, 0x21, 
+0x01, 0x70, 0x41, 0x70, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xfe, 0xf7, 0x2b, 0xfe, 0x20, 0x1c, 0x04, 0xb0, 0x90, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 
+0x00, 0xb5, 0xfe, 0xf7, 0xf7, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0xfe, 0xf7, 0xf2, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
+0xed, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xe8, 0xfe, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xe3, 0xfe, 0x08, 0xbc, 
+0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 
+0xfe, 0xf7, 0xc2, 0xfe, 0xf8, 0x88, 0x03, 0x24, 0xe4, 0x04, 0x04, 0x43, 
+0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, 0x0f, 0x4b, 0x9c, 0x42, 
+0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 
+0xfe, 0xf7, 0xf0, 0xfd, 0x01, 0x20, 0x80, 0x07, 0x20, 0x43, 0x00, 0x68, 
+0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, 0xc0, 0x46, 0xda, 0x80, 
+0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, 0xfe, 0xf7, 0xe0, 0xfd, 
+0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x84, 0xb0, 
+0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x8f, 0xfe, 0xf8, 0x88, 
+0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, 0x02, 0xd3, 0x0a, 0x4b, 
+0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xfe, 0xf7, 0xbf, 0xfd, 0x01, 0x20, 0x03, 0xe0, 0xb9, 0x68, 
+0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 
 0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, 
-0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 
-0xbf, 0xfe, 0xf8, 0x88, 0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, 
-0x02, 0xd3, 0x0a, 0x4b, 0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, 
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xef, 0xfd, 0x01, 0x20, 
-0x03, 0xe0, 0xb9, 0x68, 0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, 
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 
-0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x03, 0xf0, 
-0x5b, 0xfd, 0x38, 0x1c, 0x02, 0xa9, 0xfe, 0xf7, 0x97, 0xfe, 0x01, 0x27, 
-0x02, 0xab, 0x5f, 0x70, 0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x01, 0x68, 
-0xc0, 0x46, 0x04, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x05, 0x91, 0x81, 0x68, 
-0xc0, 0x46, 0x00, 0x91, 0x00, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46, 
-0x02, 0xa8, 0xfe, 0xf7, 0xc1, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68, 
-0x80, 0x68, 0xfe, 0xf7, 0x79, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 
+0x80, 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x04, 0xf0, 0x33, 0xf9, 0x38, 0x1c, 
+0x02, 0xa9, 0xfe, 0xf7, 0x67, 0xfe, 0x01, 0x27, 0x02, 0xab, 0x5f, 0x70, 
+0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x41, 0x68, 0xc0, 0x46, 0x04, 0x91, 
+0x81, 0x68, 0xc0, 0x46, 0x05, 0x91, 0xc1, 0x68, 
+0xc0, 0x46, 0x00, 0x91, 0x40, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46, 
+0x02, 0xa8, 0xfe, 0xf7, 0x91, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x19, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68, 
+0x80, 0x68, 0xfe, 0xf7, 0x49, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 
 0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, 
-0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x76, 0xfe, 0x01, 0xab, 0x5c, 0x80, 
-0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa1, 0xfd, 0x04, 0xb0, 
+0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x46, 0xfe, 0x01, 0xab, 0x5c, 0x80, 
+0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x71, 0xfd, 0x04, 0xb0, 
 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 
-0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x64, 0xfe, 0x01, 0xab, 0x5f, 0x80, 
-0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x90, 0xfd, 0x04, 0xb0, 0x80, 0xbc, 
+0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x34, 0xfe, 0x01, 0xab, 0x5f, 0x80, 
+0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x60, 0xfd, 0x04, 0xb0, 0x80, 0xbc, 
 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 
 0x90, 0xb5, 0x84, 0xb0, 0x00, 0x27, 0x12, 0x49, 0x09, 0x68, 0x12, 0x4a, 
 0x12, 0x6b, 0x10, 0x23, 0x1a, 0x40, 0x01, 0x24, 0x00, 0x2a, 0x00, 0xd0, 
 0x01, 0x27, 0x8a, 0x0c, 0x03, 0xd3, 0x3a, 0x04, 0x12, 0x0c, 0x02, 0x27, 
 0x17, 0x43, 0xc9, 0x0c, 0x03, 0xd3, 0x39, 0x04, 0x09, 0x0c, 0x04, 0x27, 
-0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0x2c, 0xfe, 0x01, 0xab, 0x5f, 0x80, 
-0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x66, 0xfd, 0x20, 0x1c, 0x04, 0xb0, 
+0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0xfc, 0xfd, 0x01, 0xab, 0x5f, 0x80, 
+0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x36, 0xfd, 0x20, 0x1c, 0x04, 0xb0, 
 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
-0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0, 
-0x69, 0x46, 0xfe, 0xf7, 0x17, 0xfe, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab, 
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x4f, 0xfd, 0x01, 0x20, 
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 
-0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47, 
-0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 
-0x80, 0xb5, 0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 
-0x48, 0x71, 0x13, 0x48, 0xfe, 0xf7, 0xd6, 0xfb, 0x01, 0x20, 0x40, 0x02, 
-0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, 
-0x08, 0x70, 0x0e, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, 
-0x15, 0x21, 0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 
-0x12, 0x68, 0x92, 0x0a, 0x05, 0xd3, 0x08, 0x4a, 0xc0, 0x46, 0xd1, 0x60, 
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, 
-0xf8, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, 
-0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 
+0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, 
+0xe7, 0xfd, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xfe, 0xf7, 0x1f, 0xfd, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 
+0xed, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 
 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 
-0x80, 0xb5, 0x85, 0xb0, 0x01, 0xa9, 0xfe, 0xf7, 0xbb, 0xfd, 0x00, 0x20, 
-0x01, 0xab, 0x58, 0x70, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29, 
-0x0a, 0xd1, 0x03, 0xf0, 0xb9, 0xfc, 0x03, 0x90, 0x04, 0x97, 0x03, 0x98, 
-0x00, 0x28, 0x06, 0xd0, 0x68, 0x46, 0x02, 0xf0, 0x15, 0xf8, 0x04, 0xe0, 
-0x03, 0x97, 0x04, 0x90, 0xf8, 0xe7, 0x00, 0x20, 0x00, 0x90, 0x02, 0xab, 
-0x00, 0x98, 0xc0, 0x46, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, 
-0xdb, 0xfc, 0x38, 0x1c, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 
-0x38, 0x1c, 0xfe, 0xf7, 0x8d, 0xfd, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 
-0x01, 0x24, 0x20, 0x1c, 0x12, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 
-0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x13, 0xd0, 0xf8, 0x88, 0x0f, 0x4a, 
-0x90, 0x42, 0x02, 0xd0, 0x0e, 0x4b, 0x98, 0x42, 0x08, 0xd1, 0xb9, 0x68, 
-0x27, 0x1c, 0x90, 0x42, 0x00, 0xd0, 0x00, 0x27, 0x38, 0x06, 0x00, 0x0e, 
-0x03, 0xf0, 0xa0, 0xfc, 0x03, 0xf0, 0x76, 0xfc, 0x02, 0x90, 0x00, 0xe0, 
-0x02, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa7, 0xfc, 0x20, 0x1c, 
-0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
-0xed, 0xfe, 0x00, 0x00, 0xfe, 0xca, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, 
-0x00, 0x24, 0x00, 0x2f, 0x04, 0xd3, 0x04, 0xf0, 0x9b, 0xf8, 0x01, 0x34, 
-0xbc, 0x42, 0xfa, 0xd9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
-0x14, 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0x1f, 0x1c, 0x1b, 0x4b, 0x32, 0x04, 
-0x12, 0x0c, 0x3c, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x2a, 0xfb, 0x32, 0x0c, 
-0x17, 0x4b, 0x3e, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x24, 0xfb, 0x15, 0x4b, 
-0x2a, 0x04, 0x12, 0x0c, 0x40, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x1d, 0xfb, 
-0x2a, 0x0c, 0x11, 0x4b, 0x42, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x17, 0xfb, 
-0x0e, 0x4b, 0x22, 0x04, 0x12, 0x0c, 0x44, 0x21, 0x02, 0x20, 0xfe, 0xf7, 
-0x10, 0xfb, 0x22, 0x0c, 0x0a, 0x4b, 0x46, 0x21, 0x02, 0x20, 0xfe, 0xf7, 
-0x0a, 0xfb, 0x08, 0x4b, 0x3a, 0x04, 0x12, 0x0c, 0x48, 0x21, 0x02, 0x20, 
-0xfe, 0xf7, 0x03, 0xfb, 0x3a, 0x0c, 0x04, 0x4b, 
-0x4a, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0xfd, 0xfa, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x7b, 0xb7, 0x21, 0x40, 0x88, 0xb5, 0x11, 0x27, 
-0x3f, 0x04, 0x38, 0x62, 0x79, 0x62, 0xba, 0x62, 0xfb, 0x62, 0x04, 0x20, 
-0xff, 0xf7, 0xaa, 0xff, 0x07, 0x48, 0x40, 0x6b, 0xc0, 0x46, 0x00, 0x90, 
-0x00, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x01, 0xd1, 0x01, 0x20, 
-0x00, 0xe0, 0x00, 0x20, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x00, 0x00, 0x11, 0x40, 0xf0, 0xb5, 0x8a, 0xb0, 0x00, 0x24, 0x05, 0x94, 
-0x69, 0x49, 0xc9, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x68, 0x4a, 0x11, 0x68, 
-0x01, 0x22, 0x12, 0x04, 0x0a, 0x40, 0x17, 0x21, 0x66, 0x4e, 0x00, 0x2a, 
-0x06, 0xd1, 0x64, 0x4a, 0x13, 0x68, 0x1b, 0x0c, 0x04, 0xd1, 0x12, 0x68, 
-0x92, 0x0a, 0x01, 0xd3, 0xf1, 0x60, 0x02, 0xe0, 0x61, 0x4a, 0xc0, 0x46, 
-0x11, 0x64, 0x61, 0x49, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x03, 0x29, 
-0x54, 0xd1, 0xe9, 0x21, 0x01, 0x91, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, 
-0x06, 0x94, 0x06, 0x99, 0x8a, 0x00, 0x5b, 0x49, 0x8a, 0x58, 0x00, 0x2a, 
-0x73, 0xd0, 0x80, 0x20, 0x02, 0x90, 0x06, 0x98, 0x81, 0x00, 0x57, 0x48, 
-0x41, 0x58, 0x02, 0x9a, 0x11, 0x43, 0x02, 0x91, 0x00, 0x24, 0x00, 0x27, 
-0x25, 0x02, 0x28, 0x1c, 0x38, 0x43, 0x09, 0x90, 0x09, 0x98, 0x00, 0x04, 
-0x51, 0x4b, 0x18, 0x43, 0x04, 0x90, 0x09, 0x98, 0xef, 0x23, 0xdb, 0x05, 
-0x18, 0x43, 0x03, 0x90, 0x06, 0x98, 0x80, 0x00, 0x4b, 0x49, 0x08, 0x58, 
-0x00, 0x04, 0x03, 0x99, 0x08, 0x43, 0x03, 0x90, 0x00, 0x2f, 0x02, 0xd1, 
-0x03, 0x98, 0xc0, 0x46, 0x70, 0x60, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 
-0x04, 0x98, 0xff, 0xf7, 0x89, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x99, 
-0xc0, 0x46, 0xb1, 0x60, 0x03, 0x99, 0xc0, 0x46, 0x71, 0x60, 0x5c, 0xe0, 
-0x79, 0x1c, 0x0f, 0x04, 0x3f, 0x0c, 0x17, 0x2f, 0xd1, 0xdd, 0x61, 0x1c, 
-0x0c, 0x04, 0x24, 0x0c, 0x16, 0x2c, 0xca, 0xdd, 0x06, 0x99, 0x01, 0x31, 
-0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 0x37, 0x4a, 0x51, 0x58, 0x00, 0x29, 
-0xb7, 0xd1, 0x48, 0xe0, 0xbf, 0x21, 0xc9, 0x43, 0x04, 0x91, 0xff, 0x21, 
-0x02, 0x91, 0x97, 0x21, 0x01, 0x91, 0x06, 0x94, 0x06, 0x99, 0x89, 0x00, 
-0x31, 0x4f, 0x79, 0x58, 0x00, 0x29, 0x1c, 0xd0, 0x09, 0x94, 0x08, 0x94, 
-0x06, 0x98, 0x80, 0x00, 0x38, 0x58, 0xc0, 0x46, 0x07, 0x90, 0x07, 0x98, 
-0x00, 0x04, 0x26, 0xe0, 0x05, 0x98, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 
-0x03, 0x90, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, 
-0x49, 0xff, 0x00, 0x28, 0x23, 0xd1, 0x09, 0x99, 0x01, 0x31, 0x09, 0x91, 
-0x17, 0x29, 0x06, 0xd8, 0x00, 0xe0, 0x1c, 0xe0, 0x08, 0x98, 0x00, 0x02, 
-0x09, 0x99, 0x08, 0x43, 0x07, 0xe0, 0x08, 0x99, 0x01, 0x31, 0x08, 0x91, 
-0x17, 0x29, 0x0a, 0xd8, 0x09, 0x94, 0x08, 0x98, 0x00, 0x02, 0x07, 0x99, 
-0x09, 0x04, 0x08, 0x43, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x05, 0x90, 
-0xd6, 0xe7, 0x06, 0x99, 0x01, 0x31, 0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 
-0x79, 0x58, 0x00, 0x29, 0xc4, 0xd1, 0x0c, 0x4a, 0x11, 0x68, 0x49, 0x0c, 
-0x05, 0xd2, 0x11, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x11, 0x68, 0x89, 0x0a, 
-0x03, 0xd3, 0x00, 0x99, 0xc0, 0x46, 0xf1, 0x60, 0x03, 0xe0, 0x00, 0x99, 
-0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x40, 0x01, 0x18, 0x40, 
-0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 
-0x00, 0x00, 0x18, 0x40, 0x30, 0x6e, 0x21, 0x40, 0x43, 0xff, 0x00, 0x00, 
-0x0c, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x82, 0xb0, 0x00, 0x20, 0x01, 0x90, 
-0x1e, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x1b, 0xd1, 0x40, 0x88, 0x00, 0x28, 
-0x18, 0xd1, 0x68, 0x46, 0x01, 0xf0, 0x6a, 0xfe, 0x00, 0x28, 0x13, 0xd1, 
-0xa8, 0x20, 0x01, 0xf0, 0xab, 0xfe, 0x18, 0x4f, 0x00, 0x28, 0x11, 0xd0, 
-0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0x78, 0x6b, 0xc0, 0x46, 0x01, 0x90, 
-0x01, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x06, 0xd1, 0x00, 0x20, 
-0x01, 0xf0, 0x9a, 0xfe, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x8f, 0xfe, 
-0x00, 0x23, 0xdb, 0x43, 0x18, 0x1c, 0x19, 0x1c, 0x1a, 0x1c, 0xff, 0xf7, 
-0xc7, 0xfe, 0x00, 0x28, 0x03, 0xd1, 0xff, 0xf7, 0xdf, 0xfe, 0x00, 0x28, 
-0xe5, 0xd0, 0x38, 0x6a, 0x79, 0x6a, 0xba, 0x6a, 0xfb, 0x6a, 0xff, 0xf7, 
-0x7c, 0xfe, 0xde, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x11, 0x40, 
-0xff, 0xb5, 0x85, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 
-0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x82, 0xe0, 
-0x26, 0x1c, 0x43, 0x4d, 0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, 
-0x09, 0x05, 0x41, 0x48, 0x41, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, 
-0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, 0x3e, 0x4a, 0x51, 0x69, 
-0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0xff, 0x23, 
-0x01, 0x33, 0x19, 0x43, 0x39, 0x4b, 0xc0, 0x46, 0x59, 0x61, 0xff, 0x23, 
-0x01, 0x33, 0x9a, 0x43, 0x36, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 
-0x12, 0x05, 0xd1, 0x60, 0x33, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 
-0x11, 0x61, 0x31, 0x4a, 0xff, 0x23, 0x01, 0x33, 0x91, 0x69, 0x19, 0x43, 
-0x91, 0x61, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x85, 0x21, 0x89, 0x04, 
-0x04, 0x91, 0x00, 0x2f, 0x34, 0xd0, 0x28, 0x48, 0x86, 0x42, 0x04, 0xd1, 
-0x30, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0xd5, 0xfe, 0x2a, 0x1c, 
-0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x01, 0x20, 0x06, 0x99, 0x05, 0x9a, 
-0x33, 0x1c, 0xfe, 0xf7, 0x5d, 0xf9, 0x22, 0x48, 0x22, 0x49, 0x4a, 0x68, 
-0x52, 0x0a, 0x09, 0xd3, 0xff, 0x21, 0x01, 0x31, 0x20, 0x4a, 0xc0, 0x46, 
-0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x13, 0xe0, 
-0x01, 0x38, 0xf0, 0xd1, 0xf9, 0xe7, 0x7f, 0x1b, 0x0e, 0xd0, 0x15, 0x48, 
-0x86, 0x42, 0x01, 0xd1, 0x64, 0x19, 0x00, 0xe0, 0x76, 0x19, 0x06, 0x99, 
-0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 
-0x05, 0x1c, 0xca, 0xe7, 0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 
-0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 
-0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 
-0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 
-0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
+0xdb, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x80, 0xb5, 0x85, 0xb0, 
+0x01, 0xa9, 0xfe, 0xf7, 0xbb, 0xfd, 0x00, 0x20, 0x01, 0xab, 0x58, 0x70, 
+0x10, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29, 0x0a, 0xd1, 0x04, 0xf0, 
+0xc7, 0xf8, 0x03, 0x90, 0x04, 0x97, 0x03, 0x98, 0x00, 0x28, 0x06, 0xd0, 
+0x68, 0x46, 0x02, 0xf0, 0xe5, 0xfb, 0x04, 0xe0, 0x03, 0x97, 0x04, 0x90, 
+0xf8, 0xe7, 0x00, 0x20, 0x00, 0x90, 0x02, 0xab, 0x00, 0x98, 0xc0, 0x46, 
+0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, 0xdb, 0xfc, 0x38, 0x1c, 
+0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 
+0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 
+0x8d, 0xfd, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 0x01, 0x24, 0x20, 0x1c, 
+0x12, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 0x00, 0x20, 0x00, 0x06, 
+0x00, 0x0e, 0x13, 0xd0, 0xf8, 0x88, 0x0f, 0x4a, 0x90, 0x42, 0x02, 0xd0, 
+0x0e, 0x4b, 0x98, 0x42, 0x08, 0xd1, 0xb9, 0x68, 0x27, 0x1c, 0x90, 0x42, 
+0x00, 0xd0, 0x00, 0x27, 0x38, 0x06, 0x00, 0x0e, 0x04, 0xf0, 0x88, 0xf8, 
+0x04, 0xf0, 0x84, 0xf8, 0x02, 0x90, 0x00, 0xe0, 0x02, 0x94, 0x68, 0x46, 
+0x00, 0x21, 0xfe, 0xf7, 0xa7, 0xfc, 0x20, 0x1c, 0x04, 0xb0, 0x90, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xed, 0xfe, 0x00, 0x00, 
+0xfe, 0xca, 0x00, 0x00, 0xf1, 0xb5, 0xd6, 0xb0, 
+0x00, 0x20, 0x81, 0x00, 0x56, 0x9c, 0x0a, 0x19, 0x12, 0x6a, 0x6b, 0x46, 
+0x5a, 0x50, 0x01, 0x30, 0x10, 0x28, 0xf6, 0xdb, 0x10, 0x20, 0x82, 0x00, 
+0x11, 0x1c, 0x69, 0x44, 0x40, 0x39, 0x4b, 0x6b, 0x0f, 0x6a, 0x7b, 0x40, 
+0x8f, 0x68, 0x7b, 0x40, 0x09, 0x68, 0x59, 0x40, 0x4b, 0x00, 0xc9, 0x0f, 
+0x19, 0x43, 0x6b, 0x46, 0x99, 0x50, 0x01, 0x30, 0x50, 0x28, 0xec, 0xdb, 
+0x56, 0x98, 0x01, 0x68, 0xc0, 0x46, 0x55, 0x91, 0x42, 0x68, 0xc0, 0x46, 
+0x54, 0x92, 0x86, 0x68, 0xc0, 0x46, 0x53, 0x96, 0xc5, 0x68, 0xc0, 0x46, 
+0x52, 0x95, 0x04, 0x69, 0xc0, 0x46, 0x51, 0x94, 0x48, 0x01, 0xcb, 0x0e, 
+0x18, 0x43, 0x13, 0x1c, 0x33, 0x40, 0x07, 0x1c, 0x28, 0x1c, 0x90, 0x43, 
+0x18, 0x43, 0x38, 0x18, 0x00, 0x19, 0x00, 0x9b, 0xc0, 0x18, 0xcf, 0x4b, 
+0xc0, 0x18, 0x93, 0x07, 0x92, 0x08, 0x13, 0x43, 0x42, 0x01, 0x1f, 0x1c, 
+0xc3, 0x0e, 0x1a, 0x43, 0x0b, 0x1c, 0x3b, 0x40, 0x14, 0x1c, 0x32, 0x1c, 
+0x8a, 0x43, 0x1a, 0x43, 0xa2, 0x18, 0x52, 0x19, 0x01, 0x9b, 0xd2, 0x18, 
+0xc5, 0x4b, 0xd4, 0x18, 0x8a, 0x07, 0x89, 0x08, 0x11, 0x43, 0x62, 0x01, 
+0xe3, 0x0e, 0x1a, 0x43, 0x03, 0x1c, 0x0b, 0x40, 0x15, 0x1c, 0x3a, 0x1c, 
+0x82, 0x43, 0x1a, 0x43, 0xaa, 0x18, 0x92, 0x19, 0x02, 0x9b, 0xd2, 0x18, 
+0xbc, 0x4b, 0xd2, 0x18, 0x3b, 0x1c, 0x87, 0x07, 0x80, 0x08, 0x38, 0x43, 
+0x57, 0x01, 0xd5, 0x0e, 0x3d, 0x43, 0x27, 0x1c, 0x07, 0x40, 0x0e, 0x1c, 
+0xa6, 0x43, 0x37, 0x43, 0xed, 0x19, 0xeb, 0x18, 0x03, 0x9f, 0xdf, 0x19, 
+0xb3, 0x4b, 0xff, 0x18, 0xa3, 0x07, 0xa4, 0x08, 0x1c, 0x43, 0x7b, 0x01, 
+0xfd, 0x0e, 0x2b, 0x43, 0x15, 0x1c, 0x25, 0x40, 0x1e, 0x1c, 0x03, 0x1c, 
+0x93, 0x43, 0x2b, 0x43, 0xf3, 0x18, 0x59, 0x18, 0x04, 0x9b, 0xc9, 0x18, 
+0xaa, 0x4b, 0xc9, 0x18, 0x93, 0x07, 0x92, 0x08, 0x1a, 0x43, 0x4b, 0x01, 
+0xcd, 0x0e, 0x1d, 0x43, 0x3e, 0x1c, 0x16, 0x40, 0x23, 0x1c, 0xbb, 0x43, 
+0x33, 0x43, 0xeb, 0x18, 0x18, 0x18, 0x05, 0x9b, 0xc0, 0x18, 0xa2, 0x4b, 
+0xc0, 0x18, 0xbb, 0x07, 0xbf, 0x08, 0x1f, 0x43, 0x43, 0x01, 0xc5, 0x0e, 
+0x2b, 0x43, 0x0d, 0x1c, 0x3d, 0x40, 0x1e, 0x1c, 0x13, 0x1c, 0x8b, 0x43, 
+0x2b, 0x43, 0xf3, 0x18, 0x1b, 0x19, 0x06, 0x9c, 0x1c, 0x19, 0x99, 0x4b, 
+0xe4, 0x18, 0x8b, 0x07, 0x89, 0x08, 0x19, 0x43, 0x63, 0x01, 0xe5, 0x0e, 
+0x1d, 0x43, 0x03, 0x1c, 0x0b, 0x40, 0x3e, 0x1c, 0x86, 0x43, 0x33, 0x43, 
+0xeb, 0x18, 0x9a, 0x18, 0x07, 0x9b, 0xd2, 0x18, 0x90, 0x4b, 0xd2, 0x18, 
+0x3b, 0x1c, 0x87, 0x07, 0x80, 0x08, 0x38, 0x43, 0x57, 0x01, 0xd5, 0x0e, 
+0x2f, 0x43, 0x25, 0x1c, 0x05, 0x40, 0x3e, 0x1c, 0x0f, 0x1c, 0xa7, 0x43, 
+0x2f, 0x43, 0xf5, 0x19, 0xeb, 0x18, 0x08, 0x9f, 0xdf, 0x19, 0x87, 0x4b, 
+0xff, 0x18, 0xa3, 0x07, 0xa4, 0x08, 0x1c, 0x43, 0x7b, 0x01, 0xfd, 0x0e, 
+0x1d, 0x43, 0x16, 0x1c, 0x26, 0x40, 0x03, 0x1c, 0x93, 0x43, 0x33, 0x43, 
+0xeb, 0x18, 0x59, 0x18, 0x09, 0x9b, 0xc9, 0x18, 0x7e, 0x4b, 0xc9, 0x18, 
+0x93, 0x07, 0x92, 0x08, 0x1a, 0x43, 0x4b, 0x01, 0xcd, 0x0e, 0x1d, 0x43, 
+0x3b, 0x1c, 0x13, 0x40, 0x26, 0x1c, 0xbe, 0x43, 0x33, 0x43, 0xeb, 0x18, 
+0x18, 0x18, 0x0a, 0x9b, 0xc0, 0x18, 0x76, 0x4b, 0xc0, 0x18, 0x23, 0x1c, 
+0xbc, 0x07, 0xbf, 0x08, 0x27, 0x43, 0x44, 0x01, 0xc5, 0x0e, 0x2c, 0x43, 
+0x0d, 0x1c, 0x3d, 0x40, 0x26, 0x1c, 0x14, 0x1c, 0x8c, 0x43, 0x2c, 0x43, 
+0x35, 0x19, 0xeb, 0x18, 0x0b, 0x9c, 0x1c, 0x19, 
+0x6c, 0x4b, 0xe4, 0x18, 0x8b, 0x07, 0x89, 0x08, 0x19, 0x43, 0x63, 0x01, 
+0xe5, 0x0e, 0x1d, 0x43, 0x03, 0x1c, 0x0b, 0x40, 0x3e, 0x1c, 0x86, 0x43, 
+0x33, 0x43, 0xeb, 0x18, 0x9a, 0x18, 0x0c, 0x9b, 0xd2, 0x18, 0x64, 0x4b, 
+0xd2, 0x18, 0x3b, 0x1c, 0x87, 0x07, 0x80, 0x08, 0x38, 0x43, 0x57, 0x01, 
+0xd5, 0x0e, 0x3d, 0x43, 0x27, 0x1c, 0x07, 0x40, 0x0e, 0x1c, 0xa6, 0x43, 
+0x37, 0x43, 0xed, 0x19, 0xeb, 0x18, 0x0d, 0x9f, 0xdf, 0x19, 0x5b, 0x4b, 
+0xff, 0x18, 0xa3, 0x07, 0xa4, 0x08, 0x1c, 0x43, 0x7b, 0x01, 0xfd, 0x0e, 
+0x1d, 0x43, 0x13, 0x1c, 0x23, 0x40, 0x06, 0x1c, 0x96, 0x43, 0x33, 0x43, 
+0xeb, 0x18, 0x59, 0x18, 0x0e, 0x9b, 0xc9, 0x18, 0x52, 0x4b, 0xc9, 0x18, 
+0x93, 0x07, 0x92, 0x08, 0x1a, 0x43, 0x4b, 0x01, 0xcd, 0x0e, 0x2b, 0x43, 
+0x3d, 0x1c, 0x15, 0x40, 0x1e, 0x1c, 0x23, 0x1c, 0xbb, 0x43, 0x2b, 0x43, 
+0xf3, 0x18, 0x18, 0x18, 0x0f, 0x9b, 0xc0, 0x18, 0x49, 0x4b, 0xc0, 0x18, 
+0x23, 0x1c, 0xbc, 0x07, 0xbf, 0x08, 0x27, 0x43, 0x10, 0x24, 0x50, 0x94, 
+0x44, 0x01, 0xc5, 0x0e, 0x25, 0x43, 0x0e, 0x1c, 0x3e, 0x40, 0x14, 0x1c, 
+0x8c, 0x43, 0x34, 0x43, 0x2c, 0x19, 0xe3, 0x18, 0x50, 0x9c, 0xa5, 0x00, 
+0x6c, 0x46, 0x64, 0x59, 0x1c, 0x19, 0x3e, 0x4b, 0xe4, 0x18, 0x13, 0x1c, 
+0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, 0x0f, 0x43, 0x01, 0x1c, 0x20, 0x1c, 
+0x50, 0x9c, 0x01, 0x34, 0x50, 0x94, 0x14, 0x2c, 0xe2, 0xdb, 0x14, 0x24, 
+0x45, 0x01, 0xc6, 0x0e, 0x2e, 0x43, 0x0d, 0x1c, 0x7d, 0x40, 0x55, 0x40, 
+0x75, 0x19, 0xeb, 0x18, 0xa5, 0x00, 0x6e, 0x46, 0x75, 0x59, 0x5d, 0x19, 
+0x31, 0x4b, 0xed, 0x18, 0x13, 0x1c, 0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, 
+0x0f, 0x43, 0x01, 0x1c, 0x28, 0x1c, 0x01, 0x34, 0x28, 0x2c, 0xe7, 0xdb, 
+0x28, 0x24, 0x50, 0x94, 0x44, 0x01, 0xc5, 0x0e, 0x25, 0x43, 0x3c, 0x1c, 
+0x14, 0x43, 0x0c, 0x40, 0x3e, 0x1c, 0x16, 0x40, 0x34, 0x43, 0x2c, 0x19, 
+0xe3, 0x18, 0x50, 0x9c, 0xa5, 0x00, 0x6c, 0x46, 0x64, 0x59, 0x1c, 0x19, 
+0x23, 0x4b, 0xe4, 0x18, 0x13, 0x1c, 0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, 
+0x0f, 0x43, 0x01, 0x1c, 0x20, 0x1c, 0x50, 0x9c, 0x01, 0x34, 0x50, 0x94, 
+0x3c, 0x2c, 0xe1, 0xdb, 0x3c, 0x24, 0x45, 0x01, 0xc6, 0x0e, 0x2e, 0x43, 
+0x0d, 0x1c, 0x7d, 0x40, 0x55, 0x40, 0x75, 0x19, 0xeb, 0x18, 0xa6, 0x00, 
+0x6d, 0x46, 0xad, 0x59, 0x5d, 0x19, 0x17, 0x4b, 0xed, 0x18, 0x13, 0x1c, 
+0x3a, 0x1c, 0x8f, 0x07, 0x89, 0x08, 0x0f, 0x43, 0x01, 0x1c, 0x28, 0x1c, 
+0x01, 0x34, 0x50, 0x2c, 0xe7, 0xdb, 0x55, 0x9c, 0x20, 0x18, 0x56, 0x9c, 
+0xc0, 0x46, 0x20, 0x60, 0x54, 0x98, 0x40, 0x18, 0x56, 0x9c, 0xc0, 0x46, 
+0x60, 0x60, 0x53, 0x9e, 0xf0, 0x19, 0x56, 0x9c, 0xc0, 0x46, 0xa0, 0x60, 
+0x52, 0x9d, 0xa8, 0x18, 0x56, 0x9c, 0xc0, 0x46, 0xe0, 0x60, 0x51, 0x9c, 
+0xe0, 0x18, 0x56, 0x9c, 0xc0, 0x46, 0x20, 0x61, 0x57, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x99, 0x79, 0x82, 0x5a, 0xa1, 0xeb, 0xd9, 0x6e, 
+0xdc, 0xbc, 0x1b, 0x8f, 0xd6, 0xc1, 0x62, 0xca, 0x88, 0xb4, 0x8a, 0x08, 
+0x89, 0x07, 0x00, 0xd0, 0x01, 0x32, 0x00, 0x21, 0x00, 0x2a, 0x1e, 0xdd, 
+0x07, 0x78, 0x00, 0xab, 0x1f, 0x70, 0x47, 0x78, 0xc0, 0x46, 0x5f, 0x70, 
+0x87, 0x78, 0xc0, 0x46, 0x9f, 0x70, 0xc7, 0x78, 0xc0, 0x46, 0xdf, 0x70, 
+0xdb, 0x78, 0xc0, 0x46, 0x03, 0x70, 0x00, 0xab, 0x9b, 0x78, 0xc0, 0x46, 
+0x43, 0x70, 0x00, 0xab, 0x5b, 0x78, 0xc0, 0x46, 
+0x83, 0x70, 0x00, 0xab, 0x1b, 0x78, 0xc0, 0x46, 0xc3, 0x70, 0x04, 0x30, 
+0x01, 0x31, 0x91, 0x42, 0xe0, 0xdb, 0x88, 0xbc, 0x70, 0x47, 0x00, 0x21, 
+0xc1, 0x61, 0x09, 0x4a, 0xc0, 0x46, 0x02, 0x60, 0x08, 0x4a, 0xc0, 0x46, 
+0x42, 0x60, 0x08, 0x4a, 0xc0, 0x46, 0x82, 0x60, 0x07, 0x4a, 0xc0, 0x46, 
+0xc2, 0x60, 0x07, 0x4a, 0xc0, 0x46, 0x02, 0x61, 0x41, 0x61, 0x81, 0x61, 
+0x70, 0x47, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 
+0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xf0, 0xe1, 0xd2, 0xc3, 
+0xf0, 0xb5, 0x14, 0x1c, 0x0d, 0x1c, 0x07, 0x1c, 0xe1, 0x00, 0x78, 0x69, 
+0x41, 0x18, 0x81, 0x42, 0x02, 0xd2, 0xb8, 0x69, 0x01, 0x30, 0xb8, 0x61, 
+0x79, 0x61, 0x61, 0x0f, 0xb8, 0x69, 0x40, 0x18, 0xb8, 0x61, 0x40, 0x2c, 
+0x14, 0xdb, 0xfe, 0x1d, 0x19, 0x36, 0x00, 0x20, 0x29, 0x78, 0x3a, 0x18, 
+0x20, 0x32, 0x11, 0x70, 0x01, 0x35, 0x01, 0x30, 0x40, 0x28, 0xf7, 0xd3, 
+0x40, 0x21, 0x30, 0x1c, 0xff, 0xf7, 0x96, 0xff, 0x38, 0x1c, 0xff, 0xf7, 
+0xaf, 0xfd, 0x40, 0x3c, 0x40, 0x2c, 0xec, 0xda, 0x00, 0x20, 0x00, 0x2c, 
+0x07, 0xd9, 0x29, 0x78, 0x3a, 0x18, 0x20, 0x32, 0x11, 0x70, 0x01, 0x35, 
+0x01, 0x30, 0xa0, 0x42, 0xf7, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xf8, 0xb5, 0x07, 0x1c, 0xd3, 0x00, 0x78, 0x69, 0xc6, 0x18, 0x86, 0x42, 
+0x02, 0xd2, 0xb8, 0x69, 0x01, 0x30, 0xb8, 0x61, 0x7e, 0x61, 0x53, 0x0f, 
+0xb8, 0x69, 0xc0, 0x18, 0xb8, 0x61, 0x00, 0x90, 0x00, 0x20, 0x00, 0x2a, 
+0x07, 0xdd, 0x0b, 0x78, 0x3c, 0x18, 0x20, 0x34, 0x23, 0x70, 0x01, 0x31, 
+0x01, 0x30, 0x90, 0x42, 0xf7, 0xdb, 0x80, 0x20, 0xd1, 0x19, 0x20, 0x31, 
+0x08, 0x70, 0x54, 0x1c, 0xfd, 0x1d, 0x19, 0x35, 0x38, 0x2c, 0x1c, 0xdd, 
+0x38, 0x19, 0x20, 0x30, 0x00, 0x21, 0x40, 0x22, 0x12, 0x1b, 0x00, 0x2a, 
+0x05, 0xdd, 0x00, 0x23, 0x03, 0x70, 0x01, 0x30, 0x01, 0x31, 0x8a, 0x42, 
+0xfa, 0xdc, 0x28, 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0x4d, 0xff, 0x38, 0x1c, 
+0xff, 0xf7, 0x66, 0xfd, 0x28, 0x1c, 0x00, 0x21, 0x00, 0x23, 0x03, 0x70, 
+0x01, 0x30, 0x01, 0x31, 0x38, 0x29, 0xfa, 0xdb, 0x0c, 0xe0, 0x38, 0x19, 
+0x20, 0x30, 0x00, 0x21, 0x38, 0x22, 0x12, 0x1b, 0x00, 0x2a, 0x05, 0xdd, 
+0x00, 0x23, 0x03, 0x70, 0x01, 0x30, 0x01, 0x31, 0x8a, 0x42, 0xfa, 0xdc, 
+0x28, 0x1c, 0x21, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x00, 0x98, 0xc0, 0x46, 
+0xb8, 0x65, 0xfe, 0x65, 0x38, 0x1c, 0xff, 0xf7, 0x45, 0xfd, 0x01, 0x20, 
+0xf8, 0x61, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x0c, 0x1c, 
+0x05, 0x1c, 0x17, 0x1c, 0x38, 0x1c, 0x00, 0x2f, 0x04, 0xda, 0x40, 0x42, 
+0x80, 0x06, 0x80, 0x0e, 0x40, 0x42, 0x01, 0xe0, 0x80, 0x06, 0x80, 0x0e, 
+0x00, 0x28, 0x07, 0xd1, 0x28, 0x1c, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, 
+0x57, 0xff, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0x00, 0x2f, 
+0x00, 0xda, 0x3f, 0x30, 0x80, 0x11, 0x00, 0x28, 0x07, 0xdd, 0x86, 0x01, 
+0x28, 0x1c, 0x21, 0x1c, 0x32, 0x1c, 0xff, 0xf7, 0x47, 0xff, 0xa4, 0x19, 
+0xbf, 0x1b, 0x00, 0x2f, 0xeb, 0xd0, 0x28, 0x1c, 0x21, 0x1c, 0x3a, 0x1c, 
+0xff, 0xf7, 0x74, 0xff, 0xe5, 0xe7, 0x98, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 
+0x30, 0x20, 0x00, 0xab, 0x18, 0x70, 0xf8, 0x69, 0x00, 0x28, 0x04, 0xd1, 
+0x69, 0x46, 0x00, 0x22, 0x38, 0x1c, 0xff, 0xf7, 0x65, 0xff, 0x14, 0x21, 
+0x38, 0x1c, 0xff, 0xf7, 0xe3, 0xfe, 0x00, 0x20, 
+0x81, 0x00, 0x79, 0x58, 0x02, 0xc4, 0x01, 0x30, 0x05, 0x28, 0xf9, 0xdb, 
+0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0x98, 0xb0, 0x07, 0x1c, 
+0x78, 0x68, 0x40, 0x28, 0x10, 0xd9, 0x68, 0x46, 0xff, 0xf7, 0xf9, 0xfe, 
+0x68, 0x46, 0x06, 0xcf, 0x08, 0x3f, 0xff, 0xf7, 0xa7, 0xff, 0xf8, 0x1d, 
+0xc5, 0x30, 0x69, 0x46, 0x04, 0x1c, 0xff, 0xf7, 0xd0, 0xff, 0x14, 0x20, 
+0x78, 0x60, 0x3c, 0x60, 0x00, 0x20, 0x00, 0x24, 0x39, 0x18, 0xca, 0x1d, 
+0x39, 0x32, 0x14, 0x72, 0x80, 0x31, 0x4c, 0x72, 0x7b, 0x68, 0x83, 0x42, 
+0x06, 0xd9, 0x3b, 0x68, 0x5d, 0x1c, 0x3d, 0x60, 0x1b, 0x78, 0xc0, 0x46, 
+0x13, 0x72, 0x4b, 0x72, 0x15, 0x7a, 0x36, 0x23, 0x6b, 0x40, 0x13, 0x72, 
+0x4a, 0x7a, 0x5c, 0x23, 0x5a, 0x40, 0x4a, 0x72, 0x01, 0x30, 0x40, 0x28, 
+0xe4, 0xd3, 0x18, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, 
+0xe0, 0xb0, 0x14, 0x1c, 0x0f, 0x1c, 0x00, 0x25, 0xae, 0x00, 0x01, 0x20, 
+0xf1, 0x1d, 0x1d, 0x31, 0x02, 0xf0, 0x10, 0xfe, 0x01, 0x04, 0x00, 0x91, 
+0x01, 0x20, 0xf1, 0x1d, 0x1b, 0x31, 0x02, 0xf0, 0x09, 0xfe, 0x00, 0x99, 
+0x08, 0x43, 0x19, 0xa9, 0x71, 0x18, 0x88, 0x60, 0x01, 0x35, 0x10, 0x2d, 
+0xea, 0xd3, 0x1b, 0xa8, 0x19, 0x90, 0x40, 0x20, 0x1a, 0x90, 0x19, 0xa8, 
+0xff, 0xf7, 0xa7, 0xff, 0x01, 0xa8, 0xff, 0xf7, 0xa6, 0xfe, 0x40, 0x22, 
+0x01, 0xa8, 0x2b, 0xa9, 0xff, 0xf7, 0x54, 0xff, 0x00, 0x2f, 0x0b, 0xd0, 
+0x40, 0x2f, 0x01, 0xd9, 0x40, 0x25, 0x00, 0xe0, 0x3d, 0x1c, 0x60, 0x99, 
+0x01, 0xa8, 0x2a, 0x1c, 0xff, 0xf7, 0x48, 0xff, 0x7f, 0x1b, 0xf3, 0xd1, 
+0x51, 0xa8, 0x01, 0xa9, 0x07, 0x1c, 0xff, 0xf7, 0x70, 0xff, 0x01, 0xa8, 
+0xff, 0xf7, 0x8b, 0xfe, 0x40, 0x22, 0x01, 0xa8, 0x3b, 0xa9, 0x01, 0x31, 
+0xff, 0xf7, 0x38, 0xff, 0x14, 0x22, 0x01, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 
+0x33, 0xff, 0x56, 0xa8, 0x01, 0xa9, 0xff, 0xf7, 0x5e, 0xff, 0x00, 0x20, 
+0x82, 0x00, 0x19, 0xa9, 0x51, 0x18, 0xc0, 0x31, 0x49, 0x6b, 0x02, 0xc4, 
+0x01, 0x30, 0x05, 0x28, 0xf6, 0xd3, 0x63, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, 0x00, 0x24, 0x00, 0x2f, 
+0x04, 0xd3, 0x04, 0xf0, 0x15, 0xf9, 0x01, 0x34, 0xbc, 0x42, 0xfa, 0xd9, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x14, 0x1c, 0x0d, 0x1c, 
+0x06, 0x1c, 0x1f, 0x1c, 0x1b, 0x4b, 0x32, 0x04, 0x12, 0x0c, 0x3c, 0x21, 
+0x02, 0x20, 0xfd, 0xf7, 0x8a, 0xff, 0x32, 0x0c, 0x17, 0x4b, 0x3e, 0x21, 
+0x02, 0x20, 0xfd, 0xf7, 0x84, 0xff, 0x15, 0x4b, 0x2a, 0x04, 0x12, 0x0c, 
+0x40, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x7d, 0xff, 0x2a, 0x0c, 0x11, 0x4b, 
+0x42, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x77, 0xff, 0x0e, 0x4b, 0x22, 0x04, 
+0x12, 0x0c, 0x44, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x70, 0xff, 0x22, 0x0c, 
+0x0a, 0x4b, 0x46, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x6a, 0xff, 0x08, 0x4b, 
+0x3a, 0x04, 0x12, 0x0c, 0x48, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x63, 0xff, 
+0x3a, 0x0c, 0x04, 0x4b, 0x4a, 0x21, 0x02, 0x20, 0xfd, 0xf7, 0x5d, 0xff, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xd9, 0xbf, 0x21, 0x40, 
+0x88, 0xb5, 0x11, 0x27, 0x3f, 0x04, 0x38, 0x62, 0x79, 0x62, 0xba, 0x62, 
+0xfb, 0x62, 0x04, 0x20, 0xff, 0xf7, 0xaa, 0xff, 0x07, 0x48, 0x40, 0x6b, 
+0xc0, 0x46, 0x00, 0x90, 0x00, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 
+0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 
+0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 
+0xf0, 0xb5, 0x8a, 0xb0, 0x00, 0x24, 0x05, 0x94, 0x69, 0x49, 0xc9, 0x68, 
+0xc0, 0x46, 0x00, 0x91, 0x68, 0x4a, 0x11, 0x68, 0x01, 0x22, 0x12, 0x04, 
+0x0a, 0x40, 0x17, 0x21, 0x66, 0x4e, 0x00, 0x2a, 0x06, 0xd1, 0x64, 0x4a, 
+0x13, 0x68, 0x1b, 0x0c, 0x04, 0xd1, 0x12, 0x68, 0x92, 0x0a, 0x01, 0xd3, 
+0xf1, 0x60, 0x02, 0xe0, 0x61, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0x61, 0x49, 
+0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x03, 0x29, 0x54, 0xd1, 0xe9, 0x21, 
+0x01, 0x91, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, 0x06, 0x94, 0x06, 0x99, 
+0x8a, 0x00, 0x5b, 0x49, 0x8a, 0x58, 0x00, 0x2a, 0x73, 0xd0, 0x80, 0x20, 
+0x02, 0x90, 0x06, 0x98, 0x81, 0x00, 0x57, 0x48, 0x41, 0x58, 0x02, 0x9a, 
+0x11, 0x43, 0x02, 0x91, 0x00, 0x24, 0x00, 0x27, 0x25, 0x02, 0x28, 0x1c, 
+0x38, 0x43, 0x09, 0x90, 0x09, 0x98, 0x00, 0x04, 0x51, 0x4b, 0x18, 0x43, 
+0x04, 0x90, 0x09, 0x98, 0xef, 0x23, 0xdb, 0x05, 0x18, 0x43, 0x03, 0x90, 
+0x06, 0x98, 0x80, 0x00, 0x4b, 0x49, 0x08, 0x58, 0x00, 0x04, 0x03, 0x99, 
+0x08, 0x43, 0x03, 0x90, 0x00, 0x2f, 0x02, 0xd1, 0x03, 0x98, 0xc0, 0x46, 
+0x70, 0x60, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, 
+0x89, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, 
+0x03, 0x99, 0xc0, 0x46, 0x71, 0x60, 0x5c, 0xe0, 0x79, 0x1c, 0x0f, 0x04, 
+0x3f, 0x0c, 0x17, 0x2f, 0xd1, 0xdd, 0x61, 0x1c, 0x0c, 0x04, 0x24, 0x0c, 
+0x16, 0x2c, 0xca, 0xdd, 0x06, 0x99, 0x01, 0x31, 0x06, 0x91, 0x06, 0x99, 
+0x89, 0x00, 0x37, 0x4a, 0x51, 0x58, 0x00, 0x29, 0xb7, 0xd1, 0x48, 0xe0, 
+0xbf, 0x21, 0xc9, 0x43, 0x04, 0x91, 0xff, 0x21, 0x02, 0x91, 0x97, 0x21, 
+0x01, 0x91, 0x06, 0x94, 0x06, 0x99, 0x89, 0x00, 0x31, 0x4f, 0x79, 0x58, 
+0x00, 0x29, 0x1c, 0xd0, 0x09, 0x94, 0x08, 0x94, 0x06, 0x98, 0x80, 0x00, 
+0x38, 0x58, 0xc0, 0x46, 0x07, 0x90, 0x07, 0x98, 0x00, 0x04, 0x26, 0xe0, 
+0x05, 0x98, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x03, 0x90, 0x01, 0x9b, 
+0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, 0x49, 0xff, 0x00, 0x28, 
+0x23, 0xd1, 0x09, 0x99, 0x01, 0x31, 0x09, 0x91, 0x17, 0x29, 0x06, 0xd8, 
+0x00, 0xe0, 0x1c, 0xe0, 0x08, 0x98, 0x00, 0x02, 0x09, 0x99, 0x08, 0x43, 
+0x07, 0xe0, 0x08, 0x99, 0x01, 0x31, 0x08, 0x91, 0x17, 0x29, 0x0a, 0xd8, 
+0x09, 0x94, 0x08, 0x98, 0x00, 0x02, 0x07, 0x99, 0x09, 0x04, 0x08, 0x43, 
+0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x05, 0x90, 0xd6, 0xe7, 0x06, 0x99, 
+0x01, 0x31, 0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 0x79, 0x58, 0x00, 0x29, 
+0xc4, 0xd1, 0x0c, 0x4a, 0x11, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x11, 0x68, 
+0x09, 0x0c, 0x06, 0xd1, 0x11, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x00, 0x99, 
+0xc0, 0x46, 0xf1, 0x60, 0x03, 0xe0, 0x00, 0x99, 0x06, 0x4a, 0xc0, 0x46, 
+0x11, 0x64, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x40, 0x01, 0x18, 0x40, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 
+0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x18, 0x40, 0x30, 0x6e, 0x21, 0x40, 
+0x43, 0xff, 0x00, 0x00, 0x0c, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x82, 0xb0, 
+0x00, 0x20, 0x01, 0x90, 0x1e, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x1b, 0xd1, 
+0x40, 0x88, 0x00, 0x28, 0x18, 0xd1, 0x68, 0x46, 0x01, 0xf0, 0x9a, 0xfe, 
+0x00, 0x28, 0x13, 0xd1, 0xa8, 0x20, 0x01, 0xf0, 
+0xdb, 0xfe, 0x18, 0x4f, 0x00, 0x28, 0x11, 0xd0, 0x04, 0x20, 0xff, 0xf7, 
+0x97, 0xfe, 0x78, 0x6b, 0xc0, 0x46, 0x01, 0x90, 0x01, 0x98, 0x80, 0x07, 
+0x80, 0x0f, 0x03, 0x28, 0x06, 0xd1, 0x00, 0x20, 0x01, 0xf0, 0xca, 0xfe, 
+0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23, 0x00, 0x22, 
+0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x8f, 0xfe, 0x00, 0x23, 0xdb, 0x43, 
+0x18, 0x1c, 0x19, 0x1c, 0x1a, 0x1c, 0xff, 0xf7, 0xc7, 0xfe, 0x00, 0x28, 
+0x03, 0xd1, 0xff, 0xf7, 0xdf, 0xfe, 0x00, 0x28, 0xe5, 0xd0, 0x38, 0x6a, 
+0x79, 0x6a, 0xba, 0x6a, 0xfb, 0x6a, 0xff, 0xf7, 0x7c, 0xfe, 0xde, 0xe7, 
+0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x11, 0x40, 0xff, 0xb5, 0x85, 0xb0, 
+0x14, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 0x01, 0x23, 0x5b, 0x04, 
+0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x82, 0xe0, 0x26, 0x1c, 0x43, 0x4d, 
+0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x41, 0x48, 
+0x41, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, 
+0x00, 0xd8, 0x3d, 0x1c, 0x3e, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, 
+0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0xff, 0x23, 0x01, 0x33, 0x19, 0x43, 
+0x39, 0x4b, 0xc0, 0x46, 0x59, 0x61, 0xff, 0x23, 0x01, 0x33, 0x9a, 0x43, 
+0x36, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 
+0x33, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x31, 0x4a, 
+0xff, 0x23, 0x01, 0x33, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, 0x01, 0x22, 
+0x12, 0x05, 0x11, 0x61, 0x85, 0x21, 0x89, 0x04, 0x04, 0x91, 0x00, 0x2f, 
+0x34, 0xd0, 0x28, 0x48, 0x86, 0x42, 0x04, 0xd1, 0x30, 0x1c, 0x21, 0x1c, 
+0x2a, 0x1c, 0x03, 0xf0, 0x4f, 0xff, 0x2a, 0x1c, 0x04, 0x98, 0x02, 0x43, 
+0x00, 0x92, 0x01, 0x20, 0x06, 0x99, 0x05, 0x9a, 0x33, 0x1c, 0xfd, 0xf7, 
+0xbd, 0xfd, 0x22, 0x48, 0x22, 0x49, 0x4a, 0x68, 0x52, 0x0a, 0x09, 0xd3, 
+0xff, 0x21, 0x01, 0x31, 0x20, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0x00, 0x28, 
+0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x13, 0xe0, 0x01, 0x38, 0xf0, 0xd1, 
+0xf9, 0xe7, 0x7f, 0x1b, 0x0e, 0xd0, 0x15, 0x48, 0x86, 0x42, 0x01, 0xd1, 
+0x64, 0x19, 0x00, 0xe0, 0x76, 0x19, 0x06, 0x99, 0x49, 0x19, 0x06, 0x91, 
+0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 0x05, 0x1c, 0xca, 0xe7, 
+0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 
+0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 
+0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, 
+0x81, 0x61, 0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x50, 0xab, 0x20, 0x40, 
+0x00, 0x00, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 
+0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0xb0, 0xff, 0xb5, 0x85, 0xb0, 
+0x04, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 0x01, 0x23, 0x5b, 0x04, 
+0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x7d, 0xe0, 0x26, 0x1c, 0x40, 0x4d, 
+0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x3e, 0x48, 
+0x3e, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, 
+0x00, 0xd8, 0x3d, 0x1c, 0x3b, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, 
+0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0x10, 0x23, 0x19, 0x43, 0x37, 0x4b, 
+0xc0, 0x46, 0x59, 0x61, 0x10, 0x23, 0x9a, 0x43, 
+0x34, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 
+0x31, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x2f, 0x4a, 
+0x10, 0x23, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, 0x1a, 0x04, 0x11, 0x61, 
+0x21, 0x21, 0x09, 0x05, 0x04, 0x91, 0x00, 0x2f, 0x33, 0xd0, 0x2a, 0x1c, 
+0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x00, 0x20, 0x06, 0x99, 0x07, 0x9a, 
+0x33, 0x1c, 0xfd, 0xf7, 0x27, 0xfd, 0x25, 0x48, 0x25, 0x49, 0x4a, 0x68, 
+0x52, 0x09, 0x08, 0xd3, 0x10, 0x21, 0x24, 0x4a, 0xc0, 0x46, 0x11, 0x60, 
+0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x1b, 0xe0, 0x01, 0x38, 
+0xf1, 0xd1, 0xf9, 0xe7, 0x19, 0x48, 0x86, 0x42, 0x04, 0xd1, 0x20, 0x1c, 
+0x31, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0x96, 0xfe, 0x7f, 0x1b, 0x0e, 0xd0, 
+0x14, 0x48, 0x86, 0x42, 0x01, 0xd0, 0x76, 0x19, 0x00, 0xe0, 0x64, 0x19, 
+0x06, 0x99, 0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, 
+0x28, 0x1c, 0x05, 0x1c, 0xcb, 0xe7, 0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, 
+0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, 
+0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, 
+0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 0x11, 0x61, 0x01, 0x98, 
+0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xff, 0x00, 0x00, 
+0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 
 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0xb0, 
-0xff, 0xb5, 0x85, 0xb0, 0x04, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 
-0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, 
-0x0f, 0x20, 0x7d, 0xe0, 0x26, 0x1c, 0x40, 0x4d, 0xaf, 0x42, 0x00, 0xd2, 
-0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x3e, 0x48, 0x3e, 0x4b, 0x99, 0x42, 
-0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, 
-0x3b, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, 
-0x02, 0x92, 0x10, 0x23, 0x19, 0x43, 0x37, 0x4b, 0xc0, 0x46, 0x59, 0x61, 
-0x10, 0x23, 0x9a, 0x43, 0x34, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 
-0x12, 0x05, 0xd1, 0x60, 0x31, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 
-0x11, 0x61, 0x2f, 0x4a, 0x10, 0x23, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, 
-0x1a, 0x04, 0x11, 0x61, 0x21, 0x21, 0x09, 0x05, 0x04, 0x91, 0x00, 0x2f, 
-0x33, 0xd0, 0x2a, 0x1c, 0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x00, 0x20, 
-0x06, 0x99, 0x07, 0x9a, 0x33, 0x1c, 0xfe, 0xf7, 0xc7, 0xf8, 0x25, 0x48, 
-0x25, 0x49, 0x4a, 0x68, 0x52, 0x09, 0x08, 0xd3, 0x10, 0x21, 0x24, 0x4a, 
-0xc0, 0x46, 0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 
-0x1b, 0xe0, 0x01, 0x38, 0xf1, 0xd1, 0xf9, 0xe7, 0x19, 0x48, 0x86, 0x42, 
-0x04, 0xd1, 0x20, 0x1c, 0x31, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0x1c, 0xfe, 
-0x7f, 0x1b, 0x0e, 0xd0, 0x14, 0x48, 0x86, 0x42, 0x01, 0xd0, 0x76, 0x19, 
-0x00, 0xe0, 0x64, 0x19, 0x06, 0x99, 0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 
-0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 0x05, 0x1c, 0xcb, 0xe7, 0x0f, 0x48, 
-0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 
-0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 
-0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 
-0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xf0, 0xff, 0x00, 0x00, 0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
-0x00, 0x00, 0x00, 0xb0, 0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, 
-0x0a, 0x70, 0x01, 0x30, 0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, 
-0xa0, 0x82, 0x20, 0x40, 0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, 
-0x01, 0x32, 0x88, 0x42, 0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, 
-0x02, 0xd3, 0x40, 0x1a, 0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, 
-0x01, 0x1c, 0xff, 0x27, 0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, 
-0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, 
-0x4b, 0x00, 0x59, 0x18, 0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, 
-0xdb, 0x00, 0xd7, 0x50, 0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, 
-0x57, 0x60, 0x8b, 0x68, 0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, 
-0x13, 0x61, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, 
-0xd1, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 
-0x04, 0x28, 0xd9, 0xdb, 0x38, 0x1c, 0xf6, 0xe7, 0xd0, 0xab, 0x20, 0x40, 
-0xf7, 0xb5, 0xc5, 0xb0, 0x14, 0x1c, 0x00, 0x20, 0x11, 0x21, 0x21, 0x40, 
-0x5f, 0xd0, 0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x5b, 0x4a, 
-0x51, 0x58, 0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 
-0x04, 0xe0, 0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, 
-0x00, 0x28, 0x4c, 0xd0, 0x00, 0x22, 0x01, 0x92, 0x00, 0x92, 0x40, 0x23, 
-0x00, 0x21, 0x00, 0x20, 0x03, 0xaa, 0x00, 0xf0, 
-0x8f, 0xfa, 0x05, 0xa9, 0x00, 0x20, 0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, 
-0x12, 0x0e, 0x45, 0x9b, 0x9a, 0x42, 0x05, 0xd1, 0x01, 0x9a, 0x01, 0x32, 
-0x12, 0x06, 0x12, 0x0e, 0x01, 0x92, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06, 
-0x00, 0x0e, 0x10, 0x28, 0xed, 0xdb, 0x01, 0x9a, 0x00, 0x2a, 0x4f, 0xd0, 
-0x45, 0x9b, 0x04, 0x2b, 0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 
-0x80, 0x0d, 0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x03, 0xaa, 
-0x00, 0xf0, 0x6a, 0xfa, 0x00, 0x21, 0x01, 0x91, 0x03, 0xa8, 0x06, 0x99, 
-0x49, 0x0c, 0x89, 0x05, 0x2a, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, 
-0x46, 0x9b, 0x9a, 0x42, 0x12, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, 
-0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 
-0x00, 0xf0, 0x52, 0xfa, 0x01, 0x99, 0x03, 0x9d, 0x48, 0x1c, 0x01, 0x06, 
-0x09, 0x0e, 0x01, 0x91, 0x0f, 0xe0, 0x57, 0xe0, 0x48, 0x01, 0x86, 0x0d, 
-0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 
-0x00, 0xf0, 0x40, 0xfa, 0x03, 0xa8, 0x06, 0x99, 0x49, 0x0c, 0x89, 0x05, 
-0xd7, 0xd1, 0x01, 0x99, 0x00, 0x29, 0x11, 0xd1, 0xff, 0x20, 0x3f, 0xe0, 
+0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x70, 0x01, 0x30, 
+0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, 0xa0, 0x82, 0x20, 0x40, 
+0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, 0x01, 0x32, 0x88, 0x42, 
+0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, 0x02, 0xd3, 0x40, 0x1a, 
+0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, 0x01, 0x1c, 0xff, 0x27, 
+0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, 0x43, 0x00, 0x1b, 0x18, 
+0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, 0x4b, 0x00, 0x59, 0x18, 
+0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd7, 0x50, 
+0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, 0x57, 0x60, 0x8b, 0x68, 
+0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, 0x13, 0x61, 0x4b, 0x69, 
+0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, 0xd1, 0x60, 0x90, 0xbc, 
+0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0x28, 0xd9, 0xdb, 
+0x38, 0x1c, 0xf6, 0xe7, 0xd0, 0xab, 0x20, 0x40, 0xf7, 0xb5, 0xc4, 0xb0, 
+0x04, 0x1c, 0x00, 0x20, 0x46, 0x9a, 0x11, 0x21, 0x11, 0x40, 0x6e, 0xd0, 
+0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x57, 0x4a, 0x51, 0x58, 
+0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0xe0, 
+0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, 0x00, 0x28, 
+0x5b, 0xd0, 0x00, 0x26, 0x00, 0x22, 0x00, 0x92, 0x40, 0x23, 0x00, 0x21, 
+0x00, 0x20, 0x02, 0xaa, 0x00, 0xf0, 0x88, 0xfa, 0x04, 0xa9, 0x00, 0x20, 
+0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0xa2, 0x42, 0x03, 0xd1, 
+0x72, 0x1c, 0x16, 0x06, 0x36, 0x0e, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06, 
+0x00, 0x0e, 0x10, 0x28, 0xf0, 0xdb, 0x00, 0x2e, 0x3d, 0xd0, 0x04, 0x2c, 
+0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x80, 0x0d, 0x00, 0x22, 
+0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x02, 0xaa, 
+0x00, 0xf0, 0x68, 0xfa, 0x00, 0x21, 0x01, 0x91, 0x02, 0xa8, 0x05, 0x99, 
+0x49, 0x0c, 0x89, 0x05, 0x29, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, 
+0x45, 0x9b, 0x9a, 0x42, 0x11, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, 
+0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 
+0x00, 0xf0, 0x50, 0xfa, 0x01, 0x99, 0x02, 0x9d, 0x48, 0x1c, 0x01, 0x06, 
+0x09, 0x0e, 0x01, 0x91, 0x0e, 0xe0, 0x48, 0x01, 0x86, 0x0d, 0x00, 0x22, 
+0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, 
+0x3f, 0xfa, 0x02, 0xa8, 0x05, 0x99, 0x49, 0x0c, 0x89, 0x05, 0xd8, 0xd1, 
+0x01, 0x99, 0x00, 0x29, 0x0f, 0xd1, 0xff, 0x20, 0x3d, 0xe0, 0x40, 0xe0, 
 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92, 
-0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 0x00, 0xf0, 0x2a, 0xfa, 
-0x03, 0x9d, 0x01, 0xe0, 0x20, 0x0a, 0xed, 0xd2, 0x01, 0x20, 0x00, 0x04, 
-0x20, 0x43, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, 
-0x50, 0x50, 0x30, 0x1c, 0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x45, 0x9b, 
-0x04, 0x2b, 0x00, 0xd0, 0x0c, 0x20, 0x02, 0x90, 0xb0, 0x60, 0x00, 0x20, 
-0x20, 0x21, 0x21, 0x40, 0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, 
-0x02, 0x98, 0x28, 0x18, 0xff, 0x21, 0xff, 0x30, 0x08, 0x30, 0x09, 0x31, 
-0xff, 0xf7, 0x12, 0xff, 0x43, 0x01, 0x18, 0x18, 0xc0, 0x00, 0x02, 0x99, 
-0x40, 0x1a, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21, 0x21, 0x40, 0x50, 0x29, 
-0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60, 0x38, 0x1c, 0x48, 0xb0, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xff, 0x20, 0xf9, 0xe7, 0xd0, 0xab, 0x20, 0x40, 
-0x80, 0xb4, 0x00, 0x23, 0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, 
-0x7b, 0x40, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, 
-0xd8, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 
-0xc6, 0xb0, 0x04, 0x28, 0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 
-0x45, 0x91, 0x41, 0x4a, 0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, 
-0xc0, 0x43, 0x76, 0xe0, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, 
-0x18, 0x18, 0xc0, 0x00, 0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, 
-0x00, 0x21, 0x02, 0x91, 0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, 
-0xff, 0x21, 0x68, 0x1e, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe, 0x61, 0x68, 
-0x40, 0x18, 0x01, 0x90, 0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, 
-0xaf, 0x1b, 0x09, 0xe0, 0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, 
-0xff, 0xf7, 0xc1, 0xfe, 0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, 
-0x00, 0x22, 0x00, 0x92, 0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, 
-0x00, 0xf0, 0x9e, 0xf9, 0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, 
-0xc0, 0x43, 0x02, 0x99, 0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, 
-0xed, 0x1b, 0xa0, 0x68, 0xa8, 0x42, 0x00, 0xd1, 
-0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99, 0xcf, 0x43, 0x00, 0x22, 
-0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 
-0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90, 0x05, 0x98, 0x00, 0x0a, 
-0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x05, 0x90, 0xff, 0x23, 
-0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21, 0x03, 0xa8, 0xff, 0xf7, 
-0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99, 0x99, 0x43, 0x00, 0x06, 
-0x00, 0x0e, 0x00, 0x02, 0x08, 0x43, 0x05, 0x90, 0x0c, 0x23, 0x00, 0x21, 
-0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 0xbb, 0xf9, 0x00, 0x20, 0x45, 0x99, 
-0x06, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0xc1, 0x43, 0x61, 0x60, 0xa1, 0x60, 
-0xe1, 0x60, 0x21, 0x61, 0x61, 0x61, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb4, 0x4c, 0x42, 
-0x00, 0x29, 0x00, 0xdb, 0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, 
-0x21, 0xda, 0x12, 0x4d, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, 
-0x01, 0x2a, 0x05, 0xd0, 0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, 
-0x01, 0x69, 0x0b, 0xe0, 0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, 
-0x0f, 0xd3, 0x05, 0xe0, 0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, 
-0x09, 0xd3, 0x09, 0x1b, 0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, 
-0xc1, 0x68, 0x09, 0x19, 0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, 
-0xf6, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 
-0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, 
-0xd2, 0x00, 0x2c, 0x49, 0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, 
-0x00, 0x23, 0xdb, 0x43, 0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, 
-0x01, 0xd2, 0x18, 0x1c, 0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 
-0x21, 0x69, 0x8a, 0x42, 0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, 
-0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 
-0x07, 0xfe, 0x61, 0x68, 0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 
-0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x07, 0xfe, 0xc2, 0x19, 0xff, 0x21, 
-0x09, 0x31, 0x8a, 0x42, 0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 
-0x0b, 0x1a, 0x03, 0x93, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 
-0xe1, 0xf8, 0xe0, 0x68, 0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, 
-0x5d, 0x19, 0xff, 0x1a, 0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, 
-0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 
-0x3b, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 
-0xe0, 0x60, 0x02, 0x98, 0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, 
-0xc2, 0xd8, 0x02, 0x98, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, 
-0x00, 0x21, 0x01, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, 
-0x30, 0x49, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, 
-0x04, 0x28, 0x01, 0xda, 0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, 
-0x02, 0x9a, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, 
-0x01, 0xd9, 0x22, 0x69, 0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, 
-0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 
-0xa1, 0xfd, 0x61, 0x68, 0x40, 0x18, 0x00, 0x90, 
-0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 
-0xa0, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x43, 
-0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32, 0x91, 0x42, 0x13, 0xd9, 
-0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c, 0x1e, 0x1c, 0x00, 0xf0, 
-0xd0, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19, 0xe0, 0x60, 0x21, 0x69, 
-0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b, 0x01, 0x98, 0x30, 0x18, 
-0x01, 0x90, 0x12, 0xe0, 0x01, 0x1c, 0x00, 0x9e, 0x30, 0x1c, 0x2a, 0x1c, 
-0x3b, 0x1c, 0x00, 0xf0, 0xbc, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 
-0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0x01, 0x98, 
-0xc0, 0x19, 0x01, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xb9, 0xd8, 0x01, 0x98, 
-0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, 
-0xb0, 0xb5, 0xc3, 0xb0, 0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, 
-0x06, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, 
-0x6b, 0x0c, 0x04, 0xd2, 0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x62, 0x09, 0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, 
-0x40, 0x68, 0x0c, 0x23, 0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, 
-0x11, 0x2c, 0x0d, 0xd0, 0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, 
-0x14, 0x2c, 0x0a, 0xd1, 0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, 
-0x03, 0x98, 0x07, 0x06, 0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, 
-0x02, 0x9f, 0x38, 0x1c, 0xdb, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 
-0x03, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, 
-0xfb, 0xd3, 0x70, 0x47, 0xd0, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, 
-0x9f, 0xf9, 0x57, 0x20, 0x02, 0xf0, 0xfc, 0xf8, 0x02, 0xf0, 0x70, 0xf8, 
-0x00, 0x0a, 0xfb, 0xd3, 0x02, 0xf0, 0x7e, 0xf9, 0x08, 0xbc, 0x18, 0x47, 
-0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x07, 0x9a, 0x1f, 0x1c, 0xff, 0x23, 
-0x01, 0x33, 0x1a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, 
-0x00, 0x0c, 0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0x82, 0xf9, 
-0x53, 0x20, 0x02, 0xf0, 0xdf, 0xf8, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, 
-0x02, 0xf0, 0xda, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xd7, 0xf8, 0x30, 0x1c, 
-0x02, 0xf0, 0xd4, 0xf8, 0x02, 0xf0, 0x5a, 0xf9, 0xff, 0xf7, 0xce, 0xff, 
-0x02, 0xf0, 0x6e, 0xf9, 0x54, 0x20, 0x02, 0xf0, 0xcb, 0xf8, 0x00, 0x98, 
-0x02, 0xf0, 0xc8, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xc5, 0xf8, 0x30, 0x1c, 
-0x14, 0xe0, 0x02, 0xf0, 0x61, 0xf9, 0x52, 0x20, 0x02, 0xf0, 0xbe, 0xf8, 
-0x01, 0x98, 0x02, 0xf0, 0xbb, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xb8, 0xf8, 
-0x30, 0x1c, 0x02, 0xf0, 0xb5, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xb2, 0xf8, 
-0x00, 0x20, 0x02, 0xf0, 0xaf, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xac, 0xf8, 
-0x00, 0x20, 0x02, 0xf0, 0xa9, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, 
-0x1b, 0xf8, 0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 
-0x27, 0xf9, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
-0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x40, 0x02, 0x08, 0x43, 0x05, 0x1c, 
-0x02, 0xf0, 0x32, 0xf9, 0x53, 0x20, 0x02, 0xf0, 0x8f, 0xf8, 0x28, 0x0c, 
-0x06, 0x1c, 0x02, 0xf0, 0x8b, 0xf8, 0x28, 0x0a, 0x01, 0x90, 0x00, 0x90, 
-0x02, 0xf0, 0x86, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
-0x83, 0xf8, 0x02, 0xf0, 0x09, 0xf9, 0xff, 0xf7, 0x7d, 0xff, 0x02, 0xf0, 
-0x1d, 0xf9, 0x84, 0x20, 0x02, 0xf0, 0x7a, 0xf8, 0x30, 0x1c, 0x02, 0xf0, 
-0x77, 0xf8, 0x00, 0x98, 0x02, 0xf0, 0x74, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
-0x71, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0, 
-0x6b, 0xf8, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xef, 0xf8, 0x02, 0xf0, 
-0x05, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0x62, 0xf8, 0x30, 0x1c, 0x02, 0xf0, 
-0x5f, 0xf8, 0x01, 0x98, 0x02, 0xf0, 0x5c, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
-0x59, 0xf8, 0x02, 0xf0, 0xdf, 0xf8, 0xff, 0xf7, 0x53, 0xff, 0x02, 0xb0, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 
-0x80, 0xb5, 0x01, 0xf0, 0x89, 0xf8, 0x06, 0x4f, 0xc0, 0x46, 0xf8, 0x60, 
-0x01, 0xf0, 0xe4, 0xf8, 0x78, 0x80, 0x01, 0xf0, 0xa5, 0xf8, 0x38, 0x71, 
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0xb5, 0x01, 0xf0, 0xf7, 0xf8, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x80, 
-0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0xc1, 0x68, 
-0x01, 0x29, 0x11, 0xd1, 0x02, 0x22, 0xc1, 0x6f, 0x0a, 0x43, 0xc2, 0x67, 
-0x08, 0x49, 0xc0, 0x46, 0x0a, 0x60, 0x80, 0x23, 0xc2, 0x6f, 0x1a, 0x43, 
-0xc2, 0x67, 0x0a, 0x60, 0x82, 0x22, 0x80, 0x30, 0x02, 0x60, 0x4a, 0x60, 
-0x00, 0x21, 0x81, 0x80, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0x01, 0x11, 0x00, 0xf0, 0xb4, 0x49, 0x49, 0xca, 0x1d, 0x99, 0x32, 
-0x00, 0x20, 0x00, 0x27, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28, 
-0xfa, 0xd3, 0x45, 0x4c, 0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30, 
-0x20, 0x28, 0xfa, 0xd3, 0x42, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50, 
-0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65, 
-0x8f, 0x65, 0x3e, 0x4d, 0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60, 
-0xaf, 0x61, 0xef, 0x60, 0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00, 
-0x09, 0x18, 0x49, 0x01, 0x34, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d, 
-0xf5, 0x33, 0x33, 0x4c, 0x34, 0x19, 0xe3, 0x63, 0x87, 0x23, 0x9b, 0x00, 
-0xcb, 0x18, 0x63, 0x63, 0xcf, 0x23, 0x9b, 0x00, 0xcb, 0x18, 0xb4, 0x18, 
-0xe3, 0x63, 0x30, 0x4b, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30, 0x02, 0x28, 
-0xe5, 0xdb, 0x29, 0x48, 0xc1, 0x1d, 0xf5, 0x31, 0x28, 0x4c, 0xc0, 0x46, 
-0xa1, 0x62, 0x61, 0x6b, 0xcf, 0x23, 0x9b, 0x00, 0xe1, 0x62, 0xc1, 0x18, 
-0x91, 0x62, 0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21, 0xe1, 0x64, 
-0x25, 0x49, 0xc0, 0x46, 0x21, 0x65, 0x25, 0x49, 0x0b, 0x69, 0xc0, 0x46, 
-0x63, 0x65, 0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66, 0x8b, 0x68, 
-0xc0, 0x46, 0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66, 0x1f, 0x4b, 
-0xc0, 0x46, 0xe3, 0x66, 0x27, 0x67, 0x67, 0x67, 0x1d, 0x4b, 0xc3, 0x18, 
-0x01, 0x26, 0xa3, 0x67, 0x66, 0x61, 0xe7, 0x61, 0xe3, 0x1d, 0x69, 0x33, 
-0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x19, 0x4b, 0xc0, 0x46, 0x13, 0x65, 
+0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, 0x28, 0xfa, 
+0x02, 0x9d, 0x01, 0x20, 0x00, 0x04, 0x46, 0x9a, 0x10, 0x43, 0x79, 0x00, 
+0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0x30, 0x1c, 
+0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x04, 0x2c, 0x00, 0xd0, 0x0c, 0x20, 
+0x04, 0x1c, 0xb0, 0x60, 0x00, 0x20, 0x20, 0x21, 0x46, 0x9a, 0x11, 0x40, 
+0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, 0x28, 0x19, 0xff, 0x21, 
+0xff, 0x30, 0x08, 0x30, 0x09, 0x31, 0xff, 0xf7, 0x19, 0xff, 0x43, 0x01, 
+0x18, 0x18, 0xc0, 0x00, 0x00, 0x1b, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21, 
+0x46, 0x9a, 0x11, 0x40, 0x50, 0x29, 0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60, 
+0x38, 0x1c, 0x47, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0x20, 
+0xf9, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0x80, 0xb4, 0x00, 0x23, 
+0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, 0x7b, 0x40, 0x1b, 0x06, 
+0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, 0xd8, 0x43, 0x00, 0x06, 
+0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xc6, 0xb0, 0x04, 0x28, 
+0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x45, 0x91, 0x41, 0x4a, 
+0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, 0xc0, 0x43, 0x76, 0xe0, 
+0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 
+0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, 0x00, 0x21, 0x02, 0x91, 
+0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, 0xff, 0x21, 0x68, 0x1e, 
+0x09, 0x31, 0xff, 0xf7, 0xcd, 0xfe, 0x61, 0x68, 0x40, 0x18, 0x01, 0x90, 
+0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, 0xaf, 0x1b, 0x09, 0xe0, 
+0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe, 
+0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, 0x00, 0x22, 0x00, 0x92, 
+0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, 0x00, 0xf0, 0x9e, 0xf9, 
+0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43, 0x02, 0x99, 
+0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, 0xed, 0x1b, 0xa0, 0x68, 
+0xa8, 0x42, 0x00, 0xd1, 0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99, 
+0xcf, 0x43, 0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 
+0x03, 0xaa, 0x00, 0xf0, 0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90, 
+0x05, 0x98, 0x00, 0x0a, 0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43, 
+0x05, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21, 
+0x03, 0xa8, 0xff, 0xf7, 0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99, 
+0x99, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x02, 
+0x08, 0x43, 0x05, 0x90, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, 
+0x00, 0xf0, 0xca, 0xf9, 0x00, 0x20, 0x45, 0x99, 0x06, 0x4a, 0xc0, 0x46, 
+0x50, 0x50, 0xc1, 0x43, 0x61, 0x60, 0xa1, 0x60, 0xe1, 0x60, 0x21, 0x61, 
+0x61, 0x61, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb4, 0x4c, 0x42, 0x00, 0x29, 0x00, 0xdb, 
+0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, 0x21, 0xda, 0x12, 0x4d, 
+0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, 0x01, 0x2a, 0x05, 0xd0, 
+0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, 0x01, 0x69, 0x0b, 0xe0, 
+0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, 0x0f, 0xd3, 0x05, 0xe0, 
+0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, 0x09, 0xd3, 0x09, 0x1b, 
+0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, 0xc1, 0x68, 0x09, 0x19, 
+0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, 0xf6, 0xe7, 0x00, 0x00, 
+0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, 
+0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x2c, 0x49, 
+0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, 0x00, 0x23, 0xdb, 0x43, 
+0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, 0x01, 0xd2, 0x18, 0x1c, 
+0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x21, 0x69, 0x8a, 0x42, 
+0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, 0xa0, 0x68, 0xe1, 0x68, 
+0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x0d, 0xfe, 0x61, 0x68, 
+0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 
+0xff, 0xf7, 0x0d, 0xfe, 0xc2, 0x19, 0xff, 0x21, 0x09, 0x31, 0x8a, 0x42, 
+0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x0b, 0x1a, 0x03, 0x93, 
+0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0xe1, 0xf8, 0xe0, 0x68, 
+0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, 0x5d, 0x19, 0xff, 0x1a, 
+0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, 0x01, 0x9a, 0xc0, 0x46, 
+0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0, 
+0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x02, 0x98, 
+0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xc2, 0xd8, 0x02, 0x98, 
+0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, 
+0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x01, 0x91, 
+0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, 0x30, 0x49, 0x8a, 0x58, 
+0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, 0x04, 0x28, 0x01, 0xda, 
+0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, 0x02, 0x9a, 0x54, 0x18, 
+0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, 0x01, 0xd9, 0x22, 0x69, 
+0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, 0xa0, 0x68, 0xe1, 0x68, 
+0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0xa7, 0xfd, 0x61, 0x68, 
+0x40, 0x18, 0x00, 0x90, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 
+0x09, 0x31, 0xff, 0xf7, 0xa6, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23, 
+0x5b, 0x04, 0x19, 0x43, 0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32, 
+0x91, 0x42, 0x13, 0xd9, 0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c, 
+0x1e, 0x1c, 0x00, 0xf0, 0xdf, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19, 
+0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b, 
+0x01, 0x98, 0x30, 0x18, 0x01, 0x90, 0x12, 0xe0, 
+0x01, 0x1c, 0x00, 0x9e, 0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0, 
+0xcb, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x21, 0x69, 
+0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0x01, 0x98, 0xc0, 0x19, 0x01, 0x90, 
+0x00, 0x27, 0x00, 0x2f, 0xb9, 0xd8, 0x01, 0x98, 0x03, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb5, 0xc3, 0xb0, 
+0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, 0x06, 0xda, 0x41, 0x00, 
+0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, 0x6b, 0x0c, 0x04, 0xd2, 
+0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x62, 0x09, 
+0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, 0x40, 0x68, 0x0c, 0x23, 
+0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, 0x11, 0x2c, 0x0d, 0xd0, 
+0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, 0x14, 0x2c, 0x0a, 0xd1, 
+0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, 0x03, 0x98, 0x07, 0x06, 
+0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, 0x02, 0x9f, 0x38, 0x1c, 
+0xdb, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0x03, 0x49, 0x00, 0x20, 
+0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, 0xfb, 0xd3, 0x70, 0x47, 
+0xd0, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, 0x01, 0xfa, 0x57, 0x20, 
+0x02, 0xf0, 0x5e, 0xf9, 0x02, 0xf0, 0xd2, 0xf8, 0x00, 0x0a, 0xfb, 0xd3, 
+0x02, 0xf0, 0xe0, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x82, 0xb0, 
+0x07, 0x9d, 0x14, 0x1c, 0x1f, 0x1c, 0x30, 0x4a, 0xd2, 0x6f, 0x20, 0x23, 
+0x16, 0x68, 0x9e, 0x43, 0x16, 0x60, 0x33, 0x1c, 0xff, 0x22, 0x01, 0x32, 
+0x2a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, 0x00, 0x0c, 
+0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0xdd, 0xf9, 0x53, 0x20, 
+0x02, 0xf0, 0x3a, 0xf9, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, 0x02, 0xf0, 
+0x35, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x32, 0xf9, 0x30, 0x1c, 0x02, 0xf0, 
+0x2f, 0xf9, 0x02, 0xf0, 0xb5, 0xf9, 0xff, 0xf7, 0xc7, 0xff, 0x02, 0xf0, 
+0xc9, 0xf9, 0x54, 0x20, 0x02, 0xf0, 0x26, 0xf9, 0x00, 0x98, 0x02, 0xf0, 
+0x23, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x20, 0xf9, 0x30, 0x1c, 0x14, 0xe0, 
+0x02, 0xf0, 0xbc, 0xf9, 0x52, 0x20, 0x02, 0xf0, 0x19, 0xf9, 0x01, 0x98, 
+0x02, 0xf0, 0x16, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x13, 0xf9, 0x30, 0x1c, 
+0x02, 0xf0, 0x10, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x0d, 0xf9, 0x00, 0x20, 
+0x02, 0xf0, 0x0a, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x07, 0xf9, 0x00, 0x20, 
+0x02, 0xf0, 0x04, 0xf9, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, 0x76, 0xf8, 
+0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0x82, 0xf9, 
+0x04, 0x4a, 0xd0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 
+0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 
+0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x40, 0x02, 0x08, 0x43, 
+0x05, 0x1c, 0x2c, 0x49, 0xc8, 0x6f, 0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, 
+0x02, 0x60, 0xc8, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 
+0x02, 0xf0, 0x7a, 0xf9, 0x53, 0x20, 0x02, 0xf0, 0xd7, 0xf8, 0x28, 0x0c, 
+0x06, 0x1c, 0x02, 0xf0, 0xd3, 0xf8, 0x28, 0x0a, 0x01, 0x90, 0x00, 0x90, 
+0x02, 0xf0, 0xce, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xcb, 0xf8, 0x02, 0xf0, 
+0x51, 0xf9, 0xff, 0xf7, 0x63, 0xff, 0x02, 0xf0, 0x65, 0xf9, 0x84, 0x20, 
+0x02, 0xf0, 0xc2, 0xf8, 0x30, 0x1c, 0x02, 0xf0, 
+0xbf, 0xf8, 0x00, 0x98, 0x02, 0xf0, 0xbc, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
+0xb9, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0, 
+0xb3, 0xf8, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0x37, 0xf9, 0x02, 0xf0, 
+0x4d, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0xaa, 0xf8, 0x30, 0x1c, 0x02, 0xf0, 
+0xa7, 0xf8, 0x01, 0x98, 0x02, 0xf0, 0xa4, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
+0xa1, 0xf8, 0x02, 0xf0, 0x27, 0xf9, 0xff, 0xf7, 0x39, 0xff, 0x07, 0x49, 
+0xc8, 0x6f, 0x40, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60, 0xc8, 0x6f, 
+0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x02, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 
+0x80, 0xb5, 0x01, 0xf0, 0x91, 0xf8, 0x06, 0x4f, 0xc0, 0x46, 0xf8, 0x60, 
+0x01, 0xf0, 0xf4, 0xf8, 0x78, 0x80, 0x01, 0xf0, 0xb3, 0xf8, 0x38, 0x71, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
+0x00, 0xb5, 0x01, 0xf0, 0x07, 0xf9, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x80, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x0b, 0x48, 0xc1, 0x68, 
+0x01, 0x29, 0x11, 0xd1, 0xc1, 0x6f, 0x02, 0x23, 0x0a, 0x68, 0x1a, 0x43, 
+0x0a, 0x60, 0xc1, 0x6f, 0x80, 0x23, 0x0a, 0x68, 0x1a, 0x43, 0x0a, 0x60, 
+0xc1, 0x18, 0x08, 0x68, 0x82, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, 
+0x00, 0x20, 0x08, 0x81, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
+0xf0, 0xb4, 0x4a, 0x49, 0xca, 0x1d, 0x9d, 0x32, 0x00, 0x20, 0x00, 0x27, 
+0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28, 0xfa, 0xd3, 0x46, 0x4c, 
+0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, 
+0x43, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x20, 0x28, 
+0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65, 0x8f, 0x65, 0x3f, 0x4d, 
+0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60, 0xaf, 0x61, 0xef, 0x60, 
+0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00, 0x09, 0x18, 0x49, 0x01, 
+0x35, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d, 0xf9, 0x33, 0x34, 0x4c, 
+0x34, 0x19, 0xe3, 0x63, 0x11, 0x23, 0x5b, 0x01, 0xcb, 0x18, 0x63, 0x63, 
+0x0d, 0x23, 0x9b, 0x01, 0xcb, 0x18, 0xb4, 0x18, 0xe3, 0x63, 0x23, 0x23, 
+0x5b, 0x01, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30, 0x02, 0x28, 0xe4, 0xdb, 
+0x29, 0x48, 0xc1, 0x1d, 0xf9, 0x31, 0x29, 0x4c, 0xc0, 0x46, 0xa1, 0x62, 
+0x61, 0x6b, 0x0d, 0x23, 0x9b, 0x01, 0xe1, 0x62, 0xc1, 0x18, 0x91, 0x62, 
+0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21, 0xe1, 0x64, 0x25, 0x49, 
+0xc0, 0x46, 0x21, 0x65, 0x24, 0x49, 0x0b, 0x69, 0xc0, 0x46, 0x63, 0x65, 
+0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66, 0x8b, 0x68, 0xc0, 0x46, 
+0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66, 0x1e, 0x4b, 0xc0, 0x46, 
+0xe3, 0x66, 0x27, 0x67, 0x0b, 0x23, 0xdb, 0x01, 0xc3, 0x18, 0xa3, 0x67, 
+0x67, 0x67, 0x01, 0x26, 0xe3, 0x1d, 0x69, 0x33, 0x66, 0x61, 0xe7, 0x61, 
+0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x17, 0x4b, 0xc0, 0x46, 0x13, 0x65, 
 0xcb, 0x69, 0xc0, 0x46, 0x53, 0x65, 0xc3, 0x1d, 0x51, 0x33, 0xd3, 0x65, 
 0x2b, 0x1d, 0x13, 0x66, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x66, 0x89, 0x69, 
-0xc0, 0x46, 0x91, 0x66, 0x11, 0x49, 0xc0, 0x46, 0xd1, 0x66, 0x16, 0x67, 
-0x56, 0x67, 0x10, 0x4b, 0xc0, 0x18, 0x90, 0x67, 0x56, 0x61, 0xd7, 0x61, 
-0xd0, 0x1d, 0x69, 0x30, 0x07, 0x73, 0xf0, 0xbc, 
-0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 
-0xd0, 0x2c, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x5c, 0x04, 0x00, 0x00, 
-0x30, 0x01, 0x18, 0x00, 0xf8, 0x28, 0x00, 0x80, 0x80, 0x54, 0xff, 0xff, 
-0x7c, 0x05, 0x00, 0x00, 0x38, 0x01, 0x18, 0x00, 0x90, 0x54, 0xff, 0xff, 
-0x7c, 0x07, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x21, 0x1c, 0x4a, 0xbb, 0x23, 
-0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x72, 0x19, 0x23, 0xdb, 0x01, 0xd0, 0x18, 
-0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x81, 0x61, 0x59, 0x60, 0xb9, 0x72, 
-0x01, 0x27, 0x1f, 0x73, 0x19, 0x61, 0x17, 0x23, 0xdb, 0x01, 0xd3, 0x18, 
-0xd9, 0x63, 0x13, 0x4b, 0x51, 0x27, 0xbf, 0x03, 0xc3, 0x62, 0x3b, 0x60, 
-0x44, 0x69, 0xe4, 0x18, 0x04, 0x63, 0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, 
-0xe4, 0x02, 0x44, 0x63, 0x0d, 0x4c, 0xc0, 0x46, 0xbc, 0x60, 0xc4, 0x6a, 
-0xc0, 0x46, 0x04, 0x62, 0x44, 0x69, 0xe4, 0x18, 0x0a, 0x4b, 0xe3, 0x18, 
-0xfb, 0x60, 0xc3, 0x6a, 0xc0, 0x46, 0x43, 0x62, 0x03, 0x6a, 0xc0, 0x46, 
-0xc3, 0x61, 0x81, 0x63, 0x51, 0x64, 0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, 
-0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 
-0xfc, 0x07, 0x00, 0x00, 0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22, 
-0x1c, 0x49, 0xc9, 0x23, 0x1b, 0x01, 0xc8, 0x18, 0x02, 0x70, 0x01, 0x20, 
-0xbb, 0x23, 0x1b, 0x01, 0xcb, 0x18, 0x58, 0x72, 0x18, 0x48, 0x03, 0x1c, 
-0x00, 0x27, 0xdc, 0x1d, 0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37, 
-0x3f, 0x2f, 0xf8, 0xd3, 0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18, 
-0x33, 0x23, 0x9b, 0x01, 0xcc, 0x18, 0xfa, 0x60, 0x60, 0x61, 0x40, 0x20, 
-0xb8, 0x60, 0xa2, 0x61, 0xe2, 0x61, 0xca, 0x64, 0x0a, 0x66, 0x0d, 0x48, 
-0xc0, 0x46, 0xc2, 0x60, 0x0c, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e, 
-0xb8, 0x63, 0x0b, 0x48, 0x65, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x02, 0x68, 
-0xc0, 0x46, 0x8a, 0x83, 0x42, 0x68, 0xc0, 0x46, 0xca, 0x83, 0x80, 0x68, 
-0xc0, 0x46, 0x20, 0x80, 0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
-0x3c, 0xbd, 0x20, 0x40, 0x3c, 0xef, 0x20, 0x40, 0x80, 0x00, 0x14, 0x40, 
-0x40, 0x00, 0x14, 0x40, 0x00, 0x20, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x73, 
-0xcb, 0x1d, 0xff, 0x33, 0x3a, 0x33, 0x88, 0x61, 0xc8, 0x61, 0x18, 0x70, 
-0x06, 0x4a, 0xc0, 0x46, 0x10, 0x65, 0x50, 0x66, 0x90, 0x66, 0x08, 0x70, 
-0x58, 0x70, 0xbb, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x08, 0x72, 0x70, 0x47, 
-0xa8, 0x04, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb4, 0x2f, 0x49, 
-0x2f, 0x4a, 0xc0, 0x46, 0x11, 0x61, 0x01, 0x23, 0x9b, 0x02, 0xc8, 0x18, 
-0x50, 0x61, 0x2d, 0x48, 0xc0, 0x46, 0x10, 0x62, 0xdb, 0x00, 0xc3, 0x18, 
-0x53, 0x62, 0x00, 0x23, 0x13, 0x63, 0x53, 0x63, 0x29, 0x4a, 0x2a, 0x4f, 
-0xd4, 0x1d, 0xff, 0x34, 0xfa, 0x34, 0x14, 0xc7, 0x08, 0x3f, 0x3b, 0x61, 
-0x1c, 0x1f, 0x7c, 0x61, 0x26, 0x4f, 0xc0, 0x46, 0x39, 0x60, 0xb8, 0x61, 
-0x79, 0x61, 0xf8, 0x62, 0x3b, 0x63, 0x7b, 0x64, 0xba, 0x64, 0xfa, 0x65, 
-0x22, 0x4f, 0xfe, 0x1d, 0xf9, 0x36, 0x22, 0x4d, 0xec, 0x1d, 0x79, 0x34, 
-0xe6, 0x61, 0x51, 0x26, 0xb6, 0x03, 0x37, 0x61, 0xe4, 0x69, 0xc0, 0x46, 
-0x74, 0x61, 0x2f, 0x67, 0x1d, 0x4d, 0x09, 0x27, 0x7f, 0x04, 0xec, 0x1d, 
-0x75, 0x34, 0x7c, 0x60, 0x3d, 0x60, 0x1b, 0x4c, 0xc0, 0x46, 0x3c, 0x61, 
-0xe6, 0x1d, 0x75, 0x36, 0x7e, 0x61, 0x19, 0x4f, 
-0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c, 0x00, 0x21, 0xff, 0x24, 
-0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50, 0x01, 0x31, 0xa1, 0x42, 
-0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27, 0xff, 0x02, 0x83, 0x00, 
-0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3, 0x00, 0x20, 0x81, 0x00, 
-0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3, 0xf0, 0xbc, 0x70, 0x47, 
-0x24, 0xa3, 0x20, 0x40, 0x40, 0x01, 0x18, 0x00, 0x24, 0x83, 0x20, 0x40, 
-0x24, 0xa9, 0x20, 0x40, 0x80, 0x01, 0x18, 0x00, 0x28, 0x03, 0x00, 0x80, 
-0x24, 0xa7, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0x24, 0xa8, 0x20, 0x40, 
-0xa4, 0xa8, 0x20, 0x40, 0x88, 0x03, 0x00, 0x80, 0xb8, 0xb5, 0x2d, 0x48, 
-0xfd, 0xf7, 0xc6, 0xfa, 0x01, 0x20, 0x2c, 0x49, 0x0a, 0x68, 0x52, 0x0c, 
-0x06, 0xd2, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x0a, 0x68, 0x92, 0x0a, 
-0x00, 0xd2, 0x00, 0x20, 0x04, 0x06, 0x24, 0x0e, 0x26, 0x4a, 0xd7, 0x1d, 
-0x0d, 0x37, 0x00, 0x23, 0x00, 0x20, 0x9d, 0x00, 0x78, 0x51, 0x01, 0x33, 
-0x04, 0x2b, 0xfa, 0xd3, 0x01, 0x27, 0x3f, 0x05, 0x50, 0x61, 0xf8, 0x60, 
-0xd0, 0x61, 0xf8, 0x61, 0x00, 0x23, 0xdb, 0x43, 0x93, 0x61, 0x3b, 0x61, 
-0x13, 0x62, 0x3b, 0x62, 0x00, 0x27, 0x1c, 0x4b, 0x8d, 0x68, 0xc0, 0x46, 
-0x00, 0x95, 0x8d, 0x69, 0xc0, 0x46, 0x00, 0x95, 0x00, 0x2c, 0x0b, 0xd0, 
-0xdd, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x9d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 
-0x5d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x1d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 
-0x01, 0x37, 0x40, 0x2f, 0xe8, 0xd3, 0x00, 0x27, 0x6c, 0x46, 0x01, 0x23, 
-0x5b, 0x07, 0x1c, 0x43, 0x01, 0xe0, 0x20, 0x60, 0x01, 0x37, 0x0d, 0x68, 
-0x2b, 0x09, 0x02, 0xd2, 0x80, 0x2f, 0xf8, 0xd3, 0x01, 0xe0, 0x80, 0x2f, 
-0x03, 0xd3, 0x09, 0x49, 0x4b, 0x6e, 0x01, 0x33, 0x4b, 0x66, 0xd0, 0x62, 
-0x07, 0x48, 0xfd, 0xf7, 0x71, 0xfa, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x04, 0x02, 0xff, 0xff, 
-0x90, 0xb4, 0x00, 0x21, 0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01, 
-0x64, 0x1a, 0xa4, 0x00, 0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64, 
-0x58, 0x64, 0x10, 0x53, 0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67, 
-0xdc, 0x62, 0x01, 0x31, 0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46, 
-0x08, 0x60, 0x48, 0x60, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc, 
-0x70, 0x47, 0x00, 0x00, 0x58, 0x67, 0x21, 0x40, 0xc8, 0x2a, 0x00, 0x80, 
-0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x64, 0x21, 0x07, 0x48, 0xc0, 0x46, 
-0x01, 0x63, 0x00, 0x21, 0xc9, 0x43, 0x41, 0x63, 0x81, 0x63, 0x00, 0x21, 
-0xc1, 0x63, 0x01, 0x64, 0x03, 0x48, 0x28, 0x22, 0x02, 0xf0, 0x06, 0xff, 
-0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x59, 0x03, 0xff, 0xff, 
-0x80, 0xb4, 0x01, 0x20, 0x40, 0x02, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x60, 
-0x3c, 0x20, 0x48, 0x60, 0x88, 0x60, 0x08, 0x48, 0xc0, 0x46, 0xc8, 0x60, 
-0x00, 0x20, 0x07, 0x4a, 0x87, 0x00, 0xcb, 0x68, 0xc0, 0x46, 0xda, 0x51, 
-0x01, 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 
-0x50, 0x2d, 0x00, 0x80, 0x60, 0x2d, 0x00, 0x80, 0xd5, 0x4b, 0xff, 0xff, 
-0x12, 0x49, 0x13, 0x48, 0x67, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, 
-0x08, 0x38, 0x11, 0x4b, 0xca, 0x18, 0xc1, 0x60, 
+0xc0, 0x46, 0x91, 0x66, 0x0f, 0x49, 0xc0, 0x46, 0xd1, 0x66, 0x16, 0x67, 
+0x0f, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x90, 0x67, 0x56, 0x67, 0xd7, 0x61, 
+0xd0, 0x1d, 0x69, 0x30, 0x56, 0x61, 0x07, 0x73, 
+0xf0, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80, 
+0x64, 0x2d, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x30, 0x01, 0x18, 0x00, 
+0x7c, 0x29, 0x00, 0x80, 0xec, 0x54, 0xff, 0xff, 0x38, 0x01, 0x18, 0x00, 
+0xfc, 0x54, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x21, 0x1e, 0x4a, 0xbb, 0x23, 
+0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x73, 0x19, 0x23, 0xdb, 0x01, 0xd0, 0x18, 
+0x01, 0x24, 0xcd, 0x23, 0x1b, 0x01, 0xd3, 0x18, 0xc1, 0x61, 0x1c, 0x70, 
+0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x99, 0x60, 0xb9, 0x73, 0x59, 0x61, 
+0x2f, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x19, 0x60, 0x13, 0x4b, 0x51, 0x27, 
+0xbf, 0x03, 0x03, 0x63, 0x3b, 0x60, 0x84, 0x69, 0xe4, 0x18, 0x44, 0x63, 
+0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, 0xe4, 0x02, 0x84, 0x63, 0x0e, 0x4c, 
+0xc0, 0x46, 0xbc, 0x60, 0x04, 0x6b, 0xc0, 0x46, 0x44, 0x62, 0x84, 0x69, 
+0xe4, 0x18, 0x0b, 0x4b, 0xe3, 0x18, 0xfb, 0x60, 0x03, 0x6b, 0xc0, 0x46, 
+0x83, 0x62, 0x43, 0x6a, 0xc0, 0x46, 0x03, 0x62, 0xc1, 0x63, 0x51, 0x64, 
+0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0xfc, 0x07, 0x00, 0x00, 
+0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22, 0x1b, 0x49, 0xc9, 0x23, 
+0x1b, 0x01, 0xc8, 0x18, 0x02, 0x71, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 
+0xcb, 0x18, 0x58, 0x73, 0x17, 0x48, 0x03, 0x1c, 0x00, 0x27, 0xdc, 0x1d, 
+0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37, 0x3f, 0x2f, 0xf8, 0xd3, 
+0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18, 0x33, 0x23, 0x9b, 0x01, 
+0xcb, 0x18, 0x3a, 0x61, 0x98, 0x61, 0x40, 0x20, 0xf8, 0x60, 0xda, 0x61, 
+0x1a, 0x62, 0xca, 0x64, 0x0a, 0x66, 0x0c, 0x48, 0xc0, 0x46, 0xc2, 0x60, 
+0x0b, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e, 0xf8, 0x63, 0x0a, 0x48, 
+0x01, 0x68, 0xc0, 0x46, 0x19, 0x80, 0x41, 0x68, 0xc0, 0x46, 0x59, 0x80, 
+0x80, 0x68, 0xc0, 0x46, 0x98, 0x80, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0x3c, 0xbd, 0x20, 0x40, 0x3c, 0xef, 0x20, 0x40, 
+0x80, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x40, 0x00, 0x20, 0x0a, 0x49, 
+0xc0, 0x46, 0x08, 0x73, 0xcb, 0x1d, 0xff, 0x33, 0x3a, 0x33, 0x88, 0x61, 
+0xc8, 0x61, 0x18, 0x70, 0x06, 0x4a, 0xc0, 0x46, 0x10, 0x65, 0x50, 0x66, 
+0x90, 0x66, 0x08, 0x70, 0x58, 0x70, 0xbb, 0x23, 0x1b, 0x01, 0xd1, 0x18, 
+0x08, 0x73, 0x70, 0x47, 0x28, 0x05, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 
+0xf0, 0xb4, 0x2f, 0x49, 0x2f, 0x4a, 0xc0, 0x46, 0x11, 0x61, 0x01, 0x23, 
+0x9b, 0x02, 0xc8, 0x18, 0x50, 0x61, 0x2d, 0x48, 0xc0, 0x46, 0x10, 0x62, 
+0xdb, 0x00, 0xc3, 0x18, 0x53, 0x62, 0x00, 0x23, 0x13, 0x63, 0x53, 0x63, 
+0x29, 0x4a, 0x2a, 0x4f, 0xd4, 0x1d, 0xff, 0x34, 0xfa, 0x34, 0x14, 0xc7, 
+0x08, 0x3f, 0x3b, 0x61, 0x1c, 0x1f, 0x7c, 0x61, 0x26, 0x4f, 0xc0, 0x46, 
+0x39, 0x60, 0xb8, 0x61, 0x79, 0x61, 0xf8, 0x62, 0x3b, 0x63, 0x7b, 0x64, 
+0xba, 0x64, 0xfa, 0x65, 0x22, 0x4f, 0xfe, 0x1d, 0xf9, 0x36, 0x22, 0x4d, 
+0xec, 0x1d, 0x79, 0x34, 0x26, 0x62, 0x51, 0x26, 0xb6, 0x03, 0x37, 0x61, 
+0x24, 0x6a, 0xc0, 0x46, 0x74, 0x61, 0x2f, 0x67, 0x1d, 0x4d, 0x09, 0x27, 
+0x7f, 0x04, 0xec, 0x1d, 0x75, 0x34, 0x7c, 0x60, 0x3d, 0x60, 0x1b, 0x4c, 
+0xc0, 0x46, 0x3c, 0x61, 0xe6, 0x1d, 0x75, 0x36, 0x7e, 0x61, 0x19, 0x4f, 
+0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c, 
+0x00, 0x21, 0xff, 0x24, 0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50, 
+0x01, 0x31, 0xa1, 0x42, 0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27, 
+0xff, 0x02, 0x83, 0x00, 0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3, 
+0x00, 0x20, 0x81, 0x00, 0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3, 
+0xf0, 0xbc, 0x70, 0x47, 0x24, 0xa3, 0x20, 0x40, 0x40, 0x01, 0x18, 0x00, 
+0x24, 0x83, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x80, 0x01, 0x18, 0x00, 
+0xa8, 0x03, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 
+0x24, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40, 0x08, 0x04, 0x00, 0x80, 
+0xb8, 0xb5, 0x2c, 0x48, 0xfc, 0xf7, 0x0a, 0xff, 0x01, 0x20, 0x2b, 0x49, 
+0x0a, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 
+0x0a, 0x68, 0x92, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x04, 0x06, 0x24, 0x0e, 
+0x25, 0x4a, 0xd7, 0x1d, 0x0d, 0x37, 0x00, 0x23, 0x00, 0x20, 0x9d, 0x00, 
+0x78, 0x51, 0x01, 0x33, 0x04, 0x2b, 0xfa, 0xd3, 0x01, 0x27, 0x3f, 0x05, 
+0x50, 0x61, 0xf8, 0x60, 0xd0, 0x61, 0xf8, 0x61, 0x00, 0x23, 0xdb, 0x43, 
+0x93, 0x61, 0x3b, 0x61, 0x13, 0x62, 0x3b, 0x62, 0x00, 0x27, 0x1b, 0x4b, 
+0x8d, 0x68, 0xc0, 0x46, 0x00, 0x95, 0x8d, 0x69, 0xc0, 0x46, 0x00, 0x95, 
+0x00, 0x2c, 0x0b, 0xd0, 0xdd, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x9d, 0x6b, 
+0xc0, 0x46, 0x00, 0x95, 0x5d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x1d, 0x6b, 
+0xc0, 0x46, 0x00, 0x95, 0x01, 0x37, 0x40, 0x2f, 0xe8, 0xd3, 0x00, 0x27, 
+0x6c, 0x46, 0x01, 0x23, 0x5b, 0x07, 0x1c, 0x43, 0x01, 0xe0, 0x20, 0x60, 
+0x01, 0x37, 0x0d, 0x68, 0x2b, 0x09, 0x02, 0xd2, 0x80, 0x2f, 0xf8, 0xd3, 
+0x01, 0xe0, 0x80, 0x2f, 0x03, 0xd3, 0x08, 0x49, 0x4b, 0x6e, 0x01, 0x33, 
+0x4b, 0x66, 0xd0, 0x62, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80, 
+0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x00, 0x21, 
+0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01, 0x64, 0x1a, 0xa4, 0x00, 
+0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64, 0x58, 0x64, 0x10, 0x53, 
+0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67, 0xdc, 0x62, 0x01, 0x31, 
+0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x48, 0x60, 
+0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 
+0x58, 0x67, 0x21, 0x40, 0x5c, 0x2b, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, 
+0x64, 0x21, 0x05, 0x48, 0xc0, 0x46, 0x01, 0x63, 0x00, 0x21, 0xc9, 0x43, 
+0x41, 0x63, 0x81, 0x63, 0x00, 0x21, 0xc1, 0x63, 0x01, 0x64, 0x70, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0x80, 0xb4, 0x01, 0x20, 0x40, 0x02, 0x0a, 0x49, 
+0xc0, 0x46, 0x08, 0x60, 0x3c, 0x20, 0x48, 0x60, 0x88, 0x60, 0x08, 0x48, 
+0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x07, 0x4a, 0x87, 0x00, 0xcb, 0x68, 
+0xc0, 0x46, 0xda, 0x51, 0x01, 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x80, 0xbc, 
+0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, 0xf4, 0x2d, 0x00, 0x80, 
+0x49, 0x4c, 0xff, 0xff, 0x12, 0x49, 0x13, 0x48, 0x67, 0x23, 0x9b, 0x01, 
+0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x11, 0x4b, 0xca, 0x18, 0xc1, 0x60, 
 0x82, 0x60, 0x01, 0x61, 0x0f, 0x49, 0x10, 0x48, 0xa7, 0x23, 0x9b, 0x01, 
 0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x0e, 0x4b, 0xca, 0x18, 0xc1, 0x60, 
-0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49, 0x67, 0x23, 0x9b, 0x01, 
-0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b, 0xc2, 0x18, 0xc8, 0x60, 
-0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00, 0x58, 0x1f, 0x21, 0x40, 
-0xb4, 0x2d, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00, 0x58, 0xef, 0x20, 0x40, 
-0xa0, 0x2d, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00, 0x58, 0x3f, 0x21, 0x40, 
-0xc8, 0x2d, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, 0x40, 0x4c, 0x00, 0x20, 
-0x0a, 0x01, 0x12, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0xd0, 0x62, 
-0x10, 0x63, 0x50, 0x63, 0x90, 0x63, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 
-0x3a, 0x49, 0xc0, 0x46, 0xc8, 0x62, 0x08, 0x63, 0x48, 0x63, 0x20, 0x60, 
-0x01, 0x21, 0xe3, 0x1d, 0x59, 0x33, 0x60, 0x60, 0x19, 0x71, 0x18, 0x72, 
-0x98, 0x71, 0x98, 0x72, 0x59, 0x71, 0x58, 0x72, 0xd8, 0x71, 0xd8, 0x72, 
-0xe2, 0x1d, 0x49, 0x32, 0x11, 0x73, 0x19, 0x70, 0x90, 0x73, 0x98, 0x70, 
-0x51, 0x73, 0x59, 0x70, 0xd0, 0x73, 0xd8, 0x70, 0x11, 0x71, 0x11, 0x72, 
-0x90, 0x71, 0x90, 0x72, 0x50, 0x71, 0x50, 0x72, 0xd0, 0x71, 0xd0, 0x72, 
-0x18, 0x73, 0x02, 0x22, 0xe7, 0x1d, 0x69, 0x37, 0x3a, 0x70, 0x99, 0x73, 
-0xba, 0x70, 0x58, 0x73, 0x78, 0x70, 0xd8, 0x73, 0xf8, 0x70, 0x39, 0x71, 
-0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 
-0xf9, 0x72, 0x39, 0x73, 0xe3, 0x1d, 0x79, 0x33, 0x1a, 0x70, 0xb9, 0x73, 
-0x99, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xd9, 0x70, 0x1a, 0x71, 
-0x1a, 0x72, 0x99, 0x71, 0x9a, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 
-0xda, 0x72, 0x19, 0x73, 0xe7, 0x1d, 0x89, 0x37, 0x3a, 0x70, 0x99, 0x73, 
-0xb9, 0x70, 0x58, 0x73, 0x7a, 0x70, 0xd9, 0x73, 0xf9, 0x70, 0x39, 0x71, 
-0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 
-0xf9, 0x72, 0x3a, 0x73, 0xe3, 0x1d, 0x99, 0x33, 0x1a, 0x70, 0xb9, 0x73, 
-0x9a, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xda, 0x70, 0x19, 0x71, 
-0x1a, 0x72, 0x99, 0x71, 0x99, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 
-0xd9, 0x72, 0x20, 0x61, 0xe0, 0x60, 0x60, 0x61, 0xa0, 0x60, 0x90, 0xbc, 
-0x70, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 0x68, 0x19, 0x00, 0x80, 
-0x81, 0x20, 0x00, 0x02, 0x01, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x70, 0x47, 
-0xc0, 0x00, 0x14, 0x00, 0x0a, 0x49, 0x13, 0x23, 0xdb, 0x01, 0xc8, 0x18, 
-0x25, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x63, 0x00, 0x21, 0xc2, 0x1d, 
+0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49, 
+0x67, 0x23, 0x9b, 0x01, 0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b, 
+0xc2, 0x18, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00, 
+0x58, 0x1f, 0x21, 0x40, 0x48, 0x2e, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00, 
+0x58, 0xef, 0x20, 0x40, 0x34, 0x2e, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00, 
+0x58, 0x3f, 0x21, 0x40, 0x5c, 0x2e, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, 
+0x40, 0x4c, 0x00, 0x20, 0x0a, 0x01, 0x12, 0x19, 0x19, 0x23, 0xdb, 0x01, 
+0xd2, 0x18, 0xd0, 0x62, 0x10, 0x63, 0x50, 0x63, 0x90, 0x63, 0x01, 0x31, 
+0x03, 0x29, 0xf3, 0xd3, 0x3a, 0x49, 0xc0, 0x46, 0x08, 0x63, 0x48, 0x63, 
+0x88, 0x63, 0x20, 0x60, 0x01, 0x21, 0xe3, 0x1d, 0x59, 0x33, 0x60, 0x60, 
+0x19, 0x71, 0x18, 0x72, 0x98, 0x71, 0x98, 0x72, 0x59, 0x71, 0x58, 0x72, 
+0xd8, 0x71, 0xd8, 0x72, 0xe2, 0x1d, 0x49, 0x32, 0x11, 0x73, 0x19, 0x70, 
+0x90, 0x73, 0x98, 0x70, 0x51, 0x73, 0x59, 0x70, 0xd0, 0x73, 0xd8, 0x70, 
+0x11, 0x71, 0x11, 0x72, 0x90, 0x71, 0x90, 0x72, 0x50, 0x71, 0x50, 0x72, 
+0xd0, 0x71, 0xd0, 0x72, 0x18, 0x73, 0x02, 0x22, 0xe7, 0x1d, 0x69, 0x37, 
+0x3a, 0x70, 0x99, 0x73, 0xba, 0x70, 0x58, 0x73, 0x78, 0x70, 0xd8, 0x73, 
+0xf8, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 
+0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x39, 0x73, 0xe3, 0x1d, 0x79, 0x33, 
+0x1a, 0x70, 0xb9, 0x73, 0x99, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 
+0xd9, 0x70, 0x1a, 0x71, 0x1a, 0x72, 0x99, 0x71, 0x9a, 0x72, 0x58, 0x71, 
+0x5a, 0x72, 0xd9, 0x71, 0xda, 0x72, 0x19, 0x73, 0xe7, 0x1d, 0x89, 0x37, 
+0x3a, 0x70, 0x99, 0x73, 0xb9, 0x70, 0x58, 0x73, 0x7a, 0x70, 0xd9, 0x73, 
+0xf9, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 
+0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x3a, 0x73, 0xe3, 0x1d, 0x99, 0x33, 
+0x1a, 0x70, 0xb9, 0x73, 0x9a, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 
+0xda, 0x70, 0x19, 0x71, 0x1a, 0x72, 0x99, 0x71, 0x99, 0x72, 0x58, 0x71, 
+0x5a, 0x72, 0xd9, 0x71, 0xd9, 0x72, 0x20, 0x61, 0xe0, 0x60, 0x60, 0x61, 
+0xa0, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80, 
+0xe8, 0x19, 0x00, 0x80, 0x81, 0x20, 0x00, 0x02, 0x01, 0x49, 0xc0, 0x46, 
+0x88, 0x62, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 0x09, 0x49, 0x0a, 0x4b, 
+0xc8, 0x18, 0x04, 0x3b, 0xc9, 0x18, 0x08, 0x60, 0x00, 0x21, 0xc2, 0x1d, 
 0x29, 0x32, 0xc2, 0x61, 0x10, 0x1c, 0x01, 0x31, 0x08, 0x29, 0xf8, 0xd3, 
 0xc1, 0x1f, 0x29, 0x39, 0x00, 0x20, 0xc8, 0x61, 0x70, 0x47, 0x00, 0x00, 
-0xe8, 0x0d, 0x00, 0x80, 0x06, 0x48, 0x07, 0x49, 0xc0, 0x46, 0x08, 0x80, 
-0x48, 0x80, 0x00, 0x20, 0x88, 0x80, 0xc8, 0x80, 0x88, 0x60, 0x04, 0x49, 
-0xc0, 0x46, 0x48, 0x61, 0x88, 0x61, 0x70, 0x47, 0xff, 0xff, 0x00, 0x00, 
-0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0x21, 0x06, 0x48, 
-0xc2, 0x1d, 0x19, 0x32, 0xc1, 0x60, 0x01, 0x61, 0xc1, 0x61, 0x01, 0x62, 
-0x11, 0x71, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 
-0xec, 0x05, 0x00, 0x80, 0x09, 0x48, 0x0a, 0x4b, 0xc0, 0x46, 0x18, 0x60, 
-0x00, 0x21, 0xc2, 0x1d, 0x4d, 0x32, 0xc2, 0x60, 
+0x68, 0x0e, 0x00, 0x80, 0x84, 0x09, 0x00, 0x00, 0x06, 0x48, 0x07, 0x49, 
+0xc0, 0x46, 0x08, 0x80, 0x48, 0x80, 0x00, 0x20, 0x88, 0x80, 0xc8, 0x80, 
+0x88, 0x60, 0x04, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x88, 0x61, 0x70, 0x47, 
+0xff, 0xff, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 
+0x00, 0x21, 0x06, 0x48, 0xc2, 0x1d, 0x19, 0x32, 0xc1, 0x60, 0x01, 0x61, 
+0xc1, 0x61, 0x01, 0x62, 0x11, 0x71, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 
+0x70, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x09, 0x48, 0x0a, 0x4b, 
+0xc0, 0x46, 0x18, 0x60, 0x00, 0x21, 0xc2, 0x1d, 0x4d, 0x32, 0xc2, 0x60, 
 0x10, 0x1c, 0x01, 0x31, 0x14, 0x29, 0xf8, 0xd3, 0xc1, 0x1f, 0x4d, 0x39, 
 0x00, 0x20, 0xc8, 0x60, 0x58, 0x60, 0x98, 0x60, 0x70, 0x47, 0x00, 0x00, 
-0x58, 0x07, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x0c, 0x49, 
-0x0c, 0x48, 0xfd, 0xf7, 0xea, 0xf8, 0x0c, 0x48, 0x00, 0x6a, 0x01, 0x23, 
-0xdb, 0x03, 0x98, 0x43, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x0a, 0x48, 
-0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, 0xc1, 0x6f, 0x19, 0x43, 
-0xc1, 0x67, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47, 
-0x59, 0xcd, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, 0xc0, 0x00, 0x18, 0x40, 
-0xc0, 0x00, 0x18, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
-0x00, 0xb5, 0x10, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, 
-0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x0d, 0x48, 0xc0, 0x46, 0x01, 0x60, 
-0x0c, 0x4b, 0x0d, 0x48, 0x0d, 0x4a, 0x00, 0x21, 0xfd, 0xf7, 0xb9, 0xf8, 
-0x0c, 0x48, 0x41, 0x8d, 0x01, 0x31, 0x41, 0x85, 0x00, 0x21, 0xc1, 0x85, 
-0x0a, 0x48, 0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x18, 0x43, 0x09, 0x49, 
-0xc0, 0x46, 0x08, 0x62, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
-0x00, 0x01, 0x11, 0x00, 0xf1, 0xcc, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, 
+0xd8, 0x07, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 
+0x00, 0xb5, 0x0b, 0x49, 0x0b, 0x48, 0xfc, 0xf7, 0x3a, 0xfd, 0x0b, 0x48, 
+0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x98, 0x43, 0x09, 0x49, 0xc0, 0x46, 
+0x08, 0x62, 0x09, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f, 
+0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47, 
+0x8d, 0xd5, 0x21, 0x40, 0xc1, 0xa8, 0x21, 0x40, 0xc0, 0x00, 0x18, 0x40, 
+0xc0, 0x00, 0x18, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x0f, 0x48, 
+0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f, 0x80, 0x23, 0x01, 0x68, 
+0x99, 0x43, 0x01, 0x60, 0x0b, 0x4b, 0x0c, 0x48, 0x0c, 0x4a, 0x00, 0x21, 
+0xfc, 0xf7, 0x0f, 0xfd, 0x0b, 0x48, 0x41, 0x8d, 0x01, 0x31, 0x41, 0x85, 
+0x00, 0x21, 0xc1, 0x85, 0x09, 0x48, 0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 
+0x18, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x08, 0xbc, 0x18, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0x25, 0xd5, 0x21, 0x40, 0xc1, 0xa8, 0x21, 0x40, 
 0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, 
-0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0xfe, 0xf7, 0xa3, 0xfe, 0x19, 0x4c, 
-0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x05, 0xd1, 0x60, 0x88, 0x00, 0x28, 
-0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67, 0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, 
-0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18, 0xc1, 0x43, 0xa8, 0x61, 0x29, 0x62, 
-0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03, 0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, 
-0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x70, 0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, 
-0xb8, 0x60, 0x00, 0xf0, 0x47, 0xfa, 0x00, 0xf0, 0xd9, 0xfa, 0x04, 0x20, 
-0xb8, 0x60, 0x07, 0x20, 0x78, 0x61, 0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, 
-0xe0, 0x18, 0x40, 0x8b, 0x04, 0x23, 0x18, 0x40, 0xa8, 0x62, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb4, 0x02, 0x1c, 
-0x00, 0x20, 0xff, 0x23, 0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, 
-0x00, 0xd1, 0x01, 0x20, 0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, 
-0x80, 0xbc, 0x70, 0x47, 0x18, 0x49, 0xca, 0x68, 0x18, 0x4b, 0x01, 0x2a, 
-0x0b, 0xd1, 0x4a, 0x88, 0x00, 0x2a, 0x08, 0xd1, 0xd9, 0x8a, 0x0a, 0x09, 
-0x00, 0xd3, 0x02, 0x20, 0x49, 0x09, 0xef, 0xd3, 0x01, 0x23, 0x18, 0x43, 
-0xec, 0xe7, 0x0a, 0x79, 0x00, 0x2a, 0x03, 0xd0, 0x18, 0x8a, 0x80, 0x07, 
-0x80, 0x0f, 0xe5, 0xe7, 0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x0a, 0x88, 
-0xff, 0x27, 0x01, 0x37, 0x17, 0x40, 0x0b, 0x49, 0x49, 0x88, 0x03, 0xd0, 
-0x4b, 0x0a, 0x01, 0xd3, 0x03, 0x20, 0xd7, 0xe7, 0x13, 0x0a, 0x03, 0xd3, 
-0x0b, 0x0a, 0x01, 0xd3, 0x02, 0x20, 0xd1, 0xe7, 0xd2, 0x09, 0xcf, 0xd3, 
-0xc9, 0x09, 0xcd, 0xd3, 0x01, 0x20, 0xcb, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
-0xa8, 0x1b, 0x00, 0x80, 0x88, 0x1b, 0x00, 0x80, 0xf0, 0xb5, 0xc1, 0xb0, 
-0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x52, 0x48, 
-0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x60, 0x50, 0x48, 
-0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21, 0x03, 0x03, 0x1b, 0x0b, 
-0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b, 
+0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0xfe, 0xf7, 0x9b, 0xfe, 0x1b, 0x4c, 
+0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x60, 0x88, 0x00, 0x28, 
+0x05, 0xd1, 0x20, 0x79, 0x00, 0x28, 0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67, 
+0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18, 
+0xc1, 0x43, 0xe8, 0x61, 0x69, 0x62, 0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03, 
+0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, 0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x71, 
+0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, 0xb8, 0x60, 0x00, 0xf0, 0x4c, 0xfa, 
+0x00, 0xf0, 0xf0, 0xfa, 0x04, 0x20, 0xb8, 0x60, 0x07, 0x20, 0x78, 0x61, 
+0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0xc0, 0x8b, 0x04, 0x23, 
+0x18, 0x40, 0xe8, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0x90, 0xb4, 0x02, 0x1c, 0x00, 0x20, 0xff, 0x23, 
+0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, 0x00, 0xd1, 0x01, 0x20, 
+0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, 0x90, 0xbc, 0x70, 0x47, 
+0x1b, 0x4a, 0xd7, 0x68, 0x1a, 0x4b, 0x19, 0x79, 0x1c, 0x1c, 0x37, 0x23, 
+0x9b, 0x01, 0xe3, 0x18, 0x01, 0x2f, 0x0d, 0xd1, 0x57, 0x88, 0x00, 0x2f, 
+0x0a, 0xd1, 0x00, 0x29, 0x0a, 0xd1, 0x59, 0x8b, 0x0a, 0x09, 0x00, 0xd3, 
+0x02, 0x20, 0x49, 0x09, 0xe8, 0xd3, 0x01, 0x23, 0x18, 0x43, 0xe5, 0xe7, 
+0x00, 0x29, 0x03, 0xd0, 0x98, 0x8a, 0x80, 0x07, 0x80, 0x0f, 0xdf, 0xe7, 
+0x6d, 0x23, 0x5b, 0x01, 0xd1, 0x18, 0x8a, 0x88, 0xff, 0x27, 0x01, 0x37, 
+0x17, 0x40, 0x0a, 0x49, 0xc9, 0x88, 0x03, 0xd0, 0x4b, 0x0a, 0x01, 0xd3, 
+0x03, 0x20, 0xd1, 0xe7, 0x13, 0x0a, 0x03, 0xd3, 0x0b, 0x0a, 0x01, 0xd3, 
+0x02, 0x20, 0xcb, 0xe7, 0xd2, 0x09, 0xc9, 0xd3, 0xc9, 0x09, 0xc7, 0xd3, 
+0x01, 0x20, 0xc5, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x1c, 0x00, 0x80, 
+0xf0, 0xb5, 0xc1, 0xb0, 0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x52, 0x48, 0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03, 
+0x48, 0x60, 0x50, 0x48, 0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21, 
+0x03, 0x03, 0x1b, 0x0b, 0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b, 
 0xe7, 0x1d, 0x79, 0x37, 0xab, 0x42, 0x1c, 0xd0, 0xe3, 0x1d, 0x79, 0x33, 
-0xdb, 0x69, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43, 
-0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, 0x01, 0x23, 0x9b, 0x07, 
-0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, 0x63, 0x60, 0x08, 0x30, 
-0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, 0x3f, 0x48, 0x03, 0x03, 
-0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, 0x01, 0x23, 0x1b, 0x03, 
-0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, 0x01, 0x33, 0x63, 0x62, 
-0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a, 0x01, 0x33, 0x23, 0x62, 
-0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34, 0x5c, 0x65, 0x00, 0x29, 
-0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c, 0x6b, 0x44, 0x5c, 0x68, 
-0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42, 0xf5, 0xd1, 0x30, 0x4c, 
-0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 
-0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24, 0x2b, 0x4b, 0xc0, 0x46, 
-0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b, 0x23, 0x4c, 0x51, 0x26, 
-0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0xfd, 0x69, 0xc0, 0x46, 0x75, 0x61, 
-0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60, 0x01, 0x25, 0xb5, 0x60, 
-0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x70, 0x88, 0x42, 0x21, 0xd0, 0x25, 0x1c, 
-0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f, 0x6b, 0x44, 0x34, 0x60, 
-0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60, 0x2b, 0x6f, 0x08, 0x33, 
-0x2b, 0x67, 0xfc, 0x69, 0xa3, 0x42, 0x02, 0xd3, 0x12, 0x4b, 0xc0, 0x46, 
-0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, 
-0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03, 0x2b, 0x6f, 0xc0, 0x46, 
-0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b, 0x03, 0xd3, 0x0e, 0x49, 
-0x01, 0x20, 0xfc, 0xf7, 0x72, 0xff, 0x41, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x01, 0x14, 0x40, 
-0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
-0x24, 0xa7, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
-0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x49, 0x4f, 0xff, 0xff, 
-0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22, 0x06, 0x24, 0x47, 0x4f, 
-0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33, 0x20, 0x2b, 0xf9, 0xd3, 
-0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61, 0x3c, 0x61, 0x3a, 0x61, 
-0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x3f, 0x4d, 0xab, 0x6f, 
-0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 
-0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x9e, 0x08, 0x02, 0x23, 
+0x1b, 0x6a, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43, 
+0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, 
+0x01, 0x23, 0x9b, 0x07, 0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, 
+0x63, 0x60, 0x08, 0x30, 0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, 
+0x3f, 0x48, 0x03, 0x03, 0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, 
+0x01, 0x23, 0x1b, 0x03, 0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, 
+0x01, 0x33, 0x63, 0x62, 0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a, 
+0x01, 0x33, 0x23, 0x62, 0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34, 
+0x5c, 0x65, 0x00, 0x29, 0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c, 
+0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42, 
+0xf5, 0xd1, 0x30, 0x4c, 0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 
+0x1b, 0x0c, 0x08, 0xd1, 0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24, 
+0x2b, 0x4b, 0xc0, 0x46, 0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b, 
+0x23, 0x4c, 0x51, 0x26, 0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0x3d, 0x6a, 
+0xc0, 0x46, 0x75, 0x61, 0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60, 
+0x01, 0x25, 0xb5, 0x60, 0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x71, 0x88, 0x42, 
+0x21, 0xd0, 0x25, 0x1c, 0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f, 
+0x6b, 0x44, 0x34, 0x60, 0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60, 
+0x2b, 0x6f, 0x08, 0x33, 0x2b, 0x67, 0x3c, 0x6a, 0xa3, 0x42, 0x02, 0xd3, 
+0x12, 0x4b, 0xc0, 0x46, 0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44, 
+0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03, 
+0x2b, 0x6f, 0xc0, 0x46, 0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b, 
+0x03, 0xd3, 0x0e, 0x49, 0x01, 0x20, 0xfc, 0xf7, 0xc2, 0xfb, 0x41, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
+0x00, 0x01, 0x14, 0x40, 0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40, 
+0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80, 
+0xa0, 0x82, 0x20, 0x40, 0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, 
+0xb5, 0x4f, 0xff, 0xff, 0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22, 
+0x06, 0x24, 0x47, 0x4f, 0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33, 
+0x20, 0x2b, 0xf9, 0xd3, 0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61, 
+0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61, 
+0x3f, 0x4d, 0xab, 0x6f, 0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 
+0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 
+0x9e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 
+0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23, 
 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 
-0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 
-0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x02, 0x23, 
-0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 
-0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, 
-0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 
-0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 
-0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, 
-0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 
+0x3b, 0x61, 0x02, 0x23, 0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 
+0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00, 
+0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 
+0x2b, 0x43, 0x3b, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 
+0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08, 
+0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 
 0x2b, 0x43, 0x3b, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 
 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x02, 0x25, 
-0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 
-0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x04, 0x23, 0x03, 0x43, 
-0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, 0x00, 0x25, 0x3d, 0x61, 
-0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x00, 0x20, 0x3d, 0x61, 
-0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, 0x02, 0x23, 0x33, 0x40, 
-0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30, 0x10, 0x28, 0xf2, 0xd3, 
-0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61, 0x3c, 0x61, 0x3a, 0x61, 
-0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08, 0xf0, 0xbc, 0x70, 0x47, 
-0x80, 0x00, 0x14, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0x00, 0x14, 0x40, 
-0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27, 0x44, 0x4a, 0xc0, 0x46, 
-0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c, 0xf9, 0xd3, 0x04, 0x26, 
-0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 
-0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61, 0x3c, 0x4b, 0x9b, 0x6f, 
-0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 
-0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f, 0x9d, 0x08, 0x02, 0x23, 
+0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 
+0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 
+0x04, 0x23, 0x03, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, 
+0x00, 0x25, 0x3d, 0x61, 0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, 
+0x00, 0x20, 0x3d, 0x61, 0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, 
+0x02, 0x23, 0x33, 0x40, 0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30, 
+0x10, 0x28, 0xf2, 0xd3, 0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61, 
+0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08, 
+0xf0, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80, 
+0x80, 0x00, 0x14, 0x40, 0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27, 
+0x44, 0x4a, 0xc0, 0x46, 0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c, 
+0xf9, 0xd3, 0x04, 0x26, 0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61, 
+0x07, 0x23, 0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61, 
+0x3c, 0x4b, 0x9b, 0x6f, 0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 
+0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f, 
+0x9d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 
+0x25, 0x43, 0x15, 0x61, 0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23, 
 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 
-0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 
-0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x2d, 0x4b, 0x9d, 0x6f, 
+0x2d, 0x4b, 0x9d, 0x6f, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 
+0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00, 
 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 
-0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, 
-0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0xc5, 0x08, 
+0x15, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 
+0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, 
+0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08, 
 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 
-0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 
-0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 
-0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x02, 0x25, 
-0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 
-0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c, 0x33, 0x43, 0x13, 0x61, 
-0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x16, 0x61, 
-0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21, 0x25, 0x1c, 0xcd, 0x40, 
-0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x05, 0x23, 
-0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39, 0x10, 0x28, 0xf1, 0xd3, 
-0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61, 0x13, 0x61, 0x03, 0x20, 
-0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x00, 
-0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb5, 0x47, 0x48, 0x01, 0x89, 0x47, 0x4d, 
-0x07, 0x23, 0x5b, 0x02, 0xef, 0x18, 0xb9, 0x83, 0x40, 0x8b, 0xc0, 0x46, 
-0xf8, 0x83, 0x28, 0x79, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0xb8, 0x83, 
-0xe8, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x68, 0x88, 0x00, 0x28, 0x03, 0xd1, 
-0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x54, 0xff, 0x01, 0x21, 0xc9, 0x03, 
-0x00, 0x20, 0xff, 0xf7, 0x4f, 0xff, 0x00, 0x24, 0x7d, 0x26, 0xf6, 0x00, 
-0x00, 0xe0, 0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0xad, 0xfe, 0x00, 0x0c, 
-0x01, 0xd3, 0xb4, 0x42, 0xf7, 0xd3, 0x00, 0x24, 
-0x05, 0xe0, 0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3c, 0xff, 
-0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0x9e, 0xfe, 0x40, 0x0b, 0x01, 0xd2, 
-0xb4, 0x42, 0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0xff, 0x23, 
-0xe1, 0x33, 0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0xb8, 0x8b, 0xff, 0x23, 
-0x01, 0x33, 0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01, 0x19, 0x43, 
-0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, 
-0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23, 0x19, 0x43, 
-0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, 
-0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, 
-0x04, 0x20, 0xff, 0xf7, 0x09, 0xff, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 
-0xff, 0xf7, 0x04, 0xff, 0xe8, 0x68, 0x00, 0x28, 0x0c, 0xd1, 0x00, 0x21, 
-0x1b, 0x20, 0xff, 0xf7, 0xfd, 0xfe, 0x1a, 0x20, 0xff, 0xf7, 0x60, 0xfe, 
-0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7, 0xf4, 0xfe, 
-0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f, 0x08, 0xd9, 
-0x38, 0x1c, 0xff, 0xf7, 0x51, 0xfe, 0x79, 0x00, 0x49, 0x19, 0x1b, 0x23, 
-0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, 0x01, 0x37, 0x20, 0x2f, 0xef, 0xd3, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0x81, 0xb0, 0x13, 0x48, 0x01, 0x68, 0xc0, 0x46, 
-0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x68, 0xc0, 0x46, 
-0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x69, 0xc0, 0x46, 
-0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x69, 0xc0, 0x46, 
-0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x6a, 0xc0, 0x46, 
-0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x6a, 0xc0, 0x46, 
-0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x01, 0xb0, 0x70, 0x47, 
-0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x66, 0x4e, 0x1b, 0x23, 
-0xdb, 0x01, 0xf7, 0x18, 0x78, 0x8b, 0x04, 0x22, 0x02, 0x40, 0x02, 0x92, 
-0x07, 0x23, 0x5b, 0x02, 0xf4, 0x18, 0xa0, 0x8b, 0xc0, 0x46, 0x01, 0x90, 
-0xe0, 0x8b, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x25, 0x03, 0xe0, 0x08, 0x2d, 
-0x01, 0xd3, 0x0f, 0x2d, 0x08, 0xd9, 0x28, 0x1c, 0xff, 0xf7, 0xfa, 0xfd, 
-0x69, 0x00, 0x89, 0x19, 0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, 
-0x01, 0x35, 0x20, 0x2d, 0xef, 0xd3, 0xa0, 0x69, 0x00, 0x28, 0x15, 0xd0, 
-0x54, 0x4e, 0x20, 0x25, 0x01, 0x3d, 0x52, 0x49, 0xa0, 0x69, 0x30, 0x40, 
-0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18, 0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, 
-0x01, 0x8b, 0x28, 0x1c, 0xff, 0xf7, 0x78, 0xfe, 0xa0, 0x69, 0xb0, 0x43, 
-0xa0, 0x61, 0x76, 0x08, 0x00, 0x2d, 0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, 
-0xd5, 0xfd, 0x01, 0x1c, 0x46, 0x48, 0xc0, 0x46, 0x79, 0x83, 0x79, 0x8b, 
-0xca, 0x08, 0x22, 0xd3, 0xc2, 0x68, 0x01, 0x2a, 0x10, 0xd1, 0x40, 0x88, 
-0x00, 0x28, 0x1c, 0xd1, 0x01, 0x98, 0x42, 0x4a, 0x00, 0x28, 0x05, 0xd0, 
-0x01, 0x28, 0x16, 0xd1, 0xd0, 0x8a, 0xc0, 0x08, 0x13, 0xd2, 0x0f, 0xe0, 
-0xd0, 0x8a, 0x00, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x02, 0x79, 0x00, 0x2a, 
-0x0b, 0xd1, 0x6d, 0x23, 0x5b, 0x01, 0xc0, 0x18, 0x02, 0x88, 0x40, 0x88, 
-0x10, 0x40, 0x40, 0x09, 0x00, 0x07, 0x02, 0xd1, 0x04, 0x23, 0x99, 0x43, 
-0x79, 0x83, 0x78, 0x8b, 0x04, 0x21, 0x01, 0x40, 
-0x02, 0x9a, 0x1f, 0xd0, 0x39, 0x8b, 0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, 
-0x25, 0xd3, 0xff, 0x23, 0x01, 0x98, 0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, 
-0x00, 0x25, 0x00, 0x98, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, 
-0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, 
-0x13, 0xd0, 0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x25, 0xfe, 0x3d, 0x83, 
-0x00, 0x20, 0xc0, 0x43, 0x20, 0x62, 0x0a, 0xe0, 0x38, 0x8b, 0x40, 0x0b, 
-0x07, 0xd2, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x18, 0xfe, 
-0x09, 0x20, 0x40, 0x02, 0x38, 0x83, 0x78, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, 
-0x1b, 0x48, 0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x6a, 0xfc, 
-0xc2, 0x07, 0xd2, 0x0f, 0x18, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, 
-0x2b, 0x43, 0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 
-0xcb, 0x65, 0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, 
-0x03, 0xe0, 0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, 
-0x21, 0x6a, 0x81, 0x42, 0x0c, 0xd0, 0x20, 0x62, 0x0c, 0x48, 0x00, 0x2a, 
-0x03, 0xd0, 0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, 
-0x21, 0x33, 0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
-0xa8, 0x1b, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, 
-0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22, 0x20, 0x28, 0x0f, 0xd2, 
-0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18, 0x37, 0x23, 0x9b, 0x01, 
-0xe3, 0x18, 0x1f, 0x83, 0x82, 0x40, 0x07, 0x23, 0x5b, 0x02, 0xc9, 0x18, 
-0x10, 0x1c, 0x8a, 0x69, 0x10, 0x43, 0x88, 0x61, 0x90, 0xbc, 0x70, 0x47, 
-0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69, 0x0b, 0x49, 0x49, 0x8b, 
-0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0, 0x01, 0x23, 0xdb, 0x02, 
-0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43, 0x05, 0xe0, 0x01, 0x23, 
-0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08, 0x52, 0x00, 0xca, 0x65, 
-0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0x68, 0x1b, 0x00, 0x80, 
-0x10, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xff, 0xf7, 0xde, 0xff, 
-0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20, 0x01, 0xab, 0x18, 0x80, 
-0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab, 0x5a, 0x80, 0xd9, 0x80, 
-0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91, 0x03, 0x90, 0x68, 0x46, 
-0x00, 0x21, 0xfc, 0xf7, 0x9d, 0xfd, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 
-0x10, 0x2a, 0x00, 0x80, 0x0d, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 
-0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 
-0x09, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x08, 0x48, 0x80, 0x6c, 
-0x00, 0x04, 0x00, 0x0c, 0x07, 0x4b, 0x98, 0x42, 0x02, 0xd0, 0x02, 0x33, 
-0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 
+0x15, 0x61, 0x02, 0x25, 0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 
+0x25, 0x43, 0x15, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c, 
+0x33, 0x43, 0x13, 0x61, 0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23, 
+0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21, 
+0x25, 0x1c, 0xcd, 0x40, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 
+0x13, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39, 
+0x10, 0x28, 0xf1, 0xd3, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61, 
+0x13, 0x61, 0x03, 0x20, 0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 
+0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x4f, 0x4d, 
+0x08, 0x21, 0x02, 0x20, 0x2a, 0x1c, 0xfc, 0xf7, 0x75, 0xfa, 0x4d, 0x4c, 
+0x71, 0x23, 0x5b, 0x01, 0xe7, 0x18, 0x38, 0x80, 0x1a, 0x21, 0x02, 0x20, 
+0x2a, 0x1c, 0xfc, 0xf7, 0x6b, 0xfa, 0x78, 0x80, 0x20, 0x79, 0x00, 0x28, 
+0x0b, 0xd0, 0x00, 0x20, 0x38, 0x80, 0xe0, 0x68, 0x01, 0x28, 0x10, 0xd1, 
+0x44, 0x48, 0x00, 0x68, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x99, 0x02, 
+0x08, 0x60, 0xe0, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x60, 0x88, 0x00, 0x28, 
+0x03, 0xd1, 0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x43, 0xff, 0x01, 0x21, 
+0xc9, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3e, 0xff, 0x00, 0x25, 0x7d, 0x26, 
+0xf6, 0x00, 0x00, 0xe0, 0x01, 0x35, 0x00, 0x20, 0xff, 0xf7, 0x9c, 0xfe, 
+0x00, 0x0c, 0x01, 0xd3, 0xb5, 0x42, 0xf7, 0xd3, 
+0x00, 0x25, 0x05, 0xe0, 0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, 
+0x2b, 0xff, 0x01, 0x35, 0x00, 0x20, 0xff, 0xf7, 0x8d, 0xfe, 0x40, 0x0b, 
+0x01, 0xd2, 0xb5, 0x42, 0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x86, 0xfe, 
+0xff, 0x23, 0xe1, 0x33, 0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0x38, 0x88, 
+0xff, 0x23, 0x01, 0x33, 0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01, 
+0x19, 0x43, 0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0x78, 0x88, 0x01, 0x28, 
+0x03, 0xd1, 0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23, 
+0x19, 0x43, 0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0x78, 0x88, 0x01, 0x28, 
+0x03, 0xd1, 0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 
+0x19, 0x43, 0x04, 0x20, 0xff, 0xf7, 0xf8, 0xfe, 0x09, 0x21, 0x49, 0x02, 
+0x00, 0x20, 0xff, 0xf7, 0xf3, 0xfe, 0xe0, 0x68, 0x00, 0x28, 0x0c, 0xd1, 
+0x00, 0x21, 0x1b, 0x20, 0xff, 0xf7, 0xec, 0xfe, 0x1a, 0x20, 0xff, 0xf7, 
+0x4f, 0xfe, 0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7, 
+0xe3, 0xfe, 0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f, 
+0x08, 0xd9, 0x38, 0x1c, 0xff, 0xf7, 0x40, 0xfe, 0x79, 0x00, 0x09, 0x19, 
+0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x88, 0x83, 0x01, 0x37, 0x20, 0x2f, 
+0xef, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x79, 0xbf, 0x21, 0x40, 
+0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb0, 0x13, 0x48, 
+0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91, 
+0x81, 0x68, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91, 
+0x01, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91, 
+0x81, 0x69, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91, 
+0x01, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91, 
+0x81, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90, 
+0x01, 0xb0, 0x70, 0x47, 0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 
+0x68, 0x4d, 0x1b, 0x23, 0xdb, 0x01, 0xef, 0x18, 0xf8, 0x8b, 0x04, 0x22, 
+0x02, 0x40, 0x02, 0x92, 0x71, 0x23, 0x5b, 0x01, 0xe8, 0x18, 0x01, 0x88, 
+0xc0, 0x46, 0x01, 0x91, 0x40, 0x88, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, 
+0x03, 0xe0, 0x08, 0x2c, 0x01, 0xd3, 0x0f, 0x2c, 0x08, 0xd9, 0x20, 0x1c, 
+0xff, 0xf7, 0xe8, 0xfd, 0x61, 0x00, 0x49, 0x19, 0x1b, 0x23, 0xdb, 0x01, 
+0xc9, 0x18, 0x88, 0x83, 0x01, 0x34, 0x20, 0x2c, 0xef, 0xd3, 0x58, 0x4c, 
+0xe0, 0x69, 0x00, 0x28, 0x15, 0xd0, 0x57, 0x4e, 0x20, 0x25, 0x01, 0x3d, 
+0x53, 0x49, 0xe0, 0x69, 0x30, 0x40, 0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18, 
+0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x8b, 0x28, 0x1c, 0xff, 0xf7, 
+0x65, 0xfe, 0xe0, 0x69, 0xb0, 0x43, 0xe0, 0x61, 0x76, 0x08, 0x00, 0x2d, 
+0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, 0xc2, 0xfd, 0x48, 0x49, 0xc0, 0x46, 
+0xf8, 0x83, 0xf8, 0x8b, 0xc2, 0x08, 0x25, 0xd3, 0xca, 0x68, 0x01, 0x2a, 
+0x13, 0xd1, 0x0a, 0x79, 0x00, 0x2a, 0x1f, 0xd1, 0x49, 0x88, 0x00, 0x29, 
+0x1c, 0xd1, 0x01, 0x99, 0x43, 0x4a, 0x00, 0x29, 0x05, 0xd0, 0x01, 0x29, 
+0x16, 0xd1, 0x51, 0x8b, 0xc9, 0x08, 0x13, 0xd2, 0x0f, 0xe0, 0x51, 0x8b, 
+0x09, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x0a, 0x79, 0x00, 0x2a, 0x0b, 0xd1, 
+0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x8a, 0x88, 0xc9, 0x88, 0x11, 0x40, 
+0x49, 0x09, 0x09, 0x07, 0x02, 0xd1, 0x04, 0x23, 
+0x98, 0x43, 0xf8, 0x83, 0xf8, 0x8b, 0x04, 0x21, 0x01, 0x40, 0x02, 0x9a, 
+0x1f, 0xd0, 0xb9, 0x8b, 0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, 0x25, 0xd3, 
+0xff, 0x23, 0x01, 0x98, 0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, 0x00, 0x25, 
+0x00, 0x98, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, 0x00, 0x28, 
+0x02, 0xd1, 0x01, 0x23, 0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, 0x13, 0xd0, 
+0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x10, 0xfe, 0xbd, 0x83, 0x00, 0x20, 
+0xc0, 0x43, 0x60, 0x62, 0x0a, 0xe0, 0xb8, 0x8b, 0x40, 0x0b, 0x07, 0xd2, 
+0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x03, 0xfe, 0x09, 0x20, 
+0x40, 0x02, 0xb8, 0x83, 0xf8, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, 0x1d, 0x48, 
+0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x51, 0xfc, 0xc2, 0x07, 
+0xd2, 0x0f, 0x1a, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, 0x2b, 0x43, 
+0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, 
+0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, 0x03, 0xe0, 
+0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, 0x61, 0x6a, 
+0x81, 0x42, 0x0c, 0xd0, 0x60, 0x62, 0x0e, 0x48, 0x00, 0x2a, 0x03, 0xd0, 
+0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x21, 0x33, 
+0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x68, 0x1c, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0x80, 0x28, 0x1c, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 
+0xa4, 0x2a, 0x00, 0x80, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22, 
+0x20, 0x28, 0x0f, 0xd2, 0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18, 
+0x37, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0x9f, 0x83, 0x82, 0x40, 0x07, 0x23, 
+0x5b, 0x02, 0xc9, 0x18, 0x10, 0x1c, 0xca, 0x69, 0x10, 0x43, 0xc8, 0x61, 
+0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69, 
+0x0b, 0x49, 0xc9, 0x8b, 0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0, 
+0x01, 0x23, 0xdb, 0x02, 0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43, 
+0x05, 0xe0, 0x01, 0x23, 0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08, 
+0x52, 0x00, 0xca, 0x65, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 
+0xe8, 0x1b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 
+0xff, 0xf7, 0xde, 0xff, 0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20, 
+0x01, 0xab, 0x18, 0x80, 0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab, 
+0x5a, 0x80, 0xd9, 0x80, 0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91, 
+0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfc, 0xf7, 0xd5, 0xf9, 0x04, 0xb0, 
+0x08, 0xbc, 0x18, 0x47, 0xa4, 0x2a, 0x00, 0x80, 0x0f, 0x48, 0x01, 0x68, 
+0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 
+0x80, 0x0a, 0x03, 0xd3, 0x0b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 
+0x0a, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x4b, 0x98, 0x42, 
+0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x07, 0x4b, 0x98, 0x42, 
+0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x00, 0x00, 
 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 
-0x04, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24, 0x21, 0x1c, 0x17, 0x48, 
-0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x02, 0xd1, 
-0x00, 0x68, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x21, 0x09, 0x06, 0x09, 0x0e, 
-0x11, 0x4f, 0x12, 0x4a, 0x02, 0xd0, 0x38, 0x68, 0x00, 0x0c, 0x00, 0xe0, 
-0x90, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x0f, 0x4b, 
-0x98, 0x42, 0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x0d, 0x4b, 
-0x98, 0x42, 0x0c, 0xd1, 0x00, 0x29, 0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, 
-0x00, 0xe0, 0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, 
-0x00, 0x0e, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, 
-0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 
-0x04, 0x99, 0x00, 0x00, 0x05, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, 
-0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, 
-0x80, 0x0a, 0x02, 0xd3, 0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, 
-0x40, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, 
-0x40, 0x08, 0x01, 0xd3, 0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, 
-0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 
-0xf0, 0xb5, 0x01, 0x27, 0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x7a, 0xff, 
-0x03, 0x1c, 0x19, 0x4a, 0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, 
-0x1b, 0xd1, 0xcb, 0x04, 0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, 
-0x43, 0x60, 0x06, 0x68, 0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, 
-0x43, 0x60, 0x03, 0x68, 0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, 
-0x05, 0x23, 0x0f, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, 
-0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, 
-0x23, 0x60, 0x04, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 
-0x06, 0x60, 0x27, 0x68, 0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, 
-0x00, 0x00, 0x22, 0x40, 0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, 
-0x00, 0x00, 0x28, 0x40, 0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x38, 0xff, 
-0x01, 0x28, 0x05, 0xd1, 0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, 
-0x08, 0x40, 0x22, 0xe0, 0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 
-0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 
-0x14, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, 
-0x00, 0x04, 0x00, 0x0c, 0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, 
-0x01, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, 
-0x07, 0x07, 0x05, 0x03, 0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, 
-0x00, 0x20, 0x01, 0x21, 0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, 
-0x08, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x98, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, 
-0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, 
-0xf0, 0xb5, 0x83, 0xb0, 0x07, 0x1c, 0x01, 0x20, 0x02, 0x90, 0x01, 0x25, 
-0x02, 0x24, 0x10, 0x26, 0x20, 0x21, 0x00, 0x91, 0xff, 0xf7, 0xea, 0xfe, 
-0x01, 0x28, 0x4d, 0xd1, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x3a, 0xd1, 
-0x2e, 0x4e, 0x3c, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x1c, 0xfb, 
-0x3e, 0x21, 0x05, 0x1c, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x16, 0xfb, 
-0x00, 0x04, 0x05, 0x43, 0x40, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 
-0x0f, 0xfb, 0x01, 0x90, 0x42, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 
-0x09, 0xfb, 0x00, 0x04, 0x01, 0x99, 0x08, 0x43, 0x06, 0x1c, 0xa8, 0x2f, 
-0x1b, 0xd1, 0x1f, 0x4a, 0x44, 0x21, 0x02, 0x20, 
-0xfc, 0xf7, 0xfe, 0xfa, 0x04, 0x1c, 0x1c, 0x4a, 0x46, 0x21, 0x02, 0x20, 
-0xfc, 0xf7, 0xf8, 0xfa, 0x00, 0x04, 0x04, 0x43, 0x18, 0x4a, 0x48, 0x21, 
-0x02, 0x20, 0xfc, 0xf7, 0xf1, 0xfa, 0x00, 0x90, 0x15, 0x4a, 0x4a, 0x21, 
-0x02, 0x20, 0xfc, 0xf7, 0xeb, 0xfa, 0x00, 0x04, 0x00, 0x99, 0x01, 0x43, 
-0x00, 0x91, 0x28, 0x1c, 0x30, 0x43, 0x20, 0x43, 0x00, 0x99, 0x08, 0x43, 
-0x00, 0xd1, 0x16, 0xe0, 0x11, 0x20, 0x00, 0x04, 0x05, 0x62, 0x46, 0x62, 
-0x84, 0x62, 0x00, 0x99, 0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x0a, 0x48, 
-0xc0, 0x46, 0x01, 0x60, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, 
-0x01, 0x21, 0x01, 0x60, 0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, 
-0x02, 0x98, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x39, 0xb7, 0x21, 0x40, 0x98, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x07, 0x1c, 
-0xff, 0xf7, 0x7e, 0xfe, 0x01, 0x28, 0x19, 0xd1, 0x01, 0x05, 0x11, 0x48, 
-0x00, 0x2f, 0x18, 0xd0, 0x0b, 0x0a, 0x02, 0x68, 0x9a, 0x43, 0x0a, 0x60, 
-0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x0b, 0xd1, 
-0x00, 0x68, 0x80, 0x0a, 0x08, 0xd3, 0x0a, 0x48, 0x40, 0x6a, 0xff, 0x22, 
-0x01, 0x32, 0x02, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x4a, 0x62, 0x48, 0x62, 
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x68, 0x01, 0x23, 0x1b, 0x03, 
-0x18, 0x43, 0x08, 0x60, 0xf6, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
-0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x70, 0x47, 0x00, 0x00, 
+0x04, 0x99, 0x00, 0x00, 0x07, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24, 
+0x21, 0x1c, 0x18, 0x48, 0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68, 
+0x12, 0x0c, 0x02, 0xd1, 0x00, 0x68, 0x80, 0x0a, 
+0x00, 0xd2, 0x00, 0x21, 0x09, 0x06, 0x09, 0x0e, 0x12, 0x4f, 0x13, 0x4a, 
+0x02, 0xd0, 0x38, 0x68, 0x00, 0x0c, 0x00, 0xe0, 0x90, 0x6c, 0x00, 0x04, 
+0x00, 0x0c, 0x10, 0x4b, 0x98, 0x42, 0x08, 0xd0, 0x02, 0x33, 0x98, 0x42, 
+0x05, 0xd0, 0x0e, 0x4b, 0x98, 0x42, 0x02, 0xd0, 0x02, 0x3b, 0x98, 0x42, 
+0x0c, 0xd1, 0x00, 0x29, 0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, 0x00, 0xe0, 
+0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, 0x00, 0x0e, 
+0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, 0x10, 0x40, 
+0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0x04, 0x99, 0x00, 0x00, 
+0x07, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 
+0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x02, 0xd3, 
+0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, 0x40, 0x6c, 0x00, 0x04, 
+0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, 0x40, 0x08, 0x01, 0xd3, 
+0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, 0x00, 0x00, 0x10, 0x40, 
+0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x27, 
+0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x72, 0xff, 0x03, 0x1c, 0x19, 0x4a, 
+0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, 0x1b, 0xd1, 0xcb, 0x04, 
+0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, 0x43, 0x60, 0x06, 0x68, 
+0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, 0x43, 0x60, 0x03, 0x68, 
+0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, 0x05, 0x23, 0x0f, 0x4f, 
+0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 
+0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, 0x23, 0x60, 0x04, 0x23, 
+0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x06, 0x60, 0x27, 0x68, 
+0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x22, 0x40, 
+0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x28, 0x40, 
+0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x01, 0x28, 0x05, 0xd1, 
+0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, 0x08, 0x40, 0x22, 0xe0, 
+0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 
+0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 0x14, 0x48, 0x00, 0x68, 
+0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c, 
+0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, 0x01, 0xa3, 0x1b, 0x5c, 
+0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, 0x07, 0x07, 0x05, 0x03, 
+0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x21, 
+0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, 0x08, 0x06, 0x00, 0x0e, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x98, 0x6e, 0x21, 0x40, 
+0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 
+0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, 0xf0, 0xb5, 0x83, 0xb0, 
+0x07, 0x1c, 0x01, 0x20, 0x02, 0x90, 0x01, 0x25, 0x02, 0x24, 0x10, 0x26, 
+0x20, 0x21, 0x00, 0x91, 0xff, 0xf7, 0xe2, 0xfe, 0x01, 0x28, 0x4d, 0xd1, 
+0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x3a, 0xd1, 0x2e, 0x4e, 0x3c, 0x21, 
+0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, 0x4c, 0xff, 0x3e, 0x21, 0x05, 0x1c, 
+0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, 0x46, 0xff, 0x00, 0x04, 0x05, 0x43, 
+0x40, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, 
+0x3f, 0xff, 0x01, 0x90, 0x42, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfb, 0xf7, 
+0x39, 0xff, 0x00, 0x04, 0x01, 0x99, 0x08, 0x43, 0x06, 0x1c, 0xa8, 0x2f, 
+0x1b, 0xd1, 0x1f, 0x4a, 0x44, 0x21, 0x02, 0x20, 0xfb, 0xf7, 0x2e, 0xff, 
+0x04, 0x1c, 0x1c, 0x4a, 0x46, 0x21, 0x02, 0x20, 0xfb, 0xf7, 0x28, 0xff, 
+0x00, 0x04, 0x04, 0x43, 0x18, 0x4a, 0x48, 0x21, 0x02, 0x20, 0xfb, 0xf7, 
+0x21, 0xff, 0x00, 0x90, 0x15, 0x4a, 0x4a, 0x21, 0x02, 0x20, 0xfb, 0xf7, 
+0x1b, 0xff, 0x00, 0x04, 0x00, 0x99, 0x01, 0x43, 0x00, 0x91, 0x28, 0x1c, 
+0x30, 0x43, 0x20, 0x43, 0x00, 0x99, 0x08, 0x43, 0x00, 0xd1, 0x16, 0xe0, 
+0x11, 0x20, 0x00, 0x04, 0x05, 0x62, 0x46, 0x62, 0x84, 0x62, 0x00, 0x99, 
+0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x0a, 0x48, 0xc0, 0x46, 0x01, 0x60, 
+0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, 0x01, 0x21, 0x01, 0x60, 
+0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, 0x02, 0x98, 0x03, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x79, 0xbf, 0x21, 0x40, 
+0x98, 0x6e, 0x21, 0x40, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 
 0x90, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x21, 0x68, 0x12, 0x48, 0x81, 0x42, 
-0x0b, 0xd0, 0x00, 0x23, 0x21, 0x1c, 0xe2, 0x1d, 0x6d, 0x32, 0x00, 0xe0, 
-0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0x74, 0x20, 0xa0, 0x80, 
+0x0b, 0xd0, 0x00, 0x23, 0x21, 0x1c, 0xe2, 0x1d, 0xc5, 0x32, 0x00, 0xe0, 
+0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0xcc, 0x20, 0xa0, 0x80, 
 0x67, 0x72, 0x38, 0x01, 0x00, 0xf0, 0x18, 0xf8, 0x27, 0x72, 0x0a, 0x48, 
-0xc0, 0x46, 0xe0, 0x60, 0x08, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19, 
+0xc0, 0x46, 0xe0, 0x60, 0x09, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19, 
 0x01, 0x7d, 0x01, 0x31, 0x01, 0x75, 0xe0, 0x88, 0x01, 0x30, 0xe0, 0x80, 
 0x01, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x80, 
-0xfe, 0xca, 0x01, 0x20, 0x17, 0x40, 0x00, 0x02, 0x80, 0xb4, 0x08, 0x4a, 
-0xd1, 0x1d, 0x49, 0x31, 0x0b, 0x78, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23, 
-0x0b, 0x70, 0x07, 0x1c, 0x08, 0x78, 0x43, 0x1c, 0x0b, 0x70, 0x80, 0x18, 
-0x50, 0x30, 0x47, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80, 
+0xee, 0xff, 0xc0, 0xd0, 0x02, 0x10, 0x00, 0x03, 0x80, 0xb4, 0x08, 0x4a, 
+0xd1, 0x1d, 0x89, 0x31, 0x0b, 0x7b, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23, 
+0x0b, 0x73, 0x07, 0x1c, 0x08, 0x7b, 0x43, 0x1c, 0x0b, 0x73, 0x80, 0x18, 
+0x90, 0x30, 0x47, 0x73, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80, 
 0x07, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x01, 0x20, 
 0x00, 0x2a, 0x06, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x09, 0x68, 
 0x89, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40, 
 0x90, 0xb5, 0x07, 0x1c, 0x09, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7, 
-0x4d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42, 
-0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfc, 0xf7, 
-0x81, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xbc, 0x67, 0x21, 0x40, 
+0xab, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42, 
+0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfb, 0xf7, 
+0xdf, 0xff, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x67, 0x21, 0x40, 
 0xf8, 0xb5, 0x07, 0x1c, 0x79, 0x7a, 0x76, 0x48, 0x00, 0x23, 0x76, 0x4c, 
 0x01, 0x29, 0x5d, 0xd1, 0xa2, 0x88, 0xc0, 0x46, 0x00, 0x92, 0xa1, 0x89, 
 0x8a, 0x42, 0x74, 0xda, 0xfa, 0x7a, 0x00, 0x2a, 0x15, 0xd0, 0x7a, 0x6c, 
 0x00, 0x2a, 0x12, 0xd0, 0x8a, 0x42, 0x10, 0xd8, 0x00, 0x9a, 0x51, 0x1c, 
 0xa1, 0x80, 0xa1, 0x88, 0xc0, 0x46, 0x41, 0x81, 0x78, 0x6c, 0x6b, 0x4e, 
-0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, 
-0x79, 0x6c, 0x59, 0x43, 0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, 
-0x01, 0x32, 0x12, 0x04, 0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, 
-0x23, 0x80, 0x00, 0x22, 0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, 
-0x5e, 0x4b, 0x1d, 0x88, 0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, 
-0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 
+0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, 0x79, 0x6c, 0x59, 0x43, 
+0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, 0x01, 0x32, 0x12, 0x04, 
+0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, 0x23, 0x80, 0x00, 0x22, 
+0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, 0x5e, 0x4b, 0x1d, 0x88, 
+0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, 0x01, 0x36, 0x01, 0x23, 
+0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 
 0x15, 0xd1, 0x58, 0x49, 0x00, 0x9a, 0x01, 0x32, 0x8a, 0x80, 0x8a, 0x88, 
 0xc0, 0x46, 0x42, 0x81, 0x08, 0x88, 0x01, 0x30, 0x54, 0x4e, 0xc0, 0x46, 
 0xf0, 0x80, 0x58, 0x20, 0x68, 0x43, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 
-0x65, 0xfa, 0xf0, 0x88, 0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, 
+0x8d, 0xfa, 0xf0, 0x88, 0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, 
 0x01, 0x35, 0x2d, 0x04, 0x2d, 0x0c, 0x1d, 0x80, 0x8d, 0x42, 0x01, 0xdb, 
 0x00, 0x25, 0x1d, 0x80, 0x01, 0x32, 0x12, 0x04, 0x12, 0x14, 0x91, 0x42, 
 0xce, 0xdc, 0x81, 0xe0, 0xe1, 0x88, 0xe2, 0x89, 0x91, 0x42, 0x18, 0xda, 
@@ -3446,9 +3614,9 @@ const u8 typhoon_firmware_image[] = {
 0xdb, 0x03, 0x78, 0x6c, 0x18, 0x43, 0x3a, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 
 0x00, 0xe0, 0x63, 0xe0, 0xe0, 0x6a, 0x79, 0x6c, 0x4b, 0x00, 0x59, 0x18, 
 0x49, 0x01, 0x40, 0x18, 0xc1, 0x1f, 0x59, 0x39, 0x38, 0x1c, 0x00, 0xf0, 
-0x4b, 0xfa, 0xe0, 0x6a, 0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 
+0x79, 0xfa, 0xe0, 0x6a, 0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 
 0x80, 0x18, 0x01, 0x39, 0x09, 0x04, 0x09, 0x0c, 0x60, 0x38, 0x00, 0xf0, 
-0xc5, 0xfa, 0xb6, 0xe7, 0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04, 
+0xf3, 0xfa, 0xb6, 0xe7, 0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04, 
 0x09, 0x0c, 0x61, 0x80, 0xe2, 0x89, 0x91, 0x42, 0x00, 0xdb, 0x63, 0x80, 
 0x00, 0x21, 0x00, 0x2a, 0x3e, 0xdd, 0x24, 0x4c, 0xe4, 0x6a, 0x23, 0x4b, 
 0x5d, 0x88, 0x6b, 0x00, 0x5b, 0x19, 0x5b, 0x01, 0xe3, 0x18, 0xde, 0x1d, 
@@ -3456,193 +3624,208 @@ const u8 typhoon_firmware_image[] = {
 0x20, 0xd1, 0x1c, 0x4e, 0xf1, 0x88, 0x01, 0x31, 0xf1, 0x80, 0xf1, 0x88, 
 0xc0, 0x46, 0x81, 0x81, 0x70, 0x88, 0x01, 0x23, 0xdb, 0x03, 0x01, 0x30, 
 0x18, 0x43, 0x17, 0x49, 0xc0, 0x46, 0xc8, 0x80, 0x68, 0x00, 0x40, 0x19, 
-0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xfa, 0x71, 0x88, 
+0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x39, 0xfa, 0x71, 0x88, 
 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0xf0, 0x6a, 0x80, 0x18, 0x00, 0xf0, 
-0x89, 0xfa, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35, 
+0xb7, 0xfa, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35, 
 0x2d, 0x04, 0x2d, 0x0c, 0x5d, 0x80, 0x95, 0x42, 0x01, 0xdb, 0x00, 0x25, 
 0x5d, 0x80, 0x01, 0x31, 0x09, 0x04, 0x09, 0x14, 0x8a, 0x42, 0xc2, 0xdc, 
 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x00, 0x20, 0xc0, 0x43, 0xf8, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xb8, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, 
-0xbc, 0x67, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03, 
-0x33, 0x40, 0x01, 0x24, 0x30, 0x4f, 0x00, 0x20, 0x30, 0x4a, 0x31, 0x4d, 
-0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x2f, 0xd0, 0xe3, 0x03, 0xf3, 0x1a, 
-0x51, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x4e, 0xd3, 0xee, 0x88, 0x00, 0x2e, 
-0x4b, 0xd0, 0xee, 0x6a, 0x5d, 0x1e, 0x6b, 0x00, 0x5d, 0x19, 0x6d, 0x01, 
-0x73, 0x19, 0x9e, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, 
-0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x33, 0x9b, 0x8b, 0x9b, 0x00, 
-0x21, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0xf0, 0x50, 
-0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x1e, 0x4e, 0xf2, 0x6a, 0x52, 0x19, 
-0x90, 0x60, 0xf0, 0x88, 0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, 
-0x88, 0x81, 0x19, 0x49, 0x00, 0x28, 0x23, 0xd1, 0x4f, 0x80, 0x21, 0xe0, 
-0x00, 0x2e, 0x22, 0xd9, 0xab, 0x89, 0xb3, 0x42, 0x1f, 0xd3, 0xab, 0x88, 
-0x00, 0x2b, 0x1c, 0xd0, 0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x58, 0x23, 
-0x01, 0x3e, 0x73, 0x43, 0xaa, 0x6a, 0xd2, 0x18, 0x93, 0x68, 0x1b, 0x06, 
-0x1b, 0x0e, 0x03, 0x2b, 0x02, 0xd0, 0xcb, 0x89, 0x01, 0x33, 0xcb, 0x81, 
-0x90, 0x60, 0xa8, 0x88, 0x01, 0x38, 0xa8, 0x80, 0xa8, 0x88, 0xc0, 0x46, 
-0x48, 0x81, 0x00, 0x28, 0x00, 0xd1, 0x2f, 0x80, 0x20, 0x1c, 0xf0, 0xbc, 
-0x70, 0x47, 0xca, 0x89, 0x01, 0x32, 0xca, 0x81, 0xf9, 0xe7, 0x00, 0x00, 
-0xff, 0xff, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, 
-0x00, 0xb5, 0x00, 0x21, 0x41, 0x60, 0x10, 0x49, 0x4a, 0x68, 0x00, 0x2a, 
-0x10, 0xd1, 0xca, 0x68, 0x00, 0x2a, 0x04, 0xd0, 0xca, 0x1d, 0x19, 0x32, 
-0x12, 0x79, 0x00, 0x2a, 0x08, 0xd0, 0x4a, 0x69, 0x00, 0x2a, 0x0b, 0xd1, 
-0x88, 0x61, 0x48, 0x61, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
-0x4a, 0x69, 0x00, 0x2a, 0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, 
-0x8a, 0x69, 0xc0, 0x46, 0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, 
-0xec, 0x05, 0x00, 0x80, 0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, 
-0x4c, 0xd0, 0x08, 0x22, 0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, 
-0xd9, 0x1d, 0xb9, 0x31, 0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, 
-0xc0, 0x46, 0x0c, 0x61, 0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, 
-0xc0, 0x46, 0x8c, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, 
-0xc0, 0x46, 0x0c, 0x63, 0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, 
-0xc0, 0x46, 0x0c, 0x61, 0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, 
-0xc0, 0x46, 0x8c, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, 
-0xc0, 0x46, 0x0c, 0x63, 0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, 
-0xcc, 0x82, 0x4f, 0x83, 0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, 
-0x8c, 0x00, 0x05, 0x19, 0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, 
-0x01, 0x34, 0x65, 0x62, 0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, 
-0x07, 0xd2, 0x8a, 0x00, 0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, 
-0x01, 0x31, 0x10, 0x29, 0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, 
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 
-0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, 
-0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 
-0x20, 0x01, 0x40, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 
-0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, 
-0x36, 0x36, 0x36, 0x36, 0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, 
-0x15, 0x4d, 0xe9, 0x1d, 0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, 
-0x00, 0x20, 0xfc, 0xf7, 0x1a, 0xf8, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, 
-0x23, 0x1c, 0x0d, 0x1c, 0x11, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x11, 0xf8, 
-0x29, 0x1c, 0x23, 0x1c, 0x0e, 0x4a, 0x00, 0x20, 0xfc, 0xf7, 0x0b, 0xf8, 
-0x39, 0x1c, 0x23, 0x1c, 0x0c, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x05, 0xf8, 
-0x00, 0x21, 0x0b, 0x48, 0xc2, 0x1d, 0x19, 0x32, 
-0x51, 0x71, 0x01, 0x21, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x08, 0x1c, 
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0xad, 0x20, 0x40, 
-0x75, 0x08, 0xff, 0xff, 0x28, 0x00, 0x03, 0x00, 0x40, 0x00, 0x02, 0x00, 
-0x14, 0x00, 0x07, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x37, 0x4a, 
-0x50, 0x69, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, 
-0x01, 0x06, 0x09, 0x0e, 0x33, 0x4b, 0x01, 0x29, 0x49, 0xd1, 0x1f, 0x68, 
-0x19, 0x1c, 0x32, 0x4b, 0x9f, 0x42, 0x04, 0xd1, 0xff, 0xf7, 0x3e, 0xff, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23, 0x9f, 0x00, 0xcc, 0x59, 
-0x55, 0x69, 0xef, 0x19, 0x3c, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 
-0x00, 0x0a, 0x00, 0x02, 0x02, 0x23, 0x18, 0x43, 0x53, 0x69, 0xc0, 0x46, 
-0x98, 0x60, 0x50, 0x69, 0x08, 0x23, 0xc2, 0x68, 0x13, 0x40, 0x25, 0x4f, 
-0xfa, 0x1d, 0xb9, 0x32, 0x00, 0x2b, 0x02, 0xd0, 0x04, 0x23, 0x23, 0x4c, 
-0x01, 0xe0, 0x05, 0x23, 0x22, 0x4c, 0xc0, 0x46, 0x14, 0x61, 0x40, 0x24, 
-0xd4, 0x82, 0x00, 0x24, 0x54, 0x83, 0x20, 0x4c, 0x00, 0x22, 0x00, 0x2b, 
-0x0c, 0xd9, 0x95, 0x00, 0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, 
-0xff, 0x35, 0x01, 0x35, 0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, 
-0x10, 0x2a, 0x07, 0xd2, 0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, 
-0x5c, 0x62, 0x01, 0x32, 0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, 
-0xbc, 0xe7, 0x00, 0x21, 0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, 
-0x7c, 0x62, 0x01, 0x31, 0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 
-0x03, 0x23, 0x18, 0x43, 0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, 
-0x40, 0x68, 0xc0, 0x46, 0x50, 0x61, 0x09, 0x48, 0xfb, 0xf7, 0x7a, 0xff, 
-0xa4, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, 
-0x67, 0x45, 0x23, 0x01, 0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 
-0x20, 0x01, 0x40, 0x00, 0x5c, 0x5c, 0x5c, 0x5c, 0x85, 0x30, 0xff, 0xff, 
-0x80, 0xb5, 0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0xb9, 0x6b, 
-0x0b, 0x48, 0xc2, 0x68, 0x12, 0x04, 0x51, 0x40, 0x82, 0x69, 0x51, 0x40, 
-0x39, 0x65, 0xf9, 0x6b, 0x82, 0x69, 0x12, 0x04, 0xd2, 0x43, 0x51, 0x40, 
-0xc0, 0x68, 0xc0, 0x43, 0x48, 0x40, 0x78, 0x65, 0x04, 0x48, 0x01, 0x89, 
-0x01, 0x31, 0x01, 0x81, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0x08, 0x83, 0x20, 0x40, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 
-0x0f, 0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68, 
-0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 
-0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 
-0x08, 0x43, 0x38, 0x65, 0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69, 
-0xc0, 0x46, 0xb8, 0x65, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 
-0x90, 0xb5, 0x00, 0x22, 0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18, 
-0x5f, 0x62, 0x01, 0x32, 0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08, 
-0x03, 0xd3, 0x00, 0x23, 0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b, 
+0x08, 0xbc, 0x18, 0x47, 0x4c, 0x2b, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, 
+0x70, 0x67, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03, 
+0x33, 0x40, 0x01, 0x24, 0x44, 0x4f, 0x00, 0x20, 0x44, 0x4a, 0x45, 0x4d, 
+0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x41, 0xd0, 0xe3, 0x03, 0xf3, 0x1a, 
+0x73, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x71, 0xd3, 0xee, 0x88, 0x00, 0x2e, 
+0x6d, 0xd0, 0xed, 0x6a, 0x5e, 0x1e, 0x73, 0x00, 0x9b, 0x19, 0x5b, 0x01, 
+0xed, 0x18, 0xae, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, 
+0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x35, 0xad, 0x8b, 0xad, 0x00, 
+0x35, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0x70, 0x51, 0x55, 0x89, 0x01, 0x35, 
+0x55, 0x81, 0x32, 0x4e, 0xf2, 0x6a, 0xd2, 0x18, 0x90, 0x60, 0xf2, 0x6a, 
+0xd2, 0x18, 0x90, 0x63, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x63, 0xf2, 0x6a, 
+0xd2, 0x18, 0x10, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0x50, 0x64, 0xf2, 0x6a, 
+0xd2, 0x18, 0x90, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x64, 0xf0, 0x88, 
+0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, 
+0x88, 0x81, 0x24, 0x49, 0x00, 0x28, 0x39, 0xd1, 0x4f, 0x80, 0x37, 0xe0, 
+0x00, 0x2e, 0x38, 0xd9, 0xab, 0x89, 0xb3, 0x42, 0x30, 0xd3, 0xab, 0x88, 
+0x00, 0x2b, 0x2c, 0xd0, 0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x2a, 0x1c, 
+0xad, 0x6a, 0x58, 0x23, 0x01, 0x3e, 0x73, 0x43, 0xed, 0x18, 0xae, 0x68, 
+0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, 0xce, 0x89, 0x01, 0x36, 
+0xce, 0x81, 0xa8, 0x60, 0x95, 0x6a, 0xed, 0x18, 0xa8, 0x63, 0x95, 0x6a, 
+0xed, 0x18, 0xe8, 0x63, 0x95, 0x6a, 0xed, 0x18, 0x28, 0x64, 0x95, 0x6a, 
+0xed, 0x18, 0x68, 0x64, 0x95, 0x6a, 0xed, 0x18, 0xa8, 0x64, 0x95, 0x6a, 
+0xeb, 0x18, 0xd8, 0x64, 0x90, 0x88, 0x01, 0x38, 0x90, 0x80, 0x90, 0x88, 
+0xc0, 0x46, 0x48, 0x81, 0x00, 0x28, 0x03, 0xd1, 0x01, 0xe0, 0x04, 0xe0, 
+0x03, 0xe0, 0x17, 0x80, 0x20, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0xca, 0x89, 
+0x01, 0x32, 0xca, 0x81, 0xf9, 0xe7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
+0x0c, 0x2b, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x00, 0x21, 
+0x41, 0x60, 0x10, 0x49, 0x4a, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xca, 0x68, 
+0x00, 0x2a, 0x04, 0xd0, 0xca, 0x1d, 0x19, 0x32, 0x12, 0x79, 0x00, 0x2a, 
+0x08, 0xd0, 0x4a, 0x69, 0x00, 0x2a, 0x0b, 0xd1, 0x88, 0x61, 0x48, 0x61, 
+0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x4a, 0x69, 0x00, 0x2a, 
+0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, 0x8a, 0x69, 0xc0, 0x46, 
+0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 
+0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, 0x4c, 0xd0, 0x08, 0x22, 
+0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, 0xd9, 0x1d, 0xb9, 0x31, 
+0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, 0xc0, 0x46, 0x0c, 0x61, 
+0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, 0xc0, 0x46, 0x8c, 0x62, 
+0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0x0c, 0x63, 
+0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, 0xc0, 0x46, 0x0c, 0x61, 
+0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, 0xc0, 0x46, 0x8c, 0x62, 
+0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0x0c, 0x63, 
+0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, 0xcc, 0x82, 0x4f, 0x83, 
+0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, 0x8c, 0x00, 0x05, 0x19, 
+0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, 0x01, 0x34, 0x65, 0x62, 
+0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, 0x07, 0xd2, 0x8a, 0x00, 
+0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, 0x01, 0x31, 0x10, 0x29, 
+0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 
+0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 
+0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x20, 0x01, 0x40, 0x00, 
+0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe, 
+0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, 0x36, 0x36, 0x36, 0x36, 
+0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, 0x15, 0x4d, 0xe9, 0x1d, 
+0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, 0x00, 0x20, 0xfb, 0xf7, 
+0x50, 0xfc, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, 0x23, 0x1c, 0x0d, 0x1c, 
+0x11, 0x4a, 0x01, 0x20, 0xfb, 0xf7, 0x47, 0xfc, 0x29, 0x1c, 0x23, 0x1c, 
+0x0e, 0x4a, 0x00, 0x20, 0xfb, 0xf7, 0x41, 0xfc, 
+0x39, 0x1c, 0x23, 0x1c, 0x0c, 0x4a, 0x01, 0x20, 0xfb, 0xf7, 0x3b, 0xfc, 
+0x00, 0x21, 0x0b, 0x48, 0xc2, 0x1d, 0x19, 0x32, 0x51, 0x71, 0x01, 0x21, 
+0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x08, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x1c, 0xad, 0x20, 0x40, 0x75, 0x08, 0xff, 0xff, 
+0x28, 0x00, 0x03, 0x00, 0x40, 0x00, 0x02, 0x00, 0x14, 0x00, 0x07, 0x00, 
+0x6c, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x37, 0x4a, 0x50, 0x69, 0x01, 0x23, 
+0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x09, 0x0e, 
+0x33, 0x4b, 0x01, 0x29, 0x49, 0xd1, 0x1f, 0x68, 0x19, 0x1c, 0x32, 0x4b, 
+0x9f, 0x42, 0x04, 0xd1, 0xff, 0xf7, 0x3e, 0xff, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x23, 0x9f, 0x00, 0xcc, 0x59, 0x55, 0x69, 0xef, 0x19, 
+0x3c, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 
+0x02, 0x23, 0x18, 0x43, 0x53, 0x69, 0xc0, 0x46, 0x98, 0x60, 0x50, 0x69, 
+0x08, 0x23, 0xc2, 0x68, 0x13, 0x40, 0x25, 0x4f, 0xfa, 0x1d, 0xb9, 0x32, 
+0x00, 0x2b, 0x02, 0xd0, 0x04, 0x23, 0x23, 0x4c, 0x01, 0xe0, 0x05, 0x23, 
+0x22, 0x4c, 0xc0, 0x46, 0x14, 0x61, 0x40, 0x24, 0xd4, 0x82, 0x00, 0x24, 
+0x54, 0x83, 0x20, 0x4c, 0x00, 0x22, 0x00, 0x2b, 0x0c, 0xd9, 0x95, 0x00, 
+0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, 0xff, 0x35, 0x01, 0x35, 
+0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, 0x10, 0x2a, 0x07, 0xd2, 
+0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, 0x5c, 0x62, 0x01, 0x32, 
+0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, 0xbc, 0xe7, 0x00, 0x21, 
+0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, 0x7c, 0x62, 0x01, 0x31, 
+0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 0x03, 0x23, 0x18, 0x43, 
+0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, 0x40, 0x68, 0xc0, 0x46, 
+0x50, 0x61, 0x09, 0x48, 0xfb, 0xf7, 0xb0, 0xfb, 0xa4, 0xe7, 0x00, 0x00, 
+0x6c, 0x06, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, 0x67, 0x45, 0x23, 0x01, 
+0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x20, 0x01, 0x40, 0x00, 
+0x5c, 0x5c, 0x5c, 0x5c, 0xfd, 0x30, 0xff, 0xff, 0x80, 0xb5, 0x87, 0xb0, 
+0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x48, 0xf8, 0x0e, 0x49, 0xc8, 0x68, 
+0x02, 0x04, 0x89, 0x69, 0x4a, 0x40, 0x05, 0x92, 0x09, 0x04, 0xc9, 0x43, 
+0xc0, 0x43, 0x48, 0x40, 0x06, 0x90, 0x08, 0x21, 0x6a, 0x46, 0x05, 0xa8, 
+0xfd, 0xf7, 0x8b, 0xfb, 0x00, 0x98, 0xc0, 0x46, 0x38, 0x65, 0x03, 0x98, 
+0xc0, 0x46, 0x78, 0x65, 0x04, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 
+0x07, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x83, 0x20, 0x40, 
+0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x20, 0x1c, 
+0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68, 0x01, 0x0e, 0xff, 0x22, 
+0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 
+0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x08, 0x43, 0x38, 0x65, 
+0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69, 0xc0, 0x46, 0xb8, 0x65, 
+0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x00, 0x22, 
+0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18, 0x5f, 0x62, 0x01, 0x32, 
+0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08, 0x03, 0xd3, 0x00, 0x23, 
+0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b, 
 0xc0, 0x46, 0x8f, 0x63, 0xc7, 0x6a, 0xc0, 0x46, 0xcf, 0x63, 0x87, 0x6b, 
 0xc0, 0x46, 0x0f, 0x64, 0x47, 0x6b, 0xc0, 0x46, 0x4f, 0x64, 0x07, 0x6c, 
-0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, 
-0xca, 0x64, 0xc2, 0x88, 0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, 
-0x03, 0x7a, 0x1b, 0x04, 0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, 
-0x43, 0x7a, 0xdb, 0x07, 0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, 
-0x5a, 0x08, 0x05, 0xd3, 0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, 
-0x15, 0x22, 0x00, 0xe0, 0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, 
-0xc0, 0x08, 0x02, 0xd3, 0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, 
-0x10, 0x43, 0x3a, 0x0a, 0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, 
-0x8a, 0x60, 0x08, 0x1c, 0xff, 0xf7, 0x14, 0xfe, 0x05, 0xe0, 0x38, 0x0a, 
-0x00, 0x02, 0x03, 0x23, 0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, 
-0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x78, 0x2a, 0x00, 0x80, 0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, 
-0xe7, 0x69, 0xbd, 0x40, 0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, 
-0x2e, 0x1c, 0x45, 0x6d, 0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, 
-0xfd, 0x40, 0x2f, 0x1c, 0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, 
-0x08, 0xd0, 0x23, 0x69, 0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, 
-0xbe, 0x00, 0xae, 0x59, 0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, 
-0x11, 0x43, 0x05, 0x4b, 0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, 
-0x87, 0x83, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, 
-0x00, 0x00, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x00, 0xf0, 
-0xb1, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0x0e, 0xfa, 0x38, 0x0c, 0x00, 0xf0, 
-0x0b, 0xfa, 0x38, 0x0a, 0x00, 0xf0, 0x08, 0xfa, 0x38, 0x1c, 0x00, 0xf0, 
-0x05, 0xfa, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 
-0x00, 0xf0, 0x9e, 0xfa, 0x54, 0x20, 0x00, 0xf0, 0xfb, 0xf9, 0x38, 0x0c, 
-0x00, 0xf0, 0xf8, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xf5, 0xf9, 0x38, 0x1c, 
-0x00, 0xf0, 0xf2, 0xf9, 0x00, 0x20, 0x00, 0xf0, 0xef, 0xf9, 0x80, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x89, 0xfa, 0x57, 0x20, 
-0x00, 0xf0, 0xe6, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, 
-0x41, 0x02, 0x53, 0x20, 0xff, 0xf7, 0xc8, 0xff, 0x00, 0xf0, 0x64, 0xfa, 
-0x00, 0xf0, 0xf5, 0xf8, 0x00, 0x24, 0x00, 0x26, 0x00, 0x25, 0x00, 0x27, 
-0x30, 0x1c, 0x01, 0x36, 0xff, 0xf7, 0xd0, 0xff, 0x00, 0xf0, 0x46, 0xf9, 
-0x00, 0x90, 0x00, 0xf0, 0x55, 0xfa, 0xf8, 0x00, 0x00, 0x99, 0x81, 0x40, 
-0x0d, 0x43, 0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xee, 0xd3, 0x02, 0x99, 
-0x20, 0xc1, 0x02, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42, 0xe5, 0xd3, 
-0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, 0x1c, 
-0x0f, 0x1c, 0x00, 0x26, 0x20, 0xcf, 0xb1, 0x00, 0x84, 0x20, 0xff, 0xf7, 
-0x9b, 0xff, 0x28, 0x1c, 0x00, 0xf0, 0xae, 0xf9, 0x28, 0x0a, 0x00, 0xf0, 
-0xab, 0xf9, 0x28, 0x0c, 0x00, 0xf0, 0xa8, 0xf9, 0x28, 0x0e, 0x00, 0xf0, 
-0xa5, 0xf9, 0x00, 0xf0, 0x2b, 0xfa, 0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, 
-0x61, 0x02, 0x83, 0x20, 0xff, 0xf7, 0x86, 0xff, 0x00, 0xf0, 0x22, 0xfa, 
-0x00, 0xf0, 0xb3, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 
-0x41, 0x02, 0x60, 0x20, 0xff, 0xf7, 0x7a, 0xff, 0x00, 0xf0, 0x16, 0xfa, 
-0x00, 0xf0, 0xa7, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x90, 0xb5, 0x0f, 0x1c, 0x41, 0x02, 0x53, 0x20, 
-0xff, 0xf7, 0x6c, 0xff, 0x00, 0xf0, 0x08, 0xfa, 0x00, 0xf0, 0x99, 0xf8, 
-0xf8, 0x1d, 0x05, 0x30, 0x44, 0x1c, 0xff, 0xf7, 0x77, 0xff, 0x00, 0xf0, 
-0xed, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0xfc, 0xf9, 0x20, 0x1c, 0xff, 0xf7, 
-0x6f, 0xff, 0x00, 0xf0, 0xe5, 0xf8, 0x04, 0x1c, 0x00, 0xf0, 0xf4, 0xf9, 
-0x20, 0x02, 0x38, 0x43, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 
-0xc2, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x17, 0x1c, 0x61, 0x02, 0x53, 0x20, 
-0xff, 0xf7, 0x48, 0xff, 0x00, 0xf0, 0xe4, 0xf9, 0x00, 0xf0, 0x75, 0xf8, 
-0x68, 0x46, 0x00, 0xf0, 0x5c, 0xf8, 0x6a, 0x46, 0xe8, 0x1d, 0x05, 0x30, 
-0x17, 0x54, 0x39, 0x0a, 0x68, 0x44, 0x41, 0x70, 0x68, 0x46, 0x00, 0x99, 
-0x0c, 0x30, 0x00, 0xf0, 0x73, 0xf8, 0x02, 0xab, 0x18, 0x70, 0x00, 0x20, 
-0x58, 0x70, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x6b, 0xf8, 0x02, 0xab, 
-0x58, 0x70, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x83, 0xff, 0x42, 0xb0, 
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0xc2, 0xb0, 0x04, 0x1c, 
-0x1f, 0x1c, 0x6b, 0x46, 0x00, 0x20, 0xc5, 0x43, 0x20, 0xc3, 0x01, 0x30, 
-0x42, 0x28, 0xfb, 0xd3, 0x68, 0x46, 0x0c, 0x30, 0x03, 0x1c, 0x00, 0x25, 
-0x00, 0x2a, 0x0a, 0xd9, 0x0e, 0x88, 0xc0, 0x46, 0x06, 0x70, 0x0e, 0x88, 
-0x36, 0x12, 0x46, 0x70, 0x02, 0x30, 0x02, 0x31, 0x02, 0x35, 0x95, 0x42, 
-0xf4, 0xd3, 0x00, 0x92, 0x18, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x40, 0xf8, 
-0x00, 0x26, 0x01, 0x96, 0x02, 0xab, 0x18, 0x70, 0x5e, 0x70, 0x9e, 0x70, 
-0xde, 0x70, 0x05, 0x1c, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x34, 0xf8, 
-0x02, 0xab, 0x58, 0x70, 0x38, 0x06, 0x00, 0x0e, 0x85, 0x42, 0x05, 0xd1, 
-0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x48, 0xff, 0x30, 0x1c, 0x00, 0xe0, 
-0x01, 0x20, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
-0x07, 0x1c, 0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0xff, 0xf7, 
-0xf1, 0xfe, 0x00, 0xf0, 0x67, 0xf8, 0x05, 0x1c, 0x00, 0xf0, 0x76, 0xf9, 
-0x3d, 0x70, 0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, 
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xff, 0xf7, 0xf6, 0xfe, 
-0x00, 0xf0, 0x56, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0x65, 0xf9, 0x38, 0x0a, 
-0xf6, 0xd3, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb4, 0x00, 0x22, 
-0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78, 0x7a, 0x40, 0x01, 0x30, 
-0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43, 0x00, 0x06, 0x00, 0x0e, 
-0x80, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02, 
-0x53, 0x20, 0xff, 0xf7, 0xab, 0xfe, 0x00, 0xf0, 0x47, 0xf9, 0xff, 0xf7, 
-0xd8, 0xff, 0x68, 0x46, 0xff, 0xf7, 0xbf, 0xff, 0x02, 0xad, 0x6d, 0x78, 
-0x00, 0x24, 0x02, 0xab, 0x5c, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, 
-0xd9, 0xff, 0xa8, 0x42, 0x02, 0xd1, 0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, 
-0x20, 0x1c, 0x00, 0xe0, 0x01, 0x20, 0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x80, 0xb5, 0xc2, 0xb0, 0x69, 0x46, 0x02, 0x20, 0xff, 0xf7, 
-0xbb, 0xfe, 0x68, 0x46, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x07, 0x4a, 
-0x0f, 0x88, 0x43, 0x00, 0xd7, 0x52, 0x02, 0x31, 0x01, 0x30, 0x00, 0x04, 
-0x00, 0x0c, 0x25, 0x28, 0xf6, 0xdb, 0x42, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, 0xfc, 0x46, 0x60, 0x47, 
-0x00, 0x00, 0xa0, 0xe3, 0xb4, 0x22, 0x9f, 0xe5, 
+0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, 0xca, 0x64, 0xc2, 0x88, 
+0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, 0x03, 0x7a, 0x1b, 0x04, 
+0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, 0x43, 0x7a, 0xdb, 0x07, 
+0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, 0x5a, 0x08, 0x05, 0xd3, 
+0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, 0x15, 0x22, 0x00, 0xe0, 
+0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, 0xc0, 0x08, 0x02, 0xd3, 
+0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, 0x10, 0x43, 0x3a, 0x0a, 
+0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x1c, 
+0xff, 0xf7, 0x0e, 0xfe, 0x05, 0xe0, 0x38, 0x0a, 0x00, 0x02, 0x03, 0x23, 
+0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 
+0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 
+0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, 0xe7, 0x69, 0xbd, 0x40, 
+0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, 0x2e, 0x1c, 0x45, 0x6d, 
+0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, 0xfd, 0x40, 0x2f, 0x1c, 
+0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, 0x08, 0xd0, 0x23, 0x69, 
+0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, 0xbe, 0x00, 0xae, 0x59, 
+0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, 0x11, 0x43, 0x05, 0x4b, 
+0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, 0x87, 0x83, 0xf0, 0xbc, 
+0x70, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
+0x80, 0xb4, 0x00, 0x22, 0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78, 
+0x7a, 0x40, 0x01, 0x30, 0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43, 
+0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0x07, 0x1c, 
+0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0x00, 0xf0, 0x8c, 0xf8, 
+0x00, 0xf0, 0x9e, 0xf9, 0x05, 0x1c, 0x00, 0xf0, 0xad, 0xfa, 0x3d, 0x70, 
+0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x00, 0xf0, 0x85, 0xf8, 0x00, 0xf0, 
+0x8d, 0xf9, 0x07, 0x1c, 0x00, 0xf0, 0x9c, 0xfa, 0x38, 0x0a, 0xf6, 0xd3, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, 0x41, 0x02, 
+0x53, 0x20, 0x00, 0xf0, 0x57, 0xf8, 0x00, 0xf0, 0x8f, 0xfa, 0xff, 0xf7, 
+0xe9, 0xff, 0x00, 0x24, 0x00, 0x26, 0x00, 0x25, 0x00, 0x27, 0x30, 0x1c, 
+0x01, 0x36, 0x00, 0xf0, 0x5f, 0xf8, 0x00, 0xf0, 0x71, 0xf9, 0x00, 0x90, 
+0x00, 0xf0, 0x80, 0xfa, 0xf8, 0x00, 0x00, 0x99, 0x81, 0x40, 0x0d, 0x43, 
+0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xee, 0xd3, 0x02, 0x99, 0x20, 0xc1, 
+0x02, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42, 0xe5, 0xd3, 0x03, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 
+0x16, 0x48, 0xc0, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 
+0x00, 0x26, 0x20, 0xcf, 0xb1, 0x00, 0x84, 0x20, 0x00, 0xf0, 0x24, 0xf8, 
+0x28, 0x1c, 0x00, 0xf0, 0xd3, 0xf9, 0x28, 0x0a, 0x00, 0xf0, 0xd0, 0xf9, 
+0x28, 0x0c, 0x00, 0xf0, 0xcd, 0xf9, 0x28, 0x0e, 0x00, 0xf0, 0xca, 0xf9, 
+0x00, 0xf0, 0x50, 0xfa, 0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, 0x61, 0x02, 
+0x83, 0x20, 0x00, 0xf0, 0x0f, 0xf8, 0x00, 0xf0, 
+0x47, 0xfa, 0xff, 0xf7, 0xa1, 0xff, 0x04, 0x48, 0xc0, 0x6f, 0x40, 0x23, 
+0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x00, 0xf0, 
+0x4d, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0xaa, 0xf9, 0x38, 0x0c, 0x00, 0xf0, 
+0xa7, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xa4, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 
+0xa1, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 
+0x54, 0x20, 0xff, 0xf7, 0xe7, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x96, 0xf9, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x31, 0xfa, 0x57, 0x20, 
+0x00, 0xf0, 0x8e, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x08, 0x4f, 
+0xfa, 0x6f, 0x20, 0x23, 0x14, 0x68, 0x9c, 0x43, 0x14, 0x60, 0x23, 0x1c, 
+0xff, 0xf7, 0x73, 0xff, 0xf8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 
+0x01, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 
+0x90, 0xb5, 0x08, 0x4f, 0xfa, 0x6f, 0x20, 0x23, 0x14, 0x68, 0x9c, 0x43, 
+0x14, 0x60, 0x23, 0x1c, 0xff, 0xf7, 0x89, 0xff, 0xf8, 0x6f, 0x20, 0x23, 
+0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb5, 0x0f, 0x1c, 0x15, 0x4d, 0xe9, 0x6f, 
+0x20, 0x23, 0x0a, 0x68, 0x9a, 0x43, 0x0a, 0x60, 0x41, 0x02, 0x53, 0x20, 
+0xff, 0xf7, 0xa6, 0xff, 0x00, 0xf0, 0xde, 0xf9, 0xff, 0xf7, 0x38, 0xff, 
+0xf8, 0x1d, 0x05, 0x30, 0x44, 0x1c, 0xff, 0xf7, 0xb1, 0xff, 0x00, 0xf0, 
+0xc3, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0xd2, 0xf9, 0x20, 0x1c, 0xff, 0xf7, 
+0xa9, 0xff, 0x00, 0xf0, 0xbb, 0xf8, 0x04, 0x1c, 0x00, 0xf0, 0xca, 0xf9, 
+0xe8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x21, 0x02, 
+0x39, 0x43, 0x08, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0xc2, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 
+0x17, 0x1c, 0x61, 0x02, 0x19, 0x4e, 0xf0, 0x6f, 0x20, 0x23, 0x02, 0x68, 
+0x9a, 0x43, 0x02, 0x60, 0x53, 0x20, 0xff, 0xf7, 0x73, 0xff, 0x00, 0xf0, 
+0xab, 0xf9, 0xff, 0xf7, 0x05, 0xff, 0x68, 0x46, 0xff, 0xf7, 0xec, 0xfe, 
+0x6a, 0x46, 0xe8, 0x1d, 0x05, 0x30, 0x17, 0x54, 0x39, 0x0a, 0x68, 0x44, 
+0x41, 0x70, 0x68, 0x46, 0x00, 0x99, 0x0c, 0x30, 0xff, 0xf7, 0xd0, 0xfe, 
+0x02, 0xab, 0x18, 0x70, 0x00, 0x20, 0x58, 0x70, 0x68, 0x46, 0x0c, 0x21, 
+0xff, 0xf7, 0xc8, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x69, 0x46, 0x20, 0x1c, 
+0xff, 0xf7, 0x1f, 0xff, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 
+0x01, 0x60, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0xff, 0xb5, 0xc2, 0xb0, 0x07, 0x1c, 0x6b, 0x46, 
+0x00, 0x20, 0xc4, 0x43, 0x10, 0xc3, 0x01, 0x30, 0x42, 0x28, 0xfb, 0xd3, 
+0x68, 0x46, 0x0c, 0x30, 0x03, 0x1c, 0x00, 0x24, 0x00, 0x2a, 0x0a, 0xd9, 
+0x0e, 0x88, 0xc0, 0x46, 0x06, 0x70, 0x0e, 0x88, 0x36, 0x12, 0x46, 0x70, 
+0x02, 0x30, 0x02, 0x31, 0x02, 0x34, 0x94, 0x42, 0xf4, 0xd3, 0x00, 0x92, 
+0x18, 0x1c, 0x11, 0x1c, 0xff, 0xf7, 0x96, 0xfe, 0x04, 0x1c, 0x00, 0x20, 
+0x01, 0x90, 0x02, 0xab, 0x1c, 0x70, 0x58, 0x70, 0x9d, 0x70, 0x68, 0x46, 
+0x0c, 0x21, 0xff, 0xf7, 0x8b, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x45, 0x9b, 
+0x1d, 0x06, 0x2d, 0x0e, 0xac, 0x42, 0x03, 0xd1, 0x69, 0x46, 0x38, 0x1c, 
+0xff, 0xf7, 0x4a, 0xff, 0x01, 0x20, 0xac, 0x42, 
+0x00, 0xd1, 0x00, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02, 0x14, 0x4c, 0xe0, 0x6f, 
+0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60, 0x53, 0x20, 0xff, 0xf7, 
+0xfb, 0xfe, 0x00, 0xf0, 0x33, 0xf9, 0xff, 0xf7, 0x8d, 0xfe, 0x68, 0x46, 
+0xff, 0xf7, 0x74, 0xfe, 0xe0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 
+0x02, 0xad, 0x01, 0x60, 0x6d, 0x78, 0x00, 0x24, 0x02, 0xab, 0x5c, 0x70, 
+0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, 0x56, 0xfe, 0xa8, 0x42, 0x02, 0xd1, 
+0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, 0x20, 0x1c, 0x00, 0xe0, 0x01, 0x20, 
+0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 
+0xfc, 0x46, 0x60, 0x47, 0x00, 0x00, 0xa0, 0xe3, 0xb4, 0x22, 0x9f, 0xe5, 
 0xb4, 0x32, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x03, 0x80, 0xe1, 
@@ -3675,17 +3858,17 @@ const u8 typhoon_firmware_image[] = {
 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
 0x20, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0xa0, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0xa0, 0x11, 0xa0, 0xe1, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x20, 0x11, 0xa0, 0xe1, 
 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
-0x00, 0x10, 0x82, 0xe5, 0x20, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0xa0, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 
 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
-0xa0, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe1, 
-0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
 0xfc, 0x46, 0x60, 0x47, 0xa0, 0x30, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
@@ -3714,82 +3897,82 @@ const u8 typhoon_firmware_image[] = {
 0x0a, 0x60, 0x70, 0x47, 0xb0, 0x6e, 0x21, 0x40, 0xf0, 0xb5, 0x07, 0x1c, 
 0x00, 0x24, 0x00, 0x2f, 0x21, 0xd0, 0x00, 0x26, 0xf8, 0x79, 0x00, 0x28, 
 0x1b, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, 0x05, 0x35, 0x00, 0x7b, 
-0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x92, 0xfb, 0x01, 0x1c, 0x8b, 0x68, 
+0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x9e, 0xfb, 0x01, 0x1c, 0x8b, 0x68, 
 0x00, 0x2b, 0x08, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xca, 0x68, 
-0xa9, 0x68, 0xfb, 0xf7, 0x4a, 0xfb, 0x00, 0x20, 0x68, 0x60, 0x70, 0x1c, 
+0xa9, 0x68, 0xfa, 0xf7, 0x4e, 0xff, 0x00, 0x20, 0x68, 0x60, 0x70, 0x1c, 
 0x06, 0x06, 0x36, 0x0e, 0xf8, 0x79, 0xb0, 0x42, 0xe3, 0xdc, 0xff, 0x20, 
-0x38, 0x72, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 
-0x81, 0xb0, 0x0f, 0x1c, 0x68, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x00, 0x28, 
-0x01, 0xd1, 0x0d, 0x20, 0x37, 0xe0, 0xb9, 0x88, 0xc0, 0x46, 0x01, 0x80, 
-0xf9, 0x88, 0xc0, 0x46, 0x41, 0x80, 0xb9, 0x7a, 0xc0, 0x46, 0x41, 0x71, 
-0xf9, 0x7a, 0xc0, 0x46, 0x81, 0x71, 0x8c, 0x21, 0x01, 0x71, 0x3d, 0x7e, 
-0x00, 0x21, 0x00, 0x23, 0x00, 0x2d, 0x1f, 0xdd, 0x1a, 0x01, 0xd2, 0x19, 
-0x1c, 0x32, 0x16, 0x78, 0x05, 0x2e, 0x0d, 0xdc, 0x0c, 0x01, 0x24, 0x18, 
-0x26, 0x73, 0x96, 0x68, 0xc0, 0x46, 0x66, 0x61, 0xd6, 0x68, 0xc0, 0x46, 
-0x26, 0x61, 0x00, 0x24, 0x01, 0x31, 0x09, 0x06, 0x09, 0x0e, 0xd4, 0x60, 
-0x5a, 0x1c, 0x13, 0x06, 0x1b, 0x0e, 0xab, 0x42, 0xe6, 0xdb, 0x00, 0x29, 
-0x04, 0xd0, 0xc1, 0x71, 0x00, 0x99, 0xc0, 0x46, 
+0x38, 0x72, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, 0x0f, 0x1c, 0x68, 0x46, 0xff, 0xf7, 
+0xbd, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, 0x37, 0xe0, 0xb9, 0x88, 
+0xc0, 0x46, 0x01, 0x80, 0xf9, 0x88, 0xc0, 0x46, 0x41, 0x80, 0xb9, 0x7a, 
+0xc0, 0x46, 0x41, 0x71, 0xf9, 0x7a, 0xc0, 0x46, 0x81, 0x71, 0x8c, 0x21, 
+0x01, 0x71, 0x3d, 0x7e, 0x00, 0x21, 0x00, 0x23, 0x00, 0x2d, 0x1f, 0xdd, 
+0x1a, 0x01, 0xd2, 0x19, 0x1c, 0x32, 0x16, 0x78, 0x05, 0x2e, 0x0d, 0xdc, 
+0x0c, 0x01, 0x24, 0x18, 0x26, 0x73, 0x96, 0x68, 0xc0, 0x46, 0x66, 0x61, 
+0xd6, 0x68, 0xc0, 0x46, 0x26, 0x61, 0x00, 0x24, 0x01, 0x31, 0x09, 0x06, 
+0x09, 0x0e, 0xd4, 0x60, 0x5a, 0x1c, 0x13, 0x06, 0x1b, 0x0e, 0xab, 0x42, 
+0xe6, 0xdb, 0x00, 0x29, 0x04, 0xd0, 0xc1, 0x71, 0x00, 0x99, 0xc0, 0x46, 
 0x01, 0x72, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x99, 0xc0, 0x46, 0x08, 0x60, 
 0x00, 0x20, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
 0x07, 0x1c, 0x38, 0x7e, 0x00, 0x28, 0x28, 0xd0, 0x01, 0x38, 0x05, 0x06, 
 0x2d, 0x0e, 0x00, 0x26, 0xff, 0x2d, 0x21, 0xd0, 0x28, 0x01, 0xc0, 0x19, 
 0xc4, 0x1d, 0x15, 0x34, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 
-0x1f, 0xfb, 0x01, 0x1c, 0x11, 0xd0, 0x8a, 0x68, 0x00, 0x2a, 0x0c, 0xd0, 
+0x2b, 0xfb, 0x01, 0x1c, 0x11, 0xd0, 0x8a, 0x68, 0x00, 0x2a, 0x0c, 0xd0, 
 0xe0, 0x68, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x23, 0xcb, 0x56, 0x05, 0x2b, 
-0x05, 0xdc, 0x13, 0x1c, 0xca, 0x68, 0xa1, 0x68, 0xfb, 0xf7, 0xd1, 0xfa, 
+0x05, 0xdc, 0x13, 0x1c, 0xca, 0x68, 0xa1, 0x68, 0xfa, 0xf7, 0xd5, 0xfe, 
 0xe6, 0x60, 0xff, 0x20, 0x20, 0x70, 0x68, 0x1e, 0x05, 0x06, 0x2d, 0x0e, 
 0xff, 0x2d, 0xdd, 0xd1, 0x3e, 0x76, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
 0x13, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xf8, 0x1d, 
 0xd5, 0x30, 0x39, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x00, 0x90, 0x00, 0x98, 
 0x00, 0x28, 0x3b, 0xd1, 0x38, 0x7e, 0xc0, 0x46, 0x01, 0x90, 0x00, 0x26, 
 0x01, 0x98, 0x00, 0x28, 0x2d, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, 
-0x15, 0x35, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0xe4, 0xfa, 
+0x15, 0x35, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0xf0, 0xfa, 
 0x04, 0x1c, 0x20, 0x69, 0x00, 0x28, 0x17, 0xd0, 0x28, 0x78, 0x05, 0x28, 
 0x0d, 0xdd, 0xe9, 0x68, 0xaa, 0x68, 0x60, 0x68, 0x40, 0x08, 0x40, 0x00, 
-0x01, 0xf0, 0x0e, 0xf8, 0x09, 0x22, 0xe8, 0x68, 0xa9, 0x68, 0xfb, 0xf7, 
-0x87, 0xf9, 0x00, 0x20, 0xe8, 0x60, 0x21, 0x69, 0x28, 0x1c, 0xfb, 0xf7, 
-0x8c, 0xfa, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, 
+0x01, 0xf0, 0x2c, 0xf8, 0x09, 0x22, 0xe8, 0x68, 0xa9, 0x68, 0xfa, 0xf7, 
+0x8b, 0xfd, 0x00, 0x20, 0xe8, 0x60, 0x21, 0x69, 0x28, 0x1c, 0xfa, 0xf7, 
+0x90, 0xfe, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, 
 0x0c, 0xd1, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0x01, 0x98, 0x86, 0x42, 
 0xd1, 0xdb, 0x00, 0x20, 0x38, 0x76, 0x00, 0x98, 0x02, 0xb0, 0xf0, 0xbc, 
 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x82, 0xff, 0xf6, 0xe7, 
 0xc1, 0x1d, 0x79, 0x31, 0x4a, 0x6b, 0xc0, 0x46, 0xca, 0x63, 0xc1, 0x1d, 
 0xb9, 0x31, 0x0a, 0x60, 0x00, 0x22, 0x8a, 0x60, 0x04, 0x4a, 0xc0, 0x46, 
 0x4a, 0x61, 0x8a, 0x61, 0x01, 0x21, 0xd0, 0x30, 0x41, 0x70, 0x08, 0x1c, 
-0x70, 0x47, 0x00, 0x00, 0xb9, 0xbd, 0x21, 0x40, 0xf8, 0xb5, 0x07, 0x1c, 
+0x70, 0x47, 0x00, 0x00, 0xb1, 0xc5, 0x21, 0x40, 0xf8, 0xb5, 0x07, 0x1c, 
 0x00, 0x20, 0x00, 0x90, 0xfe, 0x1d, 0xc9, 0x36, 0x30, 0x78, 0x00, 0x01, 
 0xc0, 0x19, 0xc4, 0x1d, 0x15, 0x34, 0x80, 0x6a, 0x45, 0x08, 0x6d, 0x00, 
 0x04, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xb2, 0xfe, 0x31, 0x78, 0x40, 0x18, 
 0x01, 0x06, 0x09, 0x0e, 0x00, 0x20, 0xa2, 0x68, 0x00, 0x2a, 0x0a, 0xd9, 
 0x2a, 0x78, 0x4a, 0x40, 0x2a, 0x70, 0x01, 0x30, 0x09, 0x18, 0x09, 0x06, 
-0x09, 0x0e, 0xa2, 0x68, 0x01, 0x35, 0x82, 0x42, 0xf4, 0xd8, 0xe0, 0x68, 
-0xa1, 0x68, 0x40, 0x08, 0x40, 0x00, 0xff, 0xf7, 0x99, 0xfe, 0x61, 0x78, 
-0x81, 0x42, 0x0a, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x0f, 0xf8, 0xf8, 0x1d, 
-0x79, 0x30, 0x80, 0x6b, 0xf9, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0c, 0x20, 
-0x00, 0x90, 0x30, 0x78, 0x01, 0x30, 0x30, 0x70, 0x00, 0x98, 0xf8, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 0xc9, 0x32, 0x11, 0x78, 0x09, 0x01, 
-0x09, 0x18, 0x09, 0x6a, 0xc3, 0x1d, 0x79, 0x33, 0xd9, 0x63, 0x13, 0x78, 
-0x1b, 0x01, 0x1b, 0x18, 0x5b, 0x6a, 0xcb, 0x18, 0xc1, 0x1d, 0xb9, 0x31, 
-0x0b, 0x60, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, 0x9b, 0x6a, 0xc0, 0x46, 
-0x8b, 0x60, 0x07, 0x4b, 0xc0, 0x46, 0x4b, 0x61, 0x12, 0x78, 0x00, 0x7e, 
-0x01, 0x32, 0x82, 0x42, 0x01, 0xdb, 0x04, 0x48, 
+0x09, 0x0e, 0xa2, 0x68, 0x01, 0x35, 0x82, 0x42, 
+0xf4, 0xd8, 0xe0, 0x68, 0xa1, 0x68, 0x40, 0x08, 0x40, 0x00, 0xff, 0xf7, 
+0x99, 0xfe, 0x61, 0x78, 0x81, 0x42, 0x0a, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 
+0x0f, 0xf8, 0xf8, 0x1d, 0x79, 0x30, 0x80, 0x6b, 0xf9, 0x1d, 0xb9, 0x31, 
+0xc8, 0x60, 0x0c, 0x20, 0x00, 0x90, 0x30, 0x78, 0x01, 0x30, 0x30, 0x70, 
+0x00, 0x98, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 0xc9, 0x32, 
+0x11, 0x78, 0x09, 0x01, 0x09, 0x18, 0x09, 0x6a, 0xc3, 0x1d, 0x79, 0x33, 
+0xd9, 0x63, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, 0x5b, 0x6a, 0xcb, 0x18, 
+0xc1, 0x1d, 0xb9, 0x31, 0x0b, 0x60, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, 
+0x9b, 0x6a, 0xc0, 0x46, 0x8b, 0x60, 0x07, 0x4b, 0xc0, 0x46, 0x4b, 0x61, 
+0x12, 0x78, 0x00, 0x7e, 0x01, 0x32, 0x82, 0x42, 0x01, 0xdb, 0x04, 0x48, 
 0x00, 0xe0, 0x04, 0x48, 0xc0, 0x46, 0x88, 0x61, 0x00, 0x20, 0x70, 0x47, 
-0x81, 0xbe, 0x21, 0x40, 0x55, 0xbe, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, 
+0x79, 0xc6, 0x21, 0x40, 0x4d, 0xc6, 0x21, 0x40, 0xf9, 0xc6, 0x21, 0x40, 
 0xf8, 0xb5, 0x04, 0x1c, 0x00, 0x20, 0x00, 0x90, 0x25, 0x7e, 0x29, 0x01, 
 0xe0, 0x1d, 0x15, 0x30, 0xff, 0xf7, 0x4e, 0xfe, 0xa1, 0x7e, 0x81, 0x42, 
 0x0a, 0xd0, 0x20, 0x1c, 0x00, 0xf0, 0x61, 0xf8, 0xe0, 0x1d, 0x79, 0x30, 
 0x80, 0x6b, 0xe1, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0b, 0x20, 0x55, 0xe0, 
 0x00, 0x27, 0x00, 0x2d, 0x0f, 0xdd, 0x38, 0x01, 0x00, 0x19, 0x00, 0x7f, 
-0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x10, 0xfa, 0x00, 0x28, 0x01, 0xd1, 
+0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x1c, 0xfa, 0x00, 0x28, 0x01, 0xd1, 
 0x09, 0x20, 0x47, 0xe0, 0x78, 0x1c, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 
 0xef, 0xdb, 0x00, 0x26, 0x00, 0x2d, 0x38, 0xdd, 0x30, 0x01, 0x00, 0x19, 
 0xc7, 0x1d, 0x15, 0x37, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 
-0xfb, 0xf9, 0x00, 0x23, 0xc1, 0x56, 0x05, 0x29, 0x0c, 0xdc, 0x42, 0x68, 
-0x00, 0x2a, 0x04, 0xd0, 0xc1, 0x68, 0xb8, 0x68, 0xfb, 0xf7, 0xb2, 0xf9, 
+0x07, 0xfa, 0x00, 0x23, 0xc1, 0x56, 0x05, 0x29, 0x0c, 0xdc, 0x42, 0x68, 
+0x00, 0x2a, 0x04, 0xd0, 0xc1, 0x68, 0xb8, 0x68, 0xfa, 0xf7, 0xb6, 0xfd, 
 0xf8, 0x60, 0xf8, 0x68, 0x00, 0x28, 0x1b, 0xd1, 0x0e, 0x20, 0x17, 0xe0, 
-0xc0, 0x68, 0x00, 0x28, 0x07, 0xd0, 0xfb, 0xf7, 0xa5, 0xf9, 0x00, 0x28, 
+0xc0, 0x68, 0x00, 0x28, 0x07, 0xd0, 0xfa, 0xf7, 0xa9, 0xfd, 0x00, 0x28, 
 0x05, 0xda, 0x40, 0x42, 0xb9, 0x68, 0x81, 0x42, 0x04, 0xd0, 0x05, 0x20, 
 0x0a, 0xe0, 0xb9, 0x68, 0x81, 0x42, 0xfa, 0xd8, 0x09, 0x21, 0xb8, 0x68, 
-0xfb, 0xf7, 0x7a, 0xf8, 0xf8, 0x60, 0x00, 0x28, 0x02, 0xd1, 0x06, 0x20, 
+0xfa, 0xf7, 0x7e, 0xfc, 0xf8, 0x60, 0x00, 0x28, 0x02, 0xd1, 0x06, 0x20, 
 0x00, 0x90, 0x07, 0xe0, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0xae, 0x42, 
 0xc6, 0xdb, 0x00, 0x98, 0x00, 0x28, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 
 0x92, 0xfe, 0x00, 0x98, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 
@@ -3797,25 +3980,25 @@ const u8 typhoon_firmware_image[] = {
 0x8a, 0x18, 0xc1, 0x1d, 0xb9, 0x31, 0x0a, 0x60, 0xc2, 0x1d, 0x15, 0x32, 
 0x8a, 0x60, 0x05, 0x4a, 0xc0, 0x46, 0x4a, 0x61, 0x04, 0x4a, 0xc0, 0x46, 
 0x8a, 0x61, 0x00, 0x21, 0xd0, 0x30, 0x01, 0x70, 0x08, 0x1c, 0x70, 0x47, 
-0x59, 0xbf, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, 
+0x51, 0xc7, 0x21, 0x40, 0xf9, 0xc6, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, 
 0x38, 0x68, 0x1d, 0x4b, 0x98, 0x42, 0x03, 0xd0, 0x03, 0x20, 0x90, 0xbc, 
 0x08, 0xbc, 0x18, 0x47, 0x1c, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xbc, 0xfd, 
 0xfc, 0x1d, 0x79, 0x34, 0x00, 0x28, 0x09, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 
 0x2d, 0xf8, 0xf9, 0x1d, 0xb9, 0x31, 0xa0, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 
 0x0a, 0x20, 0xea, 0xe7, 0x38, 0x7a, 0x1c, 0x28, 0x04, 0xd0, 0x78, 0x7a, 
 0x10, 0x28, 0x01, 0xd0, 0x04, 0x20, 0xe2, 0xe7, 0xb8, 0x7a, 0x01, 0x28, 
-0x01, 0xd0, 0x07, 0x20, 0xdd, 0xe7, 0x60, 0x6b, 0xf9, 0x68, 0x88, 0x42, 
-0x01, 0xd0, 0x05, 0x20, 0xd7, 0xe7, 0x38, 0x69, 0x00, 0x28, 0x04, 0xd0, 
-0x06, 0x4b, 0x98, 0x42, 0x01, 0xd0, 0x08, 0x20, 0xcf, 0xe7, 0x38, 0x7e, 
-0x08, 0x28, 0x01, 0xdd, 0x12, 0x20, 0xca, 0xe7, 0x00, 0x20, 0xc8, 0xe7, 
-0x73, 0x6e, 0x69, 0x70, 0x17, 0x40, 0x00, 0x02, 0xb8, 0xb5, 0x07, 0x1c, 
-0x38, 0x1c, 0xff, 0xf7, 0x2a, 0xfe, 0x00, 0x25, 0xf8, 0x1d, 0xc9, 0x30, 
-0x45, 0x70, 0xfc, 0x1d, 0xb9, 0x34, 0xe5, 0x61, 0x68, 0x46, 0xff, 0xf7, 
-0x9d, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, 0x0d, 0xe0, 0xf8, 0x1d, 
-0x79, 0x30, 0x85, 0x63, 0xc5, 0x63, 0x1b, 0x20, 0x20, 0x60, 0xa7, 0x60, 
-0x04, 0x48, 0xc0, 0x46, 0x60, 0x61, 0x04, 0x48, 0xc0, 0x46, 0xa0, 0x61, 
-0x28, 0x1c, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0x75, 0xc0, 0x21, 0x40, 0x3b, 0xc0, 0x21, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 
+0x01, 0xd0, 0x07, 0x20, 0xdd, 0xe7, 0x60, 0x6b, 
+0xf9, 0x68, 0x88, 0x42, 0x01, 0xd0, 0x05, 0x20, 0xd7, 0xe7, 0x38, 0x69, 
+0x00, 0x28, 0x04, 0xd0, 0x06, 0x4b, 0x98, 0x42, 0x01, 0xd0, 0x08, 0x20, 
+0xcf, 0xe7, 0x38, 0x7e, 0x08, 0x28, 0x01, 0xdd, 0x12, 0x20, 0xca, 0xe7, 
+0x00, 0x20, 0xc8, 0xe7, 0x73, 0x6e, 0x69, 0x70, 0x02, 0x10, 0x00, 0x03, 
+0xb8, 0xb5, 0x07, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x2a, 0xfe, 0x00, 0x25, 
+0xf8, 0x1d, 0xc9, 0x30, 0x45, 0x70, 0xfc, 0x1d, 0xb9, 0x34, 0xe5, 0x61, 
+0x68, 0x46, 0xff, 0xf7, 0x9d, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, 
+0x0d, 0xe0, 0xf8, 0x1d, 0x79, 0x30, 0x85, 0x63, 0xc5, 0x63, 0x1b, 0x20, 
+0x20, 0x60, 0xa7, 0x60, 0x04, 0x48, 0xc0, 0x46, 0x60, 0x61, 0x04, 0x48, 
+0xc0, 0x46, 0xa0, 0x61, 0x28, 0x1c, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x6d, 0xc8, 0x21, 0x40, 0x33, 0xc8, 0x21, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 
 0x07, 0x1c, 0x00, 0x20, 0xfd, 0x1d, 0x79, 0x35, 0xfc, 0x1d, 0xb9, 0x34, 
 0xe9, 0x6a, 0xc0, 0x46, 0x61, 0x60, 0x62, 0x68, 0xe9, 0x6b, 0x8a, 0x42, 
 0x03, 0xd2, 0x61, 0x60, 0x2a, 0x6b, 0x91, 0x42, 0x34, 0xd2, 0x66, 0x68, 
@@ -3823,52 +4006,54 @@ const u8 typhoon_firmware_image[] = {
 0x26, 0x68, 0x2a, 0x6b, 0x96, 0x42, 0x00, 0xd2, 0x32, 0x1c, 0x01, 0x9e, 
 0x96, 0x1b, 0xa2, 0x68, 0xc0, 0x46, 0x00, 0x92, 0x00, 0x2a, 0x09, 0xd0, 
 0x28, 0x6a, 0x6a, 0x6a, 0x41, 0x18, 0x00, 0x98, 0xc0, 0x18, 0x33, 0x1c, 
-0xfc, 0xf7, 0xc4, 0xff, 0x00, 0x28, 0x1b, 0xd1, 0x61, 0x68, 0x89, 0x19, 
+0xfc, 0xf7, 0x68, 0xff, 0x00, 0x28, 0x1b, 0xd1, 0x61, 0x68, 0x89, 0x19, 
 0x61, 0x60, 0x22, 0x68, 0x91, 0x42, 0x0d, 0xd1, 0x61, 0x69, 0x38, 0x1c, 
-0xfb, 0xf7, 0xc1, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x0e, 0xd1, 0xa1, 0x69, 
-0x38, 0x1c, 0xfb, 0xf7, 0xba, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x07, 0xd1, 
+0xfa, 0xf7, 0xc5, 0xfc, 0x00, 0x06, 0x00, 0x0e, 0x0e, 0xd1, 0xa1, 0x69, 
+0x38, 0x1c, 0xfa, 0xf7, 0xbe, 0xfc, 0x00, 0x06, 0x00, 0x0e, 0x07, 0xd1, 
 0x61, 0x68, 0x2a, 0x6b, 0x91, 0x42, 0xc2, 0xd3, 0xa9, 0x6b, 0xaa, 0x6a, 
 0x89, 0x18, 0xa9, 0x63, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xb0, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfb, 0xf7, 
-0xbf, 0xfa, 0xfa, 0x1d, 0x09, 0x32, 0x32, 0x48, 0x00, 0x21, 0xc9, 0x43, 
-0xc4, 0x1d, 0xb9, 0x34, 0xe1, 0x60, 0xf9, 0x88, 0xc3, 0x1d, 0x89, 0x33, 
-0x19, 0x73, 0xc1, 0x1d, 0x79, 0x31, 0xbd, 0x68, 0xc0, 0x46, 0x0d, 0x62, 
-0xff, 0x68, 0xc0, 0x46, 0x4f, 0x62, 0x17, 0x68, 0xc0, 0x46, 0x8f, 0x62, 
-0x57, 0x68, 0xc0, 0x46, 0xcf, 0x62, 0x92, 0x68, 0xc0, 0x46, 0x4a, 0x63, 
-0xca, 0x6a, 0x8f, 0x6a, 0xd2, 0x19, 0x0a, 0x63, 0x1a, 0x7b, 0x01, 0x2a, 
-0x0d, 0xd0, 0x02, 0x2a, 0x1a, 0xd0, 0x03, 0x2a, 0x2e, 0xd1, 0xc2, 0x1d, 
-0xc9, 0x32, 0x52, 0x78, 0x00, 0x2a, 0x07, 0xd1, 0x10, 0x20, 0x89, 0x6b, 
-0xc0, 0x46, 0xe1, 0x60, 0x25, 0xe0, 0xff, 0xf7, 0x4d, 0xff, 0x22, 0xe0, 
-0xff, 0xf7, 0xac, 0xfd, 0x00, 0x28, 0x1e, 0xd1, 0xe1, 0x69, 0x00, 0x29, 
-0x1b, 0xd0, 0x09, 0x7a, 0x15, 0x4b, 0xc9, 0x18, 0x02, 0x91, 0x16, 0xe0, 
-0x8a, 0x6a, 0xcb, 0x6a, 0x9f, 0x18, 0x4d, 0x6b, 0xaf, 0x42, 0x05, 0xd8, 
-0x00, 0x2a, 0x03, 0xd0, 0x9f, 0x07, 0x01, 0xd1, 0x92, 0x07, 0x01, 0xd0, 
-0x0f, 0x20, 0x08, 0xe0, 0x89, 0x6b, 0x99, 0x42, 0x01, 0xd0, 0xe1, 0x60, 
-0xf8, 0xe7, 0xff, 0xf7, 0x53, 0xff, 0x00, 0xe0, 0x10, 0x20, 0x01, 0xab, 
-0x58, 0x80, 0xe0, 0x68, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 
-0xfb, 0xf7, 0x9e, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x3c, 0xac, 0x20, 0x40, 0x0d, 0xf0, 0xfe, 0xca, 
-0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 
-0x4d, 0xfa, 0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, 0xa0, 0xfc, 0x00, 0x28, 
-0x02, 0xd1, 0x00, 0x98, 0xff, 0xf7, 0xc4, 0xfc, 0x02, 0xab, 0x58, 0x80, 
-0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x7e, 0xf9, 0x01, 0x20, 0x05, 0xb0, 
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 
-0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x32, 0xfa, 0x68, 0x46, 0xb9, 0x68, 
-0xff, 0xf7, 0x85, 0xfc, 0x00, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x02, 0xab, 
-0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x65, 0xf9, 0x01, 0x20, 
-0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x85, 0xb0, 
-0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 
-0x19, 0xfa, 0x3c, 0x69, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x14, 0xfa, 
-0x68, 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x67, 0xfc, 0x8c, 0x24, 0x00, 0x28, 
+0xf0, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfa, 0xf7, 
+0xc3, 0xfe, 0xfa, 0x1d, 0x09, 0x32, 0x37, 0x49, 0x00, 0x20, 0xc0, 0x43, 
+0xcc, 0x1d, 0xb9, 0x34, 0xe0, 0x60, 0xf8, 0x88, 0xcb, 0x1d, 0x89, 0x33, 
+0x18, 0x73, 0xc8, 0x1d, 0x79, 0x30, 0xbd, 0x68, 0xc0, 0x46, 0x05, 0x62, 
+0xff, 0x68, 0xc0, 0x46, 0x47, 0x62, 0x17, 0x68, 0xc0, 0x46, 0x87, 0x62, 
+0x57, 0x68, 0xc0, 0x46, 0xc7, 0x62, 0x92, 0x68, 0xc0, 0x46, 0x42, 0x63, 
+0xc2, 0x6a, 0x87, 0x6a, 0xd2, 0x19, 0x02, 0x63, 0x1a, 0x7b, 0x28, 0x4d, 
+0x01, 0x2a, 0x0d, 0xd0, 0x02, 0x2a, 0x1c, 0xd0, 0x03, 0x2a, 0x35, 0xd1, 
+0xca, 0x1d, 0xc9, 0x32, 0x52, 0x78, 0x00, 0x2a, 0x08, 0xd1, 0x10, 0x27, 
+0x80, 0x6b, 0xc0, 0x46, 0xe0, 0x60, 0x2c, 0xe0, 0x08, 0x1c, 0xff, 0xf7, 
+0x4b, 0xff, 0x22, 0xe0, 0x08, 0x1c, 0xff, 0xf7, 0xa9, 0xfd, 0x07, 0x1c, 
+0x23, 0xd1, 0xe0, 0x69, 0x00, 0x28, 0x1c, 0xd0, 0x00, 0x7a, 0x1a, 0x4b, 
+0xc0, 0x18, 0x02, 0x90, 0x17, 0xe0, 0x82, 0x6a, 0xc3, 0x6a, 0x9f, 0x18, 
+0x46, 0x6b, 0xb7, 0x42, 0x05, 0xd8, 0x00, 0x2a, 0x03, 0xd0, 0x9f, 0x07, 
+0x01, 0xd1, 0x92, 0x07, 0x01, 0xd0, 0x0f, 0x27, 0x0d, 0xe0, 0x80, 0x6b, 
+0x98, 0x42, 0x01, 0xd0, 0xe0, 0x60, 0xf8, 0xe7, 0x08, 0x1c, 0xff, 0xf7, 
+0x4f, 0xff, 0x07, 0x1c, 0x03, 0xd1, 0x00, 0xf0, 0x1f, 0xfe, 0x01, 0xe0, 
+0x10, 0x27, 0x00, 0x20, 0x28, 0x65, 0x01, 0xab, 0x5f, 0x80, 0xe0, 0x68, 
+0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 
+0xfa, 0xf7, 0x98, 0xfd, 0x01, 0x20, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x3c, 0xac, 0x20, 0x40, 0x00, 0x00, 0x00, 0x80, 
+0x0d, 0xf0, 0xfe, 0xca, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 
+0x01, 0xa9, 0xfa, 0xf7, 0x45, 0xfe, 0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, 
+0x94, 0xfc, 0x00, 0x28, 0x02, 0xd1, 0x00, 0x98, 0xff, 0xf7, 0xb8, 0xfc, 
+0x02, 0xab, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfa, 0xf7, 0x76, 0xfd, 
+0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 
+0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfa, 0xf7, 0x2a, 0xfe, 
+0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, 0x79, 0xfc, 0x00, 0x28, 0x00, 0xd1, 
+0x02, 0x20, 0x02, 0xab, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfa, 0xf7, 
+0x5d, 0xfd, 0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x90, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfa, 0xf7, 
+0x11, 0xfe, 0x3c, 0x69, 0x38, 0x1c, 0x01, 0xa9, 0xfa, 0xf7, 0x0c, 0xfe, 
+0x68, 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x5b, 0xfc, 0x8c, 0x24, 0x00, 0x28, 
 0x0e, 0xd1, 0xb9, 0x68, 0x00, 0x29, 0x02, 0xd1, 0xfa, 0x68, 0x00, 0x2a, 
 0x08, 0xd0, 0xf8, 0x88, 0x23, 0x1c, 0x8c, 0x28, 0x00, 0xd8, 0x03, 0x1c, 
-0xf8, 0x68, 0x00, 0x9a, 0xfc, 0xf7, 0x38, 0xfe, 0x02, 0xab, 0x58, 0x80, 
-0x03, 0x94, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x37, 0xf9, 0x01, 0x20, 
+0xf8, 0x68, 0x00, 0x9a, 0xfc, 0xf7, 0xd0, 0xfd, 0x02, 0xab, 0x58, 0x80, 
+0x03, 0x94, 0x00, 0x21, 0x01, 0xa8, 0xfa, 0xf7, 0x2f, 0xfd, 0x01, 0x20, 
 0x05, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0x04, 0x48, 
 0xff, 0x22, 0x02, 0x72, 0x8c, 0x30, 0x01, 0x31, 0x04, 0x29, 0xfa, 0xd3, 
 0x70, 0x47, 0x00, 0x00, 0xb0, 0x6e, 0x21, 0x40, 0x02, 0x48, 0x03, 0x49, 
-0x40, 0x1a, 0x40, 0x42, 0x70, 0x47, 0x00, 0x00, 0xb9, 0xce, 0x21, 0x40, 
-0xb5, 0xce, 0x21, 0x40, 0x00, 0x21, 0x08, 0x4a, 0x8b, 0x00, 0x5b, 0x18, 
+0x40, 0x1a, 0x40, 0x42, 0x70, 0x47, 0x00, 0x00, 0xed, 0xd6, 0x21, 0x40, 
+0xe9, 0xd6, 0x21, 0x40, 0x00, 0x21, 0x08, 0x4a, 0x8b, 0x00, 0x5b, 0x18, 
 0x9b, 0x00, 0xd3, 0x56, 0x83, 0x42, 0x04, 0xd1, 0x88, 0x00, 0x40, 0x18, 
 0x80, 0x00, 0x80, 0x18, 0x70, 0x47, 0x01, 0x31, 0x01, 0x29, 0xf1, 0xd3, 
 0x00, 0x20, 0xf9, 0xe7, 0xe0, 0x70, 0x21, 0x40, 0x80, 0xb5, 0x00, 0xf0, 
@@ -3883,212 +4068,215 @@ const u8 typhoon_firmware_image[] = {
 0x02, 0x6b, 0xcb, 0x69, 0xd2, 0x18, 0x02, 0x63, 0x4a, 0x6a, 0x43, 0x6b, 
 0x9b, 0x18, 0x43, 0x63, 0x93, 0x42, 0x02, 0xd2, 0x82, 0x6b, 0x01, 0x32, 
 0x82, 0x63, 0xc2, 0x6b, 0x4b, 0x69, 0xd2, 0x18, 0xc2, 0x63, 0x02, 0x6c, 
-0xc9, 0x6a, 0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0x10, 0x2a, 0x00, 0x80, 
+0xc9, 0x6a, 0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0xa4, 0x2a, 0x00, 0x80, 
 0x00, 0x08, 0x14, 0x40, 0x88, 0xb5, 0x69, 0x46, 0x00, 0xf0, 0x17, 0xf8, 
 0x81, 0x08, 0x0a, 0xd0, 0x00, 0x20, 0x00, 0x29, 0x07, 0xd9, 0x00, 0x22, 
 0x83, 0x00, 0x00, 0x9f, 0xc0, 0x46, 0xfa, 0x50, 0x01, 0x30, 0x88, 0x42, 
 0xf8, 0xd3, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 
-0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22, 
-0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, 0x02, 0x28, 0x0c, 0xd0, 
-0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, 0x08, 0x60, 0x10, 0x1c, 
-0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, 0x50, 0x22, 0x08, 0x60, 
-0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, 0xf3, 0xe7, 0x00, 0x00, 
-0x08, 0x83, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 
-0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x00, 0x27, 0x68, 0x46, 0xfe, 0xf7, 
-0xa7, 0xfb, 0x10, 0x4c, 0x00, 0x28, 0x0b, 0xd0, 0x00, 0xf0, 0x3e, 0xf8, 
-0x00, 0x28, 0x07, 0xd0, 0x01, 0x27, 0x10, 0x23, 0x20, 0x68, 0x18, 0x43, 
-0x20, 0x60, 0x60, 0x68, 0x18, 0x43, 0x0b, 0xe0, 0x10, 0x23, 0xa0, 0x68, 
-0x98, 0x43, 0xa0, 0x60, 0x20, 0x69, 0x98, 0x43, 0x20, 0x61, 0x20, 0x68, 
-0x98, 0x43, 0x20, 0x60, 0x60, 0x68, 0x98, 0x43, 0x60, 0x60, 0x38, 0x1c, 
-0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
-0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0x00, 0xf0, 0xb5, 0xfc, 0xfe, 0xf7, 
-0xc5, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x14, 0x24, 
+0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x22, 0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, 
+0x02, 0x28, 0x0c, 0xd0, 0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, 
+0x08, 0x60, 0x10, 0x1c, 0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, 
+0x50, 0x22, 0x08, 0x60, 0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, 
+0xf3, 0xe7, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80, 
+0x0c, 0x2b, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x00, 0x27, 
+0x68, 0x46, 0xfe, 0xf7, 0x6f, 0xfb, 0x10, 0x4c, 0x00, 0x28, 0x0b, 0xd0, 
+0x00, 0xf0, 0x44, 0xf8, 0x00, 0x28, 0x07, 0xd0, 0x01, 0x27, 0x10, 0x23, 
+0x60, 0x68, 0x18, 0x43, 0x60, 0x60, 0xa0, 0x68, 0x18, 0x43, 0x0b, 0xe0, 
+0x10, 0x23, 0xe0, 0x68, 0x98, 0x43, 0xe0, 0x60, 0x60, 0x69, 0x98, 0x43, 
+0x60, 0x61, 0x60, 0x68, 0x98, 0x43, 0x60, 0x60, 0xa0, 0x68, 0x98, 0x43, 
+0xa0, 0x60, 0x38, 0x1c, 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x68, 0x19, 0x00, 0x80, 0x00, 0xb5, 0x00, 0xf0, 0xc7, 0xfc, 0x04, 0x49, 
+0x09, 0x6d, 0x08, 0x43, 0xfe, 0xf7, 0x8a, 0xfb, 0x00, 0x20, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x14, 0x24, 
 0x00, 0x25, 0x00, 0x27, 0x08, 0x4e, 0x02, 0x20, 0x21, 0x1c, 0x32, 0x1c, 
-0xfa, 0xf7, 0xec, 0xfe, 0x78, 0x40, 0x07, 0x04, 0x3f, 0x0c, 0x02, 0x34, 
+0xfa, 0xf7, 0xde, 0xfa, 0x78, 0x40, 0x07, 0x04, 0x3f, 0x0c, 0x02, 0x34, 
 0x01, 0x35, 0x03, 0x2d, 0xf3, 0xd3, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x39, 0xb7, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x24, 
-0x20, 0x1c, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 0x00, 0x20, 
-0x00, 0x06, 0x00, 0x0e, 0x16, 0xd0, 0x0d, 0x4a, 0x3a, 0x21, 0x02, 0x20, 
-0xfa, 0xf7, 0xce, 0xfe, 0x07, 0x04, 0x3f, 0x0c, 0x03, 0xd1, 0x00, 0x20, 
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xf7, 0xcf, 0xff, 0xc0, 0x43, 
-0x00, 0x04, 0x00, 0x0c, 0xb8, 0x42, 0x00, 0xd0, 0x00, 0x24, 0x20, 0x06, 
-0x00, 0x0e, 0xf1, 0xe7, 0x20, 0x1c, 0xef, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
-0x39, 0xb7, 0x21, 0x40, 0xb0, 0xb5, 0x01, 0x27, 0x3a, 0x1c, 0x18, 0x4b, 
-0xdb, 0x68, 0x01, 0x2b, 0x00, 0xd0, 0x00, 0x22, 0x12, 0x06, 0x12, 0x0e, 
-0x00, 0x24, 0x00, 0x2a, 0x23, 0xd0, 0x14, 0x4a, 0x53, 0x68, 0x1b, 0x04, 
-0x1b, 0x0c, 0x1d, 0x02, 0x1b, 0x12, 0x2b, 0x43, 0x92, 0x68, 0x12, 0x04, 
-0x12, 0x0c, 0x15, 0x02, 0x12, 0x12, 0x2a, 0x43, 0x12, 0x04, 0x12, 0x0c, 
-0x1b, 0x04, 0x1a, 0x43, 0x51, 0x40, 0x01, 0x31, 0x0f, 0xd1, 0x00, 0x28, 
-0x02, 0xd0, 0xff, 0xf7, 0x9b, 0xff, 0xc4, 0x43, 0x22, 0x04, 0x12, 0x0c, 
-0x07, 0x4b, 0x3a, 0x21, 0x02, 0x20, 0xfa, 0xf7, 0x8a, 0xfe, 0x38, 0x1c, 
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 
-0xe8, 0x0d, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x7b, 0xb7, 0x21, 0x40, 
-0x80, 0xb4, 0x03, 0x22, 0xc2, 0x80, 0x15, 0x4a, 0xc0, 0x46, 0x82, 0x60, 
-0x14, 0x4a, 0x12, 0x88, 0x01, 0x32, 0xc2, 0x60, 0x00, 0x20, 0x13, 0x4a, 
-0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 
-0xf8, 0xd3, 0x20, 0x22, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x0e, 0x4b, 
-0x1f, 0x5c, 0xc0, 0x46, 0x0f, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 
-0xf8, 0xd3, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x09, 0x4a, 0x13, 0x5c, 
-0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 
-0x00, 0x20, 0x08, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x17, 0x40, 0x00, 0x02, 
-0xe8, 0x0d, 0x00, 0x80, 0xfc, 0x03, 0x00, 0x80, 0x05, 0x04, 0x00, 0x80, 
-0x0e, 0x04, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x21, 0x45, 0x4d, 0xe8, 0x1d, 
-0x79, 0x30, 0x41, 0x73, 0x01, 0x73, 0x64, 0x22, 0x42, 0x82, 0x82, 0x82, 
-0xc1, 0x82, 0x7d, 0x21, 0xc9, 0x00, 0x01, 0x83, 0x00, 0x21, 0x41, 0x83, 
-0x3f, 0x48, 0x01, 0x22, 0x00, 0xf0, 0x08, 0xfb, 0x00, 0x26, 0xf6, 0x43, 
-0x3d, 0x4c, 0xe7, 0x1d, 0x39, 0x37, 0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, 
-0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, 0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, 
-0xb3, 0xfd, 0x38, 0x48, 0x02, 0x22, 0x00, 0x21, 0x00, 0xf0, 0xf4, 0xfa, 
-0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, 0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, 
-0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, 0xa4, 0xfd, 0xe8, 0x68, 0x2f, 0x1c, 
-0x01, 0x28, 0x05, 0xd1, 0x2f, 0x48, 0x7d, 0x22, 0xd2, 0x00, 0x00, 0x21, 
-0x00, 0xf0, 0xe0, 0xfa, 0x2d, 0x4d, 0x28, 0x1c, 0xfa, 0xf7, 0x02, 0xfe, 
-0x2c, 0x48, 0xfa, 0xf7, 0xff, 0xfd, 0x2c, 0x48, 
-0xfa, 0xf7, 0xfc, 0xfd, 0x2b, 0x4e, 0x71, 0x23, 0x5b, 0x01, 0xfc, 0x18, 
-0x2a, 0x4f, 0x20, 0x79, 0x00, 0x28, 0x0f, 0xd0, 0x28, 0x1c, 0xfa, 0xf7, 
-0xf1, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xee, 0xfd, 0x00, 0x28, 0x04, 0xd0, 
-0x38, 0x1c, 0xfa, 0xf7, 0xe9, 0xfd, 0x00, 0x28, 0xfa, 0xd1, 0x30, 0x1c, 
-0xfa, 0xf7, 0xe4, 0xfd, 0x60, 0x79, 0x00, 0x28, 0x23, 0xd0, 0x28, 0x1c, 
-0xfa, 0xf7, 0xde, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xdb, 0xfd, 0x00, 0x28, 
-0x04, 0xd0, 0x38, 0x1c, 0xfa, 0xf7, 0xd6, 0xfd, 0x00, 0x28, 0xfa, 0xd1, 
-0x19, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x14, 0x20, 
-0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 
-0x89, 0x0a, 0x03, 0xd3, 0x13, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x03, 0xe0, 
-0x12, 0x49, 0xc0, 0x46, 0x08, 0x64, 0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, 
-0x1e, 0xfe, 0x10, 0x48, 0xfa, 0xf7, 0xb8, 0xfd, 0x0f, 0x48, 0xfa, 0xf7, 
-0xb5, 0xfd, 0xbc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x5d, 0x22, 0xff, 0xff, 
-0xa0, 0x82, 0x20, 0x40, 0x21, 0x21, 0xff, 0xff, 0x59, 0x7e, 0x21, 0x40, 
-0xf4, 0x01, 0xff, 0xff, 0x09, 0x2c, 0xff, 0xff, 0x04, 0x02, 0xff, 0xff, 
-0x00, 0x00, 0xff, 0xff, 0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x65, 0xa8, 0x21, 0x40, 
-0x48, 0x57, 0xff, 0xff, 0x00, 0xb5, 0x10, 0x20, 0x0f, 0x49, 0xc0, 0x46, 
-0x08, 0x60, 0x0f, 0x4a, 0x0f, 0x48, 0x64, 0x21, 0xfa, 0xf7, 0x8e, 0xfd, 
-0x0e, 0x48, 0x01, 0x22, 0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x08, 0x21, 
-0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c, 0x07, 0xd1, 0x00, 0x68, 
-0x80, 0x0a, 0x04, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x08, 0xbc, 
-0x18, 0x47, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x64, 0xf9, 0xe7, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xb0, 0x25, 0x55, 0xff, 0xff, 0xf8, 0x28, 0x00, 0x80, 
+0x18, 0x47, 0x00, 0x00, 0x79, 0xbf, 0x21, 0x40, 0x01, 0x20, 0x70, 0x47, 
+0xb0, 0xb5, 0x01, 0x27, 0x3a, 0x1c, 0x18, 0x4b, 0xdb, 0x68, 0x01, 0x2b, 
+0x00, 0xd0, 0x00, 0x22, 0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0x00, 0x2a, 
+0x23, 0xd0, 0x14, 0x4a, 0x53, 0x68, 0x1b, 0x04, 0x1b, 0x0c, 0x1d, 0x02, 
+0x1b, 0x12, 0x2b, 0x43, 0x92, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x15, 0x02, 
+0x12, 0x12, 0x2a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x1b, 0x04, 0x1a, 0x43, 
+0x51, 0x40, 0x01, 0x31, 0x0f, 0xd1, 0x00, 0x28, 0x02, 0xd0, 0xff, 0xf7, 
+0xc1, 0xff, 0xc4, 0x43, 0x22, 0x04, 0x12, 0x0c, 0x07, 0x4b, 0x3a, 0x21, 
+0x02, 0x20, 0xfa, 0xf7, 0xa2, 0xfa, 0x38, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
+0x40, 0x00, 0x14, 0x40, 0xd9, 0xbf, 0x21, 0x40, 0x80, 0xb4, 0x03, 0x22, 
+0xc2, 0x80, 0x15, 0x4a, 0xc0, 0x46, 0x82, 0x60, 0x14, 0x4a, 0x12, 0x88, 
+0x01, 0x32, 0xc2, 0x60, 0x00, 0x20, 0x13, 0x4a, 0x13, 0x5c, 0xc0, 0x46, 
+0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x20, 0x22, 
+0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x0e, 0x4b, 0x1f, 0x5c, 0xc0, 0x46, 
+0x0f, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x0a, 0x70, 
+0x01, 0x31, 0x00, 0x20, 0x09, 0x4a, 0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 
+0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x00, 0x20, 0x08, 0x70, 
+0x80, 0xbc, 0x70, 0x47, 0x02, 0x10, 0x00, 0x03, 0x68, 0x0e, 0x00, 0x80, 
+0x7c, 0x04, 0x00, 0x80, 0x85, 0x04, 0x00, 0x80, 0x8e, 0x04, 0x00, 0x80, 
+0x00, 0xb5, 0x01, 0x23, 0x0a, 0x48, 0xc1, 0x1d, 0x89, 0x31, 0x4b, 0x70, 
+0x00, 0x22, 0x0a, 0x70, 0x64, 0x21, 0x80, 0x30, 0xc1, 0x82, 0x01, 0x83, 
+0x43, 0x83, 0x7d, 0x21, 0xc9, 0x00, 0x81, 0x83, 0xc2, 0x83, 0x04, 0x48, 
+0x01, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x38, 0xfb, 0x08, 0xbc, 0x18, 0x47, 
+0x68, 0x0e, 0x00, 0x80, 0xa1, 0x22, 0xff, 0xff, 
+0x00, 0xb5, 0xff, 0xf7, 0xe1, 0xff, 0x13, 0x48, 0x02, 0x22, 0x00, 0x21, 
+0x00, 0xf0, 0x2a, 0xfb, 0x01, 0x23, 0xd8, 0x42, 0x0a, 0xd1, 0x10, 0x48, 
+0xc1, 0x1d, 0x39, 0x31, 0xca, 0x88, 0x01, 0x32, 0xca, 0x80, 0x81, 0x79, 
+0x01, 0x31, 0x81, 0x71, 0xfc, 0xf7, 0x5c, 0xfd, 0x0b, 0x48, 0xc0, 0x68, 
+0x01, 0x28, 0x05, 0xd1, 0x0a, 0x48, 0x7d, 0x22, 0xd2, 0x00, 0x00, 0x21, 
+0x00, 0xf0, 0x12, 0xfb, 0x08, 0x48, 0xfa, 0xf7, 0x1b, 0xfa, 0x08, 0x48, 
+0x28, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x0a, 0xfb, 0x08, 0xbc, 0x18, 0x47, 
+0x65, 0x21, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 
+0x95, 0x7e, 0x21, 0x40, 0x81, 0x2c, 0xff, 0xff, 0x59, 0x03, 0xff, 0xff, 
+0x00, 0xb5, 0x10, 0x20, 0x0f, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4a, 
+0x0f, 0x48, 0x64, 0x21, 0xfa, 0xf7, 0x00, 0xfa, 0x0e, 0x48, 0x01, 0x22, 
+0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x08, 0x21, 0x00, 0x2a, 0x05, 0xd1, 
+0x02, 0x68, 0x12, 0x0c, 0x07, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x04, 0xd3, 
+0x08, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x08, 0xbc, 0x18, 0x47, 0x07, 0x48, 
+0xc0, 0x46, 0x01, 0x64, 0xf9, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
+0x91, 0x55, 0xff, 0xff, 0x7c, 0x29, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 
+0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf8, 0xb5, 0x27, 0x48, 
+0x01, 0x22, 0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x07, 0x21, 0x00, 0x2a, 
+0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 
+0x03, 0xd3, 0x21, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x02, 0xe0, 0x20, 0x48, 
+0xc0, 0x46, 0x01, 0x64, 0x1f, 0x48, 0xfa, 0xf7, 0xc1, 0xf9, 0x1f, 0x48, 
+0xc1, 0x6b, 0xff, 0x29, 0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x16, 0x1c, 
+0x0f, 0x1c, 0x1c, 0x4c, 0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, 
+0xa1, 0x69, 0x99, 0x43, 0x1d, 0x04, 0xa1, 0x61, 0xe8, 0x60, 0xa0, 0x69, 
+0xc0, 0x46, 0x28, 0x61, 0x16, 0x4a, 0x17, 0x49, 0x64, 0x20, 0xfa, 0xf7, 
+0xa9, 0xf9, 0x16, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x15, 0x4b, 0x00, 0x20, 
+0x39, 0x1c, 0x32, 0x1c, 0xfa, 0xf7, 0xa8, 0xf9, 0x13, 0x48, 0xc1, 0x68, 
+0x08, 0x29, 0xfc, 0xd1, 0x12, 0x48, 0xfa, 0xf7, 0x97, 0xf9, 0x10, 0x23, 
+0x60, 0x69, 0x98, 0x43, 0x60, 0x61, 0xe8, 0x60, 0x01, 0x20, 0xe3, 0x23, 
+0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x71, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 
+0x04, 0x02, 0xff, 0xff, 0x00, 0x01, 0x18, 0x40, 0x68, 0x0e, 0x00, 0x80, 
+0x0c, 0x55, 0xff, 0xff, 0x2d, 0xcf, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, 
+0x44, 0x80, 0x20, 0x40, 0x40, 0x01, 0x18, 0x40, 0xf4, 0x01, 0xff, 0xff, 
+0x00, 0xb5, 0xfd, 0xf7, 0xeb, 0xfa, 0x06, 0x48, 0xfa, 0xf7, 0x6c, 0xf9, 
+0xfd, 0xf7, 0xc0, 0xfa, 0xfd, 0xf7, 0xee, 0xfb, 0xfd, 0xf7, 0x00, 0xfc, 
+0xfd, 0xf7, 0x0e, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x91, 0x03, 0xff, 0xff, 
+0x90, 0xb5, 0xfd, 0xf7, 0x55, 0xf8, 0x34, 0x4f, 0x00, 0x24, 0xf9, 0x68, 
+0xf8, 0x1d, 0x79, 0x30, 0x01, 0x29, 0x0f, 0xd1, 0x31, 0x49, 0xc0, 0x46, 
+0xf9, 0x67, 0x31, 0x49, 0xc0, 0x46, 0x01, 0x60, 0x30, 0x49, 0xc0, 0x46, 
+0x0c, 0x60, 0x4c, 0x60, 0x8c, 0x60, 0xcc, 0x60, 0x0c, 0x61, 0x4c, 0x61, 
+0x8c, 0x61, 0x04, 0xe0, 0xf9, 0x1d, 0x7d, 0x31, 0xf9, 0x67, 0x12, 0xc0, 
+0x08, 0x38, 0x00, 0x68, 0x60, 0x23, 0x01, 0x68, 
+0x19, 0x43, 0x01, 0x60, 0xf8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 
+0x01, 0x60, 0xf8, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 
+0x00, 0xf0, 0x54, 0xf8, 0xfd, 0xf7, 0x38, 0xf8, 0x00, 0xf0, 0x08, 0xf9, 
+0xfc, 0xf7, 0x5f, 0xfc, 0xff, 0xf7, 0x84, 0xfd, 0xfd, 0xf7, 0x18, 0xfa, 
+0xfd, 0xf7, 0xa0, 0xf9, 0xfd, 0xf7, 0xac, 0xfa, 0xfd, 0xf7, 0x3e, 0xf9, 
+0xfd, 0xf7, 0xf4, 0xf8, 0xfd, 0xf7, 0x7e, 0xf9, 0x00, 0xf0, 0xc4, 0xf9, 
+0xfd, 0xf7, 0x86, 0xfb, 0xfd, 0xf7, 0xf4, 0xfa, 0xfd, 0xf7, 0xbc, 0xfa, 
+0xfd, 0xf7, 0x26, 0xf8, 0xfa, 0xf7, 0x12, 0xf8, 0xff, 0xf7, 0x40, 0xfd, 
+0x00, 0x20, 0xff, 0xf7, 0x17, 0xfe, 0xff, 0xf7, 0x97, 0xff, 0x71, 0x23, 
+0x5b, 0x01, 0xf8, 0x18, 0x04, 0x72, 0x44, 0x72, 0x07, 0x23, 0x5b, 0x02, 
+0xf8, 0x18, 0x04, 0x63, 0x09, 0x48, 0xc0, 0x46, 0x44, 0x62, 0x00, 0xf0, 
+0xc3, 0xf9, 0x08, 0x48, 0xfa, 0xf7, 0xf8, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x11, 0x40, 
+0x04, 0x01, 0x11, 0x40, 0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x00, 
+0x65, 0x9f, 0x21, 0x40, 0x00, 0xb5, 0x04, 0x48, 0xfa, 0xf7, 0xe4, 0xf8, 
+0xfd, 0xf7, 0x48, 0xfb, 0xfd, 0xf7, 0x0e, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
+0x61, 0xa9, 0x21, 0x40, 0xfa, 0x21, 0x03, 0x48, 0xc0, 0x46, 0x41, 0x62, 
+0x40, 0x21, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x18, 0x00, 
+0x07, 0x48, 0x41, 0x69, 0x07, 0x4b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 
+0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x80, 0x69, 
+0xc0, 0x46, 0x10, 0x61, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
+0xfe, 0xaf, 0x9a, 0x10, 0x00, 0xb5, 0x02, 0x48, 0xfa, 0xf7, 0xba, 0xf8, 
+0x08, 0xbc, 0x18, 0x47, 0xb4, 0x57, 0xff, 0xff, 0xf0, 0xb5, 0x24, 0x4c, 
+0x01, 0x21, 0x09, 0x04, 0x20, 0x68, 0x01, 0x40, 0x09, 0x20, 0x22, 0x4e, 
+0x22, 0x4d, 0x00, 0x29, 0x05, 0xd1, 0x21, 0x68, 0x09, 0x0c, 0x04, 0xd1, 
+0x21, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xf0, 0x60, 0x00, 0xe0, 0x28, 0x64, 
+0x1d, 0x48, 0xfa, 0xf7, 0x9f, 0xf8, 0x1d, 0x4f, 0x1d, 0x49, 0x88, 0x69, 
+0x01, 0x30, 0x88, 0x61, 0x38, 0x7a, 0x00, 0x28, 0x02, 0xd1, 0x78, 0x7a, 
+0x00, 0x28, 0x1f, 0xd0, 0x19, 0x48, 0xfa, 0xf7, 0x91, 0xf8, 0x19, 0x48, 
+0xfa, 0xf7, 0x8e, 0xf8, 0x00, 0x28, 0xfa, 0xd1, 0x38, 0x7a, 0x00, 0x28, 
+0x02, 0xd0, 0x16, 0x48, 0xfa, 0xf7, 0x86, 0xf8, 0x01, 0x21, 0x09, 0x04, 
+0x20, 0x68, 0x01, 0x40, 0x14, 0x20, 0x00, 0x29, 0x05, 0xd1, 0x21, 0x68, 
+0x09, 0x0c, 0x04, 0xd1, 0x21, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xf0, 0x60, 
+0x01, 0xe0, 0x28, 0x64, 0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, 0xdd, 0xfc, 
+0x0b, 0x48, 0xfa, 0xf7, 0x6f, 0xf8, 0xff, 0xf7, 0xaf, 0xff, 0xcd, 0xe7, 
 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 
-0xb0, 0xb5, 0x24, 0x4f, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 
-0x06, 0x20, 0x22, 0x4d, 0x22, 0x4c, 0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, 
-0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, 
-0x00, 0xe0, 0x20, 0x64, 0x03, 0x20, 0xfe, 0xf7, 0xc5, 0xfa, 0xfb, 0xf7, 
-0xa1, 0xf9, 0x01, 0x23, 0x18, 0x43, 0xfb, 0xf7, 0x6b, 0xfa, 0x00, 0xf0, 
-0x31, 0xf8, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x07, 0x20, 
-0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 
-0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0x00, 0xf0, 
-0x89, 0xf8, 0x00, 0xf0, 0x69, 0xf8, 0x00, 0xf0, 0xd3, 0xf8, 0x01, 0x21, 
-0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x09, 0x20, 0x00, 0x29, 0x05, 0xd1, 
-0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, 
-0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, 
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 
-0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x21, 0x48, 0xfa, 0xf7, 0x14, 0xfd, 
-0xfd, 0xf7, 0x4a, 0xf8, 0x00, 0xf0, 0xa6, 0xf8, 0xfd, 0xf7, 0x58, 0xf8, 
-0x00, 0xf0, 0xc0, 0xf8, 0xfc, 0xf7, 0x9f, 0xfc, 0xff, 0xf7, 0x5c, 0xfd, 
-0xfd, 0xf7, 0x3c, 0xfa, 0xfd, 0xf7, 0xc4, 0xf9, 0xfd, 0xf7, 0xdc, 0xfa, 
-0xfd, 0xf7, 0x60, 0xf9, 0xfd, 0xf7, 0x1a, 0xf9, 
-0xfd, 0xf7, 0xa2, 0xf9, 0x00, 0xf0, 0x8a, 0xf9, 0xfd, 0xf7, 0xb6, 0xfb, 
-0xfd, 0xf7, 0x24, 0xfb, 0xfd, 0xf7, 0xec, 0xfa, 0xfd, 0xf7, 0x46, 0xf8, 
-0xfa, 0xf7, 0xf2, 0xfb, 0xff, 0xf7, 0x18, 0xfd, 0x00, 0x20, 0xff, 0xf7, 
-0xef, 0xfd, 0x00, 0xf0, 0x29, 0xf8, 0x00, 0x20, 0x0a, 0x49, 0x71, 0x23, 
-0x5b, 0x01, 0xca, 0x18, 0x10, 0x71, 0x50, 0x71, 0x07, 0x23, 0x5b, 0x02, 
-0xc9, 0x18, 0xc8, 0x62, 0x06, 0x49, 0xc0, 0x46, 0x48, 0x62, 0x00, 0xf0, 
-0x87, 0xf9, 0x05, 0x48, 0xfa, 0xf7, 0xd6, 0xfc, 0x08, 0xbc, 0x18, 0x47, 
-0xff, 0xb8, 0x21, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x00, 
-0x31, 0x98, 0x21, 0x40, 0x00, 0xb5, 0x04, 0x48, 0xfa, 0xf7, 0xc8, 0xfc, 
-0xfd, 0xf7, 0x7c, 0xfb, 0xfd, 0xf7, 0x34, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
-0x11, 0xa2, 0x21, 0x40, 0x00, 0xb5, 0xfd, 0xf7, 0x81, 0xfa, 0x06, 0x48, 
-0xfa, 0xf7, 0xba, 0xfc, 0xfd, 0xf7, 0x56, 0xfa, 0xfd, 0xf7, 0x8c, 0xfb, 
-0xfd, 0xf7, 0x9e, 0xfb, 0xfd, 0xf7, 0xac, 0xfb, 0x08, 0xbc, 0x18, 0x47, 
-0x91, 0x03, 0xff, 0xff, 0xf8, 0xb5, 0x1a, 0x48, 0xc1, 0x6b, 0xff, 0x29, 
-0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x0d, 0x1c, 0x16, 0x1c, 0x17, 0x4c, 
-0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, 0xa1, 0x69, 0x99, 0x43, 
-0x1f, 0x04, 0xa1, 0x61, 0xf8, 0x60, 0xa0, 0x69, 0xc0, 0x46, 0x38, 0x61, 
-0x11, 0x4a, 0x12, 0x49, 0x64, 0x20, 0xfa, 0xf7, 0x95, 0xfc, 0x11, 0x4a, 
-0xc0, 0x46, 0x00, 0x92, 0x10, 0x4b, 0x00, 0x20, 0x29, 0x1c, 0x32, 0x1c, 
-0xfa, 0xf7, 0x94, 0xfc, 0x0e, 0x48, 0xc1, 0x68, 0x08, 0x29, 0xfc, 0xd1, 
-0x10, 0x23, 0x60, 0x69, 0x98, 0x43, 0x60, 0x61, 0xf8, 0x60, 0x01, 0x20, 
-0xe3, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x70, 0xf8, 0xbc, 0x08, 0xbc, 
-0x18, 0x47, 0x00, 0x00, 0x00, 0x01, 0x18, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
-0xa0, 0x54, 0xff, 0xff, 0x11, 0xc8, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, 
-0x44, 0x80, 0x20, 0x40, 0x40, 0x01, 0x18, 0x40, 0xfa, 0x21, 0x03, 0x48, 
-0xc0, 0x46, 0x41, 0x62, 0x40, 0x21, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 
-0xc0, 0x00, 0x18, 0x00, 0x07, 0x48, 0x41, 0x69, 0x07, 0x4b, 0x19, 0x43, 
-0x41, 0x61, 0x82, 0x69, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 
-0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x70, 0x47, 0x00, 0x00, 
-0xe8, 0x0d, 0x00, 0x80, 0xfe, 0xaf, 0x9a, 0x10, 0xf0, 0xb4, 0x4b, 0x4a, 
-0x4b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x4b, 0x4d, 0x4b, 0x4b, 0x98, 0x42, 
-0x02, 0xd0, 0x01, 0x33, 0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x28, 0x80, 
-0x01, 0x21, 0xc9, 0x03, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0x61, 0x61, 
-0x28, 0x88, 0x40, 0x04, 0x44, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x06, 0x20, 
-0xaf, 0x60, 0x43, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x20, 0x20, 0xc8, 0x23, 
-0x43, 0x43, 0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3e, 0x4e, 0xc0, 0x46, 
-0x31, 0x61, 0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3b, 0x4e, 0xc0, 0x46, 
-0xf3, 0x61, 0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, 
-0x81, 0x42, 0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, 
-0x41, 0x1e, 0x34, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, 
-0x02, 0x38, 0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, 
-0x06, 0xe0, 0x2e, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, 
-0x88, 0x42, 0xd2, 0xd9, 0x2b, 0x49, 0x00, 0x20, 
-0x63, 0x69, 0x9b, 0x08, 0x07, 0xd0, 0x2a, 0x4b, 0x87, 0x00, 0xcb, 0x51, 
-0x67, 0x69, 0xbf, 0x08, 0x01, 0x30, 0x87, 0x42, 0xf8, 0xd8, 0x24, 0x49, 
-0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89, 0x58, 0x20, 0x60, 0x43, 0x87, 0x18, 
-0x00, 0x20, 0x00, 0x22, 0x00, 0x2c, 0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, 
-0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 
-0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc, 0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, 
-0x00, 0x19, 0x40, 0x01, 0xc7, 0x19, 0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, 
-0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01, 0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, 
-0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, 
-0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69, 0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, 
-0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51, 0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, 
-0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00, 0x08, 0x18, 0x04, 0x38, 0x28, 0x61, 
-0xf0, 0xbc, 0x70, 0x47, 0xb8, 0xce, 0x21, 0x40, 0x00, 0x00, 0x18, 0x40, 
-0xe8, 0x0d, 0x00, 0x80, 0x02, 0x99, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 
-0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00, 
+0x04, 0x02, 0xff, 0xff, 0x88, 0x1c, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40, 
+0xf4, 0x01, 0xff, 0xff, 0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 
+0xe9, 0xaf, 0x21, 0x40, 0x00, 0xb5, 0x16, 0x49, 0x01, 0x22, 0x12, 0x04, 
+0x08, 0x68, 0x02, 0x40, 0x06, 0x20, 0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68, 
+0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x10, 0x49, 
+0xc0, 0x46, 0xc8, 0x60, 0x02, 0xe0, 0x0f, 0x49, 0xc0, 0x46, 0x08, 0x64, 
+0x03, 0x20, 0xfe, 0xf7, 0x55, 0xf9, 0xfa, 0xf7, 
+0x9d, 0xfc, 0x01, 0x23, 0x18, 0x43, 0xfa, 0xf7, 0x77, 0xfd, 0xff, 0xf7, 
+0xd7, 0xfe, 0xff, 0xf7, 0x5b, 0xfe, 0xff, 0xf7, 0x4b, 0xff, 0xff, 0xf7, 
+0x5f, 0xff, 0xff, 0xf7, 0xf1, 0xfd, 0xff, 0xf7, 0x77, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 
+0x00, 0x00, 0x00, 0x80, 0xf0, 0xb4, 0x46, 0x4a, 0x01, 0x21, 0xc9, 0x03, 
+0x45, 0x4d, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0xa1, 0x61, 0x28, 0x88, 
+0x40, 0x04, 0x43, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x04, 0x20, 0xaf, 0x60, 
+0x41, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x08, 0x20, 0xc8, 0x23, 0x43, 0x43, 
+0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3d, 0x4e, 0xc0, 0x46, 0x31, 0x61, 
+0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3a, 0x4e, 0xc0, 0x46, 0xf3, 0x61, 
+0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, 0x81, 0x42, 
+0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, 0x41, 0x1e, 
+0x32, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, 0x02, 0x38, 
+0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, 0x06, 0xe0, 
+0x2c, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, 0x88, 0x42, 
+0xd2, 0xd9, 0x2a, 0x49, 0x00, 0x20, 0xa3, 0x69, 0x9b, 0x08, 0x07, 0xd0, 
+0x28, 0x4b, 0x87, 0x00, 0xcb, 0x51, 0xa7, 0x69, 0xbf, 0x08, 0x01, 0x30, 
+0x87, 0x42, 0xf8, 0xd8, 0x22, 0x49, 0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89, 
+0x58, 0x20, 0x60, 0x43, 0x87, 0x18, 0x00, 0x20, 0x00, 0x22, 0x00, 0x2c, 
+0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, 0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30, 
+0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc, 
+0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, 0x00, 0x19, 0x40, 0x01, 0xc7, 0x19, 
+0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, 0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01, 
+0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 
+0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, 0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69, 
+0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, 0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51, 
+0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, 0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00, 
+0x08, 0x18, 0x04, 0x38, 0x28, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 
+0xec, 0xd6, 0x21, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 
+0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00, 
 0x0a, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 
 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 
-0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x61, 0x01, 0x20, 0x00, 0x06, 
-0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x81, 0x61, 0x01, 0x20, 0x00, 0x06, 
+0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
 0x80, 0xb4, 0x02, 0x1c, 0x0b, 0x48, 0x1b, 0x23, 0xdb, 0x01, 0xc3, 0x18, 
-0x5a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61, 
+0x9a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61, 
 0x87, 0x69, 0x9f, 0x43, 0x01, 0x23, 0x1b, 0x05, 0x87, 0x61, 0xda, 0x60, 
 0x80, 0x69, 0xc0, 0x46, 0x18, 0x61, 0xa1, 0x20, 0x40, 0x03, 0x81, 0x61, 
-0x80, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0xff, 0xf7, 
+0x80, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0xff, 0xf7, 
 0xc9, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x20, 0xf8, 0x00, 0x20, 0x09, 0x49, 
 0x00, 0x22, 0x03, 0x01, 0x5f, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xfb, 0x18, 
-0x5a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3, 0x04, 0x48, 0x01, 0x22, 
-0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
-0xe8, 0x0d, 0x00, 0x80, 0x91, 0x3d, 0xff, 0xff, 0x00, 0xb5, 0x02, 0x48, 
-0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xa8, 0x61, 0x00, 0x00, 
-0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b, 0xa1, 0x21, 0x49, 0x03, 
-0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c, 0x59, 0x69, 0x53, 0x01, 
-0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43, 0x87, 0x61, 0xd1, 0x60, 
-0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc, 0x70, 0x47, 0x18, 0x1c, 
-0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43, 0x47, 0x61, 0xd7, 0x60, 
-0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
-0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c, 0x03, 0x01, 0x1d, 0x19, 
-0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5d, 0x6a, 0xbd, 0x42, 0x05, 0xd1, 
-0xdd, 0x6a, 0x95, 0x42, 0x02, 0xd1, 0x9b, 0x6a, 0x8b, 0x42, 0x1c, 0xd0, 
-0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20, 0x03, 0x01, 0x1d, 0x19, 
-0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5b, 0x6a, 0x00, 0x2b, 0x09, 0xd1, 
-0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0xda, 0x62, 
-0x99, 0x62, 0x1a, 0x63, 0x5f, 0x62, 0x02, 0xe0, 
+0x9a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3, 0x04, 0x48, 0x01, 0x22, 
+0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x09, 0x3e, 0xff, 0xff, 
+0x00, 0xb5, 0x02, 0x48, 0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
+0xa8, 0x61, 0x00, 0x00, 0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b, 
+0xa1, 0x21, 0x49, 0x03, 0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c, 
+0x59, 0x69, 0x53, 0x01, 0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43, 
+0x87, 0x61, 0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc, 
+0x70, 0x47, 0x18, 0x1c, 0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43, 
+0x47, 0x61, 0xd7, 0x60, 0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c, 
+0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9d, 0x6a, 
+0xbd, 0x42, 0x05, 0xd1, 0x1d, 0x6b, 0x95, 0x42, 0x02, 0xd1, 0xdb, 0x6a, 
+0x8b, 0x42, 0x1c, 0xd0, 0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20, 
+0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9b, 0x6a, 
+0x00, 0x2b, 0x09, 0xd1, 0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01, 
+0xe3, 0x18, 0x1a, 0x63, 0xd9, 0x62, 0x5a, 0x63, 0x9f, 0x62, 0x02, 0xe0, 
 0x01, 0x30, 0x0b, 0x28, 0xea, 0xd3, 0x0b, 0x28, 0x01, 0xd1, 0x00, 0x20, 
-0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
 0x90, 0xb4, 0x01, 0x1c, 0x00, 0x22, 0x01, 0x20, 0x16, 0x4f, 0x01, 0xe0, 
 0x00, 0x2a, 0x07, 0xd1, 0x03, 0x01, 0xdc, 0x19, 0x33, 0x23, 0x9b, 0x01, 
-0xe3, 0x18, 0x5b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19, 
-0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x53, 0x6a, 0xc0, 0x46, 0x53, 0x61, 
-0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61, 0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, 
-0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28, 
-0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x5a, 0x68, 0x8a, 0x42, 
-0x03, 0xd1, 0x00, 0x21, 0x59, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 
-0xc0, 0x43, 0xfa, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x68, 0x1b, 0x00, 0x80, 
+0xe3, 0x18, 0x9b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19, 
+0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61, 
+0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, 0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62, 
+0x53, 0x6b, 0xc0, 0x46, 0x53, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28, 
+0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x9a, 0x68, 0x8a, 0x42, 
+0x03, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 
+0xc0, 0x43, 0xfa, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 
 0x0b, 0x28, 0x17, 0xda, 0x0c, 0x49, 0x01, 0x23, 0x5b, 0x06, 0x8a, 0x69, 
 0x13, 0x43, 0x01, 0x22, 0x12, 0x05, 0x8b, 0x61, 0x13, 0x61, 0x00, 0x01, 
-0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc3, 0x6a, 0xc0, 0x46, 
-0x03, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61, 
-0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
+0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0xc0, 0x46, 
+0x43, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61, 
+0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x68, 0x0e, 0x00, 0x80, 
 0x90, 0xb4, 0x08, 0x4a, 0xd0, 0x69, 0x00, 0x21, 0x07, 0x4f, 0xd3, 0x69, 
 0x83, 0x42, 0x02, 0xd9, 0xfc, 0x1a, 0x20, 0x18, 0x00, 0xe0, 0xc0, 0x1a, 
 0x09, 0x18, 0x18, 0x1c, 0xb9, 0x42, 0xf4, 0xd9, 0x90, 0xbc, 0x70, 0x47, 
@@ -4100,9 +4288,9 @@ const u8 typhoon_firmware_image[] = {
 0x08, 0xc9, 0x08, 0xc0, 0x12, 0x1f, 0xfb, 0xd2, 0x0a, 0xe0, 0x08, 0xc9, 
 0x03, 0x70, 0x1b, 0x0a, 0x43, 0x70, 0x1b, 0x0a, 0x83, 0x70, 0x1b, 0x0a, 
 0xc3, 0x70, 0x00, 0x1d, 0x12, 0x1f, 0xf4, 0xd2, 0xd2, 0x1c, 0x05, 0xd3, 
-0x0b, 0x78, 0x03, 0x70, 0x49, 0x1c, 0x40, 0x1c, 0x52, 0x1e, 0xf9, 0xd2, 
-0x60, 0x46, 0x70, 0x47, 0x03, 0x1c, 0x0b, 0x43, 0x13, 0x43, 0x9b, 0x07, 
-0x04, 0xd1, 0x12, 0x1f, 0x8b, 0x58, 0x83, 0x50, 0xfb, 0xd1, 0x70, 0x47, 
-0x52, 0x1e, 0x8b, 0x5c, 0x83, 0x54, 0xfb, 0xd1, 0x70, 0x47, 0x00, 0x00, 
-0x00, 0x20, 0x70, 0x47, 
+0x0b, 0x78, 0x03, 0x70, 0x49, 0x1c, 0x40, 0x1c, 
+0x52, 0x1e, 0xf9, 0xd2, 0x60, 0x46, 0x70, 0x47, 0x03, 0x1c, 0x0b, 0x43, 
+0x13, 0x43, 0x9b, 0x07, 0x04, 0xd1, 0x12, 0x1f, 0x8b, 0x58, 0x83, 0x50, 
+0xfb, 0xd1, 0x70, 0x47, 0x52, 0x1e, 0x8b, 0x5c, 0x83, 0x54, 0xfb, 0xd1, 
+0x70, 0x47, 0x00, 0x00, 0x00, 0x20, 0x70, 0x47, 
 };
index 6d1f024..7e3494a 100644 (file)
@@ -85,8 +85,8 @@ static const int multicast_filter_limit = 32;
 #define PKT_BUF_SZ             1536
 
 #define DRV_MODULE_NAME                "typhoon"
-#define DRV_MODULE_VERSION     "1.5.2"
-#define DRV_MODULE_RELDATE     "03/11/25"
+#define DRV_MODULE_VERSION     "1.5.3"
+#define DRV_MODULE_RELDATE     "03/12/15"
 #define PFX                    DRV_MODULE_NAME ": "
 #define ERR_PFX                        KERN_ERR PFX
 
@@ -157,6 +157,7 @@ enum typhoon_cards {
        TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR,
        TYPHOON_SVR95, TYPHOON_SVR97, TYPHOON_TXM, TYPHOON_BSVR,
        TYPHOON_FX95, TYPHOON_FX97, TYPHOON_FX95SVR, TYPHOON_FX97SVR,
+       TYPHOON_FXM,
 };
 
 /* directly indexed by enum typhoon_cards, above */
@@ -185,6 +186,8 @@ static struct typhoon_card_info typhoon_card_info[] __devinitdata = {
                TYPHOON_CRYPTO_DES | TYPHOON_FIBER},
        { "3Com Typhoon (3CR990-FX-97 Server)",
                TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER},
+       { "3Com Typhoon2 (3C990B-FX-97)",
+               TYPHOON_CRYPTO_VARIABLE | TYPHOON_FIBER},
 };
 
 /* Notes on the new subsystem numbering scheme:
@@ -203,6 +206,8 @@ static struct pci_device_id typhoon_pci_tbl[] = {
        { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
          PCI_ANY_ID, 0x1000, 0, 0, TYPHOON_TXM },
        { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
+         PCI_ANY_ID, 0x1102, 0, 0, TYPHOON_FXM },
+       { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
          PCI_ANY_ID, 0x2000, 0, 0, TYPHOON_BSVR },
        { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
          PCI_ANY_ID, 0x1101, 0, 0, TYPHOON_FX95 },
@@ -1363,6 +1368,7 @@ typhoon_download_firmware(struct typhoon *tp)
        u32 section_len;
        u32 len;
        u32 load_addr;
+       u32 hmac;
        int i;
        int err;
 
@@ -1406,6 +1412,16 @@ typhoon_download_firmware(struct typhoon *tp)
 
        writel(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS);
        writel(load_addr, ioaddr + TYPHOON_REG_DOWNLOAD_BOOT_ADDR);
+       hmac = le32_to_cpu(fHdr->hmacDigest[0]);
+       writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_0);
+       hmac = le32_to_cpu(fHdr->hmacDigest[1]);
+       writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_1);
+       hmac = le32_to_cpu(fHdr->hmacDigest[2]);
+       writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_2);
+       hmac = le32_to_cpu(fHdr->hmacDigest[3]);
+       writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_3);
+       hmac = le32_to_cpu(fHdr->hmacDigest[4]);
+       writel(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_4);
        typhoon_post_pci_writes(ioaddr);
        writel(TYPHOON_BOOTCMD_RUNTIME_IMAGE, ioaddr + TYPHOON_REG_COMMAND);
 
index 5c0e395..738ee71 100644 (file)
@@ -512,6 +512,7 @@ struct typhoon_file_header {
        u32 version;
        u32 numSections;
        u32 startAddr;
+       u32 hmacDigest[5];
 } __attribute__ ((packed));
 
 struct typhoon_section_header {
@@ -548,6 +549,11 @@ struct typhoon_section_header {
 #define TYPHOON_REG_BOOT_LENGTH                        TYPHOON_REG_HOST2ARM1
 
 #define TYPHOON_REG_DOWNLOAD_BOOT_ADDR         TYPHOON_REG_HOST2ARM1
+#define TYPHOON_REG_DOWNLOAD_HMAC_0            TYPHOON_REG_HOST2ARM2
+#define TYPHOON_REG_DOWNLOAD_HMAC_1            TYPHOON_REG_HOST2ARM3
+#define TYPHOON_REG_DOWNLOAD_HMAC_2            TYPHOON_REG_HOST2ARM4
+#define TYPHOON_REG_DOWNLOAD_HMAC_3            TYPHOON_REG_HOST2ARM5
+#define TYPHOON_REG_DOWNLOAD_HMAC_4            TYPHOON_REG_HOST2ARM6
 
 #define TYPHOON_REG_BOOT_RECORD_ADDR_HI                TYPHOON_REG_HOST2ARM2
 #define TYPHOON_REG_BOOT_RECORD_ADDR_LO                TYPHOON_REG_HOST2ARM1
index 43f4a31..6be377e 100644 (file)
@@ -594,40 +594,47 @@ err_out:
 \f
 /*---------- SPPP/HDLC netdevice ---------- */
 
+static void cosa_setup(struct net_device *d)
+{
+       d->open = cosa_sppp_open;
+       d->stop = cosa_sppp_close;
+       d->hard_start_xmit = cosa_sppp_tx;
+       d->do_ioctl = cosa_sppp_ioctl;
+       d->get_stats = cosa_net_stats;
+       d->tx_timeout = cosa_sppp_timeout;
+       d->watchdog_timeo = TX_TIMEOUT;
+}
+
 static void sppp_channel_init(struct channel_data *chan)
 {
        struct net_device *d;
        chan->if_ptr = &chan->pppdev;
-       chan->pppdev.dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-       memset(chan->pppdev.dev, 0, sizeof(struct net_device));
+       d = alloc_netdev(0, chan->name, cosa_setup);
+       if (!d) {
+               printk(KERN_WARNING "%s: alloc_netdev failed.\n", chan->name);
+               return;
+       }
+       chan->pppdev.dev = d;
        sppp_attach(&chan->pppdev);
-       d=chan->pppdev.dev;
-       strcpy(d->name, chan->name);
        d->base_addr = chan->cosa->datareg;
        d->irq = chan->cosa->irq;
        d->dma = chan->cosa->dma;
        d->priv = chan;
-       d->init = NULL;
-       d->open = cosa_sppp_open;
-       d->stop = cosa_sppp_close;
-       d->hard_start_xmit = cosa_sppp_tx;
-       d->do_ioctl = cosa_sppp_ioctl;
-       d->get_stats = cosa_net_stats;
-       d->tx_timeout = cosa_sppp_timeout;
-       d->watchdog_timeo = TX_TIMEOUT;
        if (register_netdev(d)) {
                printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
-               sppp_detach(chan->pppdev.dev);
-               free_netdev(chan->pppdev.dev);
+               sppp_detach(d);
+               free_netdev(d);
+               chan->pppdev.dev = NULL;
                return;
        }
 }
 
 static void sppp_channel_delete(struct channel_data *chan)
 {
-       sppp_detach(chan->pppdev.dev);
        unregister_netdev(chan->pppdev.dev);
+       sppp_detach(chan->pppdev.dev);
        free_netdev(chan->pppdev.dev);
+       chan->pppdev.dev = NULL;
 }
 
 static int cosa_sppp_open(struct net_device *d)
index 439226b..332202b 100644 (file)
 #include "lmc_debug.h"
 #include "lmc_proto.h"
 
-
-static int Lmc_Count = 0;
-static struct net_device *Lmc_root_dev = NULL;
-static u8 cards_found = 0;
-
 static int lmc_first_load = 0;
 
-int LMC_PKT_BUF_SZ = 1542;
+static int LMC_PKT_BUF_SZ = 1542;
 
-#ifdef MODULE
 static struct pci_device_id lmc_pci_tbl[] = {
-    { 0x1011, 0x009, 0x1379, PCI_ANY_ID, 0, 0, 0},
-    { 0, }
+       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
+         PCI_VENDOR_ID_LMC, PCI_ANY_ID },
+       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
+         PCI_ANY_ID, PCI_VENDOR_ID_LMC },
+       { 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
-
 MODULE_LICENSE("GPL");
-#endif
 
 
-int lmc_probe_fake(struct net_device *dev);
-static struct net_device *lmc_probe1(struct net_device *dev, unsigned long ioaddr, unsigned int irq,
-                                int chip_id, int subdevice, int board_idx);
 static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lmc_rx (struct net_device *dev);
@@ -115,12 +107,9 @@ static void lmc_softreset(lmc_softc_t * const);
 static void lmc_running_reset(struct net_device *dev);
 static int lmc_ifdown(struct net_device * const);
 static void lmc_watchdog(unsigned long data);
-static int lmc_init(struct net_device * const);
 static void lmc_reset(lmc_softc_t * const sc);
 static void lmc_dec_reset(lmc_softc_t * const sc);
 static void lmc_driver_timeout(struct net_device *dev);
-int lmc_setup(void);
-
 
 /*
  * linux reserves 16 device specific IOCTLs.  We call them
@@ -815,67 +804,77 @@ kick_timer:
 
 }
 
-static int lmc_init(struct net_device * const dev) /*fold00*/
+static void lmc_setup(struct net_device * const dev) /*fold00*/
 {
-    lmc_trace(dev, "lmc_init in");
-    lmc_trace(dev, "lmc_init out");
-       
-    return 0;
+    lmc_trace(dev, "lmc_setup in");
+
+    dev->type = ARPHRD_HDLC;
+    dev->hard_start_xmit = lmc_start_xmit;
+    dev->open = lmc_open;
+    dev->stop = lmc_close;
+    dev->get_stats = lmc_get_stats;
+    dev->do_ioctl = lmc_ioctl;
+    dev->set_config = lmc_set_config;
+    dev->tx_timeout = lmc_driver_timeout;
+    dev->watchdog_timeo = (HZ); /* 1 second */
+    
+    lmc_trace(dev, "lmc_setup out");
 }
 
-/* This initializes each card from lmc_probe() */
-static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioaddr, unsigned int irq, /*fold00*/
-                                  int chip_id, int subdevice, int board_idx)
+
+static int __devinit lmc_init_one(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
 {
-    lmc_softc_t *sc = NULL;
+    struct net_device *dev;
+    lmc_softc_t *sc;
+    u16 subdevice;
     u_int16_t AdapModelNum;
-
-    /*
-     * Allocate our own device structure
-     */
-
-    dev = kmalloc (sizeof (struct net_device)+8, GFP_KERNEL);
-    if (dev == NULL){
-        printk (KERN_ERR "lmc: kmalloc for device failed\n");
-        return NULL;
-    }
-    memset (dev, 0, sizeof (struct net_device));
-
+    int err = -ENOMEM;
+    static int cards_found;
 #ifndef GCOM
-    /*
-     * Switch to common hdlc%d naming. We name by type not by vendor
-     */
-    
-    dev_alloc_name(dev, "hdlc%d");
+    /* We name by type not by vendor */
+    static const char lmcname[] = "hdlc%d";
 #else
-    /*
+    /* 
      * GCOM uses LMC vendor name so that clients can know which card
      * to attach to.
      */
-    dev_alloc_name(dev, "lmc%d");
+    static const char lmcname[] = "lmc%d";
 #endif
 
-    lmc_trace(dev, "lmc_probe1 in");
+
+    /*
+     * Allocate our own device structure
+     */
+    dev = alloc_netdev(sizeof(lmc_softc_t), lmcname, lmc_setup);
+    if (!dev) {
+        printk (KERN_ERR "lmc:alloc_netdev for device failed\n");
+       goto out1;
+    }
+    lmc_trace(dev, "lmc_init_one in");
+
+    err = pci_enable_device(pdev);
+    if (err) {
+           printk(KERN_ERR "lmc: pci enable failed:%d\n", err);
+           goto out2;
+    }
     
-    Lmc_Count++;
+    if (pci_request_regions(pdev, "lmc")) {
+           printk(KERN_ERR "lmc: pci_request_region failed\n");
+           err = -EIO;
+           goto out3;
+    }
+
+    pci_set_drvdata(pdev, dev);
 
     if(lmc_first_load == 0){
-        printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
+        printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",
+              DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
         lmc_first_load = 1;
     }
     
-    /*
-     * Allocate space for the private data structure
-     */
-
-    sc = kmalloc (sizeof (lmc_softc_t), GFP_KERNEL);
-    if (sc == NULL) {
-        printk (KERN_WARNING "%s: Cannot allocate memory for device state\n",
-                dev->name);
-        return (NULL);
-    }
-    memset (sc, 0, sizeof (lmc_softc_t));
-    dev->priv = sc;
+    sc = dev->priv;
     sc->lmc_device = dev;
     sc->name = dev->name;
 
@@ -883,8 +882,12 @@ static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioad
     /* An ioctl can cause a subsequent detach for raw frame interface */
     sc->if_type = LMC_PPP;
     sc->check = 0xBEAFCAFE;
-    dev->base_addr = ioaddr;
-    dev->irq = irq;
+    dev->base_addr = pci_resource_start(pdev, 0);
+    dev->irq = pdev->irq;
+
+    SET_MODULE_OWNER(dev);
+    SET_NETDEV_DEV(dev, &pdev->dev);
+
     /*
      * This will get the protocol layer ready and do any 1 time init's
      * Must have a valid sc and dev structure
@@ -893,19 +896,6 @@ static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioad
 
     lmc_proto_attach(sc);
 
-    /* Just fill in the entries for the device */
-
-    dev->init = lmc_init;
-    dev->type = ARPHRD_HDLC;
-    dev->hard_start_xmit = lmc_start_xmit;
-    dev->open = lmc_open;
-    dev->stop = lmc_close;
-    dev->get_stats = lmc_get_stats;
-    dev->do_ioctl = lmc_ioctl;
-    dev->set_config = lmc_set_config;
-    dev->tx_timeout = lmc_driver_timeout;
-    dev->watchdog_timeo = (HZ); /* 1 second */
-    
     /*
      * Why were we changing this???
      dev->tx_queue_len = 100;
@@ -914,44 +904,45 @@ static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioad
     /* Init the spin lock so can call it latter */
 
     spin_lock_init(&sc->lmc_lock);
+    pci_set_master(pdev);
 
-    printk ("%s: detected at %lx, irq %d\n", dev->name, ioaddr, dev->irq);
+    printk ("%s: detected at %lx, irq %d\n", dev->name,
+           dev->base_addr, dev->irq);
 
     if (register_netdev (dev) != 0) {
         printk (KERN_ERR "%s: register_netdev failed.\n", dev->name);
-        lmc_proto_detach(sc);
-        kfree (dev->priv);
-        kfree (dev);
-        return NULL;
+       goto out4;
     }
 
-    /*
-     * Request the region of registers we need, so that
-     * later on, no one else will take our card away from
-     * us.
-     */
-    request_region (ioaddr, LMC_REG_RANGE, dev->name);
-
     sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;
     sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
 
+    /*
+     *
+     * Check either the subvendor or the subdevice, some systems reverse
+     * the setting in the bois, seems to be version and arch dependent?
+     * Fix the error, exchange the two values 
+     */
+    if ((subdevice = pdev->subsystem_device) == PCI_VENDOR_ID_LMC)
+           subdevice = pdev->subsystem_vendor;
+
     switch (subdevice) {
-    case PCI_PRODUCT_LMC_HSSI:
+    case PCI_DEVICE_ID_LMC_HSSI:
         printk ("%s: LMC HSSI\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_HSSI;
         sc->lmc_media = &lmc_hssi_media;
         break;
-    case PCI_PRODUCT_LMC_DS3:
+    case PCI_DEVICE_ID_LMC_DS3:
         printk ("%s: LMC DS3\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_DS3;
         sc->lmc_media = &lmc_ds3_media;
         break;
-    case PCI_PRODUCT_LMC_SSI:
+    case PCI_DEVICE_ID_LMC_SSI:
         printk ("%s: LMC SSI\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_SSI;
         sc->lmc_media = &lmc_ssi_media;
         break;
-    case PCI_PRODUCT_LMC_T1:
+    case PCI_DEVICE_ID_LMC_T1:
         printk ("%s: LMC T1\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_T1;
         sc->lmc_media = &lmc_t1_media;
@@ -976,13 +967,13 @@ static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioad
     AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4;
 
     if ((AdapModelNum == LMC_ADAP_T1
-         && subdevice == PCI_PRODUCT_LMC_T1) ||                /* detect LMC1200 */
+         && subdevice == PCI_DEVICE_ID_LMC_T1) ||      /* detect LMC1200 */
         (AdapModelNum == LMC_ADAP_SSI
-         && subdevice == PCI_PRODUCT_LMC_SSI) ||       /* detect LMC1000 */
+         && subdevice == PCI_DEVICE_ID_LMC_SSI) ||     /* detect LMC1000 */
         (AdapModelNum == LMC_ADAP_DS3
-         && subdevice == PCI_PRODUCT_LMC_DS3) ||       /* detect LMC5245 */
+         && subdevice == PCI_DEVICE_ID_LMC_DS3) ||     /* detect LMC5245 */
         (AdapModelNum == LMC_ADAP_HSSI
-         && subdevice == PCI_PRODUCT_LMC_HSSI))
+         && subdevice == PCI_DEVICE_ID_LMC_HSSI))
     {                          /* detect LMC5200 */
 
     }
@@ -996,10 +987,7 @@ static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioad
      */
     LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);
 
-    sc->board_idx = board_idx;
-
-    memset (&sc->stats, 0, sizeof (struct lmc_statistics));
-
+    sc->board_idx = cards_found++;
     sc->stats.check = STATCHECK;
     sc->stats.version_size = (DRIVER_VERSION << 16) +
         sizeof (struct lmc_statistics);
@@ -1008,105 +996,40 @@ static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioad
     sc->lmc_ok = 0;
     sc->last_link_status = 0;
 
-    lmc_trace(dev, "lmc_probe1 out");
-
-    return dev;
-}
-
-
-/* This is the entry point.  This is what is called immediately. */
-/* This goes out and finds the card */
+    lmc_trace(dev, "lmc_init_one out");
+    return 0;
 
-int lmc_probe_fake(struct net_device *dev) /*fold00*/
-{
-    lmc_probe(NULL);
-    /* Return 1 to unloaded bogus device */
-    return 1;
+ out4:
+    lmc_proto_detach(sc);
+ out3:
+    if (pdev) {
+           pci_release_regions(pdev);
+           pci_set_drvdata(pdev, NULL);
+    }
+ out2:
+    free_netdev(dev);
+ out1:
+    return err;
 }
 
-int lmc_probe (struct net_device *dev) /*fold00*/
+/*
+ * Called from pci when removing module.
+ */
+static void __devexit lmc_remove_one (struct pci_dev *pdev)
 {
-    int pci_index = 0;
-    unsigned long pci_ioaddr;
-    unsigned int pci_irq_line;
-    u16 vendor, subvendor, device, subdevice;
-    u32 foundaddr = 0;
-    u8 intcf = 0;
-    struct pci_dev *pdev = NULL;
-
-    /* Loop basically until we don't find anymore. */
-    while ((pdev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
-       if (pci_enable_device(pdev))
-               break;
-
-        vendor = pdev->vendor;
-        device = pdev->device;
-        pci_irq_line = pdev->irq;
-        pci_ioaddr = pci_resource_start (pdev, 0);
-       subvendor = pdev->subsystem_vendor;
-       subdevice = pdev->subsystem_device;
-
-       pci_set_master (pdev);
-
-        /*
-         * Make sure it's the correct card.  CHECK SUBVENDOR ID!
-         * There are lots of tulip's out there.
-         * Also check the region of registers we will soon be
-         * poking, to make sure no one else has reserved them.
-         * This prevents taking someone else's device.
-         *
-         * Check either the subvendor or the subdevice, some systems reverse
-         * the setting in the bois, seems to be version and arch dependent?
-         * Fix the two variables
-         *
-         */
-        if (!(check_region (pci_ioaddr, LMC_REG_RANGE)) &&
-            (vendor == CORRECT_VENDOR_ID) &&
-            (device == CORRECT_DEV_ID) &&
-            ((subvendor == PCI_VENDOR_LMC)  || (subdevice == PCI_VENDOR_LMC))){
-            struct net_device *cur, *prev = NULL;
-
-            /* Fix the error, exchange the two values */
-            if(subdevice == PCI_VENDOR_LMC){
-                subdevice = subvendor;
-                subvendor = PCI_VENDOR_LMC ;
-            }
-
-            /* Make the call to actually setup this card */
-            dev = lmc_probe1 (dev, pci_ioaddr, pci_irq_line,
-                              device, subdevice, cards_found);
-            if (dev == NULL) {
-                printk ("lmc_probe: lmc_probe1 failed\n");
-                goto lmc_probe_next_card;
-            }
-            /* insert the device into the chain of lmc devices */
-            for (cur = Lmc_root_dev;
-                 cur != NULL;
-                 cur = ((lmc_softc_t *) cur->priv)->next_module) {
-                prev = cur;
-            }
-
-            if (prev == NULL)
-                Lmc_root_dev = dev;
-            else
-                ((lmc_softc_t *) prev->priv)->next_module = dev;
-
-            ((lmc_softc_t *) dev->priv)->next_module = NULL;
-            /* end insert */
-
-            foundaddr = dev->base_addr;
-
-            cards_found++;
-            intcf++;
-        }
-    lmc_probe_next_card:
-        pci_index++;
+    struct net_device *dev = pci_get_drvdata(pdev);
+    
+    if (dev) {
+           lmc_softc_t *sc = dev->priv;
+           
+           printk("%s: removing...\n", dev->name);
+           lmc_proto_detach(sc);
+           unregister_netdev(dev);
+           free_netdev(dev);
+           pci_release_regions(pdev);
+           pci_disable_device(pdev);
+           pci_set_drvdata(pdev, NULL);
     }
-
-    if (cards_found < 1)
-        return -1;
-
-    return foundaddr;
 }
 
 /* After this is called, packets can be sent.
@@ -1181,8 +1104,6 @@ static int lmc_open (struct net_device *dev) /*fold00*/
     
     sc->stats.tx_tbusy0++ ;
 
-    MOD_INC_USE_COUNT;
-
     /*
      * select what interrupts we want to get
      */
@@ -1352,7 +1273,6 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
 
     lmc_trace(dev, "lmc_ifdown out");
 
-    MOD_DEC_USE_COUNT;
     return 0;
 }
 
@@ -1850,12 +1770,11 @@ skip_out_of_mem:
 
 static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/
 {
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev->priv;
     unsigned long flags;
 
     lmc_trace(dev, "lmc_get_stats in");
 
-    sc = dev->priv;
 
     spin_lock_irqsave(&sc->lmc_lock, flags);
 
@@ -1868,58 +1787,21 @@ static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*
     return (struct net_device_stats *) &sc->stats;
 }
 
+static struct pci_driver lmc_driver = {
+       .name           = "lmc",
+       .id_table       = lmc_pci_tbl,
+       .probe          = lmc_init_one,
+       .remove         = __devexit_p(lmc_remove_one),
+};
+
 static int __init init_lmc(void)
 {
-    printk ("lmc: module loaded\n");
-
-    /* Have lmc_probe search for all the cards, and allocate devices */
-    if (lmc_probe (NULL) < 0)
-        return -EIO;
-
-    return 0;
+    return pci_module_init(&lmc_driver);
 }
 
 static void __exit exit_lmc(void)
 {
-    struct net_device *dev, *next;
-    lmc_softc_t *sc;
-
-    /* we have no pointer to our devices, since they are all dynamically
-     * allocated.  So, here we loop through all the network devices
-     * looking for ours.  When found, dispose of them properly.
-     */
-
-    for (dev = Lmc_root_dev;
-         dev != NULL;
-         dev = next )
-    {
-
-        next = ((lmc_softc_t *) dev->priv)->next_module; /* get it now before we deallocate it */
-        printk ("%s: removing...\n", dev->name);
-
-        /* close the syncppp stuff, and release irq. Close is run on unreg net */
-        lmc_close (dev);
-       sc = dev->priv;
-        if (sc != NULL)
-            lmc_proto_detach(sc);
-
-        /* Remove the device from the linked list */
-        unregister_netdev (dev);
-
-        /* Let go of the io region */;
-        release_region (dev->base_addr, LMC_REG_RANGE);
-
-        /* free our allocated structures. */
-        kfree (dev->priv);
-        dev->priv = NULL;
-
-        free_netdev (dev);
-        dev = NULL;
-    }
-
-
-    Lmc_root_dev = NULL;
-    printk ("lmc module unloaded\n");
+    pci_unregister_driver(&lmc_driver);
 }
 
 module_init(init_lmc);
@@ -2326,8 +2208,3 @@ bug_out:
 
 
 }
-
-int lmc_setup(void) { /*FOLD00*/
-   return lmc_probe(NULL);
-}
-
index be89c5d..6d003a3 100644 (file)
@@ -390,7 +390,7 @@ struct lmc___softc {
        struct timer_list       timer;
        lmc_ctl_t               ictl;
        u_int32_t               TxDescriptControlInit;  
-       struct net_device               *next_module;   /* Link to the next module  */
+
        int                     tx_TimeoutInd; /* additional driver state */
        int                     tx_TimeoutDisplay;
        unsigned int            lastlmc_taint_tx;
@@ -519,18 +519,7 @@ struct lmc___softc {
 #define TULIP_CMD_RECEIVEALL 0x40000000L
 #endif
 
-
-/* PCI register values */
-#define CORRECT_VENDOR_ID    0x1011
-#define CORRECT_DEV_ID       9
-
-#define PCI_VENDOR_LMC         0x1376
-#define PCI_PRODUCT_LMC_HSSI   0x0003
-#define PCI_PRODUCT_LMC_DS3    0x0004
-#define PCI_PRODUCT_LMC_SSI    0x0005
-#define PCI_PRODUCT_LMC_T1      0x0006
-
-/* Adapcter module number */
+/* Adapter module number */
 #define LMC_ADAP_HSSI           2
 #define LMC_ADAP_DS3            3
 #define LMC_ADAP_SSI            4
index 3825f88..7a94818 100644 (file)
@@ -94,7 +94,7 @@ static struct x25_asy *x25_asy_alloc(void)
                        return sl;
                } else {
                        printk("x25_asy_alloc() - register_netdev() failure.\n");
-                       kfree(dev);
+                       free_netdev(dev);
                }
        }
        return NULL;
index 278108b..cdd1eae 100644 (file)
@@ -47,7 +47,6 @@ static const char version[] =
 static unsigned int wd_portlist[] __initdata =
 {0x300, 0x280, 0x380, 0x240, 0};
 
-int wd_probe(struct net_device *dev);
 static int wd_probe1(struct net_device *dev, int ioaddr);
 
 static int wd_open(struct net_device *dev);
@@ -83,11 +82,14 @@ static int wd_close(struct net_device *dev);
        The wd_probe1() routine initializes the card and fills the
        station address field. */
 
-int __init wd_probe(struct net_device *dev)
+static int __init do_wd_probe(struct net_device *dev)
 {
        int i;
        struct resource *r;
        int base_addr = dev->base_addr;
+       int irq = dev->irq;
+       int mem_start = dev->mem_start;
+       int mem_end = dev->mem_end;
 
        SET_MODULE_OWNER(dev);
 
@@ -115,11 +117,45 @@ int __init wd_probe(struct net_device *dev)
                        return 0;
                }
                release_region(ioaddr, WD_IO_EXTENT);
+               dev->irq = irq;
+               dev->mem_start = mem_start;
+               dev->mem_end = mem_end;
        }
 
        return -ENODEV;
 }
 
+static void cleanup_card(struct net_device *dev)
+{
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
+}
+
+struct net_device * __init wd_probe(int unit)
+{
+       struct net_device *dev = alloc_ei_netdev();
+       int err;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       err = do_wd_probe(dev);
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       cleanup_card(dev);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
 static int __init wd_probe1(struct net_device *dev, int ioaddr)
 {
        int i;
@@ -262,19 +298,11 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
        } else if (dev->irq == 2)               /* Fixup bogosity: IRQ2 is really IRQ9 */
                dev->irq = 9;
 
-       /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) {
-               printk (" unable to get memory for dev->priv.\n");
-               return -ENOMEM;
-       }
-
        /* Snarf the interrupt now.  There's no point in waiting since we cannot
           share and the board will usually be enabled. */
        i = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
        if (i) {
                printk (" unable to get IRQ %d.\n", dev->irq);
-               kfree(dev->priv);
-               dev->priv = NULL;
                return i;
        }
 
@@ -446,7 +474,7 @@ wd_close(struct net_device *dev)
 \f
 #ifdef MODULE
 #define MAX_WD_CARDS   4       /* Max number of wd cards per module */
-static struct net_device dev_wd[MAX_WD_CARDS];
+static struct net_device *dev_wd[MAX_WD_CARDS];
 static int io[MAX_WD_CARDS];
 static int irq[MAX_WD_CARDS];
 static int mem[MAX_WD_CARDS];
@@ -468,29 +496,35 @@ ISA device autoprobes on a running machine are not recommended. */
 int
 init_module(void)
 {
+       struct net_device *dev;
        int this_dev, found = 0;
 
        for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
-               struct net_device *dev = &dev_wd[this_dev];
-               dev->irq = irq[this_dev];
-               dev->base_addr = io[this_dev];
-               dev->mem_start = mem[this_dev];
-               dev->mem_end = mem_end[this_dev];
-               dev->init = wd_probe;
                if (io[this_dev] == 0)  {
                        if (this_dev != 0) break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               if (register_netdev(dev) != 0) {
-                       printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) {       /* Got at least one. */
-                               return 0;
+               dev = alloc_ei_netdev();
+               if (!dev)
+                       break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               dev->mem_start = mem[this_dev];
+               dev->mem_end = mem_end[this_dev];
+               if (do_wd_probe(dev) == 0) {
+                       if (register_netdev(dev) == 0) {
+                               dev_wd[found++] = dev;
+                               continue;
                        }
-                       return -ENXIO;
+                       cleanup_card(dev);
                }
-               found++;
+               free_netdev(dev);
+               printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
+               break;
        }
-       return 0;
+       if (found)
+               return 0;
+       return -ENXIO;
 }
 
 void
@@ -499,14 +533,11 @@ cleanup_module(void)
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
-               struct net_device *dev = &dev_wd[this_dev];
-               if (dev->priv != NULL) {
-                       void *priv = dev->priv;
-                       int ioaddr = dev->base_addr - WD_NIC_OFFSET;
-                       free_irq(dev->irq, dev);
-                       release_region(ioaddr, WD_IO_EXTENT);
+               struct net_device *dev = dev_wd[this_dev];
+               if (dev) {
                        unregister_netdev(dev);
-                       kfree(priv);
+                       cleanup_card(dev);
+                       free_netdev(dev);
                }
        }
 }
index 8e105d0..46a11cc 100644 (file)
@@ -221,6 +221,29 @@ config PCI_HERMES
          common.  Some of the built-in wireless adaptors in laptops are of
          this variety.
 
+config ATMEL
+      tristate "Atmel at76c50x chipset  802.11b support"
+      depends on NET_RADIO && EXPERIMENTAL
+      enable FW_LOADER
+      enable CRC32
+       ---help---
+        A driver 802.11b wireless cards based on the Atmel fast-vnet
+        chips. This driver supports standard Linux wireless extensions. 
+        Many  cards based on this chipset do not have flash memory
+        and need their firmware loaded at start-up. If yours is 
+        one of these, you will need to provide a firmware image
+        to be loaded into the card by the driver. The Atmel
+        firmware package can be downloaded from
+        http://www.thekelleys.org.uk/atmel
+
+config PCI_ATMEL
+      tristate "Atmel at76c506 PCI cards"
+      depends on ATMEL && PCI
+       ---help---
+        Enable support for PCI and mini-PCI cards containing the
+        Atmel at76c506 chip.
+
 # If Pcmcia is compiled in, offer Pcmcia cards...
 comment "Wireless 802.11b Pcmcia/Cardbus cards support"
        depends on NET_RADIO && PCMCIA
@@ -268,21 +291,13 @@ config AIRO_CS
          available from <http://www.tldp.org/docs.html#howto>.
 
 config PCMCIA_ATMEL
-      tristate "Atmel at76c502/at76c504 PCMCIA cards"
-      depends on NET_RADIO && EXPERIMENTAL && PCMCIA
-      select FW_LOADER
-      select CRC32
-       ---help---
-         A driver for PCMCIA 802.11 wireless cards based on the 
-         Atmel fast-vnet chips. This driver supports standard
-         Linux wireless extensions. 
-         Many  cards based on this chipset do not have flash memory
-         and need their firmware loaded at start-up. If yours is 
-         one of these, you will need to provide a firmware image
-        to be loaded into the card by the driver. The Atmel
-        firmware package can be downloaded from
-        http://www.thekelleys.org.uk/atmel
+       tristate "Atmel at76c502/at76c504 PCMCIA cards"
+       depends on NET_RADIO && ATMEL && PCMCIA
+       select FW_LOADER
+       select CRC32
+       ---help---
+         Enable support for PCMCIA cards containing the
+         Atmel at76c502 and at76c504 chips.
 
 config PCMCIA_WL3501
       tristate "Planet WL3501 PCMCIA cards"
index 0d3c123..4706ee9 100644 (file)
@@ -22,7 +22,10 @@ obj-$(CONFIG_TMD_HERMES)     += orinoco_tmd.o
 obj-$(CONFIG_AIRO)             += airo.o
 obj-$(CONFIG_AIRO_CS)          += airo_cs.o airo.o
 
+obj-$(CONFIG_ATMEL)             += atmel.o
+obj-$(CONFIG_PCI_ATMEL)         += atmel_pci.o 
+obj-$(CONFIG_PCMCIA_ATMEL)      += atmel_cs.o
+
 # 16-bit wireless PCMCIA client drivers
 obj-$(CONFIG_PCMCIA_RAYCS)     += ray_cs.o
-obj-$(CONFIG_PCMCIA_ATMEL)      += atmel_cs.o atmel.o 
 obj-$(CONFIG_PCMCIA_WL3501)    += wl3501_cs.o
index e3e7265..fd533d3 100644 (file)
@@ -14,6 +14,8 @@
     Aironet.  Major code contributions were received from Javier Achirica
     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
     Code was also integrated from the Cisco Aironet driver for Linux.
+    Support for MPI350 cards was added by Fabrice Bellet
+    <fabrice@bellet.info>.
 
 ======================================================================*/
 
@@ -51,27 +53,31 @@ static struct pci_device_id card_ids[] = {
        { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
        { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
        { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
+       { 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
+       { 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, card_ids);
 
 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
 static void airo_pci_remove(struct pci_dev *);
+static int airo_pci_suspend(struct pci_dev *pdev, u32 state);
+static int airo_pci_resume(struct pci_dev *pdev);
 
 static struct pci_driver airo_driver = {
        .name     = "airo",
        .id_table = card_ids,
        .probe    = airo_pci_probe,
        .remove   = __devexit_p(airo_pci_remove),
+       .suspend  = airo_pci_suspend,
+       .resume   = airo_pci_resume,
 };
 #endif /* CONFIG_PCI */
 
 /* Include Wireless Extension definition and check version - Jean II */
 #include <linux/wireless.h>
 #define WIRELESS_SPY           // enable iwspy support
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>    // New driver API
-#endif /* WIRELESS_EXT > 12 */
 
 #define CISCO_EXT              // enable Cisco extensions
 #ifdef CISCO_EXT
@@ -235,10 +241,10 @@ static int proc_perm = 0644;
 
 MODULE_AUTHOR("Benjamin Reed");
 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
-                   cards.  Direct support for ISA/PCI cards and support \
+                   cards.  Direct support for ISA/PCI/MPI cards and support \
                   for PCMCIA when used with airo_cs.");
 MODULE_LICENSE("Dual BSD/GPL");
-MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340");
+MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
 MODULE_PARM(io,"1-4i");
 MODULE_PARM(irq,"1-4i");
 MODULE_PARM(basic_rate,"i");
@@ -380,6 +386,16 @@ static int do8bitIO = 0;
 #define AUXOFF 0x3C
 #define AUXDATA 0x3E
 
+#define FID_TX 1
+#define FID_RX 2
+/* Offset into aux memory for descriptors */
+#define AUX_OFFSET 0x800
+/* Size of allocated packets */
+#define PKTSIZE 1840
+#define RIDSIZE 2048
+/* Size of the transmit queue */
+#define MAXTXQ 64
+
 /* BAP selectors */
 #define BAP0 0 // Used for receiving packets
 #define BAP1 2 // Used for xmiting packets and working with RIDS
@@ -405,7 +421,8 @@ static int do8bitIO = 0;
 #define EV_TXCPY 0x400
 #define EV_UNKNOWN 0x800
 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
-#define STATUS_INTS ( EV_AWAKE | EV_LINK | EV_TXEXC | EV_TX | EV_RX | EV_MIC )
+#define EV_AWAKEN 0x2000
+#define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
 
 #ifdef CHECK_UNKNOWN_INTS
 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
@@ -413,6 +430,9 @@ static int do8bitIO = 0;
 #define IGNORE_INTS (~STATUS_INTS)
 #endif
 
+/* RID TYPES */
+#define RID_RW 0x20
+
 /* The RIDs */
 #define RID_CAPABILITIES 0xFF00
 #define RID_APINFO     0xFF01
@@ -615,7 +635,7 @@ typedef struct {
        /*---------- Aironet Extensions ----------*/
        u8 magicAction;
 #define MAGIC_ACTION_STSCHG 1
-#define MACIC_ACTION_RESUME 2
+#define MAGIC_ACTION_RESUME 2
 #define MAGIC_IGNORE_MCAST (1<<8)
 #define MAGIC_IGNORE_BCAST (1<<9)
 #define MAGIC_SWITCH_TO_PSP (0<<10)
@@ -869,6 +889,7 @@ typedef struct {
 #define AIRORESTART            AIROFLPUTBUF   + 1
 
 #define FLASHSIZE      32768
+#define AUXMEMSIZE     (256 * 1024)
 
 typedef struct aironet_ioctl {
        unsigned short command; // What to do
@@ -916,6 +937,110 @@ typedef struct {
        miccntx uCtx;           // Unicast context
 } mic_module;
 
+typedef struct {
+       unsigned int  rid: 16;
+       unsigned int  len: 15;
+       unsigned int  valid: 1;
+       dma_addr_t host_addr;
+} Rid;
+
+typedef struct {
+       unsigned int  offset: 15;
+       unsigned int  eoc: 1;
+       unsigned int  len: 15;
+       unsigned int  valid: 1;
+       dma_addr_t host_addr;
+} TxFid;
+
+typedef struct {
+       unsigned int  ctl: 15;
+       unsigned int  rdy: 1;
+       unsigned int  len: 15;
+       unsigned int  valid: 1;
+       dma_addr_t host_addr;
+} RxFid;
+
+/*
+ * Host receive descriptor
+ */
+typedef struct {
+       unsigned char *card_ram_off;         /* offset into card memory of the
+                                               desc */
+       RxFid         rx_desc;               /* card receive descriptor */
+       char          *virtual_host_addr;    /* virtual address of host receive
+                                               buffer */
+       int           pending;
+} HostRxDesc;
+
+/*
+ * Host transmit descriptor
+ */
+typedef struct {
+       unsigned char *card_ram_off;         /* offset into card memory of the
+                                               desc */
+       TxFid         tx_desc;               /* card transmit descriptor */
+       char          *virtual_host_addr;    /* virtual address of host receive
+                                               buffer */
+       int           pending;
+} HostTxDesc;
+
+/*
+ * Host RID descriptor
+ */
+typedef struct {
+       unsigned char *card_ram_off;      /* offset into card memory of the
+                                            descriptor */
+       Rid           rid_desc;           /* card RID descriptor */
+       char          *virtual_host_addr; /* virtual address of host receive
+                                            buffer */
+} HostRidDesc;
+
+typedef struct {
+       u16 sw0;
+       u16 sw1;
+       u16 status;
+       u16 len;
+#define HOST_SET (1 << 0)
+#define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */
+#define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */
+#define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */
+#define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */
+#define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */
+#define HOST_CLR_AID (1 << 7) /* clear AID failure */
+#define HOST_RTS (1 << 9) /* Force RTS use */
+#define HOST_SHORT (1 << 10) /* Do short preamble */
+       u16 ctl;
+       u16 aid;
+       u16 retries;
+       u16 fill;
+} TxCtlHdr;
+
+typedef struct {
+        u16 ctl;
+        u16 duration;
+        char addr1[6];
+        char addr2[6];
+        char addr3[6];
+        u16 seq;
+        char addr4[6];
+} WifiHdr;
+
+
+typedef struct {
+       TxCtlHdr ctlhdr;
+       u16 fill1;
+       u16 fill2;
+       WifiHdr wifihdr;
+       u16 gaplen;
+       u16 status;
+} WifiCtlHdr;
+
+WifiCtlHdr wifictlhdr8023 = {
+ctlhdr: {
+        ctl: HOST_DONT_RLSE,
+       }
+};
+
 #ifdef WIRELESS_EXT
 // Frequency list (map channels to frequencies)
 static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
@@ -935,14 +1060,8 @@ typedef struct wep_key_t {
 #define IW_ENCODE_MODE  (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
 #endif /* IW_ENCODE_NOKEY */
 
-#if WIRELESS_EXT > 12
 /* List of Wireless Handlers (new API) */
 static const struct iw_handler_def     airo_handler_def;
-#else  /* WIRELESS_EXT > 12 */
-/* More Wireless Extensions backward compatibility */
-/* Part of iw_handler prototype we need (apart that we don't need it) */
-struct iw_request_info {};
-#endif /* WIRELESS_EXT > 12 */
 #endif /* WIRELESS_EXT */
 
 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
@@ -975,6 +1094,11 @@ static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
 static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
 static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
 
+static int mpi_send_packet (struct net_device *dev);
+static void mpi_unmap_card(struct pci_dev *pci);
+static void mpi_receive_802_3(struct airo_info *ai);
+static int waitbusy (struct airo_info *ai);
+
 static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
                            *regs);
 static int airo_thread(void *data);
@@ -1000,26 +1124,23 @@ static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket,
 
 struct airo_info {
        struct net_device_stats stats;
-       int open;
        struct net_device             *dev;
        /* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
           use the high bit to mark whether it is in use. */
 #define MAX_FIDS 6
+#define MPI_MAX_FIDS 1
        int                           fids[MAX_FIDS];
-       int registered;
        ConfigRid config;
-       int need_commit;        // Need to set config
        char keyindex; // Used with auto wep
        char defindex; // Used with auto wep
        struct proc_dir_entry *proc_entry;
-       struct airo_info *next;
         spinlock_t aux_lock;
         unsigned long flags;
 #define FLAG_PROMISC   8       /* IFF_PROMISC 0x100 - include/linux/if.h */
 #define FLAG_RADIO_OFF 0       /* User disabling of MAC */
 #define FLAG_RADIO_DOWN        1       /* ifup/ifdown disabling of MAC */
 #define FLAG_RADIO_MASK 0x03
-#define FLAG_FLASHING  2
+#define FLAG_ENABLED   2
 #define FLAG_ADHOC     3       /* Needed by MIC */
 #define FLAG_MIC_CAPABLE 4
 #define FLAG_UPDATE_MULTI 5
@@ -1027,6 +1148,11 @@ struct airo_info {
 #define FLAG_802_11    7
 #define FLAG_PENDING_XMIT 9
 #define FLAG_PENDING_XMIT11 10
+#define FLAG_MPI       11
+#define FLAG_REGISTERED        12
+#define FLAG_COMMIT    13
+#define FLAG_RESET     14
+#define FLAG_FLASHING  15
 #define JOB_MASK       0x1ff0000
 #define JOB_DIE                16
 #define JOB_XMIT       17
@@ -1055,15 +1181,7 @@ struct airo_info {
 #ifdef WIRELESS_EXT
        struct iw_statistics    wstats;         // wireless stats
        unsigned long           scan_timestamp; /* Time started to scan */
-#if WIRELESS_EXT > 15
        struct iw_spy_data      spy_data;
-#else /* WIRELESS_EXT > 15 */
-#ifdef WIRELESS_SPY
-       int                     spy_number;
-       u_char                  spy_address[IW_MAX_SPY][ETH_ALEN];
-       struct iw_quality       spy_stat[IW_MAX_SPY];
-#endif /* WIRELESS_SPY */
-#endif /* WIRELESS_EXT > 15 */
 #endif /* WIRELESS_EXT */
 #ifdef MICSUPPORT
        /* MIC stuff */
@@ -1071,6 +1189,20 @@ struct airo_info {
        mic_module              mod[2];
        mic_statistics          micstats;
 #endif
+       HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
+       HostTxDesc txfids[MPI_MAX_FIDS];
+       HostRidDesc config_desc;
+       unsigned long ridbus; // phys addr of config_desc
+       struct sk_buff_head txq;// tx queue used by mpi350 code
+       struct pci_dev          *pci;
+       unsigned char           *pcimem;
+       unsigned char           *pciaux;
+       unsigned char           *shared;
+       dma_addr_t              shared_dma;
+       int                     power;
+       SsidRid                 *SSID;
+       APListRid               *APList;
+#define        PCI_SHARED_LEN          2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
 };
 
 static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
@@ -1550,6 +1682,7 @@ static int readBSSListRid(struct airo_info *ai, int first,
                        Resp rsp;
 
        if (first == 1) {
+                       if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
                        memset(&cmd, 0, sizeof(cmd));
                        cmd.cmd=CMD_LISTBSS;
                        if (down_interruptible(&ai->sem))
@@ -1647,8 +1780,11 @@ static int readConfigRid(struct airo_info*ai, int lock) {
        for(s = &cfg.txPower; s <= &cfg.radioSpecific; s++)
                *s = le16_to_cpu(*s);
 
-       for(s = &cfg.arlThreshold; s <= &cfg.autoWake; s++)
-               *s = le16_to_cpu(*s);
+       for(s = &cfg.arlThreshold; s <= &cfg._reserved4[0]; s++)
+               *s = cpu_to_le16(*s);
+
+       for(s = &cfg.autoWake; s <= &cfg.autoWake; s++)
+               *s = cpu_to_le16(*s);
 
        ai->config = cfg;
        return SUCCESS;
@@ -1668,10 +1804,10 @@ static int writeConfigRid(struct airo_info*ai, int lock) {
        u16 *s;
        ConfigRid cfgr;
 
-       if (!ai->need_commit)
+       if (!test_bit (FLAG_COMMIT, &ai->flags))
                return SUCCESS;
 
-       ai->need_commit = 0;
+       clear_bit (FLAG_COMMIT | FLAG_RESET, &ai->flags);
        checkThrottle(ai);
        cfgr = ai->config;
 
@@ -1688,7 +1824,10 @@ static int writeConfigRid(struct airo_info*ai, int lock) {
        for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
                *s = cpu_to_le16(*s);
 
-       for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)
+       for(s = &cfgr.arlThreshold; s <= &cfgr._reserved4[0]; s++)
+               *s = cpu_to_le16(*s);
+
+       for(s = &cfgr.autoWake; s <= &cfgr.autoWake; s++)
                *s = cpu_to_le16(*s);
 
        return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
@@ -1749,7 +1888,7 @@ static int airo_open(struct net_device *dev) {
         * Wireless Extensions may postpone config changes until the card
         * is open (to pipeline changes and speed-up card setup). If
         * those changes are not yet commited, do it now - Jean II */
-       if(info->need_commit) {
+       if (test_bit (FLAG_COMMIT, &info->flags)) {
                disable_MAC(info, 1);
                writeConfigRid(info, 1);
        }
@@ -1765,52 +1904,177 @@ static int airo_open(struct net_device *dev) {
        return 0;
 }
 
+static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
+       int npacks, pending;
+       unsigned long flags;
+       struct airo_info *ai = dev->priv;
+
+       if (!skb) {
+               printk(KERN_ERR "airo: %s: skb==NULL\n",__FUNCTION__);
+               return 0;
+       }
+       npacks = skb_queue_len (&ai->txq);
+
+       if (npacks >= MAXTXQ - 1) {
+               netif_stop_queue (dev);
+               if (npacks > MAXTXQ) {
+                       ai->stats.tx_fifo_errors++;
+                       return 1;
+               }
+               skb_queue_tail (&ai->txq, skb);
+               return 0;
+       }
+
+       spin_lock_irqsave(&ai->aux_lock, flags);
+       skb_queue_tail (&ai->txq, skb);
+       pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
+       spin_unlock_irqrestore(&ai->aux_lock,flags);
+       netif_wake_queue (dev);
+
+       if (pending == 0) {
+               set_bit(FLAG_PENDING_XMIT, &ai->flags);
+               mpi_send_packet (dev);
+       }
+       return 0;
+}
+
+/*
+ * @mpi_send_packet
+ *
+ * Attempt to transmit a packet. Can be called from interrupt
+ * or transmit . return number of packets we tried to send
+ */
+
+static int mpi_send_packet (struct net_device *dev)
+{
+       struct sk_buff *skb;
+       unsigned char *buffer;
+       s16 len, *payloadLen;
+       struct airo_info *ai = dev->priv;
+       u8 *sendbuf;
+
+       /* get a packet to send */
+
+       if ((skb = skb_dequeue(&ai->txq)) == 0) {
+               printk (KERN_ERR
+                       "airo_mpi: %s: Dequeue'd zero in send_packet()\n",
+                       __FUNCTION__);
+               return 0;
+       }
+
+       /* check min length*/
+       len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+       buffer = skb->data;
+
+       ai->txfids[0].tx_desc.offset = 0;
+       ai->txfids[0].tx_desc.valid = 1;
+       ai->txfids[0].tx_desc.eoc = 1;
+       ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
+
+       memcpy((char *)ai->txfids[0].card_ram_off,
+               (char *)&ai->txfids[0].tx_desc, sizeof(TxFid));
+
+/*
+ * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
+ * right after  TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
+ * is immediatly after it. ------------------------------------------------
+ *                         |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
+ *                         ------------------------------------------------
+ */
+
+       memcpy((char *)ai->txfids[0].virtual_host_addr,
+               (char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
+
+       payloadLen = (s16 *)(ai->txfids[0].virtual_host_addr +
+               sizeof(wifictlhdr8023));
+       sendbuf = ai->txfids[0].virtual_host_addr +
+               sizeof(wifictlhdr8023) + 2 ;
+
+       /*
+        * Firmware automaticly puts 802 header on so
+        * we don't need to account for it in the length
+        */
+#ifdef MICSUPPORT
+       if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
+               (ntohs(((u16 *)buffer)[6]) != 0x888E)) {
+               MICBuffer pMic;
+
+               if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
+                       return ERROR;
+
+               *payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
+               /* copy data into airo dma buffer */
+               memcpy (sendbuf, buffer, sizeof(etherHead));
+               buffer += sizeof(etherHead);
+               sendbuf += sizeof(etherHead);
+               memcpy (sendbuf, &pMic, sizeof(pMic));
+               sendbuf += sizeof(pMic);
+               memcpy (sendbuf, buffer, len - sizeof(etherHead));
+       } else
+#endif
+       {
+               *payloadLen = cpu_to_le16(len - sizeof(etherHead));
+
+               dev->trans_start = jiffies;
+
+               /* copy data into airo dma buffer */
+               memcpy(sendbuf, buffer, len);
+       }
+
+       OUT4500(ai, EVACK, 8);
+
+       dev_kfree_skb_any(skb);
+       return 1;
+}
+
 static void get_tx_error(struct airo_info *ai, u32 fid)
 {
        u16 status;
 
-       if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) == SUCCESS) {
+       if (fid < 0)
+               status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
+       else {
+               if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
+                       return;
                bap_read(ai, &status, 2, BAP0);
-               if (le16_to_cpu(status) & 2) /* Too many retries */
-                       ai->stats.tx_aborted_errors++;
-               if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
-                       ai->stats.tx_heartbeat_errors++;
-               if (le16_to_cpu(status) & 8) /* Aid fail */
-                       { }
-               if (le16_to_cpu(status) & 0x10) /* MAC disabled */
-                       ai->stats.tx_carrier_errors++;
-               if (le16_to_cpu(status) & 0x20) /* Association lost */
-                       { }
-#if WIRELESS_EXT > 13
-               /* We produce a TXDROP event only for retry or lifetime
-                * exceeded, because that's the only status that really mean
-                * that this particular node went away.
-                * Other errors means that *we* screwed up. - Jean II */
-               if ((le16_to_cpu(status) & 2) ||
-                    (le16_to_cpu(status) & 4)) {
-                       union iwreq_data        wrqu;
-                       char junk[0x18];
-
-                       /* Faster to skip over useless data than to do
-                        * another bap_setup(). We are at offset 0x6 and
-                        * need to go to 0x18 and read 6 bytes - Jean II */
-                       bap_read(ai, (u16 *) junk, 0x18, BAP0);
-
-                       /* Copy 802.11 dest address.
-                        * We use the 802.11 header because the frame may
-                        * not be 802.3 or may be mangled...
-                        * In Ad-Hoc mode, it will be the node address.
-                        * In managed mode, it will be most likely the AP addr
-                        * User space will figure out how to convert it to
-                        * whatever it needs (IP address or else).
-                        * - Jean II */
-                       memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
-                       wrqu.addr.sa_family = ARPHRD_ETHER;
-
-                       /* Send event to user space */
-                       wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
-               }
-#endif /* WIRELESS_EXT > 13 */
+       }
+       if (le16_to_cpu(status) & 2) /* Too many retries */
+               ai->stats.tx_aborted_errors++;
+       if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
+               ai->stats.tx_heartbeat_errors++;
+       if (le16_to_cpu(status) & 8) /* Aid fail */
+               { }
+       if (le16_to_cpu(status) & 0x10) /* MAC disabled */
+               ai->stats.tx_carrier_errors++;
+       if (le16_to_cpu(status) & 0x20) /* Association lost */
+               { }
+       /* We produce a TXDROP event only for retry or lifetime
+        * exceeded, because that's the only status that really mean
+        * that this particular node went away.
+        * Other errors means that *we* screwed up. - Jean II */
+       if ((le16_to_cpu(status) & 2) ||
+            (le16_to_cpu(status) & 4)) {
+               union iwreq_data        wrqu;
+               char junk[0x18];
+
+               /* Faster to skip over useless data than to do
+                * another bap_setup(). We are at offset 0x6 and
+                * need to go to 0x18 and read 6 bytes - Jean II */
+               bap_read(ai, (u16 *) junk, 0x18, BAP0);
+
+               /* Copy 802.11 dest address.
+                * We use the 802.11 header because the frame may
+                * not be 802.3 or may be mangled...
+                * In Ad-Hoc mode, it will be the node address.
+                * In managed mode, it will be most likely the AP addr
+                * User space will figure out how to convert it to
+                * whatever it needs (IP address or else).
+                * - Jean II */
+               memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
+               wrqu.addr.sa_family = ARPHRD_ETHER;
+
+               /* Send event to user space */
+               wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
        }
 }
 
@@ -2019,7 +2283,7 @@ static int airo_set_mac_address(struct net_device *dev, void *p)
 
        readConfigRid(ai, 1);
        memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
-       ai->need_commit = 1;
+       set_bit (FLAG_COMMIT, &ai->flags);
        disable_MAC(ai, 1);
        writeConfigRid (ai, 1);
        enable_MAC(ai, &rsp, 1);
@@ -2066,25 +2330,49 @@ void stop_airo_card( struct net_device *dev, int freeres )
        disable_interrupts(ai);
        free_irq( dev->irq, dev );
        takedown_proc_entry( dev, ai );
-       if (ai->registered) {
+       if (test_bit(FLAG_REGISTERED, &ai->flags)) {
                unregister_netdev( dev );
                if (ai->wifidev) {
                        unregister_netdev(ai->wifidev);
                        free_netdev(ai->wifidev);
                        ai->wifidev = 0;
                }
-               ai->registered = 0;
+               clear_bit(FLAG_REGISTERED, &ai->flags);
        }
        set_bit(JOB_DIE, &ai->flags);
        kill_proc(ai->thr_pid, SIGTERM, 1);
        wait_for_completion(&ai->thr_exited);
+
+       /*
+        * Clean out tx queue
+        */
+       if (test_bit(FLAG_MPI, &ai->flags) && skb_queue_len (&ai->txq) > 0) {
+               struct sk_buff *skb = 0;
+               for (;(skb = skb_dequeue(&ai->txq));)
+                       dev_kfree_skb(skb);
+       }
+
        if (ai->flash)
                kfree(ai->flash);
        if (ai->rssi)
                kfree(ai->rssi);
+       if (ai->APList)
+               kfree(ai->APList);
+       if (ai->SSID)
+               kfree(ai->SSID);
        if (freeres) {
                /* PCMCIA frees this stuff, so only for PCI and ISA */
                release_region( dev->base_addr, 64 );
+               if (test_bit(FLAG_MPI, &ai->flags)) {
+                       if (ai->pci)
+                               mpi_unmap_card(ai->pci);
+                       if (ai->pcimem)
+                               iounmap(ai->pcimem);
+                       if (ai->pciaux)
+                               iounmap(ai->pciaux);
+                       pci_free_consistent(ai->pci, PCI_SHARED_LEN,
+                               ai->shared, ai->shared_dma);
+               }
         }
 #ifdef MICSUPPORT
        if (ai->tfm)
@@ -2104,6 +2392,213 @@ int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
        return ETH_ALEN;
 }
 
+static void mpi_unmap_card(struct pci_dev *pci)
+{
+       unsigned long mem_start = pci_resource_start(pci, 1);
+       unsigned long mem_len = pci_resource_len(pci, 1);
+       unsigned long aux_start = pci_resource_start(pci, 2);
+       unsigned long aux_len = AUXMEMSIZE;
+
+       release_mem_region(aux_start, aux_len);
+       release_mem_region(mem_start, mem_len);
+}
+
+/*************************************************************
+ *  This routine assumes that descriptors have been setup .
+ *  Run at insmod time or after reset  when the decriptors
+ *  have been initialized . Returns 0 if all is well nz
+ *  otherwise . Does not allocate memory but sets up card
+ *  using previously allocated descriptors.
+ */
+static int mpi_init_descriptors (struct airo_info *ai)
+{
+       Cmd cmd;
+       Resp rsp;
+       int i;
+       int rc = SUCCESS;
+
+       /* Alloc  card RX descriptors */
+       netif_stop_queue(ai->dev);
+
+       memset(&rsp,0,sizeof(rsp));
+       memset(&cmd,0,sizeof(cmd));
+
+       cmd.cmd = CMD_ALLOCATEAUX;
+       cmd.parm0 = FID_RX;
+       cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
+       cmd.parm2 = MPI_MAX_FIDS;
+       rc=issuecommand(ai, &cmd, &rsp);
+       if (rc != SUCCESS) {
+               printk(KERN_ERR "airo:  Couldn't allocate RX FID\n");
+               return rc;
+       }
+
+       for (i=0; i<MPI_MAX_FIDS; i++) {
+               memcpy(ai->rxfids[i].card_ram_off,
+                       &ai->rxfids[i].rx_desc, sizeof(RxFid));
+       }
+
+       /* Alloc card TX descriptors */
+
+       memset(&rsp,0,sizeof(rsp));
+       memset(&cmd,0,sizeof(cmd));
+
+       cmd.cmd = CMD_ALLOCATEAUX;
+       cmd.parm0 = FID_TX;
+       cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
+       cmd.parm2 = MPI_MAX_FIDS;
+       rc=issuecommand(ai, &cmd, &rsp);
+       if (rc != SUCCESS) {
+               printk(KERN_ERR "airo:  Couldn't allocate TX FID\n");
+               return rc;
+       }
+
+       for (i=0; i<MPI_MAX_FIDS; i++) {
+               ai->txfids[i].tx_desc.valid = 1;
+               memcpy((char *)ai->txfids[i].card_ram_off,
+                       &ai->txfids[i].tx_desc, sizeof(TxFid));
+       }
+
+       /* Alloc card Rid descriptor */
+       memset(&rsp,0,sizeof(rsp));
+       memset(&cmd,0,sizeof(cmd));
+
+       cmd.cmd = CMD_ALLOCATEAUX;
+       cmd.parm0 = RID_RW;
+       cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
+       cmd.parm2 = 1; /* Magic number... */
+       rc=issuecommand(ai, &cmd, &rsp);
+       if (rc != SUCCESS) {
+               printk(KERN_ERR "airo:  Couldn't allocate RID\n");
+               return rc;
+       }
+
+       memcpy((char *)ai->config_desc.card_ram_off,
+               (char *)&ai->config_desc.rid_desc, sizeof(Rid));
+
+       return rc;
+}
+
+/*
+ * We are setting up three things here:
+ * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
+ * 2) Map PCI memory for issueing commands.
+ * 3) Allocate memory (shared) to send and receive ethernet frames.
+ */
+static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
+                   const char *name)
+{
+       unsigned long mem_start, mem_len, aux_start, aux_len;
+       int rc = -1;
+       int i;
+       unsigned char *busaddroff,*vpackoff;
+       unsigned char *pciaddroff;
+
+       mem_start = pci_resource_start(pci, 1);
+       mem_len = pci_resource_len(pci, 1);
+       aux_start = pci_resource_start(pci, 2);
+       aux_len = AUXMEMSIZE;
+
+       if (!request_mem_region(mem_start, mem_len, name)) {
+               printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
+                      (int)mem_start, (int)mem_len, name);
+               goto out;
+       }
+       if (!request_mem_region(aux_start, aux_len, name)) {
+               printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
+                      (int)aux_start, (int)aux_len, name);
+               goto free_region1;
+       }
+
+       ai->pcimem = ioremap(mem_start, mem_len);
+       if (!ai->pcimem) {
+               printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
+                      (int)mem_start, (int)mem_len, name);
+               goto free_region2;
+       }
+       ai->pciaux = ioremap(aux_start, aux_len);
+       if (!ai->pciaux) {
+               printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
+                      (int)aux_start, (int)aux_len, name);
+               goto free_memmap;
+       }
+
+       /* Reserve PKTSIZE for each fid and 2K for the Rids */
+       ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
+       if (!ai->shared) {
+               printk(KERN_ERR "airo: Couldn't alloc_consistent %d\n",
+                      PCI_SHARED_LEN);
+               goto free_auxmap;
+       }
+
+       /*
+        * Setup descriptor RX, TX, CONFIG
+        */
+       busaddroff = (unsigned char *)ai->shared_dma;
+       pciaddroff = ai->pciaux + AUX_OFFSET;
+       vpackoff   = ai->shared;
+
+       /* RX descriptor setup */
+       for(i = 0; i < MPI_MAX_FIDS; i++) {
+               ai->rxfids[i].pending = 0;
+               ai->rxfids[i].card_ram_off = pciaddroff;
+               ai->rxfids[i].virtual_host_addr = vpackoff;
+               ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
+               ai->rxfids[i].rx_desc.valid = 1;
+               ai->rxfids[i].rx_desc.len = PKTSIZE;
+               ai->rxfids[i].rx_desc.rdy = 0;
+
+               pciaddroff += sizeof(RxFid);
+               busaddroff += PKTSIZE;
+               vpackoff   += PKTSIZE;
+       }
+
+       /* TX descriptor setup */
+       for(i = 0; i < MPI_MAX_FIDS; i++) {
+               ai->txfids[i].card_ram_off = pciaddroff;
+               ai->txfids[i].virtual_host_addr = vpackoff;
+               ai->txfids[i].tx_desc.valid = 1;
+               ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
+               memcpy(ai->txfids[i].virtual_host_addr,
+                       &wifictlhdr8023, sizeof(wifictlhdr8023));
+
+               pciaddroff += sizeof(TxFid);
+               busaddroff += PKTSIZE;
+               vpackoff   += PKTSIZE;
+       }
+       ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
+
+       /* Rid descriptor setup */
+       ai->config_desc.card_ram_off = pciaddroff;
+       ai->config_desc.virtual_host_addr = vpackoff;
+       ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
+       ai->ridbus = (dma_addr_t)busaddroff;
+       ai->config_desc.rid_desc.rid = 0;
+       ai->config_desc.rid_desc.len = RIDSIZE;
+       ai->config_desc.rid_desc.valid = 1;
+       pciaddroff += sizeof(Rid);
+       busaddroff += RIDSIZE;
+       vpackoff   += RIDSIZE;
+
+       /* Tell card about descriptors */
+       if (mpi_init_descriptors (ai) != SUCCESS)
+               goto free_shared;
+
+       return 0;
+ free_shared:
+       pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
+ free_auxmap:
+       iounmap(ai->pciaux);
+ free_memmap:
+       iounmap(ai->pcimem);
+ free_region2:
+       release_mem_region(aux_start, aux_len);
+ free_region1:
+       release_mem_region(mem_start, mem_len);
+ out:
+       return rc;
+}
+
 static void wifi_setup(struct net_device *dev, struct net_device *ethdev)
 {
        struct airo_info *ai = ethdev->priv;
@@ -2120,9 +2615,7 @@ static void wifi_setup(struct net_device *dev, struct net_device *ethdev)
        dev->do_ioctl = &airo_ioctl;
 #ifdef WIRELESS_EXT
        dev->get_wireless_stats = airo_get_wireless_stats;
-#if WIRELESS_EXT > 12
        dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;
-#endif /* WIRELESS_EXT > 12 */
 #endif /* WIRELESS_EXT */
        dev->change_mtu = &airo_change_mtu;
        dev->open = &airo_open;
@@ -2161,7 +2654,24 @@ static struct net_device *init_wifidev(struct airo_info *ai,
        return dev;
 }
 
-struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
+int reset_mpi_card( struct net_device *dev ) {
+       struct airo_info *ai = dev->priv;
+
+       if (down_interruptible(&ai->sem))
+               return -1;
+       waitbusy (ai);
+       OUT4500(ai,COMMAND,CMD_SOFTRESET);
+       set_current_state (TASK_UNINTERRUPTIBLE);
+       schedule_timeout (HZ/5);
+       waitbusy (ai);
+       set_current_state (TASK_UNINTERRUPTIBLE);
+       schedule_timeout (HZ/5);
+       up(&ai->sem);
+       return 0;
+}
+
+struct net_device *_init_airo_card( unsigned short irq, int port,
+                                   int is_pcmcia, struct pci_dev *pci )
 {
        struct net_device *dev;
        struct airo_info *ai;
@@ -2180,12 +2690,16 @@ struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
 
        ai = dev->priv;
        ai->wifidev = 0;
-       ai->registered = 0;
+       ai->flags = 0;
+       if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
+               printk(KERN_DEBUG "airo: Found an MPI350 card\n");
+               set_bit(FLAG_MPI, &ai->flags);
+       }
         ai->dev = dev;
        ai->aux_lock = SPIN_LOCK_UNLOCKED;
        sema_init(&ai->sem, 1);
-       ai->need_commit = 0;
        ai->config.len = 0;
+       ai->pci = pci;
        init_waitqueue_head (&ai->thr_wait);
        init_completion (&ai->thr_exited);
        ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);
@@ -2199,16 +2713,18 @@ struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
                goto err_out_thr;
 
        /* The Airo-specific entries in the device structure. */
-       dev->hard_start_xmit = &airo_start_xmit;
+       if (test_bit(FLAG_MPI,&ai->flags)) {
+               skb_queue_head_init (&ai->txq);
+               dev->hard_start_xmit = &mpi_start_xmit;
+       } else
+               dev->hard_start_xmit = &airo_start_xmit;
        dev->get_stats = &airo_get_stats;
        dev->set_multicast_list = &airo_set_multicast_list;
        dev->set_mac_address = &airo_set_mac_address;
        dev->do_ioctl = &airo_ioctl;
 #ifdef WIRELESS_EXT
        dev->get_wireless_stats = airo_get_wireless_stats;
-#if WIRELESS_EXT > 12
        dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;
-#endif /* WIRELESS_EXT > 12 */
 #endif /* WIRELESS_EXT */
        dev->change_mtu = &airo_change_mtu;
        dev->open = &airo_open;
@@ -2216,6 +2732,9 @@ struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
        dev->irq = irq;
        dev->base_addr = port;
 
+       if (test_bit(FLAG_MPI,&ai->flags))
+               reset_mpi_card (dev);
+
        rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
        if (rc) {
                printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
@@ -2224,34 +2743,45 @@ struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
        if (!is_pcmcia) {
                if (!request_region( dev->base_addr, 64, dev->name )) {
                        rc = -EBUSY;
+                       printk(KERN_ERR "airo: Couldn't request region\n");
                        goto err_out_irq;
                }
        }
 
+       if (test_bit(FLAG_MPI,&ai->flags)) {
+               if (mpi_map_card(ai, pci, dev->name)) {
+                       printk(KERN_ERR "airo: Could not map memory\n");
+                       goto err_out_res;
+               }
+       }
+
        if (probe) {
                if ( setup_card( ai, dev->dev_addr ) != SUCCESS ) {
                        printk( KERN_ERR "airo: MAC could not be enabled\n" );
                        rc = -EIO;
-                       goto err_out_res;
+                       goto err_out_map;
                }
-       } else {
+       } else if (!test_bit(FLAG_MPI,&ai->flags)) {
                ai->bap_read = fast_bap_read;
                set_bit(FLAG_FLASHING, &ai->flags);
        }
 
        rc = register_netdev(dev);
-       if (rc)
-               goto err_out_res;
-       ai->wifidev = init_wifidev(ai, dev);
+       if (rc) {
+               printk(KERN_ERR "airo: Couldn't register_netdev\n");
+               goto err_out_map;
+       }
+       if (!test_bit(FLAG_MPI,&ai->flags))
+               ai->wifidev = init_wifidev(ai, dev);
 
-       ai->registered = 1;
+       set_bit(FLAG_REGISTERED,&ai->flags);
        printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
                dev->name,
                dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
                dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
 
        /* Allocate the transmit buffers */
-       if (probe)
+       if (probe && !test_bit(FLAG_MPI,&ai->flags))
                for( i = 0; i < MAX_FIDS; i++ )
                        ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
 
@@ -2260,6 +2790,13 @@ struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
        SET_MODULE_OWNER(dev);
        return dev;
 
+err_out_map:
+       if (test_bit(FLAG_MPI,&ai->flags) && pci) {
+               pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
+               iounmap(ai->pciaux);
+               iounmap(ai->pcimem);
+               mpi_unmap_card(ai->pci);
+       }
 err_out_res:
        if (!is_pcmcia)
                release_region( dev->base_addr, 64 );
@@ -2276,59 +2813,50 @@ err_out_free:
        return NULL;
 }
 
+struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
+{
+       return _init_airo_card ( irq, port, is_pcmcia, 0);
+}
+
 EXPORT_SYMBOL(init_airo_card);
 
 static int waitbusy (struct airo_info *ai) {
        int delay = 0;
        while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
                udelay (10);
-               if (++delay % 20)
+               if ((++delay % 20) == 0)
                        OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
        }
        return delay < 10000;
 }
 
-int reset_airo_card( struct net_device *dev ) {
+int reset_airo_card( struct net_device *dev )
+{
        int i;
        struct airo_info *ai = dev->priv;
 
-
-       if (down_interruptible(&ai->sem))
+       if (reset_mpi_card (dev))
                return -1;
-       waitbusy (ai);
-       OUT4500(ai,COMMAND,CMD_SOFTRESET);
-       set_current_state (TASK_UNINTERRUPTIBLE);
-       schedule_timeout (HZ/5);
-       waitbusy (ai);
-       set_current_state (TASK_UNINTERRUPTIBLE);
-       schedule_timeout (HZ/5);
+
        if ( setup_card(ai, dev->dev_addr ) != SUCCESS ) {
                printk( KERN_ERR "airo: MAC could not be enabled\n" );
-               up(&ai->sem);
                return -1;
-       } else {
-               printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
-                       dev->name,
-                       dev->dev_addr[0],
-                       dev->dev_addr[1],
-                       dev->dev_addr[2],
-                       dev->dev_addr[3],
-                       dev->dev_addr[4],
-                       dev->dev_addr[5]
-                       );
-               /* Allocate the transmit buffers */
-               for( i = 0; i < MAX_FIDS; i++ )
-                       ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
        }
+       printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", dev->name,
+                       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+                       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+       /* Allocate the transmit buffers if needed */
+       if (!test_bit(FLAG_MPI,&ai->flags))
+               for( i = 0; i < MAX_FIDS; i++ )
+                       ai->fids[i] = transmit_allocate (ai,2312,i>=MAX_FIDS/2);
+
        enable_interrupts( ai );
        netif_wake_queue(dev);
-       up(&ai->sem);
        return 0;
 }
 
 EXPORT_SYMBOL(reset_airo_card);
 
-#if WIRELESS_EXT > 13
 static void airo_send_event(struct net_device *dev) {
        struct airo_info *ai = dev->priv;
        union iwreq_data wrqu;
@@ -2345,7 +2873,6 @@ static void airo_send_event(struct net_device *dev) {
        /* Send event to user space */
        wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 }
-#endif
 
 static int airo_thread(void *data) {
        struct net_device *dev = data;
@@ -2405,7 +2932,7 @@ static int airo_thread(void *data) {
                        break;
                }
 
-               if (test_bit(FLAG_FLASHING, &ai->flags)) {
+               if (ai->power || test_bit(FLAG_FLASHING, &ai->flags)) {
                        up(&ai->sem);
                        continue;
                }
@@ -2424,10 +2951,8 @@ static int airo_thread(void *data) {
                else if (test_bit(JOB_MIC, &ai->flags))
                        micinit(ai);
 #endif
-#if WIRELESS_EXT > 13
                else if (test_bit(JOB_EVENT, &ai->flags))
                        airo_send_event(dev);
-#endif
                else if (test_bit(JOB_AUTOWEP, &ai->flags))
                        timer_func(dev);
        }
@@ -2471,9 +2996,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
 #endif
                }
                if ( status & EV_LINK ) {
-#if WIRELESS_EXT > 13
                        union iwreq_data        wrqu;
-#endif /* WIRELESS_EXT > 13 */
                        /* The link status has changed, if you want to put a
                           monitor hook in, do it here.  (Remember that
                           interrupts are still disabled!)
@@ -2523,7 +3046,6 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
                                set_bit(FLAG_UPDATE_UNI, &apriv->flags);
                                set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
                        }
-#if WIRELESS_EXT > 13
                        /* Question : is ASSOCIATED the only status
                         * that is valid ? We want to catch handover
                         * and reassociations as valid status
@@ -2554,7 +3076,6 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
                                /* Send event to user space */
                                wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
                        }
-#endif /* WIRELESS_EXT > 13 */
                }
 
                /* Check to see if there is something to receive */
@@ -2574,6 +3095,12 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
                        u16 tmpbuf[4];
                        u16 *buffer;
 
+                       if (test_bit(FLAG_MPI,&apriv->flags)) {
+                               mpi_receive_802_3(apriv);
+                               OUT4500(apriv, EVACK, EV_RX);
+                               goto exitrx;
+                       }
+
                        fid = IN4500( apriv, RXFID );
 
                        /* Get the packet length */
@@ -2672,7 +3199,6 @@ badrx:
                                        goto exitrx;
                                }
                        }
-#if WIRELESS_EXT > 15
 #ifdef IW_WIRELESS_SPY         /* defined in iw_handler.h */
                        if (apriv->spy_data.spy_number > 0) {
                                char *sa;
@@ -2694,33 +3220,6 @@ badrx:
                                wireless_spy_update(dev, sa, &wstats);
                        }
 #endif /* IW_WIRELESS_SPY */
-#else /* WIRELESS_EXT > 15 */
-#ifdef WIRELESS_SPY
-                       if (apriv->spy_number > 0) {
-                               int i;
-                               char *sa;
-
-                               sa = (char*)buffer + (test_bit(FLAG_802_11, &apriv->flags) ? 10 : 6);
-
-                               for (i=0; i<apriv->spy_number; i++)
-                                       if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN))
-                                       {
-                                               if (!test_bit(FLAG_802_11, &apriv->flags)) {
-                                                       bap_setup (apriv, fid, 8, BAP0);
-                                                       bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
-                                               }
-                                               apriv->spy_stat[i].qual = hdr.rssi[0];
-                                               if (apriv->rssi)
-                                                       apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
-                                               else
-                                                       apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2;
-                                               apriv->spy_stat[i].noise = 0;
-                                               apriv->spy_stat[i].updated = 3;
-                                               break;
-                                       }
-                       }
-#endif /* WIRELESS_SPY  */
-#endif /* WIRELESS_EXT > 15 */
                        OUT4500( apriv, EVACK, EV_RX);
 
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
@@ -2740,11 +3239,30 @@ badrx:
 exitrx:
 
                /* Check to see if a packet has been transmitted */
-               if (  status & ( EV_TX|EV_TXEXC ) ) {
+               if (  status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
                        int i;
                        int len = 0;
                        int index = -1;
 
+                       if (test_bit(FLAG_MPI,&apriv->flags)) {
+                               unsigned long flags;
+
+                               if (status & EV_TXEXC)
+                                       get_tx_error(apriv, -1);
+                               spin_lock_irqsave(&apriv->aux_lock, flags);
+                               if (skb_queue_len (&apriv->txq)) {
+                                       spin_unlock_irqrestore(&apriv->aux_lock,flags);
+                                       mpi_send_packet (dev);
+                               } else {
+                                       clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
+                                       spin_unlock_irqrestore(&apriv->aux_lock,flags);
+                                       netif_wake_queue (dev);
+                               }
+                               OUT4500( apriv, EVACK,
+                                       status & (EV_TX|EV_TXCPY|EV_TXEXC));
+                               goto exittx;
+                       }
+
                        fid = IN4500(apriv, TXCOMPLFID);
 
                        for( i = 0; i < MAX_FIDS; i++ ) {
@@ -2767,10 +3285,11 @@ exitrx:
                                                netif_wake_queue(apriv->wifidev);
                                }
                        } else {
-                               OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
+                               OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
                                printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
                        }
                }
+exittx:
                if ( status & ~STATUS_INTS & ~IGNORE_INTS )
                        printk( KERN_WARNING "airo: Got weird status %x\n",
                                status & ~STATUS_INTS & ~IGNORE_INTS );
@@ -2793,6 +3312,8 @@ exitrx:
  *         Why would some one do 8 bit IO in an SMP machine?!?
  */
 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
+       if (test_bit(FLAG_MPI,&ai->flags))
+               reg <<= 1;
        if ( !do8bitIO )
                outw( val, ai->dev->base_addr + reg );
        else {
@@ -2804,6 +3325,8 @@ static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
 static u16 IN4500( struct airo_info *ai, u16 reg ) {
        unsigned short rc;
 
+       if (test_bit(FLAG_MPI,&ai->flags))
+               reg <<= 1;
        if ( !do8bitIO )
                rc = inw( ai->dev->base_addr + reg );
        else {
@@ -2824,15 +3347,25 @@ static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
         * open/close functions, and testing both flags together is
         * "cheaper" - Jean II */
        if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd = MAC_ENABLE;
-       if (!lock)
-               return issuecommand(ai, &cmd, rsp);
 
-       if (down_interruptible(&ai->sem))
+       if (lock && down_interruptible(&ai->sem))
                return -ERESTARTSYS;
-       rc = issuecommand(ai, &cmd, rsp);
-       up(&ai->sem);
+
+       if (!test_bit(FLAG_ENABLED, &ai->flags)) {
+               memset(&cmd, 0, sizeof(cmd));
+               cmd.cmd = MAC_ENABLE;
+               rc = issuecommand(ai, &cmd, rsp);
+               if (rc == SUCCESS)
+                       set_bit(FLAG_ENABLED, &ai->flags);
+       } else
+               rc = SUCCESS;
+
+       if (lock)
+           up(&ai->sem);
+
+       if (rc)
+               printk(KERN_ERR "%s: Cannot enable MAC, err=%d\n",
+                       __FUNCTION__,rc);
        return rc;
 }
 
@@ -2840,17 +3373,17 @@ static void disable_MAC( struct airo_info *ai, int lock ) {
         Cmd cmd;
        Resp rsp;
 
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd = MAC_DISABLE; // disable in case already enabled
-       if (!lock) {
-               issuecommand(ai, &cmd, &rsp);
+       if (lock && down_interruptible(&ai->sem))
                return;
-       }
 
-       if (down_interruptible(&ai->sem))
-               return;
-       issuecommand(ai, &cmd, &rsp);
-       up(&ai->sem);
+       if (test_bit(FLAG_ENABLED, &ai->flags)) {
+               memset(&cmd, 0, sizeof(cmd));
+               cmd.cmd = MAC_DISABLE; // disable in case already enabled
+               issuecommand(ai, &cmd, &rsp);
+               clear_bit(FLAG_ENABLED, &ai->flags);
+       }
+       if (lock)
+               up(&ai->sem);
 }
 
 static void enable_interrupts( struct airo_info *ai ) {
@@ -2863,8 +3396,86 @@ static void enable_interrupts( struct airo_info *ai ) {
           I don't know how to get rid of right now... */
 }
 
-static void disable_interrupts( struct airo_info *ai ) {
-       OUT4500( ai, EVINTEN, 0 );
+static void disable_interrupts( struct airo_info *ai ) {
+       OUT4500( ai, EVINTEN, 0 );
+}
+
+static void mpi_receive_802_3(struct airo_info *ai)
+{
+       RxFid rxd;
+       int len = 0;
+       struct sk_buff *skb;
+       char *buffer;
+#ifdef MICSUPPORT
+       int off = 0;
+       MICBuffer micbuf;
+#endif
+
+       memcpy ((char *)&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
+       /* Make sure we got something */
+       if (rxd.rdy && rxd.valid == 0) {
+               len = rxd.len + 12;
+               if (len < 12 && len > 2048)
+                       goto badrx;
+
+               skb = dev_alloc_skb(len);
+               if (!skb) {
+                       ai->stats.rx_dropped++;
+                       goto badrx;
+               }
+               buffer = skb_put(skb,len);
+#ifdef MICSUPPORT
+               memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
+               if (ai->micstats.enabled) {
+                       memcpy(&micbuf,
+                               ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
+                               sizeof(micbuf));
+                       if (ntohs(micbuf.typelen) <= 0x05DC) {
+                               if (len <= sizeof(micbuf) + ETH_ALEN * 2)
+                                       goto badmic;
+
+                               off = sizeof(micbuf);
+                               skb_trim (skb, len - off);
+                       }
+               }
+               memcpy(buffer + ETH_ALEN * 2,
+                       ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
+                       len - ETH_ALEN * 2 - off);
+               if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off)) {
+badmic:
+                       dev_kfree_skb_irq (skb);
+                       goto badrx;
+               }
+#else
+               memcpy(buffer, ai->rxfids[0].virtual_host_addr, len);
+#endif
+#ifdef IW_WIRELESS_SPY         /* defined in iw_handler.h */
+               if (ai->spy_data.spy_number > 0) {
+                       char *sa;
+                       struct iw_quality wstats;
+                       /* Prepare spy data : addr + qual */
+                       sa = buffer + ETH_ALEN;
+                       wstats.qual = 0; /* XXX Where do I get that info from ??? */
+                       wstats.level = 0;
+                       wstats.updated = 0;
+                       /* Update spy records */
+                       wireless_spy_update(ai->dev, sa, &wstats);
+               }
+#endif /* IW_WIRELESS_SPY */
+
+               skb->dev = ai->dev;
+               skb->ip_summed = CHECKSUM_NONE;
+               skb->protocol = eth_type_trans(skb, ai->dev);
+               skb->dev->last_rx = jiffies;
+               netif_rx(skb);
+       }
+badrx:
+       if (rxd.valid == 0) {
+               rxd.valid = 1;
+               rxd.rdy = 0;
+               rxd.len = PKTSIZE;
+               memcpy (ai->rxfids[0].card_ram_off, (char *)&rxd, sizeof(rxd));
+       }
 }
 
 static u16 setup_card(struct airo_info *ai, u8 *mac)
@@ -2893,32 +3504,37 @@ static u16 setup_card(struct airo_info *ai, u8 *mac)
                up(&ai->sem);
                return ERROR;
        }
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd = MAC_DISABLE; // disable in case already enabled
-       if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
-               up(&ai->sem);
-               return ERROR;
-       }
+       disable_MAC( ai, 0);
 
        // Let's figure out if we need to use the AUX port
-       cmd.cmd = CMD_ENABLEAUX;
-       if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
-               up(&ai->sem);
-               printk(KERN_ERR "airo: Error checking for AUX port\n");
-               return ERROR;
-       }
-       if (!aux_bap || rsp.status & 0xff00) {
-               ai->bap_read = fast_bap_read;
-               printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
-       } else {
-               ai->bap_read = aux_bap_read;
-               printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
+       if (!test_bit(FLAG_MPI,&ai->flags)) {
+               cmd.cmd = CMD_ENABLEAUX;
+               if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
+                       up(&ai->sem);
+                       printk(KERN_ERR "airo: Error checking for AUX port\n");
+                       return ERROR;
+               }
+               if (!aux_bap || rsp.status & 0xff00) {
+                       ai->bap_read = fast_bap_read;
+                       printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
+               } else {
+                       ai->bap_read = aux_bap_read;
+                       printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
+               }
        }
        up(&ai->sem);
        if (ai->config.len == 0) {
                tdsRssiRid rssi_rid;
                CapabilityRid cap_rid;
 
+               if (ai->APList) {
+                       kfree(ai->APList);
+                       ai->APList = NULL;
+               }
+               if (ai->SSID) {
+                       kfree(ai->SSID);
+                       ai->SSID = NULL;
+               }
                // general configuration (read/modify/write)
                status = readConfigRid(ai, 1);
                if ( status != SUCCESS ) return ERROR;
@@ -2926,6 +3542,12 @@ static u16 setup_card(struct airo_info *ai, u8 *mac)
                status = readCapabilityRid(ai, &cap_rid);
                if ( status != SUCCESS ) return ERROR;
 
+               if (test_bit(FLAG_MPI, &ai->flags) &&
+                   strcmp (cap_rid.prodVer, "5.00.01") &&
+                   strcmp (cap_rid.prodVer, "5.00.03") &&
+                   strcmp (cap_rid.prodVer, "5b00.08"))
+                       printk(KERN_ERR "airo: Firmware version %s is not supported. Use it at your own risk!\n", cap_rid.prodVer);
+
                status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),1);
                if ( status == SUCCESS ) {
                        if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
@@ -2977,7 +3599,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac)
                                }
                        }
                }
-               ai->need_commit = 1;
+               set_bit (FLAG_COMMIT, &ai->flags);
        }
 
        /* Setup the SSIDs if present */
@@ -2997,8 +3619,10 @@ static u16 setup_card(struct airo_info *ai, u8 *mac)
        if ( status != SUCCESS ) return ERROR;
 
        /* Set up the SSID list */
-       status = writeSsidRid(ai, &mySsid);
-       if ( status != SUCCESS ) return ERROR;
+       if ( ssids[0] ) {
+               status = writeSsidRid(ai, &mySsid);
+               if ( status != SUCCESS ) return ERROR;
+       }
 
        status = enable_MAC(ai, &rsp, 1);
        if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
@@ -3029,6 +3653,9 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
        int max_tries = 600000;
        u16 cmd;
 
+       if (IN4500(ai, EVSTAT) & EV_CMD)
+               OUT4500(ai, EVACK, EV_CMD);
+
        OUT4500(ai, PARAM0, pCmd->parm0);
        OUT4500(ai, PARAM1, pCmd->parm1);
        OUT4500(ai, PARAM2, pCmd->parm2);
@@ -3058,6 +3685,13 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
        pRsp->rsp0 = IN4500(ai, RESP0);
        pRsp->rsp1 = IN4500(ai, RESP1);
        pRsp->rsp2 = IN4500(ai, RESP2);
+       if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) {
+               printk (KERN_ERR "airo: cmd= %x\n", pCmd->cmd);
+               printk (KERN_ERR "airo: status= %x\n", pRsp->status);
+               printk (KERN_ERR "airo: Rsp0= %x\n", pRsp->rsp0);
+               printk (KERN_ERR "airo: Rsp1= %x\n", pRsp->rsp1);
+               printk (KERN_ERR "airo: Rsp2= %x\n", pRsp->rsp2);
+       }
 
        // clear stuck command busy if necessary
        if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
@@ -3213,29 +3847,54 @@ static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, in
                if (down_interruptible(&ai->sem))
                        return ERROR;
        }
-       if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS) {
-                rc = status;
-                goto done;
-        }
-       if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
-               rc = ERROR;
-                goto done;
-        }
-       // read the rid length field
-       bap_read(ai, pBuf, 2, BAP1);
-       // length for remaining part of rid
-       len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
+       if (test_bit(FLAG_MPI,&ai->flags)) {
+               Cmd cmd;
+               Resp rsp;
 
-       if ( len <= 2 ) {
-               printk( KERN_ERR
+               memset(&cmd, 0, sizeof(cmd));
+               memset(&rsp, 0, sizeof(rsp));
+               ai->config_desc.rid_desc.valid = 1;
+               ai->config_desc.rid_desc.len = RIDSIZE;
+               ai->config_desc.rid_desc.rid = 0;
+               ai->config_desc.rid_desc.host_addr = ai->ridbus;
+
+               cmd.cmd = CMD_ACCESS;
+               cmd.parm0 = rid;
+
+               memcpy((char *)ai->config_desc.card_ram_off,
+                       (char *)&ai->config_desc.rid_desc, sizeof(Rid));
+
+               rc = issuecommand(ai, &cmd, &rsp);
+
+               if (rsp.status & 0x7f00)
+                       rc = rsp.rsp0;
+               if (!rc)
+                       memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
+               goto done;
+       } else {
+               if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
+                       rc = status;
+                       goto done;
+               }
+               if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
+                       rc = ERROR;
+                       goto done;
+               }
+               // read the rid length field
+               bap_read(ai, pBuf, 2, BAP1);
+               // length for remaining part of rid
+               len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
+
+               if ( len <= 2 ) {
+                       printk( KERN_ERR
                        "airo: Rid %x has a length of %d which is too short\n",
-                       (int)rid,
-                       (int)len );
-               rc = ERROR;
-                goto done;
+                               (int)rid, (int)len );
+                       rc = ERROR;
+                       goto done;
+               }
+               // read remainder of the rid
+               rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
        }
-       // read remainder of the rid
-       rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
 done:
        if (lock)
                up(&ai->sem);
@@ -3256,20 +3915,60 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
                if (down_interruptible(&ai->sem))
                        return ERROR;
        }
-       // --- first access so that we can write the rid data
-       if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
-                rc = status;
-                goto done;
-        }
-       // --- now write the rid data
-       if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
-                rc = ERROR;
-                goto done;
-        }
-       bap_write(ai, pBuf, len, BAP1);
-       // ---now commit the rid data
-       rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
- done:
+       if (test_bit(FLAG_MPI,&ai->flags)) {
+               Cmd cmd;
+               Resp rsp;
+
+               if (test_bit(FLAG_ENABLED, &ai->flags))
+                       printk(KERN_ERR "%s: MAC should be disabled (rid=%d)\n",
+                               __FUNCTION__, rid);
+               memset(&cmd, 0, sizeof(cmd));
+               memset(&rsp, 0, sizeof(rsp));
+
+               ai->config_desc.rid_desc.valid = 1;
+               ai->config_desc.rid_desc.len = RIDSIZE;
+               ai->config_desc.rid_desc.rid = 0;
+
+               cmd.cmd = CMD_WRITERID;
+               cmd.parm0 = rid;
+
+               memcpy((char *)ai->config_desc.card_ram_off,
+                       (char *)&ai->config_desc.rid_desc, sizeof(Rid));
+
+               if (len < 4 || len > 2047) {
+                       printk(KERN_ERR "%s: len=%d\n",__FUNCTION__,len);
+                       rc = -1;
+               } else {
+                       memcpy((char *)ai->config_desc.virtual_host_addr,
+                               pBuf, len);
+
+                       rc = issuecommand(ai, &cmd, &rsp);
+                       if ((rc & 0xff00) != 0) {
+                               printk(KERN_ERR "%s: Write rid Error %d\n",
+                                       __FUNCTION__,rc);
+                               printk(KERN_ERR "%s: Cmd=%04x\n",
+                                               __FUNCTION__,cmd.cmd);
+                       }
+
+                       if ((rsp.status & 0x7f00))
+                               rc = rsp.rsp0;
+               }
+       } else {
+               // --- first access so that we can write the rid data
+               if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
+                       rc = status;
+                       goto done;
+               }
+               // --- now write the rid data
+               if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
+                       rc = ERROR;
+                       goto done;
+               }
+               bap_write(ai, pBuf, len, BAP1);
+               // ---now commit the rid data
+               rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
+       }
+done:
        if (lock)
                up(&ai->sem);
         return rc;
@@ -3791,7 +4490,7 @@ static int proc_stats_rid_open( struct inode *inode,
        struct airo_info *apriv = dev->priv;
        StatsRid stats;
        int i, j;
-       int *vals = stats.vals;
+       u32 *vals = stats.vals;
 
        if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
                return -ENOMEM;
@@ -3813,7 +4512,7 @@ static int proc_stats_rid_open( struct inode *inode,
                               "airo: Potentially disasterous buffer overflow averted!\n");
                        break;
                }
-               j+=sprintf(data->rbuffer+j, "%s: %d\n", statsLabels[i], vals[i]);
+               j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]);
        }
        if (i*4>=stats.len){
                printk(KERN_WARNING
@@ -3851,7 +4550,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
        if ( !data->writelen ) return;
 
        readConfigRid(ai, 1);
-       ai->need_commit = 1;
+       set_bit (FLAG_COMMIT, &ai->flags);
 
        line = data->wbuffer;
        while( line[0] ) {
@@ -3859,7 +4558,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                if ( !strncmp( line, "Mode: ", 6 ) ) {
                        line += 6;
                        if ((ai->config.rmode & 0xff) >= RXMODE_RFMON)
-                                       ai->need_commit = 2;
+                                       set_bit (FLAG_RESET, &ai->flags);
                        ai->config.rmode &= 0xfe00;
                        clear_bit (FLAG_802_11, &ai->flags);
                        ai->config.opmode &= 0xFF00;
@@ -3879,7 +4578,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                                } else if ( line[0] == 'l' )
                                        ai->config.rmode |= RXMODE_LANMON;
                        }
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                }
 
 /*** Radio status */
@@ -3901,7 +4600,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
                                ai->config.nodeName[j] = line[j];
                        }
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                }
 
 /*** PowerMode processing */
@@ -3909,13 +4608,13 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 11;
                        if ( !strncmp( line, "PSPCAM", 6 ) ) {
                                ai->config.powerSaveMode = POWERSAVE_PSPCAM;
-                               ai->need_commit = 1;
+                               set_bit (FLAG_COMMIT, &ai->flags);
                        } else if ( !strncmp( line, "PSP", 3 ) ) {
                                ai->config.powerSaveMode = POWERSAVE_PSP;
-                               ai->need_commit = 1;
+                               set_bit (FLAG_COMMIT, &ai->flags);
                        } else {
                                ai->config.powerSaveMode = POWERSAVE_CAM;
-                               ai->need_commit = 1;
+                               set_bit (FLAG_COMMIT, &ai->flags);
                        }
                } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
                        int v, i = 0, k = 0; /* i is index into line,
@@ -3927,14 +4626,14 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                                line += i + 1;
                                i = 0;
                        }
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "Channel: ", 9 ) ) {
                        int v, i = 0;
                        line += 9;
                        v = get_dec_u16(line, &i, i+3);
                        if ( v != -1 ) {
                                ai->config.channelSet = (u16)v;
-                               ai->need_commit = 1;
+                               set_bit (FLAG_COMMIT, &ai->flags);
                        }
                } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
                        int v, i = 0;
@@ -3942,7 +4641,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = get_dec_u16(line, &i, i+3);
                        if ( v != -1 ) {
                                ai->config.txPower = (u16)v;
-                               ai->need_commit = 1;
+                               set_bit (FLAG_COMMIT, &ai->flags);
                        }
                } else if ( !strncmp( line, "WEP: ", 5 ) ) {
                        line += 5;
@@ -3957,7 +4656,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                                ai->config.authType = (u16)AUTH_OPEN;
                                break;
                        }
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
                        int v, i = 0;
 
@@ -3965,7 +4664,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = get_dec_u16(line, &i, 3);
                        v = (v<0) ? 0 : ((v>255) ? 255 : v);
                        ai->config.longRetryLimit = (u16)v;
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
                        int v, i = 0;
 
@@ -3973,7 +4672,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = get_dec_u16(line, &i, 3);
                        v = (v<0) ? 0 : ((v>255) ? 255 : v);
                        ai->config.shortRetryLimit = (u16)v;
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
                        int v, i = 0;
 
@@ -3981,7 +4680,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = get_dec_u16(line, &i, 4);
                        v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
                        ai->config.rtsThres = (u16)v;
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
                        int v, i = 0;
 
@@ -3989,7 +4688,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = get_dec_u16(line, &i, 5);
                        v = (v<0) ? 0 : v;
                        ai->config.txLifetime = (u16)v;
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
                        int v, i = 0;
 
@@ -3997,17 +4696,17 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = get_dec_u16(line, &i, 5);
                        v = (v<0) ? 0 : v;
                        ai->config.rxLifetime = (u16)v;
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
                        ai->config.txDiversity =
                                (line[13]=='l') ? 1 :
                                ((line[13]=='r')? 2: 3);
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
                        ai->config.rxDiversity =
                                (line[13]=='l') ? 1 :
                                ((line[13]=='r')? 2: 3);
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
                        int v, i = 0;
 
@@ -4016,22 +4715,22 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
                        v = v & 0xfffe; /* Make sure its even */
                        ai->config.fragThresh = (u16)v;
-                       ai->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &ai->flags);
                } else if (!strncmp(line, "Modulation: ", 12)) {
                        line += 12;
                        switch(*line) {
-                       case 'd':  ai->config.modulation=MOD_DEFAULT; ai->need_commit=1; break;
-                       case 'c':  ai->config.modulation=MOD_CCK; ai->need_commit=1; break;
-                       case 'm':  ai->config.modulation=MOD_MOK; ai->need_commit=1; break;
+                       case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
+                       case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
+                       case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
                        default:
                                printk( KERN_WARNING "airo: Unknown modulation\n" );
                        }
                } else if (!strncmp(line, "Preamble: ", 10)) {
                        line += 10;
                        switch(*line) {
-                       case 'a': ai->config.preamble=PREAMBLE_AUTO; ai->need_commit=1; break;
-                       case 'l': ai->config.preamble=PREAMBLE_LONG; ai->need_commit=1; break;
-                       case 's': ai->config.preamble=PREAMBLE_SHORT; ai->need_commit=1; break;
+                       case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
+                       case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
+                       case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
                        default: printk(KERN_WARNING "airo: Unknown preamble\n");
                        }
                } else {
@@ -4255,6 +4954,7 @@ static int set_wep_key(struct airo_info *ai, u16 index,
                       const char *key, u16 keylen, int perm, int lock ) {
        static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
        WepKeyRid wkr;
+       Resp rsp;
 
        memset(&wkr, 0, sizeof(wkr));
        if (keylen == 0) {
@@ -4274,7 +4974,9 @@ static int set_wep_key(struct airo_info *ai, u16 index,
                printk(KERN_INFO "Setting key %d\n", index);
        }
 
+       disable_MAC(ai, lock);
        writeWepKeyRid(ai, &wkr, perm, lock);
+       enable_MAC(ai, &rsp, lock);
        return 0;
 }
 
@@ -4490,6 +5192,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
                        Cmd cmd;
                        Resp rsp;
 
+                       if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
                        memset(&cmd, 0, sizeof(cmd));
                        cmd.cmd=CMD_LISTBSS;
                        if (down_interruptible(&ai->sem))
@@ -4577,7 +5280,7 @@ static void timer_func( struct net_device *dev ) {
                default:  /* We'll escalate to SHAREDKEY */
                        apriv->config.authType = AUTH_SHAREDKEY;
        }
-       apriv->need_commit = 1;
+       set_bit (FLAG_COMMIT, &apriv->flags);
        writeConfigRid(apriv, 0);
        enable_MAC(apriv, &rsp, 0);
        up(&apriv->sem);
@@ -4617,7 +5320,10 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev,
                return -ENODEV;
        pci_set_master(pdev);
 
-       dev = init_airo_card(pdev->irq, pdev->resource[2].start, 0);
+       if (pdev->device == 0x5000 || pdev->device == 0xa504)
+                       dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev);
+       else
+                       dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev);
        if (!dev)
                return -ENODEV;
 
@@ -4627,7 +5333,89 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev,
 
 static void __devexit airo_pci_remove(struct pci_dev *pdev)
 {
-       stop_airo_card(pci_get_drvdata(pdev), 1);
+}
+
+static int airo_pci_suspend(struct pci_dev *pdev, u32 state)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct airo_info *ai = dev->priv;
+       Cmd cmd;
+       Resp rsp;
+
+       printk(KERN_DEBUG "%s: airo_mpi entering sleep mode (state=%d)\n",
+              dev->name, state);
+
+       if ((ai->APList == NULL) &&
+               (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL)
+               return -ENOMEM;
+       if ((ai->SSID == NULL) &&
+               (ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL)
+               return -ENOMEM;
+       readAPListRid(ai, ai->APList);
+       readSsidRid(ai, ai->SSID);
+       memset(&cmd, 0, sizeof(cmd));
+       if (down_interruptible(&ai->sem))
+               return -EAGAIN;
+       disable_MAC(ai, 0);
+       netif_device_detach(dev);
+       ai->power = state;
+       cmd.cmd=HOSTSLEEP;
+       issuecommand(ai, &cmd, &rsp);
+       up(&ai->sem);
+       return 0;
+}
+
+static int airo_pci_resume(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct airo_info *ai = dev->priv;
+       Resp rsp;
+       int err;
+
+       printk(KERN_DEBUG "%s: airo_mpi waking up\n", dev->name);
+
+       if (!ai->power)
+               return 0;
+
+       if (ai->power > 2) {
+               err = reset_mpi_card(dev);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d resetting on %s()\n",
+                              dev->name, err, __FUNCTION__);
+                       return err;
+               }
+               schedule_timeout (HZ/2);
+               mpi_init_descriptors(ai);
+               setup_card(ai, dev->dev_addr);
+               clear_bit(FLAG_RADIO_OFF, &ai->flags);
+               clear_bit(FLAG_RADIO_DOWN, &ai->flags);
+               clear_bit(FLAG_PENDING_XMIT, &ai->flags);
+       } else {
+               OUT4500(ai, EVACK, EV_AWAKEN);
+               OUT4500(ai, EVACK, EV_AWAKEN);
+               schedule_timeout(HZ/10);
+       }
+
+       set_bit (FLAG_COMMIT, &ai->flags);
+       disable_MAC(ai, 1);
+        schedule_timeout (HZ/5);
+       if (ai->SSID) {
+               writeSsidRid(ai, ai->SSID);
+               kfree(ai->SSID);
+               ai->SSID = NULL;
+       }
+       if (ai->APList) {
+               writeAPListRid(ai, ai->APList);
+               kfree(ai->APList);
+               ai->APList = NULL;
+       }
+       writeConfigRid(ai, 1);
+       enable_MAC(ai, &rsp, 1);
+       ai->power = 0;
+       netif_device_attach(dev);
+       netif_wake_queue(dev);
+       enable_interrupts(ai);
+       return 0;
 }
 #endif
 
@@ -4667,11 +5455,10 @@ static void __exit airo_cleanup_module( void )
                printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
                stop_airo_card( airo_devices->dev, 1 );
        }
-       remove_proc_entry("aironet", proc_root_driver);
-
 #ifdef CONFIG_PCI
        pci_unregister_driver(&airo_driver);
 #endif
+       remove_proc_entry("aironet", proc_root_driver);
 }
 
 #ifdef WIRELESS_EXT
@@ -4736,7 +5523,7 @@ static int airo_set_freq(struct net_device *dev,
                        readConfigRid(local, 1);
                        /* Yes ! We can set it !!! */
                        local->config.channelSet = (u16)(channel - 1);
-                       local->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &local->flags);
                }
        }
        return rc;
@@ -4811,8 +5598,8 @@ static int airo_set_essid(struct net_device *dev,
                       sizeof(SSID_rid.ssids[index].ssid));
                memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
                SSID_rid.ssids[index].len = dwrq->length - 1;
-               SSID_rid.len = sizeof(SSID_rid);
        }
+       SSID_rid.len = sizeof(SSID_rid);
        /* Write it to the card */
        disable_MAC(local, 1);
        writeSsidRid(local, &SSID_rid);
@@ -4924,7 +5711,7 @@ static int airo_set_nick(struct net_device *dev,
        readConfigRid(local, 1);
        memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
        memcpy(local->config.nodeName, extra, dwrq->length);
-       local->need_commit = 1;
+       set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
 }
@@ -5013,7 +5800,7 @@ static int airo_set_rate(struct net_device *dev,
                memset(local->config.rates, 0, 8);
                local->config.rates[0] = brate;
        }
-       local->need_commit = 1;
+       set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
 }
@@ -5059,7 +5846,7 @@ static int airo_set_rts(struct net_device *dev,
        }
        readConfigRid(local, 1);
        local->config.rtsThres = rthr;
-       local->need_commit = 1;
+       set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
 }
@@ -5103,7 +5890,7 @@ static int airo_set_frag(struct net_device *dev,
        fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
        readConfigRid(local, 1);
        local->config.fragThresh = (u16)fthr;
-       local->need_commit = 1;
+       set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
 }
@@ -5137,11 +5924,11 @@ static int airo_set_mode(struct net_device *dev,
                         char *extra)
 {
        struct airo_info *local = dev->priv;
-       int commit = 1;
+       int reset = 0;
 
        readConfigRid(local, 1);
        if ((local->config.rmode & 0xff) >= RXMODE_RFMON)
-               commit = 2;
+               reset = 1;
 
        switch(*uwrq) {
                case IW_MODE_ADHOC:
@@ -5183,7 +5970,9 @@ static int airo_set_mode(struct net_device *dev,
                default:
                        return -EINVAL;
        }
-       local->need_commit = commit;
+       if (reset)
+               set_bit (FLAG_RESET, &local->flags);
+       set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
 }
@@ -5253,7 +6042,7 @@ static int airo_set_encode(struct net_device *dev,
                        return -EINVAL;
                }
                /* Check the index (none -> use current) */
-               if ((index < 0) || (index>=(cap_rid.softCap&0x80)?4:1))
+               if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4:1)))
                        index = current_index;
                /* Set the length */
                if (dwrq->length > MIN_KEY_SIZE)
@@ -5279,12 +6068,12 @@ static int airo_set_encode(struct net_device *dev,
                if((index == current_index) && (key.len > 0) &&
                   (local->config.authType == AUTH_OPEN)) {
                        local->config.authType = AUTH_ENCRYPT;
-                       local->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &local->flags);
                }
        } else {
                /* Do we want to just set the transmit key index ? */
                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-               if ((index>=0) && (index<(cap_rid.softCap&0x80)?4:1)) {
+               if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) {
                        set_wep_key(local, index, 0, 0, 1, 1);
                } else
                        /* Don't complain if only change the mode */
@@ -5301,7 +6090,7 @@ static int airo_set_encode(struct net_device *dev,
                local->config.authType = AUTH_ENCRYPT;  // Only Wep
        /* Commit the changes to flags if needed */
        if(dwrq->flags & IW_ENCODE_MODE)
-               local->need_commit = 1;
+               set_bit (FLAG_COMMIT, &local->flags);
        return -EINPROGRESS;            /* Call commit handler */
 }
 
@@ -5342,7 +6131,7 @@ static int airo_get_encode(struct net_device *dev,
        memset(extra, 0, 16);
 
        /* Which key do we want ? -1 -> tx index */
-       if((index < 0) || (index >= (cap_rid.softCap & 0x80) ? 4 : 1))
+       if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4 : 1)))
                index = get_wep_key(local, 0xffff);
        dwrq->flags |= index + 1;
        /* Copy the key to the user buffer */
@@ -5370,8 +6159,7 @@ static int airo_set_txpow(struct net_device *dev,
        readCapabilityRid(local, &cap_rid);
 
        if (vwrq->disabled) {
-               set_bit (FLAG_RADIO_OFF, &local->flags);
-               local->need_commit = 1;
+               set_bit (FLAG_RADIO_OFF | FLAG_COMMIT, &local->flags);
                return -EINPROGRESS;            /* Call commit handler */
        }
        if (vwrq->flags != IW_TXPOW_MWATT) {
@@ -5382,7 +6170,7 @@ static int airo_set_txpow(struct net_device *dev,
                if ((vwrq->value==cap_rid.txPowerLevels[i])) {
                        readConfigRid(local, 1);
                        local->config.txPower = vwrq->value;
-                       local->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &local->flags);
                        rc = -EINPROGRESS;      /* Call commit handler */
                        break;
                }
@@ -5435,12 +6223,12 @@ static int airo_set_retry(struct net_device *dev,
                        local->config.longRetryLimit = vwrq->value;
                        local->config.shortRetryLimit = vwrq->value;
                }
-               local->need_commit = 1;
+               set_bit (FLAG_COMMIT, &local->flags);
                rc = -EINPROGRESS;              /* Call commit handler */
        }
        if(vwrq->flags & IW_RETRY_LIFETIME) {
                local->config.txLifetime = vwrq->value / 1024;
-               local->need_commit = 1;
+               set_bit (FLAG_COMMIT, &local->flags);
                rc = -EINPROGRESS;              /* Call commit handler */
        }
        return rc;
@@ -5606,17 +6394,17 @@ static int airo_set_power(struct net_device *dev,
                local->config.powerSaveMode = POWERSAVE_CAM;
                local->config.rmode &= 0xFF00;
                local->config.rmode |= RXMODE_BC_MC_ADDR;
-               local->need_commit = 1;
+               set_bit (FLAG_COMMIT, &local->flags);
                return -EINPROGRESS;            /* Call commit handler */
        }
        if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
                local->config.fastListenDelay = (vwrq->value + 500) / 1024;
                local->config.powerSaveMode = POWERSAVE_PSPCAM;
-               local->need_commit = 1;
+               set_bit (FLAG_COMMIT, &local->flags);
        } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
                local->config.fastListenInterval = local->config.listenInterval = (vwrq->value + 500) / 1024;
                local->config.powerSaveMode = POWERSAVE_PSPCAM;
-               local->need_commit = 1;
+               set_bit (FLAG_COMMIT, &local->flags);
        }
        switch (vwrq->flags & IW_POWER_MODE) {
                case IW_POWER_UNICAST_R:
@@ -5625,7 +6413,7 @@ static int airo_set_power(struct net_device *dev,
                        }
                        local->config.rmode &= 0xFF00;
                        local->config.rmode |= RXMODE_ADDR;
-                       local->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &local->flags);
                        break;
                case IW_POWER_ALL_R:
                        if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
@@ -5633,7 +6421,7 @@ static int airo_set_power(struct net_device *dev,
                        }
                        local->config.rmode &= 0xFF00;
                        local->config.rmode |= RXMODE_BC_MC_ADDR;
-                       local->need_commit = 1;
+                       set_bit (FLAG_COMMIT, &local->flags);
                case IW_POWER_ON:
                        break;
                default:
@@ -5688,7 +6476,7 @@ static int airo_set_sens(struct net_device *dev,
 
        readConfigRid(local, 1);
        local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value;
-       local->need_commit = 1;
+       set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
 }
@@ -5776,7 +6564,6 @@ static int airo_get_aplist(struct net_device *dev,
        return 0;
 }
 
-#if WIRELESS_EXT > 13
 /*------------------------------------------------------------------*/
 /*
  * Wireless Handler : Initiate Scan
@@ -5796,6 +6583,7 @@ static int airo_set_scan(struct net_device *dev,
         * This is not an error, while the device perform scanning,
         * traffic doesn't flow, so it's a perfect DoS...
         * Jean II */
+       if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 
        /* Initiate a scan command */
        memset(&cmd, 0, sizeof(cmd));
@@ -5964,72 +6752,6 @@ static int airo_get_scan(struct net_device *dev,
 
        return 0;
 }
-#endif /* WIRELESS_EXT > 13 */
-
-#if WIRELESS_EXT <= 15
-#ifdef WIRELESS_SPY
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set Spy List
- */
-static int airo_set_spy(struct net_device *dev,
-                       struct iw_request_info *info,
-                       struct iw_point *dwrq,
-                       char *extra)
-{
-       struct airo_info *local = dev->priv;
-       struct sockaddr *address = (struct sockaddr *) extra;
-
-       /* Disable spy while we copy the addresses.
-        * As we don't disable interrupts, we need to do this to avoid races */
-       local->spy_number = 0;
-
-       if (dwrq->length > 0) {
-               int i;
-
-               /* Copy addresses */
-               for (i = 0; i < dwrq->length; i++)
-                       memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN);
-               /* Reset stats */
-               memset(local->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
-       }
-       /* Enable addresses */
-       local->spy_number = dwrq->length;
-
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get Spy List
- */
-static int airo_get_spy(struct net_device *dev,
-                       struct iw_request_info *info,
-                       struct iw_point *dwrq,
-                       char *extra)
-{
-       struct airo_info *local = dev->priv;
-       struct sockaddr *address = (struct sockaddr *) extra;
-       int i;
-
-       dwrq->length = local->spy_number;
-
-       /* Copy addresses. */
-       for(i = 0; i < local->spy_number; i++)  {
-               memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN);
-               address[i].sa_family = AF_UNIX;
-       }
-       /* Copy stats to the user buffer (just after). */
-       if(local->spy_number > 0)
-               memcpy(extra  + (sizeof(struct sockaddr) * local->spy_number),
-                      local->spy_stat, sizeof(struct iw_quality) * local->spy_number);
-       /* Reset updated flags. */
-       for (i=0; i<local->spy_number; i++)
-               local->spy_stat[i].updated = 0;
-       return 0;
-}
-#endif                 /* WIRELESS_SPY */
-#endif /* WIRELESS_EXT <= 15 */
 
 /*------------------------------------------------------------------*/
 /*
@@ -6043,13 +6765,13 @@ static int airo_config_commit(struct net_device *dev,
        struct airo_info *local = dev->priv;
        Resp rsp;
 
-       if (!local->need_commit)
+       if (!test_bit (FLAG_COMMIT, &local->flags))
                return 0;
 
        /* Some of the "SET" function may have modified some of the
         * parameters. It's now time to commit them in the card */
        disable_MAC(local, 1);
-       if (local->need_commit > 1) {
+       if (test_bit (FLAG_RESET, &local->flags)) {
                APListRid APList_rid;
                SsidRid SSID_rid;
 
@@ -6064,7 +6786,7 @@ static int airo_config_commit(struct net_device *dev,
                return -ERESTARTSYS;
        writeConfigRid(local, 0);
        enable_MAC(local, &rsp, 0);
-       if (local->need_commit > 1)
+       if (test_bit (FLAG_RESET, &local->flags))
                airo_set_promisc(local);
        else
                up(&local->sem);
@@ -6085,7 +6807,6 @@ static const struct iw_priv_args airo_private_args[] = {
     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
 };
 
-#if WIRELESS_EXT > 12
 static const iw_handler                airo_handler[] =
 {
        (iw_handler) airo_config_commit,        /* SIOCSIWCOMMIT */
@@ -6104,33 +6825,16 @@ static const iw_handler         airo_handler[] =
        (iw_handler) NULL,                      /* SIOCGIWPRIV */
        (iw_handler) NULL,                      /* SIOCSIWSTATS */
        (iw_handler) NULL,                      /* SIOCGIWSTATS */
-#if WIRELESS_EXT > 15
        iw_handler_set_spy,                     /* SIOCSIWSPY */
        iw_handler_get_spy,                     /* SIOCGIWSPY */
        iw_handler_set_thrspy,                  /* SIOCSIWTHRSPY */
        iw_handler_get_thrspy,                  /* SIOCGIWTHRSPY */
-#else /* WIRELESS_EXT > 15 */
-#ifdef WIRELESS_SPY
-       (iw_handler) airo_set_spy,              /* SIOCSIWSPY */
-       (iw_handler) airo_get_spy,              /* SIOCGIWSPY */
-#else  /* WIRELESS_SPY */
-       (iw_handler) NULL,                      /* SIOCSIWSPY */
-       (iw_handler) NULL,                      /* SIOCGIWSPY */
-#endif /* WIRELESS_SPY */
-       (iw_handler) NULL,                      /* -- hole -- */
-       (iw_handler) NULL,                      /* -- hole -- */
-#endif /* WIRELESS_EXT > 15 */
        (iw_handler) airo_set_wap,              /* SIOCSIWAP */
        (iw_handler) airo_get_wap,              /* SIOCGIWAP */
        (iw_handler) NULL,                      /* -- hole -- */
        (iw_handler) airo_get_aplist,           /* SIOCGIWAPLIST */
-#if WIRELESS_EXT > 13
        (iw_handler) airo_set_scan,             /* SIOCSIWSCAN */
        (iw_handler) airo_get_scan,             /* SIOCGIWSCAN */
-#else  /* WIRELESS_EXT > 13 */
-       (iw_handler) NULL,                      /* SIOCSIWSCAN */
-       (iw_handler) NULL,                      /* SIOCGIWSCAN */
-#endif /* WIRELESS_EXT > 13 */
        (iw_handler) airo_set_essid,            /* SIOCSIWESSID */
        (iw_handler) airo_get_essid,            /* SIOCGIWESSID */
        (iw_handler) airo_set_nick,             /* SIOCSIWNICKN */
@@ -6173,14 +6877,11 @@ static const struct iw_handler_def      airo_handler_def =
        .standard       = (iw_handler *) airo_handler,
        .private        = (iw_handler *) airo_private_handler,
        .private_args   = (struct iw_priv_args *) airo_private_args,
-#if WIRELESS_EXT > 15
        .spy_offset     = ((void *) (&((struct airo_info *) NULL)->spy_data) -
                           (void *) NULL),
-#endif /* WIRELESS_EXT > 15 */
 
 };
 
-#endif /* WIRELESS_EXT > 12 */
 #endif /* WIRELESS_EXT */
 
 /*
@@ -6199,290 +6900,12 @@ static const struct iw_handler_def     airo_handler_def =
 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        int rc = 0;
-#if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
-       struct iwreq *wrq = (struct iwreq *) rq;
-#endif /* WIRELESS_EXT < 13 */
-
-       switch (cmd) {
-/* WE 13 and higher will use airo_handler_def */
-#if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
-       case SIOCGIWNAME:       // Get name
-               airo_get_name(dev, NULL, (char *) &(wrq->u.name), NULL);
-               break;
-
-       case SIOCSIWFREQ:       // Set frequency/channel
-               rc = airo_set_freq(dev, NULL, &(wrq->u.freq), NULL);
-               break;
-
-       case SIOCGIWFREQ:       // Get frequency/channel
-               rc = airo_get_freq(dev, NULL, &(wrq->u.freq), NULL);
-               break;
-
-       case SIOCSIWESSID:      // Set desired network name (ESSID)
-               {
-                       char essidbuf[IW_ESSID_MAX_SIZE+1];
-                       if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
-                               rc = -E2BIG;
-                               break;
-                       }
-                       if (copy_from_user(essidbuf, wrq->u.essid.pointer,
-                                          wrq->u.essid.length)) {
-                               rc = -EFAULT;
-                               break;
-                       }
-                       rc = airo_set_essid(dev, NULL,
-                                           &(wrq->u.essid), essidbuf);
-               }
-               break;
-
-       case SIOCGIWESSID:      // Get current network name (ESSID)
-               {
-                       char essidbuf[IW_ESSID_MAX_SIZE+1];
-                       if (wrq->u.essid.pointer)
-                               rc = airo_get_essid(dev, NULL,
-                                                   &(wrq->u.essid), essidbuf);
-                               if ( copy_to_user(wrq->u.essid.pointer,
-                                                 essidbuf,
-                                                 wrq->u.essid.length) )
-                                       rc = -EFAULT;
-               }
-               break;
-
-       case SIOCSIWAP:
-               rc = airo_set_wap(dev, NULL, &(wrq->u.ap_addr), NULL);
-               break;
-
-       case SIOCGIWAP:         // Get current Access Point (BSSID)
-               rc = airo_get_wap(dev, NULL, &(wrq->u.ap_addr), NULL);
-               break;
-
-       case SIOCSIWNICKN:      // Set desired station name
-               {
-                       char nickbuf[IW_ESSID_MAX_SIZE+1];
-                       if (wrq->u.data.length > IW_ESSID_MAX_SIZE) {
-                               rc = -E2BIG;
-                               break;
-                       }
-                       if (copy_from_user(nickbuf, wrq->u.data.pointer,
-                                          wrq->u.data.length)) {
-                               rc = -EFAULT;
-                               break;
-                       }
-                       rc = airo_set_nick(dev, NULL,
-                                          &(wrq->u.data), nickbuf);
-               }
-               break;
-
-       case SIOCGIWNICKN:      // Get current station name
-               {
-                       char nickbuf[IW_ESSID_MAX_SIZE+1];
-                       if (wrq->u.data.pointer)
-                               rc = airo_get_nick(dev, NULL,
-                                                  &(wrq->u.data), nickbuf);
-                               if ( copy_to_user(wrq->u.data.pointer,
-                                                 nickbuf,
-                                                 wrq->u.data.length) )
-                                       rc = -EFAULT;
-               }
-               break;
-
-       case SIOCSIWRATE:       // Set the desired bit-rate
-               rc = airo_set_rate(dev, NULL, &(wrq->u.bitrate), NULL);
-               break;
-
-       case SIOCGIWRATE:       // Get the current bit-rate
-               rc = airo_get_rate(dev, NULL, &(wrq->u.bitrate), NULL);
-               break;
-
-       case SIOCSIWRTS:        // Set the desired RTS threshold
-               rc = airo_set_rts(dev, NULL, &(wrq->u.rts), NULL);
-               break;
-
-       case SIOCGIWRTS:        // Get the current RTS threshold
-               rc = airo_get_rts(dev, NULL, &(wrq->u.rts), NULL);
-               break;
-
-       case SIOCSIWFRAG:       // Set the desired fragmentation threshold
-               rc = airo_set_frag(dev, NULL, &(wrq->u.frag), NULL);
-               break;
-
-       case SIOCGIWFRAG:       // Get the current fragmentation threshold
-               rc = airo_get_frag(dev, NULL, &(wrq->u.frag), NULL);
-               break;
-
-       case SIOCSIWMODE:       // Set mode of operation
-               rc = airo_set_mode(dev, NULL, &(wrq->u.mode), NULL);
-               break;
-
-       case SIOCGIWMODE:       // Get mode of operation
-               rc = airo_get_mode(dev, NULL, &(wrq->u.mode), NULL);
-               break;
-
-       case SIOCSIWENCODE:     // Set WEP keys and mode
-               {
-                       char keybuf[MAX_KEY_SIZE];
-                       if (wrq->u.encoding.pointer) {
-                               /* We actually have a key to set */
-                               if (wrq->u.encoding.length > MAX_KEY_SIZE) {
-                                       rc = -E2BIG;
-                                       break;
-                               }
-                               if (copy_from_user(keybuf,
-                                                  wrq->u.encoding.pointer,
-                                                  wrq->u.encoding.length)) {
-                                       rc = -EFAULT;
-                                       break;
-                               }
-                       } else if (wrq->u.encoding.length != 0) {
-                               rc = -EINVAL;
-                               break;
-                       }
-                       rc = airo_set_encode(dev, NULL,
-                                            &(wrq->u.encoding), keybuf);
-               }
-               break;
-
-       case SIOCGIWENCODE:     // Get the WEP keys and mode
-               // Only super-user can see WEP key
-               // Note : this is needed only for very old versions of WE
-               if (!capable(CAP_NET_ADMIN)) {
-                       rc = -EPERM;
-                       break;
-               }
-               {
-                       char keybuf[MAX_KEY_SIZE];
-                       rc = airo_get_encode(dev, NULL,
-                                            &(wrq->u.encoding), keybuf);
-                       if (wrq->u.encoding.pointer) {
-                               if (copy_to_user(wrq->u.encoding.pointer,
-                                                keybuf,
-                                                wrq->u.encoding.length))
-                                       rc = -EFAULT;
-                       }
-               }
-               break;
-
-       case SIOCGIWTXPOW:      // Get the current Tx-Power
-               rc=airo_get_txpow(dev, NULL, &(wrq->u.txpower), NULL);
-               break;
-       case SIOCSIWTXPOW:
-               rc=airo_set_txpow(dev, NULL, &(wrq->u.txpower), NULL);
-               break;
-
-       case SIOCSIWRETRY:
-               rc=airo_set_retry(dev, NULL, &(wrq->u.retry), NULL);
-               break;
-       case SIOCGIWRETRY:
-               rc=airo_get_retry(dev, NULL, &(wrq->u.retry), NULL);
-               break;
-
-       case SIOCGIWRANGE:      // Get range of parameters
-               {
-                       struct iw_range range;
-                       rc = airo_get_range(dev, NULL,
-                                           &(wrq->u.data), (char *) &range);
-                       if (copy_to_user(wrq->u.data.pointer, &range,
-                                        sizeof(struct iw_range)))
-                               rc = -EFAULT;
-               }
-               break;
-
-       case SIOCGIWPOWER:
-               rc=airo_get_power(dev, NULL, &(wrq->u.power), NULL);
-               break;
-
-       case SIOCSIWPOWER:
-               rc=airo_set_power(dev, NULL, &(wrq->u.power), NULL);
-               break;
-
-       case SIOCGIWSENS:
-               rc = airo_get_sens(dev, NULL, &(wrq->u.sens), NULL);
-               break;
-
-       case SIOCSIWSENS:
-               rc = airo_set_sens(dev, NULL, &(wrq->u.sens), NULL);
-               break;
-
-       case SIOCGIWAPLIST:
-               {
-                       char buffer[IW_MAX_AP * (sizeof(struct sockaddr) +
-                                                 sizeof(struct iw_quality))];
-                       if (wrq->u.data.pointer) {
-                               rc = airo_get_aplist(dev, NULL,
-                                                    &(wrq->u.data), buffer);
-                               if (copy_to_user(wrq->u.data.pointer,
-                                                buffer,
-                                                (wrq->u.data.length *
-                                                 (sizeof(struct sockaddr) +
-                                                  sizeof(struct iw_quality)))
-                                                ))
-                                       rc = -EFAULT;
-                       }
-               }
-               break;
-
-#ifdef WIRELESS_SPY
-       case SIOCSIWSPY:        // Set the spy list
-               {
-                       struct sockaddr address[IW_MAX_SPY];
-                       /* Check the number of addresses */
-                       if (wrq->u.data.length > IW_MAX_SPY) {
-                               rc = -E2BIG;
-                               break;
-                       }
-                       /* Get the data in the driver */
-                       if (wrq->u.data.pointer) {
-                               if (copy_from_user((char *) address,
-                                                  wrq->u.data.pointer,
-                                                  sizeof(struct sockaddr) *
-                                                  wrq->u.data.length)) {
-                               rc = -EFAULT;
-                               break;
-                               }
-                       } else if (wrq->u.data.length != 0) {
-                               rc = -EINVAL;
-                               break;
-                       }
-                       rc=airo_set_spy(dev, NULL, &(wrq->u.data),
-                                       (char *) address);
-               }
-               break;
+       struct airo_info *ai = (struct airo_info *)dev->priv;
 
-       case SIOCGIWSPY:        // Get the spy list
-               {
-                       char buffer[IW_MAX_SPY * (sizeof(struct sockaddr) +
-                                                 sizeof(struct iw_quality))];
-                       if (wrq->u.data.pointer) {
-                               rc = airo_get_spy(dev, NULL,
-                                                 &(wrq->u.data), buffer);
-                               if (copy_to_user(wrq->u.data.pointer,
-                                                buffer,
-                                                (wrq->u.data.length *
-                                                 (sizeof(struct sockaddr) +
-                                                  sizeof(struct iw_quality)))
-                                                ))
-                                       rc = -EFAULT;
-                       }
-               }
-               break;
-#endif /* WIRELESS_SPY */
-
-#ifdef CISCO_EXT
-       case SIOCGIWPRIV:
-               if(wrq->u.data.pointer) {
-                       /* Set the number of ioctl available */
-                       wrq->u.data.length = sizeof(airo_private_args) / sizeof( airo_private_args[0]);
-
-                       /* Copy structure to the user buffer */
-                       if(copy_to_user(wrq->u.data.pointer,
-                                       (u_char *) airo_private_args,
-                                       sizeof(airo_private_args)))
-                               rc = -EFAULT;
-               }
-               break;
-#endif /* CISCO_EXT */
-#endif /* WIRELESS_EXT < 13 */
+       if (ai->power)
+               return 0;
 
+       switch (cmd) {
 #ifdef CISCO_EXT
        case AIROIDIFC:
 #ifdef AIROOLDIDIFC
@@ -6530,16 +6953,6 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        default:
                rc = -EOPNOTSUPP;
        }
-
-#if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
-       /* WE 13 and higher will use airo_config_commit */
-       /* Some of the "SET" function may have modified some of the
-        * parameters. It's now time to commit them in the card */
-       airo_config_commit(dev, NULL, NULL, NULL);
-       if (rc == -EINPROGRESS)
-               return 0;
-#endif /* WIRELESS_EXT < 13 */
-
        return rc;
 }
 
@@ -6561,6 +6974,10 @@ static void airo_read_wireless_stats(struct airo_info *local)
 
        /* Get stats out of the card */
        clear_bit(JOB_WSTATS, &local->flags);
+       if (local->power) {
+               up(&local->sem);
+               return;
+       }
        readStatusRid(local, &status_rid, 0);
        readStatsRid(local, &stats_rid, RID_STATS, 0);
        up(&local->sem);
@@ -6608,7 +7025,6 @@ struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
 #endif /* WIRELESS_EXT */
 
 #ifdef CISCO_EXT
-#define RIDS_SIZE      2048
 /*
  * This just translates from driver IOCTL codes to the command codes to
  * feed to the radio's host interface. Things can be added/deleted
@@ -6659,10 +7075,10 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
                break;
        }
 
-       if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
+       if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
                return -ENOMEM;
 
-       PC4500_readrid(ai,ridcode,iobuf,RIDS_SIZE, 1);
+       PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
        /* get the count of bytes in the rid  docs say 1st 2 bytes is it.
         * then return it to the user
         * 9/22/2000 Honor user given length
@@ -6672,7 +7088,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
        else
                len = comp->len;
 
-       if (copy_to_user(comp->data, iobuf, min(len, (int)RIDS_SIZE))) {
+       if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
                kfree (iobuf);
                return -EFAULT;
        }
@@ -6735,10 +7151,10 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
                 * writerid routines.
                 */
        case AIROPSTCLR:
-               if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
+               if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
                        return -ENOMEM;
 
-               PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDS_SIZE, 1);
+               PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
 
 #ifdef MICSUPPORT
                enabled = ai->micstats.enabled;
@@ -6747,7 +7163,7 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 #endif
 
                if (copy_to_user(comp->data, iobuf,
-                                min((int)comp->len, (int)RIDS_SIZE))) {
+                                min((int)comp->len, (int)RIDSIZE))) {
                        kfree (iobuf);
                        return -EFAULT;
                }
@@ -6757,10 +7173,10 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
        default:
                return -EOPNOTSUPP;     /* Blarg! */
        }
-       if(comp->len > RIDS_SIZE)
+       if(comp->len > RIDSIZE)
                return -EINVAL;
 
-       if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
+       if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
                return -ENOMEM;
 
        if (copy_from_user(iobuf,comp->data,comp->len)) {
@@ -6990,13 +7406,16 @@ int flashputbuf(struct airo_info *ai){
        int            nwords;
 
        /* Write stuff */
-       OUT4500(ai,AUXPAGE,0x100);
-       OUT4500(ai,AUXOFF,0);
+       if (test_bit(FLAG_MPI,&ai->flags))
+               memcpy(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
+       else {
+               OUT4500(ai,AUXPAGE,0x100);
+               OUT4500(ai,AUXOFF,0);
 
-       for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
-               OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
+               for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
+                       OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
+               }
        }
-
        OUT4500(ai,SWS0,0x8000);
 
        return 0;
@@ -7013,9 +7432,11 @@ int flashrestart(struct airo_info *ai,struct net_device *dev){
        clear_bit (FLAG_FLASHING, &ai->flags);
        status = setup_card(ai, dev->dev_addr);
 
-       for( i = 0; i < MAX_FIDS; i++ ) {
-               ai->fids[i] = transmit_allocate( ai, 2312, i >= MAX_FIDS / 2 );
-       }
+       if (!test_bit(FLAG_MPI,&ai->flags))
+               for( i = 0; i < MAX_FIDS; i++ ) {
+                       ai->fids[i] = transmit_allocate
+                               ( ai, 2312, i >= MAX_FIDS / 2 );
+               }
 
        set_current_state (TASK_UNINTERRUPTIBLE);
        schedule_timeout (HZ);          /* Added 12/7/00 */
index dbe71e9..c6af531 100644 (file)
@@ -19,9 +19,7 @@ struct net_device *arlan_device[MAX_ARLANS];
 static int SID = SIDUNKNOWN;
 static int radioNodeId = radioNodeIdUNKNOWN;
 static char encryptionKey[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
-static int mem = memUNKNOWN;
 int arlan_debug = debugUNKNOWN;
-static int numDevices = numDevicesUNKNOWN;
 static int spreadingCode = spreadingCodeUNKNOWN;
 static int channelNumber = channelNumberUNKNOWN;
 static int channelSet = channelSetUNKNOWN;
@@ -45,9 +43,7 @@ static int mdebug;
 
 MODULE_PARM(irq, "i");
 MODULE_PARM(mem, "i");
-MODULE_PARM(probe, "i");
 MODULE_PARM(arlan_debug, "i");
-MODULE_PARM(numDevices, "i");
 MODULE_PARM(testMemory, "i");
 MODULE_PARM(spreadingCode, "i");
 MODULE_PARM(channelNumber, "i");
@@ -69,9 +65,7 @@ MODULE_PARM(arlan_entry_and_exit_debug, "i");
 MODULE_PARM(arlan_EEPROM_bad, "i");
 MODULE_PARM_DESC(irq, "(unused)");
 MODULE_PARM_DESC(mem, "Arlan memory address for single device probing");
-MODULE_PARM_DESC(probe, "Arlan probe at initialization (0-1)");
 MODULE_PARM_DESC(arlan_debug, "Arlan debug enable (0-1)");
-MODULE_PARM_DESC(numDevices, "Number of Arlan devices; ignored if >1");
 MODULE_PARM_DESC(testMemory, "(unused)");
 MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)");
 MODULE_PARM_DESC(retries, "Arlan maximum packet retransmisions");
@@ -88,7 +82,6 @@ MODULE_PARM_DESC(arlan_entry_and_exit_debug, "(ignored)");
 struct arlan_conf_stru arlan_conf[MAX_ARLANS];
 static int arlans_found;
 
-static  int    arlan_probe_here(struct net_device *dev, int ioaddr);
 static  int    arlan_open(struct net_device *dev);
 static  int    arlan_tx(struct sk_buff *skb, struct net_device *dev);
 static  irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -975,24 +968,27 @@ static int lastFoundAt = 0xbe000;
  * probes on the ISA bus. A good device probes avoids doing writes, and
  * verifies that the correct device exists and functions.
  */
-
-static int __init arlan_check_fingerprint(int memaddr)
+#define ARLAN_SHMEM_SIZE       0x2000
+static int __init arlan_check_fingerprint(unsigned long memaddr)
 {
-       static char probeText[] = "TELESYSTEM SLW INC.    ARLAN \0";
-       char tempBuf[49];
+       static const char probeText[] = "TELESYSTEM SLW INC.    ARLAN \0";
        volatile struct arlan_shmem *arlan = (struct arlan_shmem *) memaddr;
+       unsigned long paddr = virt_to_phys((void *) memaddr);
+       char tempBuf[49];
 
        ARLAN_DEBUG_ENTRY("arlan_check_fingerprint");
-       if (check_mem_region(virt_to_phys((void *)memaddr),0x2000 )){
-               // printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",virt_to_phys((void*)memaddr));
+
+       if (!request_mem_region(paddr, ARLAN_SHMEM_SIZE, "arlan")) {
+               // printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",paddr);
                return -ENODEV;
        }
+
        memcpy_fromio(tempBuf, arlan->textRegion, 29);
        tempBuf[30] = 0;
 
        /* check for card at this address */
        if (0 != strncmp(tempBuf, probeText, 29)){
-// not                 release_mem_region(virt_to_phys((void*)memaddr),0x2000);
+               release_mem_region(paddr, ARLAN_SHMEM_SIZE);
                return -ENODEV;
        }
 
@@ -1000,51 +996,8 @@ static int __init arlan_check_fingerprint(int memaddr)
        ARLAN_DEBUG_EXIT("arlan_check_fingerprint");
 
        return 0;
-
-
 }
 
-static int __init arlan_probe_everywhere(struct net_device *dev)
-{
-       int m;
-       int probed = 0;
-       int found = 0;
-
-       SET_MODULE_OWNER(dev);
-
-       ARLAN_DEBUG_ENTRY("arlan_probe_everywhere");
-       if (mem != 0 && numDevices == 1)        /* Check a single specified location. */
-       {
-               if (arlan_probe_here(dev, (int) phys_to_virt(  mem) ) == 0)
-                       return 0;
-               else
-                       return -ENODEV;
-       }
-       for (m = (int)phys_to_virt(lastFoundAt) + 0x2000; m <= (int)phys_to_virt(0xDE000); m += 0x2000)
-       {
-               if (arlan_probe_here(dev, m) == 0)
-               {
-                       found++;
-                       lastFoundAt = (int)virt_to_phys((void*)m);
-                       break;
-               }
-               probed++;
-       }
-       if (found == 0 && probed != 0)
-       {
-               if (lastFoundAt == 0xbe000)
-                       printk(KERN_ERR "arlan: No Arlan devices found \n");
-               return -ENODEV;
-       }
-       else
-               return 0;
-
-       ARLAN_DEBUG_EXIT("arlan_probe_everywhere");
-
-       return -ENODEV;
-}
-
-
 static int arlan_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct arlan_private *priv = dev->priv;
@@ -1085,47 +1038,15 @@ static int arlan_mac_addr(struct net_device *dev, void *p)
 
 
 
-
-static int __init
-             arlan_allocate_device(int num, struct net_device *devs)
+static int __init arlan_setup_device(struct net_device *dev, int num)
 {
+       struct arlan_private *ap = dev->priv;
+       int err;
 
-       struct net_device *dev;
-       struct arlan_private *ap;
+       ARLAN_DEBUG_ENTRY("arlan_setup_device");
 
-       ARLAN_DEBUG_ENTRY("arlan_allocate_device");
+       ap->conf = (struct arlan_shmem *)(ap+1);
 
-       if (!devs) {
-               dev = init_etherdev(0, sizeof(struct arlan_private) + sizeof(struct arlan_shmem));
-               if (!dev) {
-                       printk(KERN_ERR "ARLAN: init_etherdev failed\n");
-                       return 0;
-               }
-               ap = dev->priv;
-               ap->conf = dev->priv + sizeof(struct arlan_private);
-               ap->init_etherdev_alloc = 1;
-       } else {
-               dev = devs;
-               dev->priv = kmalloc(sizeof(struct arlan_private) + sizeof(struct arlan_shmem), GFP_KERNEL);
-               if (!dev->priv) {
-                       printk(KERN_ERR "ARLAN: kmalloc of dev->priv failed\n");
-                       return 0;
-               }
-               ap = dev->priv;
-               ap->conf = dev->priv + sizeof(struct arlan_private);
-               memset(ap, 0, sizeof(*ap));
-       }
-
-       /* Fill in the 'dev' fields. */
-       dev->base_addr = 0;
-       dev->mem_start = 0;
-       dev->mem_end = 0;
-       dev->mtu = 1500;
-       dev->flags = 0;         /* IFF_BROADCAST & IFF_MULTICAST & IFF_PROMISC; */
-       dev->irq = 0;
-       dev->dma = 0;
-       dev->tx_queue_len = tx_queue_len;
-       ether_setup(dev);
        dev->tx_queue_len = tx_queue_len;
        dev->open = arlan_open;
        dev->stop = arlan_close;
@@ -1138,41 +1059,45 @@ static int __init
        dev->watchdog_timeo = 3*HZ;
        
        ap->irq_test_done = 0;
-       arlan_device[num] = dev;
        ap->Conf = &arlan_conf[num];
 
        ap->Conf->pre_Command_Wait = 40;
        ap->Conf->rx_tweak1 = 30;
        ap->Conf->rx_tweak2 = 0;
 
-       ARLAN_DEBUG_EXIT("arlan_allocate_device");
-       return (int) dev;
-}
 
+       err = register_netdev(dev);
+       if (err) {
+               release_mem_region(virt_to_phys((void *) dev->mem_start), 
+                          ARLAN_SHMEM_SIZE);
+               free_netdev(dev);
+               return err;
+       }
+       arlan_device[num] = dev;
+       ARLAN_DEBUG_EXIT("arlan_setup_device");
+       return 0;
+}
 
-static int __init arlan_probe_here(struct net_device *dev, int memaddr)
+static int __init arlan_probe_here(struct net_device *dev, 
+                                  unsigned long memaddr)
 {
-       volatile struct arlan_shmem *arlan;
+       struct arlan_private *ap = dev->priv;
 
        ARLAN_DEBUG_ENTRY("arlan_probe_here");
 
        if (arlan_check_fingerprint(memaddr))
                return -ENODEV;
 
-       printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name, (int) virt_to_phys((void*)memaddr));
-
-       if (!arlan_allocate_device(arlans_found, dev))
-               return -1;
-
-       ((struct arlan_private *) dev->priv)->card = (struct arlan_shmem *) memaddr;
-       arlan = (void *) memaddr;
+       printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name, 
+              (int) virt_to_phys((void*)memaddr));
 
+       ap->card = (void *) memaddr;
        dev->mem_start = memaddr;
-       dev->mem_end = memaddr + 0x1FFF;
+       dev->mem_end = memaddr + ARLAN_SHMEM_SIZE-1;
 
        if (dev->irq < 2)
        {
-               READSHM(dev->irq, arlan->irqLevel, u_char);
+               READSHM(dev->irq, ap->card->irqLevel, u_char);
        } else if (dev->irq == 2)
                dev->irq = 9;
 
@@ -1183,8 +1108,6 @@ static int __init arlan_probe_here(struct net_device *dev, int memaddr)
 }
 
 
-
-
 static int arlan_open(struct net_device *dev)
 {
        struct arlan_private *priv = dev->priv;
@@ -1193,12 +1116,6 @@ static int arlan_open(struct net_device *dev)
 
        ARLAN_DEBUG_ENTRY("arlan_open");
 
-       if (dev->mem_start == 0)
-               ret = arlan_probe_everywhere(dev);
-       if (ret != 0)
-               return ret;
-
-       arlan = priv->card;
        ret = request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev);
        if (ret)
        {
@@ -1768,14 +1685,9 @@ static int arlan_close(struct net_device *dev)
 {
        struct arlan_private *priv = dev->priv;
 
-       if (!priv)
-       {
-               printk(KERN_CRIT "arlan: No Device priv \n");
-               return 0;
-       }
        ARLAN_DEBUG_ENTRY("arlan_close");
 
-       del_timer(&priv->timer);
+       del_timer_sync(&priv->timer);
 
        arlan_command(dev, ARLAN_COMMAND_POWERDOWN);
 
@@ -1867,39 +1779,70 @@ static void arlan_set_multicast(struct net_device *dev)
 }
 
 
-int __init arlan_probe(struct net_device *dev)
+struct net_device * __init arlan_probe(int unit)
 {
-       printk("Arlan driver %s\n", arlan_version);
+       struct net_device *dev;
+       int err;
+       int m;
 
-       if (arlan_probe_everywhere(dev))
-               return -ENODEV;
+       ARLAN_DEBUG_ENTRY("arlan_probe");
 
-       arlans_found++;
-       return 0;
-}
+       if (arlans_found == MAX_ARLANS)
+               return ERR_PTR(-ENODEV);
 
-#ifdef  MODULE
+       /* 
+        * Reserve space for local data and a copy of the shared memory
+        * that is used by the /proc interface.
+        */
+       dev = alloc_etherdev(sizeof(struct arlan_private)
+                            + sizeof(struct arlan_shmem));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-static int probe = probeUNKNOWN;
+       SET_MODULE_OWNER(dev);
 
-static int __init arlan_find_devices(void)
-{
-       int m;
-       int found = 0;
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               
+               if (dev->mem_start) {
+                       if (arlan_probe_here(dev, dev->mem_start) == 0)
+                               goto found;
+                       goto not_found;
+               }
+                       
+       }
 
-       ARLAN_DEBUG_ENTRY("arlan_find_devices");
-       if (mem != 0 && numDevices == 1)        /* Check a single specified location. */
-               return 1;
-       for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000)
+
+       for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE; 
+            m <= (int)phys_to_virt(0xDE000); 
+            m += ARLAN_SHMEM_SIZE)
        {
-               if (arlan_check_fingerprint(m) == 0)
-                       found++;
+               if (arlan_probe_here(dev, m) == 0)
+               {
+                       lastFoundAt = (int)virt_to_phys((void*)m);
+                       goto found;
+               }
        }
-       ARLAN_DEBUG_EXIT("arlan_find_devices");
 
-       return found;
+       if (lastFoundAt == 0xbe000)
+               printk(KERN_ERR "arlan: No Arlan devices found \n");
+
+ not_found:
+       free_netdev(dev);
+       return ERR_PTR(-ENODEV);
+
+ found:
+       err = arlan_setup_device(dev, arlans_found);
+       if (err)
+               dev = ERR_PTR(err);
+       else if (!arlans_found++)
+               printk(KERN_INFO "Arlan driver %s\n", arlan_version);
+
+       return dev;
 }
 
+#ifdef  MODULE
 int init_module(void)
 {
        int i = 0;
@@ -1909,21 +1852,11 @@ int init_module(void)
        if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN)
                return -EINVAL;
 
-       numDevices = arlan_find_devices();
-       if (numDevices == 0)
-               return -ENODEV;
-
-       for (i = 0; i < numDevices && i < MAX_ARLANS; i++)
-       {
-               if (!arlan_allocate_device(i, NULL))
-                       return -ENOMEM;
+       for (i = 0; i < MAX_ARLANS; i++) {
+               struct net_device *dev = arlan_probe(i);
 
-               if (arlan_device[i] == NULL)
-                       return -ENOMEM;
-
-               if (probe)
-                       arlan_probe_everywhere(arlan_device[i]);
-//             arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN );
+               if (IS_ERR(dev)) 
+                       return PTR_ERR(dev);
        }
        init_arlan_proc();
        printk(KERN_INFO "Arlan driver %s\n", arlan_version);
@@ -1935,7 +1868,7 @@ int init_module(void)
 void cleanup_module(void)
 {
        int i = 0;
-       struct arlan_private *ap;
+       struct net_device *dev;
 
        ARLAN_DEBUG_ENTRY("cleanup_module");
 
@@ -1946,22 +1879,18 @@ void cleanup_module(void)
 
        for (i = 0; i < MAX_ARLANS; i++)
        {
-               if (arlan_device[i])
-               {
-                       arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN );
-
-//                     release_mem_region(virt_to_phys(arlan_device[i]->mem_start), 0x2000 );
-                       unregister_netdev(arlan_device[i]);
-                       ap = arlan_device[i]->priv;
-                       if (ap->init_etherdev_alloc) {
-                               free_netdev(arlan_device[i]);
-                               arlan_device[i] = NULL;
-                       } else {
-                               kfree(ap);
-                               ap = NULL;
-                       }
+               dev = arlan_device[i];
+               if (dev) {
+                       arlan_command(dev, ARLAN_COMMAND_POWERDOWN );
+
+                       unregister_netdev(dev);
+                       release_mem_region(virt_to_phys((void *) dev->mem_start), 
+                                          ARLAN_SHMEM_SIZE);
+                       free_netdev(dev);
+                       arlan_device[i] = NULL;
                }
        }
+
        ARLAN_DEBUG_EXIT("cleanup_module");
 }
 
index 261bbdf..eacf37f 100644 (file)
@@ -57,12 +57,8 @@ extern int     arlan_command(struct net_device * dev, int command);
  
 #define SIDUNKNOWN -1
 #define radioNodeIdUNKNOWN -1
-#define encryptionKeyUNKNOWN '\0';
 #define irqUNKNOWN 0
-#define memUNKNOWN 0
 #define debugUNKNOWN 0
-#define probeUNKNOWN 1
-#define numDevicesUNKNOWN 1
 #define testMemoryUNKNOWN 1
 #define spreadingCodeUNKNOWN 0
 #define channelNumberUNKNOWN 0
@@ -82,6 +78,8 @@ extern int     arlan_command(struct net_device * dev, int command);
        #define ARLAN_DEBUG(a,b) 
 #endif
 
+#define ARLAN_SHMEM_SIZE       0x2000
+
 struct arlan_shmem
 {
       /* Header Signature */ 
index ec3909b..0518b9e 100644 (file)
@@ -17,9 +17,6 @@
     This file contains the module in binary form and, under the terms
     of the GPL, in source form. The source is located at the end of the file.
 
-    For all queries about this code, please contact the current author, 
-    Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
-
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     along with Atmel wireless lan drivers; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+    For all queries about this code, please contact the current author, 
+    Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
+
+    Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
+    hardware used during development of this driver.
+
 ******************************************************************************/
 
 #include <linux/config.h>
@@ -67,7 +70,7 @@
 #include "ieee802_11.h"
 
 #define DRIVER_MAJOR 0
-#define DRIVER_MINOR 9
+#define DRIVER_MINOR 91
 
 MODULE_AUTHOR("Simon Kelley");
 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
@@ -469,7 +472,6 @@ struct atmel_private {
                CARD_TYPE_SPI_FLASH,
                CARD_TYPE_EEPROM 
        } card_type;
-       int is3com; /* is this a 3com card? they are uniquely borken */
        int do_rx_crc; /* If we need to CRC incoming packets */
        int probe_crc; /* set if we don't yet know */
        int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
@@ -484,7 +486,7 @@ struct atmel_private {
        u8 group_cipher_suite, pairwise_cipher_suite;
        u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
        int wep_key_len[MAX_ENCRYPTION_KEYS]; 
-       int use_wpa;
+       int use_wpa, radio_on_broken; /* firmware dependent stuff. */
 
        u16 host_info_base;
        struct host_info_struct { 
@@ -1386,7 +1388,7 @@ static int atmel_read_proc(char *page, char **start, off_t off,
         return len;
 }
 
-struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware_id, int is3com,  
+struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware_id,  
                                    struct device *sys_dev, int (*card_present)(void *), void *card)
 {
        struct net_device *dev;
@@ -1418,7 +1420,6 @@ struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware
                strcpy(priv->firmware_template, firmware_id);
        priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
        priv->station_state = STATION_STATE_DOWN;
-       priv->is3com = is3com;
        priv->do_rx_crc = 0;
        /* For PCMCIA cards, some chips need CRC, some don't
           so we have to probe. */
@@ -1525,16 +1526,15 @@ EXPORT_SYMBOL(init_atmel_card);
 void stop_atmel_card(struct net_device *dev, int freeres)
 {
        struct atmel_private *priv = dev->priv;
-       unregister_netdev(dev);
-       
+               
        /* put a brick on it... */
-
        if (priv->bus_type == BUS_TYPE_PCCARD) 
                atmel_write16(dev, GCR, 0x0060);
        atmel_write16(dev, GCR, 0x0040);
-
-       remove_proc_entry("driver/atmel", NULL);
+       
        del_timer_sync(&priv->management_timer);
+       unregister_netdev(dev);
+       remove_proc_entry("driver/atmel", NULL);
        free_irq(dev->irq, dev);
        if (priv->firmware)
                kfree(priv->firmware);
@@ -1995,8 +1995,8 @@ static int atmel_set_freq(struct net_device *dev,
        
        /* If setting by frequency, convert to a channel */
        if((fwrq->e == 1) &&
-          (fwrq->m >= (int) 2.412e8) &&
-          (fwrq->m <= (int) 2.487e8)) {
+          (fwrq->m >= (int) 241200000) &&
+          (fwrq->m <= (int) 248700000)) {
                int f = fwrq->m / 100000;
                int c = 0;
                while((c < 14) && (f != frequency_list[c]))
@@ -3594,8 +3594,12 @@ int reset_atmel_card(struct net_device *dev)
                return 0;
 
        /* Check the version and set the correct flag for wpa stuff,
-          old and new firmware is incompatible. */
-       priv->use_wpa = (priv->host_info.major_version >= 4);
+          old and new firmware is incompatible.
+          The pre-wpa 3com firmware reports major version 5,
+          the wpa 3com firmware is major version 4 and doesn't need
+          the 3com broken-ness filter. */
+       priv->use_wpa = (priv->host_info.major_version == 4);
+       priv->radio_on_broken = (priv->host_info.major_version == 5);
        
         /* unmask all irq sources */
        atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
@@ -3640,7 +3644,7 @@ int reset_atmel_card(struct net_device *dev)
        if ((channel = atmel_validate_channel(priv, priv->channel)))
                priv->channel = channel;
        
-       if (!priv->is3com) {
+       if (!priv->radio_on_broken) {
                if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == 
                    CMD_STATUS_REJECTED_RADIO_OFF) {
                        printk(KERN_INFO 
@@ -3854,7 +3858,6 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
        atmel_write16(priv->dev, DR, data >> 16);
 }
 
-
 /***************************************************************************/
 /* There follows the source form of the MAC address reading firmware       */
 /***************************************************************************/
index 468ef41..71b19e3 100644 (file)
@@ -101,7 +101,7 @@ MODULE_PARM(irq_list, "1-4i");
    event handler. 
 */
 
-struct net_device *init_atmel_card(int, int, char *, int, struct device *, 
+struct net_device *init_atmel_card(int, int, char *, struct device *, 
                                    int (*present_func)(void *), void * );
 void stop_atmel_card( struct net_device *, int );
 int reset_atmel_card( struct net_device * );
@@ -332,15 +332,20 @@ static struct {
        { 0, 0, "ATMEL/AT76C502AR_D", "atmel_at76c502d%s.bin", "NoName-revD" }, 
        { 0, 0, "ATMEL/AT76C502AR_E", "atmel_at76c502e%s.bin", "NoName-revE" },
        { 0, 0, "ATMEL/AT76C504", "atmel_at76c504%s.bin", "NoName-504" },
+       { 0, 0, "ATMEL/AT76C504A", "atmel_at76c504a_2958%s.bin", "NoName-504a-2958" },
+       { 0, 0, "ATMEL/AT76C504_R", "atmel_at76c504_2958%s.bin", "NoName-504-2958" },
        { MANFID_3COM, 0x0620, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRWE62092B" }, 
        { MANFID_3COM, 0x0696, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRSHPW_96" }, 
        { 0, 0, "SMC/2632W-V2", "atmel_at76c502%s.bin", "SMC 2632W-V2" },
         { 0, 0, "SMC/2632W", "atmel_at76c502d%s.bin", "SMC 2632W-V3" },
-       { 0xd601, 0x0007, NULL, "atmel_at76c502%s.bin", "Sitecom WLAN-011"}, /* suspect - from a usenet posting. */
-       { 0x01bf, 0x3302, NULL, "atmel_at76c502d%s.bin", "Belkin F5D6060u"},  /*    "        "  "    "      "     */
-       { 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502%s.bin", "BT Voyager 1020"},
+       { 0xd601, 0x0007, NULL, "atmel_at76c502%s.bin", "Sitecom WLAN-011" }, 
+       { 0x01bf, 0x3302, NULL, "atmel_at76c502e%s.bin", "Belkin F5D6020-V2" }, 
+       { 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502%s.bin", "BT Voyager 1020" },
         { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", "atmel_at76c502%s.bin", "Siemens Gigaset PC Card II" },
-       { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", "atmel_at76c502e%s.bin", "CNet CNWLC-811ARL" }
+       { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", "atmel_at76c502e%s.bin", "CNet CNWLC-811ARL" },
+       { 0, 0, "Wireless/PC_CARD", "atmel_at76c502d%s.bin", "Planet WL-3552" },
+       { 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", "atmel_at76c502%s.bin", "OEM 11Mbps WLAN PCMCIA Card" },
+       { 0, 0, "11WAVE/11WP611AL-E", "atmel_at76c502e%s.bin", "11WAVE WaveBuddy" } 
 };
 
 /* This is strictly temporary, until PCMCIA devices get integrated into the device model. */
@@ -538,7 +543,6 @@ static void atmel_config(dev_link_t *link)
                init_atmel_card(link->irq.AssignedIRQ,
                                link->io.BasePort1,
                                card_index == -1 ? NULL :  card_table[card_index].firmware,
-                               card_index == -1 ? 0 : (card_table[card_index].manf == MANFID_3COM),
                                &atmel_device,
                                card_present, 
                                link);
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
new file mode 100644 (file)
index 0000000..a7fe4d5
--- /dev/null
@@ -0,0 +1,91 @@
+/*** -*- linux-c -*- **********************************************************
+
+     Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
+
+         Copyright 2004 Simon Kelley.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This software is distributed in the hope that 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 Atmel wireless lan drivers; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+******************************************************************************/
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+
+MODULE_AUTHOR("Simon Kelley");
+MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("Atmel at76c506 PCI wireless cards");
+
+static struct pci_device_id card_ids[] = {
+       { 0x1114, 0x0506, PCI_ANY_ID, PCI_ANY_ID },
+       { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, card_ids);
+
+static int atmel_pci_probe(struct pci_dev *, const struct pci_device_id *);
+static void atmel_pci_remove(struct pci_dev *);
+struct net_device *init_atmel_card(int, int, char *, struct device *, 
+                                  int (*present_func)(void *), void * );
+void stop_atmel_card( struct net_device *, int );
+
+static struct pci_driver atmel_driver = {
+       .name     = "atmel",
+       .id_table = card_ids,
+       .probe    = atmel_pci_probe,
+       .remove   = __devexit_p(atmel_pci_remove),
+};
+
+
+static int __devinit atmel_pci_probe(struct pci_dev *pdev,
+                                    const struct pci_device_id *pent)
+{
+       struct net_device *dev;
+               
+       if (pci_enable_device(pdev))
+               return -ENODEV;
+       
+       pci_set_master(pdev);
+       
+       dev = init_atmel_card(pdev->irq, pdev->resource[1].start, 
+                             "atmel_at76c506%s.bin",
+                             &pdev->dev, NULL, NULL);
+       if (!dev)
+               return -ENODEV;
+       
+       pci_set_drvdata(pdev, dev);
+       return 0;
+}
+
+static void __devexit atmel_pci_remove(struct pci_dev *pdev)
+{
+       stop_atmel_card(pci_get_drvdata(pdev), 1);
+}
+
+static int __init atmel_init_module(void)
+{
+       return pci_module_init(&atmel_driver);
+}
+
+static void __exit atmel_cleanup_module(void)
+{
+       pci_unregister_driver(&atmel_driver);
+}
+
+module_init(atmel_init_module);
+module_exit(atmel_cleanup_module);
index 85f642b..625c15c 100644 (file)
@@ -261,7 +261,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
                if (dev->irq)
                        free_irq(dev->irq, dev);
 
-               kfree(dev);
+               free_netdev(dev);
        }
 
        if (pci_ioaddr)
index bc3b5d6..6a42fa1 100644 (file)
@@ -263,7 +263,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
                if (dev->irq)
                        free_irq(dev->irq, dev);
                
-               kfree(dev);
+               free_netdev(dev);
        }
 
        if (pccard_ioaddr)
index 7b551fb..725e4b5 100644 (file)
@@ -157,7 +157,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
                if (dev->irq)
                        free_irq(dev->irq, dev);
                
-               kfree(dev);
+               free_netdev(dev);
        }
 
        if (pccard_ioaddr)
index aaf15d3..82b049d 100644 (file)
@@ -344,19 +344,14 @@ static dev_link_t *ray_attach(void)
            return NULL;
 
     /* Allocate space for private device-specific data */
-    dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+    dev = alloc_etherdev(sizeof(ray_dev_t));
 
     if (!dev)
            goto fail_alloc_dev;
 
-    local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL);
-
-    if (!local)
-           goto fail_alloc_local;
+    local = dev->priv;
 
     memset(link, 0, sizeof(struct dev_link_t));
-    memset(dev, 0, sizeof(struct net_device));
-    memset(local, 0, sizeof(ray_dev_t));
 
     /* The io structure describes IO port mapping. None used here */
     link->io.NumPorts1 = 0;
@@ -379,7 +374,6 @@ static dev_link_t *ray_attach(void)
     link->priv = dev;
     link->irq.Instance = dev;
     
-    dev->priv = local;
     local->finder = link;
     local->card_status = CARD_INSERTED;
     local->authentication_state = UNAUTHENTICATED;
@@ -401,7 +395,6 @@ static dev_link_t *ray_attach(void)
 
     DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
     SET_MODULE_OWNER(dev);
-    ether_setup(dev);
     dev->init = &ray_dev_init;
     dev->open = &ray_open;
     dev->stop = &ray_dev_close;
@@ -434,8 +427,6 @@ static dev_link_t *ray_attach(void)
     DEBUG(2,"ray_cs ray_attach ending\n");
     return link;
 
-fail_alloc_local:
-    kfree(dev);
 fail_alloc_dev:
     kfree(link);
     return NULL;
@@ -478,9 +469,7 @@ static void ray_detach(dev_link_t *link)
     if (link->priv) {
         struct net_device *dev = link->priv;
        if (link->dev) unregister_netdev(dev);
-        if (dev->priv)
-            kfree(dev->priv);
-        kfree(link->priv);
+        free_netdev(dev);
     }
     kfree(link);
     DEBUG(2,"ray_cs ray_detach ending\n");
index 57463d8..711de79 100644 (file)
@@ -2564,7 +2564,7 @@ static void strip_free(struct strip *strip_info)
 
        strip_info->magic = 0;
 
-       kfree(strip_info->dev);
+       free_netdev(strip_info->dev);
 }
 
 
index 6751898..1cbd34b 100644 (file)
@@ -153,7 +153,7 @@ static inline void wv_16_on(unsigned long ioaddr, u16 hacr)
  * Disable interrupts on the WaveLAN hardware.
  * (called by wv_82586_stop())
  */
-static inline void wv_ints_off(device * dev)
+static inline void wv_ints_off(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -167,7 +167,7 @@ static inline void wv_ints_off(device * dev)
  * Enable interrupts on the WaveLAN hardware.
  * (called by wv_hw_reset())
  */
-static inline void wv_ints_on(device * dev)
+static inline void wv_ints_on(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -268,7 +268,7 @@ static inline u16 psa_crc(u8 * psa, /* The PSA */
 /*
  * update the checksum field in the Wavelan's PSA
  */
-static void update_psa_checksum(device * dev, unsigned long ioaddr, u16 hacr)
+static void update_psa_checksum(struct net_device * dev, unsigned long ioaddr, u16 hacr)
 {
 #ifdef SET_PSA_CRC
        psa_t psa;
@@ -547,7 +547,7 @@ static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n)
 /*
  * Acknowledge the reading of the status issued by the i82586.
  */
-static void wv_ack(device * dev)
+static void wv_ack(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -589,7 +589,7 @@ static void wv_ack(device * dev)
  * Set channel attention bit and busy wait until command has
  * completed, then acknowledge completion of the command.
  */
-static inline int wv_synchronous_cmd(device * dev, const char *str)
+static inline int wv_synchronous_cmd(struct net_device * dev, const char *str)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -636,7 +636,7 @@ static inline int wv_synchronous_cmd(device * dev, const char *str)
  * Check if done, and if OK.
  */
 static inline int
-wv_config_complete(device * dev, unsigned long ioaddr, net_local * lp)
+wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
 {
        unsigned short mcs_addr;
        unsigned short status;
@@ -703,7 +703,7 @@ wv_config_complete(device * dev, unsigned long ioaddr, net_local * lp)
  * (called in wavelan_interrupt()).
  * Note : the spinlock is already grabbed for us.
  */
-static int wv_complete(device * dev, unsigned long ioaddr, net_local * lp)
+static int wv_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
 {
        int nreaped = 0;
 
@@ -845,7 +845,7 @@ if (lp->tx_n_in_use > 0)
  * wavelan_interrupt is not an option), so you may experience
  * delays sometimes.
  */
-static inline void wv_82586_reconfig(device * dev)
+static inline void wv_82586_reconfig(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long flags;
@@ -954,7 +954,7 @@ static void wv_psa_show(psa_t * p)
  * Print the formatted status of the Modem Management Controller.
  * This function needs to be completed.
  */
-static void wv_mmc_show(device * dev)
+static void wv_mmc_show(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
        net_local *lp = (net_local *) dev->priv;
@@ -1137,7 +1137,7 @@ static void wv_scb_show(unsigned long ioaddr)
 /*
  * Print the formatted status of the i82586's receive unit.
  */
-static void wv_ru_show(device * dev)
+static void wv_ru_show(struct net_device * dev)
 {
        /* net_local *lp = (net_local *) dev->priv; */
 
@@ -1154,7 +1154,7 @@ static void wv_ru_show(device * dev)
 /*
  * Display info about one control block of the i82586 memory.
  */
-static void wv_cu_show_one(device * dev, net_local * lp, int i, u16 p)
+static void wv_cu_show_one(struct net_device * dev, net_local * lp, int i, u16 p)
 {
        unsigned long ioaddr;
        ac_tx_t actx;
@@ -1183,7 +1183,7 @@ static void wv_cu_show_one(device * dev, net_local * lp, int i, u16 p)
 /*
  * Print status of the command unit of the i82586.
  */
-static void wv_cu_show(device * dev)
+static void wv_cu_show(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned int i;
@@ -1209,7 +1209,7 @@ static void wv_cu_show(device * dev)
 /*
  * Print the formatted status of the WaveLAN PCMCIA device driver.
  */
-static void wv_dev_show(device * dev)
+static void wv_dev_show(struct net_device * dev)
 {
        printk(KERN_DEBUG "dev:");
        printk(" state=%lX,", dev->state);
@@ -1223,7 +1223,7 @@ static void wv_dev_show(device * dev)
  * Print the formatted status of the WaveLAN PCMCIA device driver's
  * private information.
  */
-static void wv_local_show(device * dev)
+static void wv_local_show(struct net_device * dev)
 {
        net_local *lp;
 
@@ -1285,7 +1285,7 @@ static inline void wv_packet_info(u8 * p, /* Packet to dump */
  * This is the information which is displayed by the driver at startup.
  * There are lots of flags for configuring it to your liking.
  */
-static inline void wv_init_info(device * dev)
+static inline void wv_init_info(struct net_device * dev)
 {
        short ioaddr = dev->base_addr;
        net_local *lp = (net_local *) dev->priv;
@@ -1395,7 +1395,7 @@ static inline void wv_init_info(device * dev)
  * card open or closed.
  * Used when the user read /proc/net/dev
  */
-static en_stats *wavelan_get_stats(device * dev)
+static en_stats *wavelan_get_stats(struct net_device * dev)
 {
 #ifdef DEBUG_IOCTL_TRACE
        printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
@@ -1412,7 +1412,7 @@ static en_stats *wavelan_get_stats(device * dev)
  * num_addrs > 0       Multicast mode, receive normal and MC packets,
  *                     and do best-effort filtering.
  */
-static void wavelan_set_multicast_list(device * dev)
+static void wavelan_set_multicast_list(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
 
@@ -1485,7 +1485,7 @@ static void wavelan_set_multicast_list(device * dev)
  * (Note : it was a nice way to test the reconfigure stuff...)
  */
 #ifdef SET_MAC_ADDRESS
-static int wavelan_set_mac_address(device * dev, void *addr)
+static int wavelan_set_mac_address(struct net_device * dev, void *addr)
 {
        struct sockaddr *mac = addr;
 
@@ -1724,7 +1724,7 @@ static inline int wv_frequency_list(unsigned long ioaddr, /* I/O port of the car
  * address with our list, and if they match, get the statistics.
  * Sorry, but this function really needs the wireless extensions.
  */
-static inline void wl_spy_gather(device * dev,
+static inline void wl_spy_gather(struct net_device * dev,
                                 u8 *   mac,    /* MAC address */
                                 u8 *   stats)  /* Statistics to gather */
 {
@@ -1750,7 +1750,7 @@ static inline void wl_spy_gather(device * dev,
  * With this histogram you may detect if one WaveLAN is really weak,
  * or you may also calculate the mean and standard deviation of the level.
  */
-static inline void wl_his_gather(device * dev, u8 * stats)
+static inline void wl_his_gather(struct net_device * dev, u8 * stats)
 {                              /* Statistics to gather */
        net_local *lp = (net_local *) dev->priv;
        u8 level = stats[0] & MMR_SIGNAL_LVL;
@@ -2415,7 +2415,7 @@ static const struct iw_handler_def        wavelan_handler_def =
  * Get wireless statistics.
  * Called by /proc/net/wireless
  */
-static iw_stats *wavelan_get_wireless_stats(device * dev)
+static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
        net_local *lp = (net_local *) dev->priv;
@@ -2492,7 +2492,7 @@ static iw_stats *wavelan_get_wireless_stats(device * dev)
  * (called by wv_packet_rcv())
  */
 static inline void
-wv_packet_read(device * dev, u16 buf_off, int sksize)
+wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -2587,7 +2587,7 @@ wv_packet_read(device * dev, u16 buf_off, int sksize)
  * (called in wavelan_interrupt()).
  * Note : the spinlock is already grabbed for us.
  */
-static inline void wv_receive(device * dev)
+static inline void wv_receive(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
        net_local *lp = (net_local *) dev->priv;
@@ -2770,7 +2770,7 @@ static inline void wv_receive(device * dev)
  *
  * (called in wavelan_packet_xmit())
  */
-static inline int wv_packet_write(device * dev, void *buf, short length)
+static inline int wv_packet_write(struct net_device * dev, void *buf, short length)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -2901,7 +2901,7 @@ static inline int wv_packet_write(device * dev, void *buf, short length)
  * the packet.  We also prevent reentrance.  Then we call the function
  * to send the packet.
  */
-static int wavelan_packet_xmit(struct sk_buff *skb, device * dev)
+static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long flags;
@@ -2966,7 +2966,7 @@ static int wavelan_packet_xmit(struct sk_buff *skb, device * dev)
  * Routine to initialize the Modem Management Controller.
  * (called by wv_hw_reset())
  */
-static inline int wv_mmc_init(device * dev)
+static inline int wv_mmc_init(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
        net_local *lp = (net_local *) dev->priv;
@@ -3138,7 +3138,7 @@ static inline int wv_mmc_init(device * dev)
  * Start the receive unit.
  * (called by wv_hw_reset())
  */
-static inline int wv_ru_start(device * dev)
+static inline int wv_ru_start(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -3230,7 +3230,7 @@ static inline int wv_ru_start(device * dev)
  *
  * (called by wv_hw_reset())
  */
-static inline int wv_cu_start(device * dev)
+static inline int wv_cu_start(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -3331,7 +3331,7 @@ static inline int wv_cu_start(device * dev)
  *
  * (called by wv_hw_reset())
  */
-static inline int wv_82586_start(device * dev)
+static inline int wv_82586_start(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -3463,7 +3463,7 @@ static inline int wv_82586_start(device * dev)
  *
  * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit())
  */
-static void wv_82586_config(device * dev)
+static void wv_82586_config(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -3643,7 +3643,7 @@ static void wv_82586_config(device * dev)
  * WaveLAN controller (i82586).
  * (called by wavelan_close())
  */
-static inline void wv_82586_stop(device * dev)
+static inline void wv_82586_stop(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -3680,7 +3680,7 @@ static inline void wv_82586_stop(device * dev)
  *     5. Start the LAN controller's receive unit
  * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open())
  */
-static int wv_hw_reset(device * dev)
+static int wv_hw_reset(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long ioaddr = dev->base_addr;
@@ -3770,7 +3770,7 @@ static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac)
  */
 static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       device *dev;
+       struct net_device *dev;
        unsigned long ioaddr;
        net_local *lp;
        u16 hasr;
@@ -3923,7 +3923,7 @@ static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs
  * kernel.  If the transmission completes, this timer is disabled. If
  * the timer expires, we are called and we try to unlock the hardware.
  */
-static void wavelan_watchdog(device *  dev)
+static void wavelan_watchdog(struct net_device *       dev)
 {
        net_local *     lp = (net_local *)dev->priv;
        u_long          ioaddr = dev->base_addr;
@@ -4003,7 +4003,7 @@ static void wavelan_watchdog(device *     dev)
  * Configure and start up the WaveLAN PCMCIA adaptor.
  * Called by NET3 when it "opens" the device.
  */
-static int wavelan_open(device * dev)
+static int wavelan_open(struct net_device * dev)
 {
        net_local *     lp = (net_local *)dev->priv;
        unsigned long   flags;
@@ -4058,7 +4058,7 @@ static int wavelan_open(device * dev)
  * Shut down the WaveLAN ISA card.
  * Called by NET3 when it "closes" the device.
  */
-static int wavelan_close(device * dev)
+static int wavelan_close(struct net_device * dev)
 {
        net_local *lp = (net_local *) dev->priv;
        unsigned long flags;
@@ -4091,12 +4091,24 @@ static int wavelan_close(device * dev)
  * device structure
  * (called by wavelan_probe() and via init_module()).
  */
-static int __init wavelan_config(device * dev)
+static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
 {
-       unsigned long ioaddr = dev->base_addr;
        u8 irq_mask;
        int irq;
        net_local *lp;
+       mac_addr mac;
+       int err;
+
+       if (!request_region(ioaddr, sizeof(ha_t), "wavelan"))
+               return -EADDRINUSE;
+
+       err = wv_check_ioaddr(ioaddr, mac);
+       if (err)
+               goto out;
+
+       memcpy(dev->dev_addr, mac, 6);
+
+       dev->base_addr = ioaddr;
 
 #ifdef DEBUG_CALLBACK_TRACE
        printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n",
@@ -4136,25 +4148,18 @@ static int __init wavelan_config(device * dev)
                       "%s: wavelan_config(): could not wavelan_map_irq(%d).\n",
                       dev->name, irq_mask);
 #endif
-               return -EAGAIN;
+               err = -EAGAIN;
+               goto out;
        }
 
        dev->irq = irq;
 
-       if (!request_region(ioaddr, sizeof(ha_t), "wavelan"))
-               return -EBUSY;
-
        dev->mem_start = 0x0000;
        dev->mem_end = 0x0000;
        dev->if_port = 0;
 
        /* Initialize device structures */
-       dev->priv = kmalloc(sizeof(net_local), GFP_KERNEL);
-       if (dev->priv == NULL) {
-               release_region(ioaddr, sizeof(ha_t));
-               return -ENOMEM;
-       }
-       memset(dev->priv, 0x00, sizeof(net_local));
+       memset(dev->priv, 0, sizeof(net_local));
        lp = (net_local *) dev->priv;
 
        /* Back link to the device structure. */
@@ -4172,12 +4177,6 @@ static int __init wavelan_config(device * dev)
        /* Init spinlock */
        spin_lock_init(&lp->spinlock);
 
-       /*
-        * Fill in the fields of the device structure
-        * with generic Ethernet values.
-        */
-       ether_setup(dev);
-
        SET_MODULE_OWNER(dev);
        dev->open = wavelan_open;
        dev->stop = wavelan_close;
@@ -4204,6 +4203,9 @@ static int __init wavelan_config(device * dev)
        printk(KERN_DEBUG "%s: <-wavelan_config()\n", dev->name);
 #endif
        return 0;
+out:
+       release_region(ioaddr, sizeof(ha_t));
+       return err;
 }
 
 /*------------------------------------------------------------------*/
@@ -4214,19 +4216,13 @@ static int __init wavelan_config(device * dev)
  * We follow the example in drivers/net/ne.c.
  * (called in "Space.c")
  */
-int __init wavelan_probe(device * dev)
+struct net_device * __init wavelan_probe(int unit)
 {
+       struct net_device *dev;
        short base_addr;
-       mac_addr mac;           /* MAC address (check existence of WaveLAN) */
+       int def_irq;
        int i;
-       int r;
-
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG
-              "%s: ->wavelan_probe(dev=0x%x (base_addr=0x%x))\n",
-              dev->name, (unsigned int) dev,
-              (unsigned int) dev->base_addr);
-#endif
+       int r = 0;
 
 #ifdef STRUCT_CHECK
        if (wv_struct_check() != (char *) NULL) {
@@ -4237,8 +4233,20 @@ int __init wavelan_probe(device * dev)
        }
 #endif                         /* STRUCT_CHECK */
 
-       /* Check the value of the command line parameter for base address. */
+       dev = alloc_etherdev(sizeof(net_local));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
        base_addr = dev->base_addr;
+       def_irq = dev->irq;
+
+#ifdef DEBUG_CALLBACK_TRACE
+       printk(KERN_DEBUG
+              "%s: ->wavelan_probe(dev=%p (base_addr=0x%x))\n",
+              dev->name, dev, (unsigned int) dev->base_addr);
+#endif
 
        /* Don't probe at all. */
        if (base_addr < 0) {
@@ -4247,16 +4255,9 @@ int __init wavelan_probe(device * dev)
                       "%s: wavelan_probe(): invalid base address\n",
                       dev->name);
 #endif
-               return -ENXIO;
-       }
-
-       /* Check a single specified location. */
-       if (base_addr > 0x100) {
-               /* Check if there is something at this base address */
-               if ((r = wv_check_ioaddr(base_addr, mac)) == 0) {
-                       memcpy(dev->dev_addr, mac, 6);  /* Copy MAC address. */
-                       r = wavelan_config(dev);
-               }
+               r = -ENXIO;
+       } else if (base_addr > 0x100) { /* Check a single specified location. */
+               r = wavelan_config(dev, base_addr);
 #ifdef DEBUG_CONFIG_INFO
                if (r != 0)
                        printk(KERN_DEBUG
@@ -4267,35 +4268,33 @@ int __init wavelan_probe(device * dev)
 #ifdef DEBUG_CALLBACK_TRACE
                printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name);
 #endif
-               return r;
-       }
-
-       /* Scan all possible addresses of the WaveLAN hardware. */
-       for (i = 0; i < NELS(iobase); i++) {
-               /* Check whether there is something at this base address. */
-               if (wv_check_ioaddr(iobase[i], mac) == 0) {
-                       dev->base_addr = iobase[i];     /* Copy base address. */
-                       memcpy(dev->dev_addr, mac, 6);  /* Copy MAC address. */
-                       if (wavelan_config(dev) == 0) {
+       } else { /* Scan all possible addresses of the WaveLAN hardware. */
+               for (i = 0; i < NELS(iobase); i++) {
+                       dev->irq = def_irq;
+                       if (wavelan_config(dev, iobase[i]) == 0) {
 #ifdef DEBUG_CALLBACK_TRACE
                                printk(KERN_DEBUG
                                       "%s: <-wavelan_probe()\n",
                                       dev->name);
 #endif
-                               return 0;
+                               break;
                        }
                }
+               if (i == NELS(iobase))
+                       r = -ENODEV;
        }
-
-       /* We may have touched base_addr.  Another driver may not like it. */
-       dev->base_addr = base_addr;
-
-#ifdef DEBUG_CONFIG_INFO
-       printk(KERN_DEBUG "%s: wavelan_probe(): no device found\n",
-              dev->name);
-#endif
-
-       return -ENODEV;
+       if (r) 
+               goto out;
+       r = register_netdev(dev);
+       if (r)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, sizeof(ha_t));
+       wavelan_list = wavelan_list->next;
+out:
+       free_netdev(dev);
+       return ERR_PTR(r);
 }
 
 /****************************** MODULE ******************************/
@@ -4311,7 +4310,6 @@ int __init wavelan_probe(device * dev)
  */
 int init_module(void)
 {
-       mac_addr mac;           /* MAC address (check WaveLAN existence) */
        int ret = -EIO;         /* Return error if no cards found */
        int i;
 
@@ -4337,38 +4335,28 @@ int init_module(void)
        /* Loop on all possible base addresses. */
        i = -1;
        while ((io[++i] != 0) && (i < NELS(io))) {
+               struct net_device *dev = alloc_etherdev(sizeof(net_local));
+               if (!dev)
+                       break;
+               memcpy(dev->name, name[i], IFNAMSIZ);   /* Copy name */
+               dev->base_addr = io[i];
+               dev->irq = irq[i];
+
                /* Check if there is something at this base address. */
-               if (wv_check_ioaddr(io[i], mac) == 0) {
-                       device *dev;
-
-                       /* Create device and set basic arguments. */
-                       dev =
-                           kmalloc(sizeof(struct net_device), GFP_KERNEL);
-                       if (dev == NULL) {
-                               ret = -ENOMEM;
-                               break;
-                       }
-                       memset(dev, 0x00, sizeof(struct net_device));
-                       memcpy(dev->name, name[i], IFNAMSIZ);   /* Copy name */
-                       dev->base_addr = io[i];
-                       dev->irq = irq[i];
-                       dev->init = &wavelan_config;
-                       memcpy(dev->dev_addr, mac, 6);  /* Copy MAC address. */
-
-                       /* Try to create the device. */
+               if (wavelan_config(dev, io[i]) == 0) {
                        if (register_netdev(dev) != 0) {
-                               /* Deallocate everything. */
-                               /* Note: if dev->priv is mallocated, there is no way to fail. */
-                               kfree(dev);
+                               release_region(dev->base_addr, sizeof(ha_t));
+                               wavelan_list = wavelan_list->next;
                        } else {
-                               /* If at least one device OK, we do not fail */
                                ret = 0;
+                               continue;
                        }
-               }               /* if there is something at the address */
-       }                       /* Loop on all addresses. */
+               }
+               free_netdev(dev);
+       }
 
 #ifdef DEBUG_CONFIG_ERROR
-       if (wavelan_list == (net_local *) NULL)
+       if (!wavelan_list)
                printk(KERN_WARNING
                       "WaveLAN init_module(): no device found\n");
 #endif
@@ -4390,26 +4378,19 @@ void cleanup_module(void)
 #endif
 
        /* Loop on all devices and release them. */
-       while (wavelan_list != (net_local *) NULL) {
-               device *dev = wavelan_list->dev;
+       while (wavelan_list) {
+               struct net_device *dev = wavelan_list->dev;
 
 #ifdef DEBUG_CONFIG_INFO
                printk(KERN_DEBUG
                       "%s: cleanup_module(): removing device at 0x%x\n",
                       dev->name, (unsigned int) dev);
 #endif
-
-               /* Release the ioport region. */
-               release_region(dev->base_addr, sizeof(ha_t));
-
-               /* Definitely remove the device. */
                unregister_netdev(dev);
 
-               /* Unlink the device. */
+               release_region(dev->base_addr, sizeof(ha_t));
                wavelan_list = wavelan_list->next;
 
-               /* Free pieces. */
-               kfree(dev->priv);
                free_netdev(dev);
        }
 
index 11a8013..d35ac4d 100644 (file)
@@ -469,7 +469,6 @@ static const char   *version        = "wavelan.c : v24 (SMP + wireless extensions) 11/12/
 /****************************** TYPES ******************************/
 
 /* Shortcuts */
-typedef struct net_device              device;
 typedef struct net_device_stats        en_stats;
 typedef struct iw_statistics   iw_stats;
 typedef struct iw_quality      iw_qual;
@@ -492,7 +491,7 @@ typedef u_char              mac_addr[WAVELAN_ADDR_SIZE];    /* Hardware address */
 struct net_local
 {
   net_local *  next;           /* linked list of the devices */
-  device *     dev;            /* reverse link */
+  struct net_device *  dev;            /* reverse link */
   spinlock_t   spinlock;       /* Serialize access to the hardware (SMP) */
   en_stats     stats;          /* Ethernet interface statistics */
   int          nresets;        /* number of hardware resets */
@@ -542,8 +541,8 @@ static inline void
                  u_short),     /* hacr   */
        wv_16_on(u_long,        /* ioaddr */
                 u_short),      /* hacr   */
-       wv_ints_off(device *),
-       wv_ints_on(device *);
+       wv_ints_off(struct net_device *),
+       wv_ints_on(struct net_device *);
 /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
 static void
        psa_read(u_long,        /* Read the Parameter Storage Area. */
@@ -592,57 +591,57 @@ static inline void
                    u_char *,   /* b */
                    int);       /* n */
 static void
-       wv_ack(device *);
+       wv_ack(struct net_device *);
 static inline int
-       wv_synchronous_cmd(device *,
+       wv_synchronous_cmd(struct net_device *,
                           const char *),
-       wv_config_complete(device *,
+       wv_config_complete(struct net_device *,
                           u_long,
                           net_local *);
 static int
-       wv_complete(device *,
+       wv_complete(struct net_device *,
                    u_long,
                    net_local *);
 static inline void
-       wv_82586_reconfig(device *);
+       wv_82586_reconfig(struct net_device *);
 /* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
 #ifdef DEBUG_I82586_SHOW
 static void
        wv_scb_show(unsigned short);
 #endif
 static inline void
-       wv_init_info(device *); /* display startup info */
+       wv_init_info(struct net_device *);      /* display startup info */
 /* ------------------- IOCTL, STATS & RECONFIG ------------------- */
 static en_stats        *
-       wavelan_get_stats(device *);    /* Give stats /proc/net/dev */
+       wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
 static void
-       wavelan_set_multicast_list(device *);
+       wavelan_set_multicast_list(struct net_device *);
 /* ----------------------- PACKET RECEPTION ----------------------- */
 static inline void
-       wv_packet_read(device *,        /* Read a packet from a frame. */
+       wv_packet_read(struct net_device *,     /* Read a packet from a frame. */
                       u_short,
                       int),
-       wv_receive(device *);   /* Read all packets waiting. */
+       wv_receive(struct net_device *);        /* Read all packets waiting. */
 /* --------------------- PACKET TRANSMISSION --------------------- */
 static inline int
-       wv_packet_write(device *,       /* Write a packet to the Tx buffer. */
+       wv_packet_write(struct net_device *,    /* Write a packet to the Tx buffer. */
                        void *,
                        short);
 static int
        wavelan_packet_xmit(struct sk_buff *,   /* Send a packet. */
-                           device *);
+                           struct net_device *);
 /* -------------------- HARDWARE CONFIGURATION -------------------- */
 static inline int
-       wv_mmc_init(device *),          /* Initialize the modem. */
-       wv_ru_start(device *),          /* Start the i82586 receiver unit. */
-       wv_cu_start(device *),          /* Start the i82586 command unit. */
-       wv_82586_start(device *);       /* Start the i82586. */
+       wv_mmc_init(struct net_device *),       /* Initialize the modem. */
+       wv_ru_start(struct net_device *),       /* Start the i82586 receiver unit. */
+       wv_cu_start(struct net_device *),       /* Start the i82586 command unit. */
+       wv_82586_start(struct net_device *);    /* Start the i82586. */
 static void
-       wv_82586_config(device *);      /* Configure the i82586. */
+       wv_82586_config(struct net_device *);   /* Configure the i82586. */
 static inline void
-       wv_82586_stop(device *);
+       wv_82586_stop(struct net_device *);
 static int
-       wv_hw_reset(device *),          /* Reset the WaveLAN hardware. */
+       wv_hw_reset(struct net_device *),       /* Reset the WaveLAN hardware. */
        wv_check_ioaddr(u_long,         /* ioaddr */
                        u_char *);      /* mac address (read) */
 /* ---------------------- INTERRUPT HANDLING ---------------------- */
@@ -651,14 +650,13 @@ static irqreturn_t
                          void *,
                          struct pt_regs *);
 static void
-       wavelan_watchdog(device *);     /* transmission watchdog */
+       wavelan_watchdog(struct net_device *);  /* transmission watchdog */
 /* ------------------- CONFIGURATION CALLBACKS ------------------- */
 static int
-       wavelan_open(device *),         /* Open the device. */
-       wavelan_close(device *),        /* Close the device. */
-       wavelan_config(device *);       /* Configure one device. */
-extern int
-       wavelan_probe(device *);        /* See Space.c. */
+       wavelan_open(struct net_device *),      /* Open the device. */
+       wavelan_close(struct net_device *),     /* Close the device. */
+       wavelan_config(struct net_device *, unsigned short);/* Configure one device. */
+extern struct net_device *wavelan_probe(int unit);     /* See Space.c. */
 
 /**************************** VARIABLES ****************************/
 
index 17b930b..52dc265 100644 (file)
@@ -131,7 +131,7 @@ hacr_write_slow(u_long      base,
  * Read the Parameter Storage Area from the WaveLAN card's memory
  */
 static void
-psa_read(device *      dev,
+psa_read(struct net_device *   dev,
         int            o,      /* offset in PSA */
         u_char *       b,      /* buffer to fill */
         int            n)      /* size to read */
@@ -155,7 +155,7 @@ psa_read(device *   dev,
  * Write the Paramter Storage Area to the WaveLAN card's memory
  */
 static void
-psa_write(device *     dev,
+psa_write(struct net_device *  dev,
          int           o,      /* Offset in psa */
          u_char *      b,      /* Buffer in memory */
          int           n)      /* Length of buffer */
@@ -229,7 +229,7 @@ psa_crc(unsigned char *     psa,    /* The PSA */
  * update the checksum field in the Wavelan's PSA
  */
 static void
-update_psa_checksum(device *   dev)
+update_psa_checksum(struct net_device *        dev)
 {
 #ifdef SET_PSA_CRC
   psa_t                psa;
@@ -753,7 +753,7 @@ void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
 }
 
 /* Called when a WavePoint beacon is received */
-static inline void wl_roam_gather(device *  dev,
+static inline void wl_roam_gather(struct net_device *  dev,
                                  u_char *  hdr,   /* Beacon header */
                                  u_char *  stats) /* SNR, Signal quality 
                                                      of packet */
@@ -831,7 +831,7 @@ static inline int WAVELAN_BEACON(unsigned char *data)
  *  wv_82593_config() & wv_diag())
  */
 static int
-wv_82593_cmd(device *  dev,
+wv_82593_cmd(struct net_device *       dev,
             char *     str,
             int        cmd,
             int        result)
@@ -942,7 +942,7 @@ wv_82593_cmd(device *       dev,
  * status for the WaveLAN.
  */
 static inline int
-wv_diag(device *       dev)
+wv_diag(struct net_device *    dev)
 {
   int          ret = FALSE;
 
@@ -963,7 +963,7 @@ wv_diag(device *    dev)
  * The return value is the address to use for next the call.
  */
 static int
-read_ringbuf(device *  dev,
+read_ringbuf(struct net_device *       dev,
             int        addr,
             char *     buf,
             int        len)
@@ -1004,10 +1004,10 @@ read_ringbuf(device *   dev,
  * some delay sometime...
  */
 static inline void
-wv_82593_reconfig(device *     dev)
+wv_82593_reconfig(struct net_device *  dev)
 {
   net_local *          lp = (net_local *)dev->priv;
-  dev_link_t *         link = ((net_local *) dev->priv)->link;
+  dev_link_t *         link = lp->link;
   unsigned long                flags;
 
   /* Arm the flag, will be cleard in wv_82593_config() */
@@ -1132,7 +1132,7 @@ wv_psa_show(psa_t *       p)
  * This function need to be completed...
  */
 static void
-wv_mmc_show(device *   dev)
+wv_mmc_show(struct net_device *        dev)
 {
   ioaddr_t     base = dev->base_addr;
   net_local *  lp = (net_local *)dev->priv;
@@ -1222,7 +1222,7 @@ wv_mmc_show(device *      dev)
  * Print the formatted status of the i82593's receive unit.
  */
 static void
-wv_ru_show(device *    dev)
+wv_ru_show(struct net_device * dev)
 {
   net_local *lp = (net_local *) dev->priv;
 
@@ -1241,7 +1241,7 @@ wv_ru_show(device *       dev)
  * Print the formatted status of the WaveLAN PCMCIA device driver.
  */
 static void
-wv_dev_show(device *   dev)
+wv_dev_show(struct net_device *        dev)
 {
   printk(KERN_DEBUG "dev:");
   printk(" state=%lX,", dev->state);
@@ -1256,7 +1256,7 @@ wv_dev_show(device *      dev)
  * private information.
  */
 static void
-wv_local_show(device * dev)
+wv_local_show(struct net_device *      dev)
 {
   net_local *lp;
 
@@ -1314,7 +1314,7 @@ wv_packet_info(u_char *           p,              /* Packet to dump */
  * There  is a lot of flag to configure it at your will...
  */
 static inline void
-wv_init_info(device *  dev)
+wv_init_info(struct net_device *       dev)
 {
   ioaddr_t     base = dev->base_addr;
   psa_t                psa;
@@ -1412,7 +1412,7 @@ wv_init_info(device *     dev)
  * Used when the user read /proc/net/dev
  */
 static en_stats        *
-wavelan_get_stats(device *     dev)
+wavelan_get_stats(struct net_device *  dev)
 {
 #ifdef DEBUG_IOCTL_TRACE
   printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
@@ -1431,7 +1431,7 @@ wavelan_get_stats(device *        dev)
  */
 
 static void
-wavelan_set_multicast_list(device *    dev)
+wavelan_set_multicast_list(struct net_device * dev)
 {
   net_local *  lp = (net_local *) dev->priv;
 
@@ -1529,7 +1529,7 @@ wavelan_set_multicast_list(device *       dev)
  */
 #ifdef SET_MAC_ADDRESS
 static int
-wavelan_set_mac_address(device *       dev,
+wavelan_set_mac_address(struct net_device *    dev,
                        void *          addr)
 {
   struct sockaddr *    mac = addr;
@@ -1796,7 +1796,7 @@ wv_frequency_list(u_long  base,   /* i/o port of the card */
  * Sorry, but this function really need wireless extensions...
  */
 static inline void
-wl_spy_gather(device * dev,
+wl_spy_gather(struct net_device *      dev,
              u_char *  mac,            /* MAC address */
              u_char *  stats)          /* Statistics to gather */
 {
@@ -1823,7 +1823,7 @@ wl_spy_gather(device *    dev,
  * or you may also calculate the mean and standard deviation of the level...
  */
 static inline void
-wl_his_gather(device * dev,
+wl_his_gather(struct net_device *      dev,
              u_char *  stats)          /* Statistics to gather */
 {
   net_local *  lp = (net_local *) dev->priv;
@@ -2785,7 +2785,7 @@ wavelan_ioctl(struct net_device * dev,    /* Device on wich the ioctl apply */
  * Called by /proc/net/wireless...
  */
 static iw_stats *
-wavelan_get_wireless_stats(device *    dev)
+wavelan_get_wireless_stats(struct net_device * dev)
 {
   ioaddr_t             base = dev->base_addr;
   net_local *          lp = (net_local *) dev->priv;
@@ -2847,7 +2847,7 @@ wavelan_get_wireless_stats(device *       dev)
  * (called by wv_packet_rcv())
  */
 static inline int
-wv_start_of_frame(device *     dev,
+wv_start_of_frame(struct net_device *  dev,
                  int           rfp,    /* end of frame */
                  int           wrap)   /* start of buffer */
 {
@@ -2909,7 +2909,7 @@ wv_start_of_frame(device *        dev,
  * (called by wv_packet_rcv())
  */
 static inline void
-wv_packet_read(device *                dev,
+wv_packet_read(struct net_device *             dev,
               int              fd_p,
               int              sksize)
 {
@@ -3012,7 +3012,7 @@ wv_packet_read(device *           dev,
  * Note : the spinlock is already grabbed for us and irq are disabled.
  */
 static inline void
-wv_packet_rcv(device * dev)
+wv_packet_rcv(struct net_device *      dev)
 {
   ioaddr_t     base = dev->base_addr;
   net_local *  lp = (net_local *) dev->priv;
@@ -3146,7 +3146,7 @@ wv_packet_rcv(device *    dev)
  * (called in wavelan_packet_xmit())
  */
 static inline void
-wv_packet_write(device *       dev,
+wv_packet_write(struct net_device *    dev,
                void *          buf,
                short           length)
 {
@@ -3209,7 +3209,7 @@ wv_packet_write(device *  dev,
  */
 static int
 wavelan_packet_xmit(struct sk_buff *   skb,
-                   device *            dev)
+                   struct net_device *         dev)
 {
   net_local *          lp = (net_local *)dev->priv;
   unsigned long                flags;
@@ -3273,7 +3273,7 @@ wavelan_packet_xmit(struct sk_buff *      skb,
  * (called by wv_hw_config())
  */
 static inline int
-wv_mmc_init(device *   dev)
+wv_mmc_init(struct net_device *        dev)
 {
   ioaddr_t     base = dev->base_addr;
   psa_t                psa;
@@ -3467,7 +3467,7 @@ wv_mmc_init(device *      dev)
  * (called in wv_ru_start() and wavelan_close() and wavelan_event())
  */
 static int
-wv_ru_stop(device *    dev)
+wv_ru_stop(struct net_device * dev)
 {
   ioaddr_t     base = dev->base_addr;
   net_local *  lp = (net_local *) dev->priv;
@@ -3530,7 +3530,7 @@ wv_ru_stop(device *       dev)
  * (called in wv_hw_reset() & wavelan_open())
  */
 static int
-wv_ru_start(device *   dev)
+wv_ru_start(struct net_device *        dev)
 {
   ioaddr_t     base = dev->base_addr;
   net_local *  lp = (net_local *) dev->priv;
@@ -3618,7 +3618,7 @@ wv_ru_start(device *      dev)
  * (called by wv_hw_config(), wv_82593_reconfig() & wavelan_packet_xmit())
  */
 static int
-wv_82593_config(device *       dev)
+wv_82593_config(struct net_device *    dev)
 {
   ioaddr_t                     base = dev->base_addr;
   net_local *                  lp = (net_local *) dev->priv;
@@ -3792,7 +3792,7 @@ wv_82593_config(device *  dev)
  * (called by wv_config())
  */
 static inline int
-wv_pcmcia_reset(device *       dev)
+wv_pcmcia_reset(struct net_device *    dev)
 {
   int          i;
   conf_reg_t   reg = { 0, CS_READ, CISREG_COR, 0 };
@@ -3854,7 +3854,7 @@ wv_pcmcia_reset(device *  dev)
  * (called by wavelan_event() & wv_hw_reset())
  */
 static int
-wv_hw_config(device *  dev)
+wv_hw_config(struct net_device *       dev)
 {
   net_local *          lp = (net_local *) dev->priv;
   ioaddr_t             base = dev->base_addr;
@@ -3961,7 +3961,7 @@ wv_hw_config(device *     dev)
  * (called by wavelan_event(), wavelan_watchdog() and wavelan_open())
  */
 static inline void
-wv_hw_reset(device *   dev)
+wv_hw_reset(struct net_device *        dev)
 {
   net_local *  lp = (net_local *) dev->priv;
 
@@ -4004,7 +4004,7 @@ wv_pcmcia_config(dev_link_t *     link)
   memreq_t             mem;
 
   handle = link->handle;
-  dev = (device *) link->priv;
+  dev = (struct net_device *) link->priv;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
@@ -4149,7 +4149,7 @@ wv_pcmcia_config(dev_link_t *     link)
 static void
 wv_pcmcia_release(dev_link_t *link)
 {
-  device *     dev = (device *) link->priv;
+  struct net_device *  dev = (struct net_device *) link->priv;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
@@ -4199,13 +4199,13 @@ wavelan_interrupt(int           irq,
                  void *        dev_id,
                  struct pt_regs * regs)
 {
-  device *     dev;
+  struct net_device *  dev;
   net_local *  lp;
   ioaddr_t     base;
   int          status0;
   u_int                tx_status;
 
-  if((dev = (device *)dev_id) == (device *) NULL)
+  if ((dev = dev_id) == NULL)
     {
 #ifdef DEBUG_INTERRUPT_ERROR
       printk(KERN_WARNING "wavelan_interrupt(): irq %d for unknown device.\n",
@@ -4466,7 +4466,7 @@ wavelan_interrupt(int             irq,
  * deal with the multiple Tx buffers...
  */
 static void
-wavelan_watchdog(device *      dev)
+wavelan_watchdog(struct net_device *   dev)
 {
   net_local *          lp = (net_local *) dev->priv;
   ioaddr_t             base = dev->base_addr;
@@ -4541,7 +4541,7 @@ wavelan_watchdog(device * dev)
  * Called by NET3 when it "open" the device.
  */
 static int
-wavelan_open(device *  dev)
+wavelan_open(struct net_device *       dev)
 {
   dev_link_t * link = ((net_local *) dev->priv)->link;
   net_local *  lp = (net_local *)dev->priv;
@@ -4596,7 +4596,7 @@ wavelan_open(device *     dev)
  * Called by NET3 when it "close" the device.
  */
 static int
-wavelan_close(device * dev)
+wavelan_close(struct net_device *      dev)
 {
   dev_link_t * link = ((net_local *) dev->priv)->link;
   ioaddr_t     base = dev->base_addr;
@@ -4660,7 +4660,7 @@ wavelan_attach(void)
 {
   client_reg_t client_reg;     /* Register with cardmgr */
   dev_link_t * link;           /* Info for cardmgr */
-  device *     dev;            /* Interface generic data */
+  struct net_device *  dev;            /* Interface generic data */
   net_local *  lp;             /* Interface specific data */
   int          i, ret;
 
@@ -4698,22 +4698,14 @@ wavelan_attach(void)
   dev_list = link;
 
   /* Allocate the generic data structure */
-  dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+  dev = alloc_etherdev(sizeof(net_local));
   if (!dev) {
       kfree(link);
       return NULL;
   }
-  memset(dev, 0x00, sizeof(struct net_device));
   link->priv = link->irq.Instance = dev;
 
-  /* Allocate the wavelan-specific data structure. */
-  dev->priv = lp = (net_local *) kmalloc(sizeof(net_local), GFP_KERNEL);
-  if (!lp) {
-      kfree(link);
-      kfree(dev);
-      return NULL;
-  }
-  memset(lp, 0x00, sizeof(net_local));
+  lp = dev->priv;
 
   /* Init specific data */
   lp->configured = 0;
@@ -4731,9 +4723,6 @@ wavelan_attach(void)
   lp->link = link;
   lp->dev = dev;
 
-  /* Standard setup for generic data */
-  ether_setup(dev);
-
   /* wavelan NET3 callbacks */
   SET_MODULE_OWNER(dev);
   dev->open = &wavelan_open;
@@ -4851,22 +4840,16 @@ wavelan_detach(dev_link_t *     link)
   /* Free pieces */
   if(link->priv)
     {
-      device * dev = (device *) link->priv;
+      struct net_device *      dev = (struct net_device *) link->priv;
 
       /* Remove ourselves from the kernel list of ethernet devices */
       /* Warning : can't be called from interrupt, timer or wavelan_close() */
-      if(link->dev != NULL)
+      if (link->dev)
        unregister_netdev(dev);
       link->dev = NULL;
-
-      if(dev->priv)
-       {
-         /* Sound strange, but safe... */
-         ((net_local *) dev->priv)->link = (dev_link_t *) NULL;
-         ((net_local *) dev->priv)->dev = (device *) NULL;
-         kfree(dev->priv);
-       }
-      kfree(link->priv);
+      ((net_local *) dev->priv)->link = NULL;
+      ((net_local *) dev->priv)->dev = NULL;
+      free_netdev(dev);
     }
   kfree(link);
 
@@ -4888,7 +4871,7 @@ wavelan_event(event_t             event,          /* The event received */
              event_callback_args_t *   args)
 {
   dev_link_t * link = (dev_link_t *) args->client_data;
-  device *     dev = (device *) link->priv;
+  struct net_device *  dev = (struct net_device *) link->priv;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "->wavelan_event(): %s\n",
index 62baa3a..f7dfc2f 100644 (file)
@@ -588,7 +588,6 @@ struct wavepoint_table
 /****************************** TYPES ******************************/
 
 /* Shortcuts */
-typedef struct net_device      device;
 typedef struct net_device_stats        en_stats;
 typedef struct iw_statistics   iw_stats;
 typedef struct iw_quality      iw_qual;
@@ -611,7 +610,7 @@ typedef u_char              mac_addr[WAVELAN_ADDR_SIZE];    /* Hardware address */
 struct net_local
 {
   dev_node_t   node;           /* ???? What is this stuff ???? */
-  device *     dev;            /* Reverse link... */
+  struct net_device *  dev;            /* Reverse link... */
   spinlock_t   spinlock;       /* Serialize access to the hardware (SMP) */
   dev_link_t * link;           /* pcmcia structure */
   en_stats     stats;          /* Ethernet interface statistics */
@@ -673,11 +672,11 @@ static inline void
        hacr_write_slow(u_long,
                   u_char);
 static void
-       psa_read(device *,      /* Read the Parameter Storage Area */
+       psa_read(struct net_device *,   /* Read the Parameter Storage Area */
                 int,           /* offset in PSA */
                 u_char *,      /* buffer to fill */
                 int),          /* size to read */
-       psa_write(device *,     /* Write to the PSA */
+       psa_write(struct net_device *,  /* Write to the PSA */
                  int,          /* Offset in psa */
                  u_char *,     /* Buffer in memory */
                  int);         /* Length of buffer */
@@ -707,57 +706,57 @@ static void
                 int);          /* number of registers */
 /* ---------------------- I82593 SUBROUTINES ----------------------- */
 static int
-       wv_82593_cmd(device *,  /* synchronously send a command to i82593 */ 
+       wv_82593_cmd(struct net_device *,       /* synchronously send a command to i82593 */ 
                     char *,
                     int,
                     int);
 static inline int
-       wv_diag(device *);      /* Diagnostique the i82593 */
+       wv_diag(struct net_device *);   /* Diagnostique the i82593 */
 static int
-       read_ringbuf(device *,  /* Read a receive buffer */
+       read_ringbuf(struct net_device *,       /* Read a receive buffer */
                     int,
                     char *,
                     int);
 static inline void
-       wv_82593_reconfig(device *);    /* Reconfigure the controller */
+       wv_82593_reconfig(struct net_device *); /* Reconfigure the controller */
 /* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
 static inline void
-       wv_init_info(device *); /* display startup info */
+       wv_init_info(struct net_device *);      /* display startup info */
 /* ------------------- IOCTL, STATS & RECONFIG ------------------- */
 static en_stats        *
-       wavelan_get_stats(device *);    /* Give stats /proc/net/dev */
+       wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
 /* ----------------------- PACKET RECEPTION ----------------------- */
 static inline int
-       wv_start_of_frame(device *,     /* Seek beggining of current frame */
+       wv_start_of_frame(struct net_device *,  /* Seek beggining of current frame */
                          int,  /* end of frame */
                          int); /* start of buffer */
 static inline void
-       wv_packet_read(device *,        /* Read a packet from a frame */
+       wv_packet_read(struct net_device *,     /* Read a packet from a frame */
                       int,
                       int),
-       wv_packet_rcv(device *);        /* Read all packets waiting */
+       wv_packet_rcv(struct net_device *);     /* Read all packets waiting */
 /* --------------------- PACKET TRANSMISSION --------------------- */
 static inline void
-       wv_packet_write(device *,       /* Write a packet to the Tx buffer */
+       wv_packet_write(struct net_device *,    /* Write a packet to the Tx buffer */
                        void *,
                        short);
 static int
        wavelan_packet_xmit(struct sk_buff *,   /* Send a packet */
-                           device *);
+                           struct net_device *);
 /* -------------------- HARDWARE CONFIGURATION -------------------- */
 static inline int
-       wv_mmc_init(device *);  /* Initialize the modem */
+       wv_mmc_init(struct net_device *);       /* Initialize the modem */
 static int
-       wv_ru_stop(device *),   /* Stop the i82593 receiver unit */
-       wv_ru_start(device *);  /* Start the i82593 receiver unit */
+       wv_ru_stop(struct net_device *),        /* Stop the i82593 receiver unit */
+       wv_ru_start(struct net_device *);       /* Start the i82593 receiver unit */
 static int
-       wv_82593_config(device *);      /* Configure the i82593 */
+       wv_82593_config(struct net_device *);   /* Configure the i82593 */
 static inline int
-       wv_pcmcia_reset(device *);      /* Reset the pcmcia interface */
+       wv_pcmcia_reset(struct net_device *);   /* Reset the pcmcia interface */
 static int
-       wv_hw_config(device *); /* Reset & configure the whole hardware */
+       wv_hw_config(struct net_device *);      /* Reset & configure the whole hardware */
 static inline void
-       wv_hw_reset(device *);  /* Same, + start receiver unit */
+       wv_hw_reset(struct net_device *);       /* Same, + start receiver unit */
 static inline int
        wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */
 static void
@@ -768,11 +767,11 @@ static irqreturn_t
                          void *,
                          struct pt_regs *);
 static void
-       wavelan_watchdog(device *);     /* Transmission watchdog */
+       wavelan_watchdog(struct net_device *);  /* Transmission watchdog */
 /* ------------------- CONFIGURATION CALLBACKS ------------------- */
 static int
-       wavelan_open(device *),         /* Open the device */
-       wavelan_close(device *);        /* Close the device */
+       wavelan_open(struct net_device *),              /* Open the device */
+       wavelan_close(struct net_device *);     /* Close the device */
 static dev_link_t *
        wavelan_attach(void);           /* Create a new device */
 static void
index f5db2ef..079ffd8 100644 (file)
@@ -1449,18 +1449,6 @@ fail:
        goto out;
 }
 
-/**
- * wl3501_init - "initialize" board
- * @dev - network device
- *
- * We never need to do anything when a wl3501 device is "initialized" by the net
- * software, because we only register already-found cards.
- */
-static int wl3501_init(struct net_device *dev)
-{
-       return 0;
-}
-
 struct net_device_stats *wl3501_get_stats(struct net_device *dev)
 {
        struct wl3501_card *this = dev->priv;
@@ -2056,7 +2044,6 @@ static dev_link_t *wl3501_attach(void)
        dev = alloc_etherdev(sizeof(struct wl3501_card));
        if (!dev)
                goto out_link;
-       dev->init               = wl3501_init;
        dev->open               = wl3501_open;
        dev->stop               = wl3501_close;
        dev->hard_start_xmit    = wl3501_hard_start_xmit;
index 910d5e8..9ebd5ea 100644 (file)
@@ -372,10 +372,8 @@ static int __init znet_probe (void)
        struct znet_private *znet;
        struct net_device *dev;
        char *p;
+       int err = -ENOMEM;
 
-       if (znet_dev)                           /* Only look for a single adaptor */
-               return -ENODEV;
-       
        /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
        for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++)
                if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0)
@@ -387,12 +385,14 @@ static int __init znet_probe (void)
                return -ENODEV;
        }
 
-       if (!(znet_dev = dev = init_etherdev(0, sizeof(struct znet_private))))
-                       return -ENOMEM;
+       dev = alloc_etherdev(sizeof(struct znet_private));
+       if (!dev)
+               return -ENOMEM;
+
+       SET_MODULE_OWNER (dev);
 
        znet = dev->priv;
 
-       SET_MODULE_OWNER (dev);
        netinfo = (struct netidblk *)p;
        dev->base_addr = netinfo->iobase1;
        dev->irq = netinfo->irq1;
@@ -430,7 +430,7 @@ static int __init znet_probe (void)
        znet->io_size  = 2;
 
        if (!(znet->rx_start = kmalloc (DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA)))
-               goto free_netdev;
+               goto free_dev;
        if (!(znet->tx_start = kmalloc (DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA)))
                goto free_rx;
 
@@ -452,19 +452,19 @@ static int __init znet_probe (void)
        dev->set_multicast_list = &znet_set_multicast_list;
        dev->tx_timeout = znet_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
-
+       err = register_netdev(dev);
+       if (err)
+               goto free_tx;
+       znet_dev = dev;
        return 0;
 
  free_tx:
-       kfree (znet->tx_start);
+       kfree(znet->tx_start);
  free_rx:
-       kfree (znet->rx_start);
- free_netdev:
-       unregister_netdev (dev);
-       kfree (dev);
-       znet_dev = NULL;
-
-       return -ENOMEM;
+       kfree(znet->rx_start);
+ free_dev:
+       free_netdev(dev);
+       return err;
 }
 
 \f
@@ -934,16 +934,14 @@ static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
 
 static __exit void znet_cleanup (void)
 {
-#ifdef MODULE
        if (znet_dev) {
                struct znet_private *znet = znet_dev->priv;
 
+               unregister_netdev (znet_dev);
                kfree (znet->rx_start);
                kfree (znet->tx_start);
-               unregister_netdev (znet_dev);
                free_netdev (znet_dev);
        }
-#endif
 }
 
 module_init (znet_probe);
index 05b9d98..c3272c2 100644 (file)
@@ -103,18 +103,18 @@ static int __init zorro8390_probe(void)
            continue;
        board = z->resource.start;
        ioaddr = board+cards[i].offset;
-       dev = init_etherdev(0, 0);
-       SET_MODULE_OWNER(dev);
+       dev = alloc_ei_netdev();
        if (!dev)
            return -ENOMEM;
+       SET_MODULE_OWNER(dev);
        if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, dev->name)) {
-           kfree(dev);
+           free_netdev(dev);
            continue;
        }
        if ((err = zorro8390_init(dev, board, cards[i].name,
                                  ZTWO_VADDR(ioaddr)))) {
            release_mem_region(ioaddr, NE_IO_EXTENT*2);
-           kfree(dev);
+           free_netdev(dev);
            return err;
        }
        err = 0;
@@ -129,6 +129,7 @@ static int __init zorro8390_init(struct net_device *dev, unsigned long board,
                                 const char *name, unsigned long ioaddr)
 {
     int i;
+    int err;
     unsigned char SA_prom[32];
     int start_page, stop_page;
     static u32 zorro8390_offsets[16] = {
@@ -195,12 +196,6 @@ static int __init zorro8390_init(struct net_device *dev, unsigned long board,
     i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, dev->name, dev);
     if (i) return i;
 
-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
-    if (ethdev_init(dev)) {
-       printk("Unable to get memory for dev->priv.\n");
-       return -ENOMEM;
-    }
-
     for(i = 0; i < ETHER_ADDR_LEN; i++) {
 #ifdef DEBUG
        printk(" %2.2x", SA_prom[i]);
@@ -232,7 +227,10 @@ static int __init zorro8390_init(struct net_device *dev, unsigned long board,
     root_zorro8390_dev = dev;
 #endif
     NS8390_init(dev, 0);
-    return 0;
+    err = register_netdev(dev);
+    if (err)
+       free_irq(IRQ_AMIGA_PORTS, dev);
+    return err;
 }
 
 static int zorro8390_open(struct net_device *dev)
index 37aa2f6..fa875ae 100644 (file)
@@ -106,6 +106,9 @@ config IOMMU_SBA
 #config PCI_EPIC
 #      bool "EPIC/SAGA PCI support"
 #      depends on PCI
+#      default y
+#      help
+#        Say Y here for V-class PCI, DMA/IOMMU, IRQ subsystem support.
 
 config SUPERIO
        bool "SuperIO (SuckyIO) support"
index d88555b..696c3e1 100644 (file)
@@ -364,11 +364,11 @@ ccio_alloc_range(struct ioc *ioc, unsigned long pages_needed)
                CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 64);
 #endif
        } else {
-               panic(__FILE__ ": %s() Too many pages to map. pages_needed: %ld\n", 
-                     __FUNCTION__, pages_needed);
+               panic("%s: %s() Too many pages to map. pages_needed: %ld\n",
+                      __FILE__,  __FUNCTION__, pages_needed);
        }
 
-       panic(__FILE__ ": %s() I/O MMU is out of mapping resources.\n", 
+       panic("%s: %s() I/O MMU is out of mapping resources.\n", __FILE__,
              __FUNCTION__);
        
 resource_found:
@@ -441,7 +441,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
                CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 64);
 #endif
        } else {
-               panic(__FILE__ ":%s() Too many pages to unmap.\n", 
+               panic("%s:%s() Too many pages to unmap.\n", __FILE__,
                      __FUNCTION__);
        }
 }
@@ -1447,7 +1447,8 @@ ccio_ioc_init(struct ioc *ioc)
        ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL, 
                                                 get_order(ioc->pdir_size));
        if(NULL == ioc->pdir_base) {
-               panic(__FILE__ ":%s() could not allocate I/O Page Table\n", __FUNCTION__);
+               panic("%s:%s() could not allocate I/O Page Table\n", __FILE__,
+                     __FUNCTION__);
        }
        memset(ioc->pdir_base, 0, ioc->pdir_size);
 
@@ -1461,7 +1462,8 @@ ccio_ioc_init(struct ioc *ioc)
        ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL, 
                                              get_order(ioc->res_size));
        if(NULL == ioc->res_map) {
-               panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__);
+               panic("%s:%s() could not allocate resource map\n", __FILE__,
+                     __FUNCTION__);
        }
        memset(ioc->res_map, 0, ioc->res_size);
 
@@ -1627,11 +1629,11 @@ int ccio_request_resource(const struct parisc_device *dev,
 
        if (!ioc) {
                parent = &iomem_resource;
-       } else if ((ioc->mmio_region->start <= dev->hpa) &&
-                       (dev->hpa < ioc->mmio_region->end)) {
+       } else if ((ioc->mmio_region->start <= res->start) &&
+                       (res->end <= ioc->mmio_region->end)) {
                parent = ioc->mmio_region;
-       } else if (((ioc->mmio_region + 1)->start <= dev->hpa) &&
-                       (dev->hpa < (ioc->mmio_region + 1)->end)) {
+       } else if (((ioc->mmio_region + 1)->start <= res->start) &&
+                       (res->end <= (ioc->mmio_region + 1)->end)) {
                parent = ioc->mmio_region + 1;
        } else {
                return -EBUSY;
index a2bfdfa..0b28122 100644 (file)
@@ -175,7 +175,7 @@ static int dino_current_bus = 0;
 static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
                int size, u32 *val)
 {
-       struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
+       struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
        u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
        u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
        unsigned long base_addr = d->hba.base_addr;
@@ -209,7 +209,7 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
 static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where,
        int size, u32 val)
 {
-       struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
+       struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
        u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
        u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
        unsigned long base_addr = d->hba.base_addr;
@@ -468,14 +468,14 @@ static void __init
 dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
 {
        int i;
-       struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
+       struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
        struct resource *res;
        char name[128];
        int size;
 
        res = &dino_dev->hba.lmmio_space;
        res->flags = IORESOURCE_MEM;
-       size = snprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->dev->bus_id);
+       size = snprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->bridge->bus_id);
        res->name = kmalloc(size+1, GFP_KERNEL);
        if(res->name)
                strcpy((char *)res->name, name);
@@ -489,7 +489,7 @@ dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
                struct list_head *ln, *tmp_ln;
 
                printk(KERN_ERR "Dino: cannot attach bus %s\n",
-                      bus->dev->bus_id);
+                      bus->bridge->bus_id);
                /* kill the bus, we can't do anything with it */
                list_for_each_safe(ln, tmp_ln, &bus->devices) {
                        struct pci_dev *dev = pci_dev_b(ln);
@@ -560,11 +560,11 @@ dino_fixup_bus(struct pci_bus *bus)
 {
        struct list_head *ln;
         struct pci_dev *dev;
-        struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
+        struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
        int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
 
        DBG(KERN_WARNING "%s(0x%p) bus %d sysdata 0x%p\n",
-                       __FUNCTION__, bus, bus->secondary, bus->dev->platform_data);
+                       __FUNCTION__, bus, bus->secondary, bus->bridge->platform_data);
 
        /* Firmware doesn't set up card-mode dino, so we have to */
        if (is_card_dino(&dino_dev->hba.dev->id)) {
@@ -572,15 +572,23 @@ dino_fixup_bus(struct pci_bus *bus)
        } else if(bus->parent == NULL) {
                /* must have a dino above it, reparent the resources
                 * into the dino window */
+               int i;
+               struct resource *res = &dino_dev->hba.lmmio_space;
+
                bus->resource[0] = &(dino_dev->hba.io_space);
-               bus->resource[1] = &(dino_dev->hba.lmmio_space); 
+               for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) {
+                       if(res[i].flags == 0)
+                               break;
+                       bus->resource[i+1] = &res[i];
+               }
+
        } else if(bus->self) {
                int i;
 
                pci_read_bridge_bases(bus);
 
 
-               for(i = 0; i < PCI_NUM_RESOURCES; i++) {
+               for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
                        if((bus->self->resource[i].flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
                                continue;
                        
@@ -642,11 +650,10 @@ dino_fixup_bus(struct pci_bus *bus)
                 * care about an expansion rom on parisc, since it
                 * usually contains (x86) bios code) */
                dev->resource[PCI_ROM_RESOURCE].flags = 0;
-               dev->resource[PCI_ROM_RESOURCE].start = 0;
-               dev->resource[PCI_ROM_RESOURCE].end = 0;
                                
                if(dev->irq == 255) {
 
+#define DINO_FIX_UNASSIGNED_INTERRUPTS
 #ifdef DINO_FIX_UNASSIGNED_INTERRUPTS
 
                        /* This code tries to assign an unassigned
@@ -660,7 +667,7 @@ dino_fixup_bus(struct pci_bus *bus)
                        dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin);
                        dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
                        dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq);
-                       dev->irq += dino_dev->dino_region->data.irqbase
+                       dev->irq += dino_dev->dino_region->data.irqbase;
                        printk(KERN_WARNING "Device %s has undefined IRQ, setting to %d\n", dev->slot_name, irq_pin);
 #else
                        dev->irq = 65535;
@@ -741,9 +748,9 @@ dino_card_init(struct dino_device *dino_dev)
 static int __init
 dino_bridge_init(struct dino_device *dino_dev, const char *name)
 {
-       unsigned long io_addr, bpos;
-       int result;
-       struct resource *res;
+       unsigned long io_addr;
+       int result, i, count=0;
+       struct resource *res, *prevres = NULL;
        /*
         * Decoding IO_ADDR_EN only works for Built-in Dino
         * since PDC has already initialized this.
@@ -755,21 +762,51 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name)
                return -ENODEV;
        }
 
-       for (bpos = 0; (io_addr & (1 << bpos)) == 0; bpos++)
-               ;
-
        res = &dino_dev->hba.lmmio_space;
-       res->flags = IORESOURCE_MEM;
+       for (i = 0; i < 32; i++) {
+               unsigned long start, end;
+
+               if((io_addr & (1 << i)) == 0)
+                       continue;
 
-       res->start = (unsigned long)(signed int)(0xf0000000 | (bpos << 23));
-       res->end = res->start + 8 * 1024 * 1024 - 1;
+               start = (unsigned long)(signed int)(0xf0000000 | (i << 23));
+               end = start + 8 * 1024 * 1024 - 1;
 
-       result = ccio_request_resource(dino_dev->hba.dev, res);
-       if (result < 0) {
-               printk(KERN_ERR "%s: failed to claim PCI Bus address space!\n", name);
-               return result;
+               DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count,
+                   start, end);
+
+               if(prevres && prevres->end + 1 == start) {
+                       prevres->end = end;
+               } else {
+                       if(count >= DINO_MAX_LMMIO_RESOURCES) {
+                               printk(KERN_ERR "%s is out of resource windows for range %d (0x%lx-0x%lx)\n", name, count, start, end);
+                               break;
+                       }
+                       prevres = res;
+                       res->start = start;
+                       res->end = end;
+                       res->flags = IORESOURCE_MEM;
+                       res->name = kmalloc(64, GFP_KERNEL);
+                       if(res->name)
+                               snprintf((char *)res->name, 64, "%s LMMIO %d",
+                                        name, count);
+                       res++;
+                       count++;
+               }
        }
 
+       res = &dino_dev->hba.lmmio_space;
+
+       for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) {
+               if(res[i].flags == 0)
+                       break;
+
+               result = ccio_request_resource(dino_dev->hba.dev, &res[i]);
+               if (result < 0) {
+                       printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end);
+                       return result;
+               }
+       }
        return 0;
 }
 
@@ -850,10 +887,8 @@ static int __init dino_common_init(struct parisc_device *dev,
        res = &dino_dev->hba.io_space;
        if (dev->id.hversion == 0x680 || is_card_dino(&dev->id)) {
                res->name = "Dino I/O Port";
-               dino_dev->hba.lmmio_space.name = "Dino LMMIO";
        } else {
                res->name = "Cujo I/O Port";
-               dino_dev->hba.lmmio_space.name = "Cujo LMMIO";
        }
        res->start = HBA_PORT_BASE(dino_dev->hba.hba_num);
        res->end = res->start + (HBA_PORT_SPACE_SIZE - 1);
index bda206c..d16724d 100644 (file)
@@ -1,3 +1,24 @@
+/* 
+ *    EISA "eeprom" support routines
+ *
+ *    Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
index 9eb6ada..60466bd 100644 (file)
@@ -610,19 +610,19 @@ iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
        struct vector_info *vi = (struct vector_info *)dev_id;
        extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-       int irq_num = vi->vi_ios->isi_region->data.irqbase + vi->vi_irqline;
+       int irq_num = vi->iosapic->isi_region->data.irqbase + vi->irqline;
 
        DBG("iosapic_interrupt(): irq %d line %d eoi %p\n",
-               irq, vi->vi_irqline, vi->vi_eoi_addr);
+               irq, vi->irqline, vi->eoi_addr);
 
 /* FIXME: Need to mask/unmask? processor IRQ is already masked... */
-       do_irq(&vi->vi_ios->isi_region->action[vi->vi_irqline], irq_num, regs);
+       do_irq(&vi->iosapic->isi_region->action[vi->irqline], irq_num, regs);
 
        /*
        ** PCI only supports level triggered in order to share IRQ lines.
        ** I/O SAPIC must always issue EOI.
        */
-       IOSAPIC_EOI(vi->vi_eoi_addr, vi->vi_eoi_data);
+       IOSAPIC_EOI(vi->eoi_addr, vi->eoi_data);
 
        return IRQ_HANDLED;
 }
@@ -636,10 +636,6 @@ iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
        struct vector_info *vi;
        int isi_line;   /* line used by device */
        int tmp;
-       int return_irq;
-#ifdef CONFIG_SUPERIO
-       int superio_irq = -1;
-#endif
 
        if (NULL == isi) {
                printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
@@ -648,30 +644,29 @@ iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
        }
 
 #ifdef CONFIG_SUPERIO
+       /*
+        * HACK ALERT! (non-compliant PCI device support)
+        *
+        * All SuckyIO interrupts are routed through the PIC's on function 1.
+        * But SuckyIO OHCI USB controller gets an IRT entry anyway because
+        * it advertises INT D for INT_PIN.  Use that IRT entry to get the
+        * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
+        */
        if (is_superio_device(pcidev)) {
-               superio_irq = superio_fixup_irq(pcidev);
-               if (superio_irq == -1)
-                   return(-1);
-
-               if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN) {
-
-                       /*
-                        * SuperIO USB controller has an irt entry.
-                        * Only let the USB controller hookup the rest
-                        * of the interrupt routing when it comes through.
-                        * Note that interrupts for all three functions
-                        * actually come through the PIC's on function 1!
-                        */
-
-                       pcidev->irq = superio_irq;
-                       return superio_irq;
-               }
+               /* We must call superio_fixup_irq() to register the pdev */
+               pcidev->irq = superio_fixup_irq(pcidev);
+
+               /* Don't return if need to program the IOSAPIC's IRT... */
+               if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
+                       return pcidev->irq;
        }
 #endif /* CONFIG_SUPERIO */
 
        /* lookup IRT entry for isi/slot/pin set */
        irte = iosapic_xlate_pin(isi, pcidev);
        if (NULL == irte) {
+               printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
+                               pci_name(pcidev));
                return(-1);
        }
        DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
@@ -685,15 +680,21 @@ iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
                irte->dest_iosapic_intin,
                (u32) irte->dest_iosapic_addr);
        isi_line = irte->dest_iosapic_intin;
+       pcidev->irq = isi->isi_region->data.irqbase + isi_line;
 
        /* get vector info for this input line */
        ASSERT(NULL != isi->isi_vector);
        vi = &(isi->isi_vector[isi_line]);
        DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
-       vi->vi_irte = irte;
+
+       /* If this IRQ line has already been setup, skip it */
+       if (vi->irte)
+               return pcidev->irq;
+
+       vi->irte = irte;
 
        /* Allocate processor IRQ */
-       vi->vi_txn_irq = txn_alloc_irq();
+       vi->txn_irq = txn_alloc_irq();
 
 /* XXX/FIXME The txn_alloc_irq() code and related code should be moved
 ** to enable_irq(). That way we only allocate processor IRQ bits
@@ -701,47 +702,36 @@ iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
 ** Right now we assign an IRQ to every PCI device present regardless
 ** of whether it's used or not.
 */
-       if (vi->vi_txn_irq < 0)
+       if (vi->txn_irq < 0)
                panic("I/O sapic: couldn't get TXN IRQ\n");
 
        /* enable_irq() will use txn_* to program IRdT */
-       vi->vi_txn_addr = txn_alloc_addr(vi->vi_txn_irq);
-       vi->vi_txn_data = txn_alloc_data(vi->vi_txn_irq, 8);
-        ASSERT(vi->vi_txn_data < 256);  /* matches 8 above */
+       vi->txn_addr = txn_alloc_addr(vi->txn_irq);
+       vi->txn_data = txn_alloc_data(vi->txn_irq, 8);
+        ASSERT(vi->txn_data < 256);  /* matches 8 above */
 
-       tmp = request_irq(vi->vi_txn_irq, iosapic_interrupt, 0,
-                                               vi->vi_name, vi);
+       tmp = request_irq(vi->txn_irq, iosapic_interrupt, 0,
+                                               vi->name, vi);
        ASSERT(tmp == 0);
 
-       vi->vi_eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
-       vi->vi_eoi_data = cpu_to_le32(vi->vi_irqline);
+       vi->eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
+       vi->eoi_data = cpu_to_le32(vi->irqline);
 
        ASSERT(NULL != isi->isi_region);
-       /* pcidev->irq still needs to be virtualized.  */
-
-       return_irq = isi->isi_region->data.irqbase + isi_line;
-
-#ifdef CONFIG_SUPERIO
-       if (superio_irq != -1) {
-               superio_inform_irq(return_irq);
-               return_irq = superio_irq;
-       }
-#endif
-       pcidev->irq = return_irq;
 
        DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
-               PCI_SLOT(pcidev->devfn),
-       PCI_FUNC(pcidev->devfn), pcidev->vendor, pcidev->device, isi_line, return_irq);
+               PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->irq),
+               pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
 
-       return return_irq;
+       return pcidev->irq;
 }
 
 
 static void
 iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
 {
-       struct iosapic_info *isp = vi->vi_ios;
-       u8 idx = vi->vi_irqline;
+       struct iosapic_info *isp = vi->iosapic;
+       u8 idx = vi->irqline;
 
        /* point the window register to the lower word */
        WRITE_U32(IOSAPIC_IRDT_ENTRY(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
@@ -756,24 +746,24 @@ iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
 static void
 iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
 {
-       struct iosapic_info *isp = vi->vi_ios;
+       struct iosapic_info *isp = vi->iosapic;
 
        ASSERT(NULL != isp);
        ASSERT(0 != isp->isi_hpa);
        DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p WINDOW %p  0x%x 0x%x\n",
-               vi->vi_irqline,
+               vi->irqline,
                isp->isi_hpa, isp->isi_hpa+IOSAPIC_REG_WINDOW,
                dp0, dp1);
 
        /* point the window register to the lower word */
-       WRITE_U32(IOSAPIC_IRDT_ENTRY(vi->vi_irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
+       WRITE_U32(IOSAPIC_IRDT_ENTRY(vi->irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
        WRITE_U32( dp0, isp->isi_hpa+IOSAPIC_REG_WINDOW);
 
        /* Read the window register to flush the writes down to HW  */
        dp0 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
 
        /* point the window register to the higher word */
-       WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(vi->vi_irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
+       WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(vi->irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
        WRITE_U32( dp1, isp->isi_hpa+IOSAPIC_REG_WINDOW);
 
        /* Read the window register to flush the writes down to HW  */
@@ -790,8 +780,8 @@ static void
 iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
 {
        u32 mode = 0;
-       struct irt_entry *p = vi->vi_irte;
-       ASSERT(NULL != vi->vi_irte);
+       struct irt_entry *p = vi->irte;
+       ASSERT(NULL != vi->irte);
 
        if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
                mode |= IOSAPIC_IRDT_PO_LOW;
@@ -804,8 +794,8 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
        ** PA doesn't support EXTINT or LPRIO bits.
        */
 
-       ASSERT(vi->vi_txn_data);
-       *dp0 = mode | (u32) vi->vi_txn_data;
+       ASSERT(vi->txn_data);
+       *dp0 = mode | (u32) vi->txn_data;
 
        /*
        ** Extracting id_eid isn't a real clean way of getting it.
@@ -814,9 +804,9 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
        if (is_pdc_pat()) {
                /*
                ** PAT PDC just hands it to us "right".
-               ** vi_txn_addr comes from cpu_data[x].txn_addr.
+               ** txn_addr comes from cpu_data[x].txn_addr.
                */
-               *dp1 = (u32) (vi->vi_txn_addr);
+               *dp1 = (u32) (vi->txn_addr);
        } else {
                /* 
                ** eg if base_addr == 0xfffa0000),
@@ -825,8 +815,8 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
                ** eid  0x0ff00000 -> 0x00ff0000
                ** id   0x000ff000 -> 0xff000000
                */
-               *dp1 = (((u32)vi->vi_txn_addr & 0x0ff00000) >> 4) |
-                       (((u32)vi->vi_txn_addr & 0x000ff000) << 12);
+               *dp1 = (((u32)vi->txn_addr & 0x0ff00000) >> 4) |
+                       (((u32)vi->txn_addr & 0x000ff000) << 12);
        }
        DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
 }
@@ -872,7 +862,7 @@ Need more info on how Linux supports shared IRQ lines on a PC.
        IOSAPIC_UNLOCK(&iosapic_lock);
 
        /* disable ISR for parent */
-       disable_irq(vi->vi_txn_irq);
+       disable_irq(vi->txn_irq);
 }
 
 
@@ -883,11 +873,11 @@ iosapic_enable_irq(void *dev, int irq)
        u32 d0, d1;
 
        ASSERT(NULL != vi);
-       ASSERT(NULL != vi->vi_irte);
+       ASSERT(NULL != vi->irte);
 
        /* data is initialized by fixup_irq */
-       ASSERT(0 < vi->vi_txn_irq);
-       ASSERT(0UL != vi->vi_txn_data);
+       ASSERT(0 < vi->txn_irq);
+       ASSERT(0UL != vi->txn_data);
 
        iosapic_set_irt_data(vi, &d0, &d1);
        iosapic_wr_irt_entry(vi, d0, d1);
@@ -895,15 +885,15 @@ iosapic_enable_irq(void *dev, int irq)
 
 #ifdef DEBUG_IOSAPIC_IRT
 {
-       u32 *t = (u32 *) ((ulong) vi->vi_eoi_addr & ~0xffUL);
-       printk("iosapic_enable_irq(): regs %p", vi->vi_eoi_addr);
-       while (t < vi->vi_eoi_addr) printk(" %x", READ_U32(t++));
+       u32 *t = (u32 *) ((ulong) vi->eoi_addr & ~0xffUL);
+       printk("iosapic_enable_irq(): regs %p", vi->eoi_addr);
+       while (t < vi->eoi_addr) printk(" %x", READ_U32(t++));
        printk("\n");
 }
 
 printk("iosapic_enable_irq(): sel ");
 {
-       struct iosapic_info *isp = vi->vi_ios;
+       struct iosapic_info *isp = vi->iosapic;
 
        for (d0=0x10; d0<0x1e; d0++) {
                /* point the window register to the lower word */
@@ -924,7 +914,7 @@ printk("\n");
        ** Issueing I/O SAPIC an EOI causes an interrupt iff IRQ line is
        ** asserted.
        */
-       IOSAPIC_EOI(vi->vi_eoi_addr, vi->vi_eoi_data);
+       IOSAPIC_EOI(vi->eoi_addr, vi->eoi_data);
 }
 
 
@@ -1034,9 +1024,9 @@ iosapic_register(unsigned long hpa)
        ** Initialize vector array
        */
        for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
-               vip->vi_irqline = (unsigned char) cnt;
-               vip->vi_ios = isi;
-               sprintf(vip->vi_name, "%s-L%d", isi->isi_name, cnt);
+               vip->irqline = (unsigned char) cnt;
+               vip->iosapic = isi;
+               sprintf(vip->name, "%s-L%d", isi->isi_name, cnt);
        }
 
        isi->isi_region = alloc_irq_region(isi->isi_num_vectors,
@@ -1071,13 +1061,13 @@ iosapic_prt_vi(struct vector_info *vi)
 {
        ASSERT(NULL != vi);
 
-       printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->vi_irqline, vi);
-       printk(KERN_DEBUG "\t\tvi_status:        %.4x\n", vi->vi_status);
-       printk(KERN_DEBUG "\t\tvi_txn_irq:  %d\n",  vi->vi_txn_irq);
-       printk(KERN_DEBUG "\t\tvi_txn_addr: %lx\n", vi->vi_txn_addr);
-       printk(KERN_DEBUG "\t\tvi_txn_data: %lx\n", vi->vi_txn_data);
-       printk(KERN_DEBUG "\t\tvi_eoi_addr: %p\n",  vi->vi_eoi_addr);
-       printk(KERN_DEBUG "\t\tvi_eoi_data: %x\n",  vi->vi_eoi_data);
+       printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->irqline, vi);
+       printk(KERN_DEBUG "\t\tstatus:   %.4x\n", vi->status);
+       printk(KERN_DEBUG "\t\ttxn_irq:  %d\n",  vi->txn_irq);
+       printk(KERN_DEBUG "\t\ttxn_addr: %lx\n", vi->txn_addr);
+       printk(KERN_DEBUG "\t\ttxn_data: %lx\n", vi->txn_data);
+       printk(KERN_DEBUG "\t\teoi_addr: %p\n",  vi->eoi_addr);
+       printk(KERN_DEBUG "\t\teoi_data: %x\n",  vi->eoi_data);
 }
 
 
index e2d297b..8eae695 100644 (file)
@@ -1,3 +1,26 @@
+/* 
+ *    Private structs/constants for PARISC IOSAPIC support
+ *
+ *    Copyright (C) 2000 Hewlett Packard (Grant Grundler)
+ *    Copyright (C) 2000,2003 Grant Grundler (grundler at parisc-linux.org)
+ *    Copyright (C) 2002 Matthew Wilcox (willy at parisc-linux.org)
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 /*
 ** This file is private to iosapic driver.
 ** If stuff needs to be used by another driver, move it to a common file.
@@ -107,16 +130,16 @@ struct iosapic_irt {
 #endif
 
 struct vector_info {
-       struct iosapic_info *vi_ios;    /* I/O SAPIC this vector is on */
-       struct irt_entry *vi_irte;      /* IRT entry */
-       u32     *vi_eoi_addr;   /* precalculate EOI reg address */
-       u32     vi_eoi_data;    /* IA64: ?       PA: swapped txn_data */
-       int     vi_txn_irq;     /* virtual IRQ number for processor */
-       ulong   vi_txn_addr;    /* IA64: id_eid  PA: partial HPA */
-       ulong   vi_txn_data;    /* IA64: vector  PA: EIR bit */
-       u8      vi_status;      /* status/flags */
-       u8      vi_irqline;     /* INTINn(IRQ) */
-       char    vi_name[32];    /* user visible identity */
+       struct iosapic_info *iosapic;   /* I/O SAPIC this vector is on */
+       struct irt_entry *irte;         /* IRT entry */
+       u32     *eoi_addr;              /* precalculate EOI reg address */
+       u32     eoi_data;               /* IA64: ?       PA: swapped txn_data */
+       int     txn_irq;                /* virtual IRQ number for processor */
+       ulong   txn_addr;               /* IA64: id_eid  PA: partial HPA */
+       ulong   txn_data;               /* IA64: vector  PA: EIR bit */
+       u8      status;                 /* status/flags */
+       u8      irqline;                /* INTINn(IRQ) */
+       char    name[32];               /* user visible identity */
 };
 
 
index b1a1180..269265d 100644 (file)
@@ -185,8 +185,6 @@ struct lba_device {
        void            *iosapic_obj;
 
 #ifdef __LP64__
-       unsigned long   lmmio_base;  /* PA_VIEW - fixup MEM addresses */
-       unsigned long   gmmio_base;  /* PA_VIEW - Not used (yet) */
        unsigned long   iop_base;    /* PA_VIEW - for IO port accessor funcs */
 #endif
 
@@ -508,7 +506,7 @@ lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
 
 static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
 {
-       struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
+       struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
        u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
        u32 tok = LBA_CFG_TOK(local_bus, devfn);
 
@@ -518,7 +516,7 @@ static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int si
                  with risk we will miss PCI bus errors. */
                *data = lba_rd_cfg(d, tok, pos, size);
                DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __FUNCTION__, tok, pos, *data);
-               return(*data == ~0UL);
+               return(*data == ~0U);
        }
 
        if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d)))
@@ -592,7 +590,7 @@ lba_wr_cfg( struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
 
 static int lba_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
 {
-       struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
+       struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
        u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
        u32 tok = LBA_CFG_TOK(local_bus,devfn);
 
@@ -695,20 +693,23 @@ lba_fixup_bus(struct pci_bus *bus)
 {
        struct list_head *ln;
 #ifdef FBB_SUPPORT
-       u16 fbb_enable = PCI_STATUS_FAST_BACK;
        u16 status;
 #endif
-       struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->dev));
+       struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
        int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
 
        DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
-               bus, bus->secondary, bus->dev->platform_data);
+               bus, bus->secondary, bus->bridge->platform_data);
 
        /*
        ** Properly Setup MMIO resources for this bus.
        ** pci_alloc_primary_bus() mangles this.
        */
-       if (NULL == bus->self) {
+       if (bus->self) {
+               /* PCI-PCI Bridge */
+               pci_read_bridge_bases(bus);
+       } else {
+               /* Host-PCI Bridge */
                int err;
 
                DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
@@ -725,59 +726,29 @@ lba_fixup_bus(struct pci_bus *bus)
                        BUG();
                        lba_dump_res(&ioport_resource, 2);
                }
+
                err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
                if (err < 0) {
                        BUG();
                        lba_dump_res(&iomem_resource, 2);
                }
 
-               bus->resource[0] = &(ldev->hba.io_space);
-               bus->resource[1] = &(ldev->hba.lmmio_space);
-       } else {
-               /* KLUGE ALERT!
-               ** PCI-PCI Bridge resource munging.
-               ** This hack should go away in the near future.
-               ** It's based on the Alpha port.
-               */
-               int i;
-               u16 cmd;
-
-               for (i = 0; i < 4; i++) {
-                       bus->resource[i] =
-                               &bus->self->resource[PCI_BRIDGE_RESOURCES+i];
-                       bus->resource[i]->name = bus->name;
+#ifdef __LP64__
+               if (ldev->hba.gmmio_space.flags) {
+                       err = request_resource(&iomem_resource, &(ldev->hba.gmmio_space));
+                       if (err < 0) {
+                               BUG();
+                               lba_dump_res(&iomem_resource, 2);
+                       }
+                       bus->resource[2] = &(ldev->hba.gmmio_space);
                }
-#if 0
-               bus->resource[0]->flags |= pci_bridge_check_io(bus->self);
-#else
-               bus->resource[0]->flags |= IORESOURCE_IO;
 #endif
-               bus->resource[1]->flags |= IORESOURCE_MEM;
-               bus->resource[2]->flags = 0;    /* Don't support prefetchable */
-               bus->resource[3]->flags = 0;    /* not used */
-
-               /* 
-               ** If the PPB is enabled (ie already configured) then
-               ** just read those values.
-               */
-               (void) pci_read_config_word(bus->self, PCI_COMMAND, &cmd);
-               if (cmd & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) {
-                       pci_read_bridge_bases(bus);
-               } else {
-                       /* Not configured.
-                       ** For now, propagate HBA limits to the bus;
-                       **      PCI will adjust them later.
-                       */
-                       bus->resource[0]->end = ldev->hba.io_space.end;
-                       bus->resource[1]->end = ldev->hba.lmmio_space.end;
-               }
 
-               /* Turn off downstream PF memory address range by default */
-               bus->resource[2]->start = 1024*1024;
-               bus->resource[2]->end = bus->resource[2]->start - 1;
+               /* advertize Host bridge resources to PCI bus */
+               bus->resource[0] = &(ldev->hba.io_space);
+               bus->resource[1] = &(ldev->hba.lmmio_space);
        }
 
-
        list_for_each(ln, &bus->devices) {
                int i;
                struct pci_dev *dev = pci_dev_b(ln);
@@ -785,7 +756,7 @@ lba_fixup_bus(struct pci_bus *bus)
                DBG("lba_fixup_bus() %s\n", pci_name(dev));
 
                /* Virtualize Device/Bridge Resources. */
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+               for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
                        struct resource *res = &dev->resource[i];
 
                        /* If resource not allocated - skip it */
@@ -817,7 +788,7 @@ lba_fixup_bus(struct pci_bus *bus)
                ** No one on the bus can be allowed to use them.
                */
                (void) pci_read_config_word(dev, PCI_STATUS, &status);
-               fbb_enable &= status;
+               bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
 #endif
 
 #ifdef __LP64__
@@ -1069,6 +1040,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                        lba_dev->hba.bus_num.start = p->start;
                        lba_dev->hba.bus_num.end   = p->end;
                        break;
+
                case PAT_LMMIO:
                        /* used to fix up pre-initialized MEM BARs */
                        lba_dev->hba.lmmio_space_offset = p->start - io->start;
@@ -1080,23 +1052,28 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                        r->flags  = IORESOURCE_MEM;
                        r->parent = r->sibling = r->child = NULL;
                        break;
+
                case PAT_GMMIO:
-                       printk(KERN_WARNING MODULE_NAME
-                               " range[%d] : ignoring GMMIO (0x%lx)\n",
-                               i, p->start);
-                       lba_dev->gmmio_base = p->start;
+                       /* MMIO space > 4GB phys addr; for 64-bit BAR */
+                       r = &(lba_dev->hba.gmmio_space);
+                       r->name   = "LBA GMMIO";
+                       r->start  = p->start;
+                       r->end    = p->end;
+                       r->flags  = IORESOURCE_MEM;
+                       r->parent = r->sibling = r->child = NULL;
                        break;
+
                case PAT_NPIOP:
                        printk(KERN_WARNING MODULE_NAME
                                " range[%d] : ignoring NPIOP (0x%lx)\n",
                                i, p->start);
                        break;
+
                case PAT_PIOP:
                        /*
                        ** Postable I/O port space is per PCI host adapter.
+                       ** base of 64MB PIOP region
                        */
-
-                       /* save base of 64MB PIOP region */
                        lba_dev->iop_base = p->start;
 
                        r = &(lba_dev->hba.io_space);
@@ -1106,6 +1083,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                        r->flags  = IORESOURCE_IO;
                        r->parent = r->sibling = r->child = NULL;
                        break;
+
                default:
                        printk(KERN_WARNING MODULE_NAME
                                " range[%d] : unknown pat range type (0x%lx)\n",
@@ -1259,7 +1237,11 @@ lba_hw_init(struct lba_device *d)
 #endif /* DEBUG_LBA_PAT */
 
 #ifdef __LP64__
-#warning FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
+/*
+ * FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
+ * Only N-Class and up can really make use of Get slot status.
+ * maybe L-class too but I've never played with it there.
+ */
 #endif
 
        /* PDC_PAT_BUG: exhibited in rev 40.48  on L2000 */
index 612fb29..7d49780 100644 (file)
@@ -3,7 +3,7 @@
  *
  *      (c) Copyright 2000 Red Hat Software
  *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- *      (c) Copyright 2001-2003 Helge Deller <deller@gmx.de>
+ *      (c) Copyright 2001-2004 Helge Deller <deller@gmx.de>
  *      (c) Copyright 2001 Randolph Chung <tausq@debian.org>
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -56,6 +56,7 @@ static int led_heartbeat = 1;
 static int led_diskio = 1;
 static int led_lanrxtx = 1;
 static char lcd_text[32];
+static char lcd_text_default[] = "Linux " UTS_RELEASE;
 
 #if 0
 #define DPRINTK(x)     printk x
@@ -196,19 +197,11 @@ static int led_proc_write(struct file *file, const char *buf,
 
                break;
        case LED_HASLCD:
+               while (*cur && cur[strlen(cur)-1] == '\n')
+                       cur[strlen(cur)-1] = 0;
                if (*cur == 0) 
-               {
-                       /* reset to default */
-                       lcd_print("Linux " UTS_RELEASE);
-               }
-               else
-               {
-                       /* chop off trailing \n.. if the user gives multiple
-                        * \n then it's all their fault.. */
-                       if (*cur && cur[strlen(cur)-1] == '\n')
-                               cur[strlen(cur)-1] = 0;
-                       lcd_print(cur);
-               }
+                       cur = lcd_text_default;
+               lcd_print(cur);
                break;
        default:
                return 0;
@@ -438,11 +431,7 @@ static __inline__ int led_get_diskio_activity(void)
 #define HEARTBEAT_2ND_RANGE_START (HZ*22/100)
 #define HEARTBEAT_2ND_RANGE_END   (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)
 
-#if HZ==100
- #define NORMALIZED_COUNT(count) (count)
-#else
- #define NORMALIZED_COUNT(count) (count/(HZ/100))
-#endif
+#define NORMALIZED_COUNT(count) (count/(HZ/100))
 
 static void led_tasklet_func(unsigned long unused)
 {
@@ -567,7 +556,7 @@ int __init register_led_driver(int model, char *cmd_reg, char *data_reg)
                printk(KERN_INFO "LCD display at %p,%p registered\n", 
                        LCD_CMD_REG , LCD_DATA_REG);
                led_func_ptr = led_LCD_driver;
-               lcd_print( "Linux " UTS_RELEASE );
+               lcd_print( lcd_text_default );
                led_type = LED_HASLCD;
                break;
 
index ce2412a..b756cf6 100644 (file)
 
 #define MODULE_NAME "SBA"
 
+#ifdef CONFIG_PROC_FS
+/* depends on proc fs support. But costs CPU performance */
+#undef SBA_COLLECT_STATS
+#endif
+
 /*
 ** The number of debug flags is a clue - this code is fragile.
 ** Don't even think about messing with it unless you have
@@ -217,7 +222,7 @@ struct ioc {
        } saved[DELAYED_RESOURCE_CNT];
 #endif
 
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
 #define SBA_SEARCH_SAMPLE      0x100
        unsigned long avg_search[SBA_SEARCH_SAMPLE];
        unsigned long avg_idx;  /* current index into avg_search */
@@ -560,7 +565,7 @@ static int
 sba_alloc_range(struct ioc *ioc, size_t size)
 {
        unsigned int pages_needed = size >> IOVP_SHIFT;
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
        unsigned long cr_start = mfctl(16);
 #endif
        unsigned long pide;
@@ -579,7 +584,8 @@ sba_alloc_range(struct ioc *ioc, size_t size)
        if (pide >= (ioc->res_size << 3)) {
                pide = sba_search_bitmap(ioc, pages_needed);
                if (pide >= (ioc->res_size << 3))
-                       panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
+                       panic("%s: I/O MMU @ %lx is out of mapping resources\n",
+                             __FILE__, ioc->ioc_hpa);
        }
 
 #ifdef ASSERT_PDIR_SANITY
@@ -594,7 +600,7 @@ sba_alloc_range(struct ioc *ioc, size_t size)
                (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
                ioc->res_bitshift );
 
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
        {
                unsigned long cr_end = mfctl(16);
                unsigned long tmp = cr_end - cr_start;
@@ -636,7 +642,7 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
                __FUNCTION__, (uint) iova, size,
                bits_not_wanted, m, pide, res_ptr, *res_ptr);
 
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
        ioc->used_pages -= bits_not_wanted;
 #endif
 
@@ -854,7 +860,7 @@ sba_map_single(struct device *dev, void *addr, size_t size,
        sba_check_pdir(ioc,"Check before sba_map_single()");
 #endif
 
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
        ioc->msingle_calls++;
        ioc->msingle_pages += size >> IOVP_SHIFT;
 #endif
@@ -929,7 +935,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
 
        spin_lock_irqsave(&ioc->res_lock, flags);
 
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
        ioc->usingle_calls++;
        ioc->usingle_pages += size >> IOVP_SHIFT;
 #endif
@@ -1057,7 +1063,7 @@ sba_fill_pdir(
                        printk(KERN_DEBUG " %2d : %08lx/%05x %p/%05x\n",
                                nents,
                                (unsigned long) sg_dma_address(startsg), cnt,
-                               sg_virt_address(startsg), startsg->length
+                               sg_virt_addr(startsg), startsg->length
                );
 #else
                DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n",
@@ -1093,7 +1099,7 @@ sba_fill_pdir(
                        cnt += dma_offset;
                        dma_offset=0;   /* only want offset on first chunk */
                        cnt = ROUNDUP(cnt, IOVP_SIZE);
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
                        ioc->msg_pages += cnt >> IOVP_SHIFT;
 #endif
                        do {
@@ -1300,7 +1306,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
        }
 #endif
 
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
        ioc->msg_calls++;
 #endif
 
@@ -1365,7 +1371,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
        ioc = GET_IOC(dev);
        ASSERT(ioc);
 
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
        ioc->usg_calls++;
 #endif
 
@@ -1378,7 +1384,7 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
        while (sg_dma_len(sglist) && nents--) {
 
                sba_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
-#ifdef CONFIG_PROC_FS
+#ifdef SBA_COLLECT_STATS
                ioc->usg_pages += ((sg_dma_address(sglist) & ~IOVP_MASK) + sg_dma_len(sglist) + IOVP_SIZE - 1) >> PAGE_SHIFT;
                ioc->usingle_calls--;   /* kluge since call is unmap_sg() */
 #endif
@@ -1680,6 +1686,21 @@ sba_hw_init(struct sba_device *sba_dev)
        int num_ioc;
        u64 ioc_ctl;
 
+       if (!is_pdc_pat()) {
+               /* Shutdown the USB controller on Astro-based workstations.
+               ** Once we reprogram the IOMMU, the next DMA performed by
+               ** USB will HPMC the box.
+               */
+               pdc_io_reset_devices();
+
+               /*
+               ** XXX May need something more sophisticated to deal
+               **     with DMA from LAN. Maybe use page zero boot device
+               **     as a handle to talk to PDC about which device to
+               **     shutdown. This also needs to work for is_pdc_pat(). 
+               */
+       }
+
        ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
        DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
                __FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
@@ -1766,7 +1787,8 @@ sba_common_init(struct sba_device *sba_dev)
 
                if (NULL == sba_dev->ioc[i].res_map)
                {
-                       panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__ );
+                       panic("%s:%s() could not allocate resource map\n",
+                             __FILE__, __FUNCTION__ );
                }
 
                memset(sba_dev->ioc[i].res_map, 0, res_size);
@@ -1829,7 +1851,9 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len)
        struct sba_device *sba_dev = sba_list;
        struct ioc *ioc = &sba_dev->ioc[0];     /* FIXME: Multi-IOC support! */
        int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
+#ifdef SBA_COLLECT_STATS
        unsigned long i = 0, avg = 0, min, max;
+#endif
 
        sprintf(buf, "%s rev %d.%d\n",
                sba_dev->name,
@@ -1841,12 +1865,13 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len)
                (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
                total_pages);
 
+       sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
+               buf, ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
+
+#ifdef SBA_COLLECT_STATS
        sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
                total_pages - ioc->used_pages, ioc->used_pages,
                (int) (ioc->used_pages * 100 / total_pages));
-       
-       sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-               buf, ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
 
        min = max = ioc->avg_search[0];
        for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
@@ -1876,6 +1901,7 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len)
        sprintf(buf, "%spci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
                buf, ioc->usg_calls, ioc->usg_pages,
                (int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
+#endif
 
        return strlen(buf);
 }
index 7673be9..0ff55af 100644 (file)
@@ -9,7 +9,8 @@
  *     (C) Copyright 2000 Linuxcare Canada, Inc.
  *     (C) Copyright 2000 Martin K. Petersen <mkp@linuxcare.com>
  *     (C) Copyright 2000 Alex deVries <alex@linuxcare.com>
- *      (C) Copyright 2001 John Marvin <jsm@fc.hp.com>
+ *      (C) Copyright 2001 John Marvin <jsm fc hp com>
+ *      (C) Copyright 2003 Grant Grundler <grundler parisc-linux org>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
 #include <asm/irq.h>
 #include <asm/superio.h>
 
-static struct superio_device sio_dev = {
-       .iosapic_irq = -1
-};
-
+static struct superio_device sio_dev;
 
-#undef DEBUG_INIT
 
-void
-superio_inform_irq(int irq)
-{
-    if (sio_dev.iosapic_irq != -1) {
-       printk(KERN_ERR "SuperIO: superio_inform_irq called twice! (more than one SuperIO?)\n");
-       BUG();
-       return;
-    }
+#undef DEBUG_SUPERIO_INIT
 
-    sio_dev.iosapic_irq = irq;
-}
+#ifdef DEBUG_SUPERIO_INIT
+#define DBG_INIT(x...)  printk(x)
+#else
+#define DBG_INIT(x...)
+#endif
 
 static irqreturn_t
 superio_interrupt(int irq, void *devp, struct pt_regs *regs)
@@ -135,7 +128,6 @@ superio_interrupt(int irq, void *devp, struct pt_regs *regs)
        }
 
        /* Call the appropriate device's interrupt */
-
        do_irq(&sio->irq_region->action[local_irq],
                sio->irq_region->data.irqbase + local_irq,
                regs);
@@ -153,34 +145,39 @@ superio_init(struct superio_device *sio)
 {
        struct pci_dev *pdev = sio->lio_pdev;
        u16 word;
-       u8  i;
 
-       if (!pdev || sio->iosapic_irq == -1) {
-               printk(KERN_ERR "All SuperIO functions not found!\n");
-               BUG();
+        if (sio->suckyio_irq_enabled)                                       
                return;
-       }
+
+       if (!pdev) BUG();
+       if (!sio->usb_pdev) BUG();
+
+       /* use the IRQ iosapic found for USB INT D... */
+       pdev->irq = sio->usb_pdev->irq;
+
+       /* ...then properly fixup the USB to point at suckyio PIC */
+       sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
 
        printk (KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
-               pci_name(pdev),sio->iosapic_irq);
+               pci_name(pdev),pdev->irq);
 
        /* Find our I/O devices */
-       pci_read_config_word (pdev, SIO_SP1BAR, &sio->sp1_base);
+       pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
        sio->sp1_base &= ~1;
        printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base);
 
-       pci_read_config_word (pdev, SIO_SP2BAR, &sio->sp2_base);
+       pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base);
        sio->sp2_base &= ~1;
        printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base);
 
-       pci_read_config_word (pdev, SIO_PPBAR, &sio->pp_base);
+       pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base);
        sio->pp_base &= ~1;
        printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base);
 
-       pci_read_config_word (pdev, SIO_FDCBAR, &sio->fdc_base);
+       pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base);
        sio->fdc_base &= ~1;
        printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base);
-       pci_read_config_word (pdev, SIO_ACPIBAR, &sio->acpi_base);
+       pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base);
        sio->acpi_base &= ~1;
        printk (KERN_INFO "SuperIO: ACPI at 0x%x\n", sio->acpi_base);
 
@@ -192,24 +189,53 @@ superio_init(struct superio_device *sio)
         pci_read_config_word (pdev, PCI_COMMAND, &word);
        word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO;
        pci_write_config_word (pdev, PCI_COMMAND, word);
+
        pci_set_master (pdev);
+       pci_enable_device(pdev);
 
-       /* Next project is programming the onboard interrupt
-        * controllers.  PDC hasn't done this for us, since it's using
-        * polled I/O.
+       /*
+        * Next project is programming the onboard interrupt controllers.
+        * PDC hasn't done this for us, since it's using polled I/O.
+        *
+        * XXX Use dword writes to avoid bugs in Elroy or Suckyio Config
+        *     space access.  PCI is by nature a 32-bit bus and config
+        *     space can be sensitive to that.
         */
 
-       /* Set PIC interrupts to edge triggered */
-       pci_write_config_byte (pdev, TRIGGER_1, 0x0);
-       pci_write_config_byte (pdev, TRIGGER_2, 0x0);
-
-       /* Disable all interrupt routing */
-       for (i = IR_LOW ; i < IR_HIGH ; i++)
-               pci_write_config_byte (pdev, i, 0x0);
+       /* 0x64 - 0x67 :
+               DMA Rtg 2
+               DMA Rtg 3
+               DMA Chan Ctl
+               TRIGGER_1    == 0x82   USB & IDE level triggered, rest to edge
+       */
+       pci_write_config_dword (pdev, 0x64,         0x82000000U);
+
+       /* 0x68 - 0x6b :
+               TRIGGER_2    == 0x00   all edge triggered (not used)
+               CFG_IR_SER   == 0x43   SerPort1 = IRQ3, SerPort2 = IRQ4
+               CFG_IR_PF    == 0x65   ParPort  = IRQ5, FloppyCtlr = IRQ6
+               CFG_IR_IDE   == 0x07   IDE1 = IRQ7, reserved
+       */
+       pci_write_config_dword (pdev, TRIGGER_2,    0x07654300U);
+
+       /* 0x6c - 0x6f :
+               CFG_IR_INTAB == 0x00
+               CFG_IR_INTCD == 0x10   USB = IRQ1
+               CFG_IR_PS2   == 0x00
+               CFG_IR_FXBUS == 0x00
+       */
+       pci_write_config_dword (pdev, CFG_IR_INTAB, 0x00001000U);
+
+       /* 0x70 - 0x73 :
+               CFG_IR_USB   == 0x00  not used. USB is connected to INTD.
+               CFG_IR_ACPI  == 0x00  not used.
+               DMA Priority == 0x4c88  Power on default value. NFC.
+       */
+       pci_write_config_dword (pdev, CFG_IR_USB, 0x4c880000U);
 
        /* PIC1 Initialization Command Word register programming */
        outb (0x11,IC_PIC1+0);  /* ICW1: ICW4 write req | ICW1 */
-       outb (0x00,IC_PIC1+1);  /* ICW2: N/A */
+       outb (0x00,IC_PIC1+1);  /* ICW2: interrupt vector table - not used */
        outb (0x04,IC_PIC1+1);  /* ICW3: Cascade */
        outb (0x01,IC_PIC1+1);  /* ICW4: x86 mode */
 
@@ -228,19 +254,8 @@ superio_init(struct superio_device *sio)
        outb (0x68,IC_PIC1+0);  /* OCW3: OCW3 select | ESMM | SMM */
 
        /* Write master mask reg */
-
        outb (0xff,IC_PIC1+1);
 
-       /* Set up interrupt routing */
-
-       pci_write_config_byte (pdev, IR_USB, 0x10); /* USB on IRQ1 */
-       pci_write_config_byte (pdev, IR_SER, 0x43); /* SP1 on IRQ3, SP2 on IRQ4 */
-       pci_write_config_byte (pdev, IR_PFD, 0x65); /* PAR on IRQ5, FDC on IRQ6 */
-       pci_write_config_byte (pdev, IR_IDE, 0x07); /* IDE1 on IRQ7 */
-       
-       /* Set USB and IDE to level triggered interrupts, rest to edge */
-       pci_write_config_byte (pdev, TRIGGER_1, 0x82); /* IRQ 1 and 7 */
-
        /* Setup USB power regulation */
        outb(1, sio->acpi_base + USB_REG_CR);
        if (inb(sio->acpi_base + USB_REG_CR) & 1)
@@ -248,20 +263,18 @@ superio_init(struct superio_device *sio)
        else
                printk(KERN_ERR "USB regulator not initialized!\n");
 
-       pci_enable_device(pdev);
-
-       if (request_irq(sio->iosapic_irq,superio_interrupt,SA_INTERRUPT,
-                       "SuperIO",(void *)sio)) {
+       if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT,
+                       "SuperIO", (void *)sio)) {
 
                printk(KERN_ERR "SuperIO: could not get irq\n");
                BUG();
                return;
        }
 
-       sio->iosapic_irq_enabled = 1;
-       
+       sio->suckyio_irq_enabled = 1;
 }
 
+
 static void
 superio_disable_irq(void *dev, int local_irq)
 {
@@ -283,30 +296,21 @@ superio_disable_irq(void *dev, int local_irq)
 static void
 superio_enable_irq(void *dev, int local_irq)
 {
-       struct superio_device *sio = (struct superio_device *)dev;
        u8 r8;
 
        if ((local_irq < 1) || (local_irq == 2) || (local_irq > 7)) {
-           printk(KERN_ERR "SuperIO: Illegal irq number.\n");
+           printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", local_irq);
            BUG();
            return;
        }
 
-       /*
-        * It's possible that we haven't initialized the legacy IO
-        * function yet. If not, do it now.
-        */
-
-       if (!sio->iosapic_irq_enabled)
-               superio_init(sio);
-
        /* Unmask interrupt */
-
        r8 = inb(IC_PIC1+1);
        r8 &= ~(1 << local_irq);
        outb (r8,IC_PIC1+1);
 }
 
+
 static void
 superio_mask_irq(void *dev, int local_irq)
 {
@@ -326,7 +330,7 @@ static struct irq_region_ops superio_irq_ops = {
        .unmask_irq =   superio_unmask_irq
 };
 
-#ifdef DEBUG_INIT
+#ifdef DEBUG_SUPERIO_INIT
 static unsigned short expected_device[3] = {
        PCI_DEVICE_ID_NS_87415,
        PCI_DEVICE_ID_NS_87560_LIO,
@@ -338,7 +342,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
 {
        int local_irq;
 
-#ifdef DEBUG_INIT
+#ifdef DEBUG_SUPERIO_INIT
        int fn;
        fn = PCI_FUNC(pcidev->devfn);
 
@@ -375,9 +379,10 @@ int superio_fixup_irq(struct pci_dev *pcidev)
                local_irq = IDE_IRQ;
                break;
        case PCI_DEVICE_ID_NS_87560_LIO:        /* Function 1 */
-               sio_dev.lio_pdev = pcidev; /* save for later initialization */
+               sio_dev.lio_pdev = pcidev;      /* save for superio_init() */
                return -1;
        case PCI_DEVICE_ID_NS_87560_USB:        /* Function 2 */
+               sio_dev.usb_pdev = pcidev;      /* save for superio_init() */
                local_irq = USB_IRQ;
                break;
        default:
@@ -411,20 +416,29 @@ superio_serial_init(void)
 {
 #ifdef CONFIG_SERIAL_8250
        int retval;
+       extern void serial8250_console_init(void); /* drivers/serial/8250.c */
        
        if (!sio_dev.irq_region)
                return; /* superio not present */
 
-       if (!sio_dev.iosapic_irq_enabled)
-               superio_init(&sio_dev);
+       if (!serial) {
+               printk(KERN_WARNING "SuperIO: Could not get memory for serial struct.\n");
+               return;
+       }
 
        serial[0].iobase = sio_dev.sp1_base;
-       retval = early_serial_setup(&serial[0]);
+       serial[0].irq = sio_dev.irq_region->data.irqbase + SP1_IRQ;
 
-       if (retval < 0)
+       retval = early_serial_setup(&serial[0]);
+       if (retval < 0) {
                printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n");
+               return;
+       }
+
+       serial8250_console_init();
 
        serial[1].iobase = sio_dev.sp2_base;
+       serial[1].irq = sio_dev.irq_region->data.irqbase + SP2_IRQ;
        retval = early_serial_setup(&serial[1]);
 
        if (retval < 0)
@@ -432,30 +446,20 @@ superio_serial_init(void)
 #endif /* CONFIG_SERIAL_8250 */
 }
 
-EXPORT_SYMBOL(superio_serial_init);
-
 
-#ifdef CONFIG_PARPORT_PC
-void __devinit
+static void __devinit
 superio_parport_init(void)
 {
-       if (!sio_dev.irq_region)
-               return; /* superio not present */
-
-       if (!sio_dev.iosapic_irq_enabled)
-               superio_init(&sio_dev);
-
-       if (!parport_pc_probe_port(sio_dev.pp_base, 
-               0 /*base_hi*/,
-               sio_dev.irq_region->data.irqbase + PAR_IRQ, 
-               PARPORT_DMA_NONE /* dma */,
-               NULL /*struct pci_dev* */))
+#ifdef CONFIG_PARPORT_PC
+       if (!parport_pc_probe_port(sio_dev.pp_base,
+                       0 /*base_hi*/,
+                       sio_dev.irq_region->data.irqbase + PAR_IRQ, 
+                       PARPORT_DMA_NONE /* dma */,
+                       NULL /*struct pci_dev* */) )
 
                printk(KERN_WARNING "SuperIO: Probing parallel port failed.\n");
-}
-
-EXPORT_SYMBOL(superio_parport_init);
 #endif /* CONFIG_PARPORT_PC */
+}
 
 
 int
@@ -471,36 +475,35 @@ EXPORT_SYMBOL(superio_get_ide_irq);
 
 static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-#ifdef DEBUG_INIT
-       printk("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n",
+
+       /*
+       ** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a
+       ** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000
+       ** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310
+       */
+       DBG_INIT("superio_probe(%s) ven 0x%x dev 0x%x sv 0x%x sd 0x%x class 0x%x\n",
                pci_name(dev),
                dev->vendor, dev->device,
                dev->subsystem_vendor, dev->subsystem_device,
                dev->class);
-/*
-** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a
-** superio_probe(00:0e.1) ven 0x100b dev 0xe sv 0x0 sd 0x0 class 0x68000
-** superio_probe(00:0e.2) ven 0x100b dev 0x12 sv 0x0 sd 0x0 class 0xc0310
-*/
-#endif
 
-       /* superio_fixup_irq(dev); */
+       superio_init(&sio_dev);
 
-       if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) {
-#ifdef CONFIG_PARPORT_PC
+       if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) {        /* Function 1 */
                superio_parport_init();
-#endif
-#ifdef CONFIG_SERIAL_8250
                superio_serial_init();
-#endif
-               /* REVISIT : superio_fdc_init() ? */
+               /* REVISIT XXX : superio_fdc_init() ? */
                return 0;
+       } else if (dev->device == PCI_DEVICE_ID_NS_87415) {     /* Function 0 */
+               DBG_INIT("superio_probe: ignoring IDE 87415\n");
+       } else if (dev->device == PCI_DEVICE_ID_NS_87560_USB) { /* Function 2 */
+               DBG_INIT("superio_probe: ignoring USB OHCI controller\n");
        } else {
-               /* don't claim this device; let whatever either driver
-                * do it 
-                */ 
-               return -1;
+               DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n");
        }
+
+       /* Let appropriate other driver claim this device. */ 
+       return -ENODEV;
 }
 
 static struct pci_device_id superio_tbl[] = {
@@ -524,10 +527,6 @@ static void __exit superio_exit(void)
        pci_unregister_driver(&superio_driver);
 }
 
-/* Make late initcall to ensure the serial and tty layers are initialised
- * before we start superio.
- *
- * FIXME: does this break the superio console?
- */
+
 module_init(superio_modinit);
 module_exit(superio_exit);
index 70934ed..50df37e 100644 (file)
@@ -40,6 +40,7 @@ static struct daisydev {
        int daisy;
        int devnum;
 } *topology = NULL;
+static spinlock_t topology_lock = SPIN_LOCK_UNLOCKED;
 
 static int numdevs = 0;
 
@@ -52,22 +53,18 @@ static int assign_addrs (struct parport *port);
 /* Add a device to the discovered topology. */
 static void add_dev (int devnum, struct parport *port, int daisy)
 {
-       struct daisydev *newdev;
+       struct daisydev *newdev, **p;
        newdev = kmalloc (sizeof (struct daisydev), GFP_KERNEL);
        if (newdev) {
                newdev->port = port;
                newdev->daisy = daisy;
                newdev->devnum = devnum;
-               newdev->next = topology;
-               if (!topology || topology->devnum >= devnum)
-                       topology = newdev;
-               else {
-                       struct daisydev *prev = topology;
-                       while (prev->next && prev->next->devnum < devnum)
-                               prev = prev->next;
-                       newdev->next = prev->next;
-                       prev->next = newdev;
-               }
+               spin_lock(&topology_lock);
+               for (p = &topology; *p && (*p)->devnum<devnum; p = &(*p)->next)
+                       ;
+               newdev->next = *p;
+               *p = newdev;
+               spin_unlock(&topology_lock);
        }
 }
 
@@ -157,26 +154,25 @@ int parport_daisy_init (struct parport *port)
 /* Forget about devices on a physical port. */
 void parport_daisy_fini (struct parport *port)
 {
-       struct daisydev *dev, *prev = topology;
-       while (prev && prev->port == port) {
-               topology = topology->next;
-               kfree (prev);
-               prev = topology;
-       }
-
-       while (prev) {
-               dev = prev->next;
-               if (dev && dev->port == port) {
-                       prev->next = dev->next;
-                       kfree (dev);
+       struct daisydev **p;
+
+       spin_lock(&topology_lock);
+       p = &topology;
+       while (*p) {
+               struct daisydev *dev = *p;
+               if (dev->port != port) {
+                       p = &dev->next;
+                       continue;
                }
-               prev = prev->next;
+               *p = dev->next;
+               kfree(dev);
        }
 
        /* Gaps in the numbering could be handled better.  How should
            someone enumerate through all IEEE1284.3 devices in the
            topology?. */
        if (!topology) numdevs = 0;
+       spin_unlock(&topology_lock);
        return;
 }
 
@@ -205,30 +201,34 @@ struct pardevice *parport_open (int devnum, const char *name,
                                void (*irqf) (int, void *, struct pt_regs *),
                                int flags, void *handle)
 {
-       struct parport *port = parport_enumerate ();
+       struct daisydev *p = topology;
+       struct parport *port;
        struct pardevice *dev;
-       int portnum;
-       int muxnum;
-       int daisynum;
-
-       if (parport_device_coords (devnum,  &portnum, &muxnum, &daisynum))
-               return NULL;
+       int daisy;
 
-       while (port && ((port->portnum != portnum) ||
-                       (port->muxport != muxnum)))
-               port = port->next;
+       spin_lock(&topology_lock);
+       while (p && p->devnum != devnum)
+               p = p->next;
 
-       if (!port)
-               /* No corresponding parport. */
+       if (!p) {
+               spin_unlock(&topology_lock);
                return NULL;
+       }
+
+       daisy = p->daisy;
+       port = parport_get_port(p->port);
+       spin_unlock(&topology_lock);
 
        dev = parport_register_device (port, name, pf, kf,
                                       irqf, flags, handle);
-       if (dev)
-               dev->daisy = daisynum;
+       parport_put_port(port);
+       if (!dev)
+               return NULL;
+
+       dev->daisy = daisy;
 
        /* Check that there really is a device to select. */
-       if (daisynum >= 0) {
+       if (daisy >= 0) {
                int selected;
                parport_claim_or_block (dev);
                selected = port->daisy;
@@ -271,16 +271,19 @@ void parport_close (struct pardevice *dev)
 
 int parport_device_num (int parport, int mux, int daisy)
 {
-       struct daisydev *dev = topology;
+       int res = -ENXIO;
+       struct daisydev *dev;
 
+       spin_lock(&topology_lock);
+       dev = topology;
        while (dev && dev->port->portnum != parport &&
               dev->port->muxport != mux && dev->daisy != daisy)
                dev = dev->next;
+       if (dev)
+               res = dev->devnum;
+       spin_unlock(&topology_lock);
 
-       if (!dev)
-               return -ENXIO;
-
-       return dev->devnum;
+       return res;
 }
 
 /**
@@ -310,17 +313,23 @@ int parport_device_num (int parport, int mux, int daisy)
 
 int parport_device_coords (int devnum, int *parport, int *mux, int *daisy)
 {
-       struct daisydev *dev = topology;
+       struct daisydev *dev;
+
+       spin_lock(&topology_lock);
 
+       dev = topology;
        while (dev && dev->devnum != devnum)
                dev = dev->next;
 
-       if (!dev)
+       if (!dev) {
+               spin_unlock(&topology_lock);
                return -ENXIO;
+       }
 
        if (parport) *parport = dev->port->portnum;
        if (mux) *mux = dev->port->muxport;
        if (daisy) *daisy = dev->daisy;
+       spin_unlock(&topology_lock);
        return 0;
 }
 
@@ -557,9 +566,13 @@ static int assign_addrs (struct parport *port)
 
 int parport_find_device (const char *mfg, const char *mdl, int from)
 {
-       struct daisydev *d = topology; /* sorted by devnum */
+       struct daisydev *d;
+       int res = -1;
 
        /* Find where to start. */
+
+       spin_lock(&topology_lock);
+       d = topology; /* sorted by devnum */
        while (d && d->devnum <= from)
                d = d->next;
 
@@ -575,9 +588,10 @@ int parport_find_device (const char *mfg, const char *mdl, int from)
        }
 
        if (d)
-               return d->devnum;
+               res = d->devnum;
 
-       return -1;
+       spin_unlock(&topology_lock);
+       return res;
 }
 
 /**
@@ -601,8 +615,11 @@ int parport_find_device (const char *mfg, const char *mdl, int from)
 
 int parport_find_class (parport_device_class cls, int from)
 {
-       struct daisydev *d = topology; /* sorted by devnum */
+       struct daisydev *d;
+       int res = -1;
 
+       spin_lock(&topology_lock);
+       d = topology; /* sorted by devnum */
        /* Find where to start. */
        while (d && d->devnum <= from)
                d = d->next;
@@ -612,7 +629,8 @@ int parport_find_class (parport_device_class cls, int from)
                d = d->next;
 
        if (d)
-               return d->devnum;
+               res = d->devnum;
 
-       return -1;
+       spin_unlock(&topology_lock);
+       return res;
 }
index 3783b0d..2b27a29 100644 (file)
@@ -445,6 +445,7 @@ static int __initdata parport_count;
 
 static int __devinit parport_init_chip(struct parisc_device *dev)
 {
+       struct parport *p;
        unsigned long port;
 
        if (!dev->irq) {
@@ -467,13 +468,36 @@ static int __devinit parport_init_chip(struct parisc_device *dev)
                printk("%s: enhanced parport-modes not supported.\n", __FUNCTION__);
        }
        
-       if (parport_gsc_probe_port(port, 0, dev->irq,
-                       /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL))
+       p = parport_gsc_probe_port(port, 0, dev->irq,
+                       /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL);
+       if (p)
                parport_count++;
+       dev->dev.driver_data = p;
 
        return 0;
 }
 
+static void __devexit parport_remove_chip(struct parisc_device *dev)
+{
+       struct parport *p = dev->dev.driver_data;
+       if (p) {
+               struct parport_gsc_private *priv = p->private_data;
+               struct parport_operations *ops = p->ops;
+               if (p->dma != PARPORT_DMA_NONE)
+                       free_dma(p->dma);
+               if (p->irq != PARPORT_IRQ_NONE)
+                       free_irq(p->irq, p);
+               parport_proc_unregister(p);
+               if (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 */
+       }
+}
+
 static struct parisc_device_id parport_tbl[] = {
        { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 },
        { 0, }
@@ -485,6 +509,7 @@ static struct parisc_driver parport_driver = {
        .name           = "Parallel",
        .id_table       = parport_tbl,
        .probe          = parport_init_chip,
+       .remove         = parport_remove_chip,
 };
 
 int __devinit parport_gsc_init(void)
@@ -494,27 +519,6 @@ int __devinit parport_gsc_init(void)
 
 static void __devexit parport_gsc_exit(void)
 {
-       struct parport *p = parport_enumerate(), *tmp;
-       while (p) {
-               tmp = p->next;
-               if (p->modes & PARPORT_MODE_PCSPP) { 
-                       struct parport_gsc_private *priv = p->private_data;
-                       struct parport_operations *ops = p->ops;
-                       if (p->dma != PARPORT_DMA_NONE)
-                               free_dma(p->dma);
-                       if (p->irq != PARPORT_IRQ_NONE)
-                               free_irq(p->irq, p);
-                       parport_proc_unregister(p);
-                       if (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 */
-               }
-               p = tmp;
-       }
        unregister_parisc_driver(&parport_driver);
 }
 
index b6198f6..ae02714 100644 (file)
@@ -44,8 +44,13 @@ int parport_default_spintime =  DEFAULT_SPIN_TIME;
 static struct parport *portlist = NULL, *portlist_tail = NULL;
 static spinlock_t parportlist_lock = SPIN_LOCK_UNLOCKED;
 
+/* list of all allocated ports, sorted by ->number */
+static LIST_HEAD(all_ports);
+static spinlock_t full_list_lock = SPIN_LOCK_UNLOCKED;
+
 static struct parport_driver *driver_chain = NULL;
-static spinlock_t driverlist_lock = SPIN_LOCK_UNLOCKED;
+
+static DECLARE_MUTEX(registration_lock);
 
 /* What you can do to a port that's gone away.. */
 static void dead_write_lines (struct parport *p, unsigned char b){}
@@ -98,55 +103,19 @@ static struct parport_operations dead_ops = {
 /* Call attach(port) for each registered driver. */
 static void attach_driver_chain(struct parport *port)
 {
+       /* caller has exclusive registration_lock */
        struct parport_driver *drv;
-       void (**attach) (struct parport *);
-       int count = 0, i;
-
-       /* This is complicated because attach() must be able to block,
-        * but we can't let it do that while we're holding a
-        * spinlock. */
-
-       spin_lock (&driverlist_lock);
        for (drv = driver_chain; drv; drv = drv->next)
-               count++;
-       spin_unlock (&driverlist_lock);
-
-       /* Drivers can unregister here; that's okay.  If they register
-        * they'll be given an attach during parport_register_driver,
-        * so that's okay too.  The only worry is that someone might
-        * get given an attach twice if they registered just before
-        * this function gets called. */
-
-       /* Hmm, this could be fixed with a generation number..
-        * FIXME */
-
-       attach = kmalloc (sizeof (void(*)(struct parport *)) * count,
-                         GFP_KERNEL);
-       if (!attach) {
-               printk (KERN_WARNING "parport: not enough memory to attach\n");
-               return;
-       }
-
-       spin_lock (&driverlist_lock);
-       for (i = 0, drv = driver_chain; drv && i < count; drv = drv->next)
-               attach[i++] = drv->attach;
-       spin_unlock (&driverlist_lock);
-
-       for (count = 0; count < i; count++)
-               (*attach[count]) (port);
-
-       kfree (attach);
+               drv->attach(port);
 }
 
 /* Call detach(port) for each registered driver. */
 static void detach_driver_chain(struct parport *port)
 {
+       /* caller has exclusive registration_lock */
        struct parport_driver *drv;
-
-       spin_lock (&driverlist_lock);
        for (drv = driver_chain; drv; drv = drv->next)
                drv->detach (port);
-       spin_unlock (&driverlist_lock);
 }
 
 /* Ask kmod for some lowlevel drivers. */
@@ -174,7 +143,7 @@ static void get_lowlevel_driver (void)
  *     pointer it must call parport_get_port() to do so.  Calling
  *     parport_register_device() on that port will do this for you.
  *
- *     The driver's detach() function may not block.  The port that
+ *     The driver's detach() function may block.  The port that
  *     detach() is given will be valid for the duration of the
  *     callback, but if the driver wants to take a copy of the
  *     pointer it must call parport_get_port() to do so.
@@ -185,8 +154,6 @@ static void get_lowlevel_driver (void)
 int parport_register_driver (struct parport_driver *drv)
 {
        struct parport *port;
-       struct parport **ports;
-       int count = 0, i;
 
        if (!portlist)
                get_lowlevel_driver ();
@@ -199,31 +166,12 @@ int parport_register_driver (struct parport_driver *drv)
         * it.  But we need to hold a spinlock to iterate over the
         * list of ports.. */
 
-       spin_lock (&parportlist_lock);
+       down(&registration_lock);
        for (port = portlist; port; port = port->next)
-               count++;
-       spin_unlock (&parportlist_lock);
-
-       ports = kmalloc (sizeof (struct parport *) * count, GFP_KERNEL);
-       if (!ports)
-               printk (KERN_WARNING "parport: not enough memory to attach\n");
-       else {
-               spin_lock (&parportlist_lock);
-               for (i = 0, port = portlist; port && i < count;
-                    port = port->next)
-                       ports[i++] = port;
-               spin_unlock (&parportlist_lock);
-
-               for (count = 0; count < i; count++)
-                       drv->attach (ports[count]);
-
-               kfree (ports);
-       }
-
-       spin_lock (&driverlist_lock);
+               drv->attach(port);
        drv->next = driver_chain;
        driver_chain = drv;
-       spin_unlock (&driverlist_lock);
+       up(&registration_lock);
 
        return 0;
 }
@@ -241,49 +189,46 @@ int parport_register_driver (struct parport_driver *drv)
  *     be called, and for each port that attach() was called for, the
  *     detach() routine will have been called.
  *
- *     If the caller's attach() function can block, it is their
- *     responsibility to make sure to wait for it to exit before
- *     unloading.
- *
- *     All the driver's detach() calls are guaranteed to have
+ *     All the driver's attach() and detach() calls are guaranteed to have
  *     finished by the time this function returns.
- *
- *     The driver's detach() call is not allowed to block.
  **/
 
 void parport_unregister_driver (struct parport_driver *arg)
 {
-       struct parport_driver *drv = driver_chain, *olddrv = NULL;
+       struct parport_driver *drv, *olddrv = NULL;
 
+       down(&registration_lock);
+       drv = driver_chain;
        while (drv) {
                if (drv == arg) {
                        struct parport *port;
 
-                       spin_lock (&driverlist_lock);
                        if (olddrv)
                                olddrv->next = drv->next;
                        else
                                driver_chain = drv->next;
-                       spin_unlock (&driverlist_lock);
 
                        /* Call the driver's detach routine for each
                         * port to clean up any resources that the
                         * attach routine acquired. */
-                       spin_lock (&parportlist_lock);
                        for (port = portlist; port; port = port->next)
                                drv->detach (port);
-                       spin_unlock (&parportlist_lock);
+                       up(&registration_lock);
 
                        return;
                }
                olddrv = drv;
                drv = drv->next;
        }
+       up(&registration_lock);
 }
 
 static void free_port (struct parport *port)
 {
        int d;
+       spin_lock(&full_list_lock);
+       list_del(&port->full_list);
+       spin_unlock(&full_list_lock);
        for (d = 0; d < 5; d++) {
                if (port->probe_info[d].class_name)
                        kfree (port->probe_info[d].class_name);
@@ -386,8 +331,9 @@ struct parport *parport_enumerate(void)
 struct parport *parport_register_port(unsigned long base, int irq, int dma,
                                      struct parport_operations *ops)
 {
+       struct list_head *l;
        struct parport *tmp;
-       int portnum;
+       int num;
        int device;
        char *name;
 
@@ -418,6 +364,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
        init_MUTEX_LOCKED (&tmp->ieee1284.irq); /* actually a semaphore at 0 */
        tmp->spintime = parport_default_spintime;
        atomic_set (&tmp->ref_count, 1);
+       INIT_LIST_HEAD(&tmp->full_list);
 
        name = kmalloc(15, GFP_KERNEL);
        if (!name) {
@@ -427,53 +374,22 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
        }
        /* Search for the lowest free parport number. */
 
-       spin_lock_irq (&parportlist_lock);
-       for (portnum = 0; ; portnum++) {
-               struct parport *itr = portlist;
-               while (itr) {
-                       if (itr->number == portnum)
-                               /* No good, already used. */
-                               break;
-                       else
-                               itr = itr->next;
-               }
-
-               if (itr == NULL)
-                       /* Got to the end of the list. */
+       spin_lock(&full_list_lock);
+       for (l = all_ports.next, num = 0; l != &all_ports; l = l->next, num++) {
+               struct parport *p = list_entry(l, struct parport, full_list);
+               if (p->number != num)
                        break;
        }
+       tmp->portnum = tmp->number = num;
+       list_add_tail(&tmp->full_list, l);
+       spin_unlock(&full_list_lock);
 
        /*
         * Now that the portnum is known finish doing the Init.
         */
-       tmp->portnum = tmp->number = portnum;
-       sprintf(name, "parport%d", portnum);
+       sprintf(name, "parport%d", tmp->portnum = tmp->number);
        tmp->name = name;
 
-       
-       /*
-        * Chain the entry to our list.
-        *
-        * This function must not run from an irq handler so we don' t need
-        * to clear irq on the local CPU. -arca
-        */
-
-       /* We are locked against anyone else performing alterations, but
-        * because of parport_enumerate people can still _read_ the list
-        * while we are changing it; so be careful..
-        *
-        * It's okay to have portlist_tail a little bit out of sync
-        * since it's only used for changing the list, not for reading
-        * from it.
-        */
-
-       if (portlist_tail)
-               portlist_tail->next = tmp;
-       portlist_tail = tmp;
-       if (!portlist)
-               portlist = tmp;
-       spin_unlock_irq(&parportlist_lock);
-
        for (device = 0; device < 5; device++)
                /* assume the worst */
                tmp->probe_info[device].class = PARPORT_CLASS_LEGACY;
@@ -497,6 +413,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
 
 void parport_announce_port (struct parport *port)
 {
+
 #ifdef CONFIG_PARPORT_1284
        /* Analyse the IEEE1284.3 topology of the port. */
        if (parport_daisy_init (port) == 0) {
@@ -514,8 +431,27 @@ void parport_announce_port (struct parport *port)
        }
 #endif
 
+       down(&registration_lock);
+       /* We are locked against anyone else performing alterations, but
+        * because of parport_enumerate people can still _read_ the list
+        * while we are changing it; so be careful..
+        *
+        * It's okay to have portlist_tail a little bit out of sync
+        * since it's only used for changing the list, not for reading
+        * from it.
+        */
+
+       spin_lock_irq(&parportlist_lock);
+       if (portlist_tail)
+               portlist_tail->next = port;
+       portlist_tail = port;
+       if (!portlist)
+               portlist = port;
+       spin_unlock_irq(&parportlist_lock);
+
        /* Let drivers know that a new port has arrived. */
        attach_driver_chain (port);
+       up(&registration_lock);
 }
 
 /**
@@ -541,6 +477,7 @@ void parport_unregister_port(struct parport *port)
 {
        struct parport *p;
 
+       down(&registration_lock);
        port->ops = &dead_ops;
 
        /* Spread the word. */
@@ -570,6 +507,7 @@ void parport_unregister_port(struct parport *port)
                             "%s not found in port list!\n", port->name);
        }
        spin_unlock(&parportlist_lock);
+       up(&registration_lock);
 
        /* Yes, parport_enumerate _is_ unsafe.  Don't use it. */
        parport_put_port (port);
index 4534bae..7e227ec 100644 (file)
@@ -31,33 +31,9 @@ config PNP_DEBUG
 comment "Protocols"
        depends on PNP
 
-config ISAPNP
-       bool "ISA Plug and Play support (EXPERIMENTAL)"
-       depends on PNP && EXPERIMENTAL
-       help
-         Say Y here if you would like support for ISA Plug and Play devices.
-         Some information is in <file:Documentation/isapnp.txt>.
-
-         If unsure, say Y.
-
-config PNPBIOS
-       bool "Plug and Play BIOS support (EXPERIMENTAL)"
-       depends on PNP && EXPERIMENTAL
-       ---help---
-         Linux uses the PNPBIOS as defined in "Plug and Play BIOS
-         Specification Version 1.0A May 5, 1994" to autodetect built-in
-         mainboard resources (e.g. parallel port resources).
+source "drivers/pnp/isapnp/Kconfig"
 
-         Some features (e.g. event notification, docking station information,
-         ISAPNP services) are not used.
-
-         Note: ACPI is expected to supersede PNPBIOS some day, currently it
-         co-exists nicely.
-
-         See latest pcmcia-cs (stand-alone package) for a nice "lspnp" tools,
-         or have a look at /proc/bus/pnp.
-
-         If unsure, say Y.
+source "drivers/pnp/pnpbios/Kconfig"
 
 endmenu
 
index 4a0cff3..97eeecf 100644 (file)
@@ -26,8 +26,25 @@ static const struct pnp_card_device_id * match_card(struct pnp_card_driver * drv
 {
        const struct pnp_card_device_id * drv_id = drv->id_table;
        while (*drv_id->id){
-               if (compare_pnp_id(card->id,drv_id->id))
-                       return drv_id;
+               if (compare_pnp_id(card->id,drv_id->id)) {
+                       int i = 0;
+                       for (;;) {
+                               int found;
+                               struct pnp_dev *dev;
+                               if (i == PNP_MAX_DEVICES || ! *drv_id->devs[i].id)
+                                       return drv_id;
+                               found = 0;
+                               card_for_each_dev(card, dev) {
+                                       if (compare_pnp_id(dev->id, drv_id->devs[i].id)) {
+                                               found = 1;
+                                               break;
+                                       }
+                               }
+                               if (! found)
+                                       break;
+                               i++;
+                       }
+               }
                drv_id++;
        }
        return NULL;
@@ -122,6 +139,39 @@ static void pnp_release_card(struct device *dmdev)
        kfree(card);
 }
 
+
+static ssize_t pnp_show_card_name(struct device *dmdev, char *buf)
+{
+       char *str = buf;
+       struct pnp_card *card = to_pnp_card(dmdev);
+       str += sprintf(str,"%s\n", card->name);
+       return (str - buf);
+}
+
+static DEVICE_ATTR(name,S_IRUGO,pnp_show_card_name,NULL);
+
+static ssize_t pnp_show_card_ids(struct device *dmdev, char *buf)
+{
+       char *str = buf;
+       struct pnp_card *card = to_pnp_card(dmdev);
+       struct pnp_id * pos = card->id;
+
+       while (pos) {
+               str += sprintf(str,"%s\n", pos->id);
+               pos = pos->next;
+       }
+       return (str - buf);
+}
+
+static DEVICE_ATTR(card_id,S_IRUGO,pnp_show_card_ids,NULL);
+
+static int pnp_interface_attach_card(struct pnp_card *card)
+{
+       device_create_file(&card->dev,&dev_attr_name);
+       device_create_file(&card->dev,&dev_attr_card_id);
+       return 0;
+}
+
 /**
  * pnp_add_card - adds a PnP card to the PnP Layer
  * @card: pointer to the card to add
@@ -141,6 +191,7 @@ int pnp_add_card(struct pnp_card * card)
        error = device_register(&card->dev);
 
        if (error == 0) {
+               pnp_interface_attach_card(card);
                spin_lock(&pnp_lock);
                list_add_tail(&card->global_list, &pnp_cards);
                list_add_tail(&card->protocol_list, &card->protocol->cards);
diff --git a/drivers/pnp/isapnp/Kconfig b/drivers/pnp/isapnp/Kconfig
new file mode 100644 (file)
index 0000000..bb63261
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# ISA Plug and Play configuration
+#
+config ISAPNP
+       bool "ISA Plug and Play support (EXPERIMENTAL)"
+       depends on PNP && EXPERIMENTAL
+       help
+         Say Y here if you would like support for ISA Plug and Play devices.
+         Some information is in <file:Documentation/isapnp.txt>.
+
+         If unsure, say Y.
index 3c05c31..565242a 100644 (file)
@@ -1039,17 +1039,17 @@ static int isapnp_set_resources(struct pnp_dev *dev, struct pnp_resource_table *
 
        isapnp_cfg_begin(dev->card->number, dev->number);
        dev->active = 1;
-       for (tmp = 0; tmp < PNP_MAX_PORT && !(res->port_resource[tmp].flags & IORESOURCE_UNSET); tmp++)
+       for (tmp = 0; tmp < PNP_MAX_PORT && (res->port_resource[tmp].flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO; tmp++)
                isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), res->port_resource[tmp].start);
-       for (tmp = 0; tmp < PNP_MAX_IRQ && !(res->irq_resource[tmp].flags & IORESOURCE_UNSET); tmp++) {
+       for (tmp = 0; tmp < PNP_MAX_IRQ && (res->irq_resource[tmp].flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ; tmp++) {
                int irq = res->irq_resource[tmp].start;
                if (irq == 2)
                        irq = 9;
                isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
        }
-       for (tmp = 0; tmp < PNP_MAX_DMA && !(res->dma_resource[tmp].flags & IORESOURCE_UNSET); tmp++)
+       for (tmp = 0; tmp < PNP_MAX_DMA && (res->dma_resource[tmp].flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA; tmp++)
                isapnp_write_byte(ISAPNP_CFG_DMA+tmp, res->dma_resource[tmp].start);
-       for (tmp = 0; tmp < PNP_MAX_MEM && !(res->mem_resource[tmp].flags & IORESOURCE_UNSET); tmp++)
+       for (tmp = 0; tmp < PNP_MAX_MEM && (res->mem_resource[tmp].flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM; tmp++)
                isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (res->mem_resource[tmp].start >> 8) & 0xffff);
        /* FIXME: We aren't handling 32bit mems properly here */
        isapnp_activate(dev->number);
diff --git a/drivers/pnp/pnpbios/Kconfig b/drivers/pnp/pnpbios/Kconfig
new file mode 100644 (file)
index 0000000..58eb949
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# Plug and Play BIOS configuration
+#
+config PNPBIOS
+       bool "Plug and Play BIOS support (EXPERIMENTAL)"
+       depends on PNP && EXPERIMENTAL
+       ---help---
+         Linux uses the PNPBIOS as defined in "Plug and Play BIOS
+         Specification Version 1.0A May 5, 1994" to autodetect built-in
+         mainboard resources (e.g. parallel port resources).
+
+         Some features (e.g. event notification, docking station information,
+         ISAPNP services) are not currently implemented.
+
+         If you would like the kernel to detect and allocate resources to
+         your mainboard devices (on some systems they are disabled by the
+         BIOS) say Y here.  Also the PNPBIOS can help prevent resource
+         conflicts between mainboard devices and other bus devices.
+
+         Note: ACPI is expected to supersede PNPBIOS some day, currently it
+         co-exists nicely.  If you have a non-ISA system that supports ACPI,
+         you probably don't need PNPBIOS support.
+
+config PNPBIOS_PROC_FS
+       bool "Plug and Play BIOS /proc interface"
+       depends on PNPBIOS && PROC_FS
+       ---help---
+         If you say Y here and to "/proc file system support", you will be
+         able to directly access the PNPBIOS.  This includes resource
+         allocation, ESCD, and other PNPBIOS services.  Using this
+         interface is potentially dangerous because the PNPBIOS driver will
+         not be notified of any resource changes made by writting directly.
+         Also some buggy systems will fault when accessing certain features
+         in the PNPBIOS /proc interface (e.g. "boot" configs).
+
+         See the latest pcmcia-cs (stand-alone package) for a nice set of
+         PNPBIOS /proc interface tools (lspnp and setpnp).
+
+         Unless you are debugging or have other specific reasons, it is
+         recommended that you say N here.
+
index fe3dd8f..3cd3ed7 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for the kernel PNPBIOS driver.
 #
 
-pnpbios-proc-$(CONFIG_PROC_FS) = proc.o
+pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
 
 obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
index f2dd3e4..967ecb2 100644 (file)
@@ -264,19 +264,49 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table
        return ret;
 }
 
+static void pnpbios_zero_data_stream(struct pnp_bios_node * node)
+{
+       unsigned char * p = (char *)node->data;
+       unsigned char * end = (char *)(node->data + node->size);
+       unsigned int len;
+       int i;
+       while ((char *)p < (char *)end) {
+               if(p[0] & 0x80) { /* large tag */
+                       len = (p[2] << 8) | p[1];
+                       p += 3;
+               } else {
+                       if (((p[0]>>3) & 0x0f) == 0x0f)
+                               return;
+                       len = p[0] & 0x07;
+                       p += 1;
+               }
+               for (i = 0; i < len; i++)
+                       p[i] = 0;
+               p += len;
+       }
+       printk(KERN_ERR "PnPBIOS: Resource structure did not contain an end tag.\n");
+}
+
 static int pnpbios_disable_resources(struct pnp_dev *dev)
 {
        struct pnp_bios_node * node;
+       u8 nodenum = dev->number;
        int ret;
 
        /* just in case */
        if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev))
                return -EPERM;
 
-       /* the value of this will be zero */
        node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -ENOMEM;
+
+       if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) {
+               kfree(node);
+               return -ENODEV;
+       }
+       pnpbios_zero_data_stream(node);
+
        ret = pnp_bios_set_dev_node(dev->number, (char)PNPMODE_DYNAMIC, node);
        kfree(node);
        if (ret > 0)
index 9287ffa..01896e7 100644 (file)
@@ -36,7 +36,7 @@ extern void pnpid32_to_pnpid(u32 id, char *str);
 extern void pnpbios_print_status(const char * module, u16 status);
 extern void pnpbios_calls_init(union pnp_bios_install_struct * header);
 
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_PNPBIOS_PROC_FS
 extern int pnpbios_interface_attach_device(struct pnp_bios_node * node);
 extern int pnpbios_proc_init (void);
 extern void pnpbios_proc_exit (void);
@@ -44,4 +44,4 @@ extern void pnpbios_proc_exit (void);
 static inline int pnpbios_interface_attach_device(struct pnp_bios_node * node) { return 0; }
 static inline int pnpbios_proc_init (void) { return 0; }
 static inline void pnpbios_proc_exit (void) { ; }
-#endif /* CONFIG_PROC */
+#endif /* CONFIG_PNPBIOS_PROC_FS */
index a01fb0c..8f660aa 100644 (file)
@@ -9802,28 +9802,28 @@ static int
 qeth_get_internal_functions(void)
 {
        struct net_device *dev;
-
-       dev = (struct net_device *) kmalloc(sizeof (struct net_device),
-                                           GFP_KERNEL);
+#ifdef CONFIG_NET_ETHERNET
+       dev = alloc_etherdev(0);
        if (!dev) {
                PRINT_ERR("Not enough memory for internal functions.\n");
                return -ENOMEM;
        }
-#ifdef CONFIG_NET_ETHERNET
-       ether_setup(dev);
        qeth_my_eth_header = dev->hard_header;
        qeth_my_eth_rebuild_header = dev->rebuild_header;
        qeth_my_eth_header_cache = dev->hard_header_cache;
        qeth_my_eth_header_cache_update = dev->header_cache_update;
+       free_netdev(dev);
 #endif
 #ifdef CONFIG_TR
-       tr_setup(dev);
+       dev = alloc_trdev(0);
+       if (!dev) {
+               PRINT_ERR("Not enough memory for internal functions.\n");
+               return -ENOMEM;
+       }
        qeth_my_tr_header = dev->hard_header;
        qeth_my_tr_rebuild_header = dev->rebuild_header;
+       free_netdev(dev);
 #endif
-
-       kfree(dev);
-
        return 0;
 }
 
index defa4ff..6bb6cb0 100644 (file)
@@ -1207,6 +1207,23 @@ config SCSI_QLOGIC_ISP
          To compile this driver as a module, choose M here: the
          module will be called qlogicisp.
 
+config SCSI_QLOGIC_FC
+       tristate "Qlogic ISP FC SCSI support"
+       depends on PCI && SCSI
+       help
+         This is a driver for the QLogic ISP2100 SCSI-FCP host adapter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called qlogicfc.
+
+config SCSI_QLOGIC_FC_FIRMWARE
+       bool "Include loadable firmware in driver"
+       depends on SCSI_QLOGIC_FC
+       help
+         Say Y to include ISP2X00 Fabric Initiator/Target Firmware, with
+         expanded LUN addressing and FcTape (FCP-2) support, in the
+         qlogicfc driver. This is required on some platforms.
+
 config SCSI_QLOGIC_1280
        tristate "Qlogic QLA 1280 SCSI support"
        depends on PCI && SCSI
index 9a8fc70..c6f498e 100644 (file)
@@ -69,6 +69,7 @@ obj-$(CONFIG_SCSI_NCR_Q720)   += NCR_Q720_mod.o
 obj-$(CONFIG_SCSI_SYM53C416)   += sym53c416.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas.o
 obj-$(CONFIG_SCSI_QLOGIC_ISP)  += qlogicisp.o 
+obj-$(CONFIG_SCSI_QLOGIC_FC)   += qlogicfc.o 
 obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o 
 obj-$(CONFIG_SCSI_QLA2XXX)     += qla2xxx/
 obj-$(CONFIG_SCSI_PAS16)       += pas16.o
index bcee9b2..0a3f553 100644 (file)
 #include <linux/config.h>
 
 /* The following #define is to avoid a clash with hosts.c */
-#define IMM_CODE 1
 #define IMM_PROBE_SPP   0x0001
 #define IMM_PROBE_PS2   0x0002
 #define IMM_PROBE_ECR   0x0010
 #define IMM_PROBE_EPP17 0x0100
 #define IMM_PROBE_EPP19 0x0200
 
-void imm_reset_pulse(unsigned int base);
-static int device_check(int host_no);
-
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/blkdev.h>
 #include <asm/io.h>
 #include <linux/parport.h>
@@ -32,205 +31,86 @@ static int device_check(int host_no);
 #include "hosts.h"
 
 typedef struct {
-    struct pardevice *dev;     /* Parport device entry         */
-    int base;                  /* Actual port address          */
-    int base_hi;               /* Hi Base address for ECP-ISA chipset */
-    int mode;                  /* Transfer mode                */
-    int host;                  /* Host number (for proc)       */
-    Scsi_Cmnd *cur_cmd;                /* Current queued command       */
-    struct work_struct imm_tq;         /* Polling interrupt stuff       */
-    unsigned long jstart;      /* Jiffies at start             */
-    unsigned failed:1;         /* Failure flag                 */
-    unsigned dp:1;             /* Data phase present           */
-    unsigned rd:1;             /* Read data in data phase      */
-    unsigned p_busy:1;         /* Parport sharing busy flag    */
+       struct pardevice *dev;  /* Parport device entry         */
+       int base;               /* Actual port address          */
+       int base_hi;            /* Hi Base address for ECP-ISA chipset */
+       int mode;               /* Transfer mode                */
+       Scsi_Cmnd *cur_cmd;     /* Current queued command       */
+       struct work_struct imm_tq;      /* Polling interrupt stuff       */
+       unsigned long jstart;   /* Jiffies at start             */
+       unsigned failed:1;      /* Failure flag                 */
+       unsigned dp:1;          /* Data phase present           */
+       unsigned rd:1;          /* Read data in data phase      */
+       unsigned wanted:1;      /* Parport sharing busy flag    */
+       wait_queue_head_t *waiting;
+       struct Scsi_Host *host;
+       struct list_head list;
 } imm_struct;
 
-#define IMM_EMPTY \
-{      .base           = -1,           \
-       .mode           = IMM_AUTODETECT,       \
-       .host           = -1,           \
-}
+static void imm_reset_pulse(unsigned int base);
+static int device_check(imm_struct *dev);
 
 #include "imm.h"
-#define NO_HOSTS 4
-static imm_struct imm_hosts[NO_HOSTS] =
-{IMM_EMPTY, IMM_EMPTY, IMM_EMPTY, IMM_EMPTY};
-
-#define IMM_BASE(x)    imm_hosts[(x)].base
-#define IMM_BASE_HI(x)     imm_hosts[(x)].base_hi
 
-int parbus_base[NO_HOSTS] =
-{0x03bc, 0x0378, 0x0278, 0x0000};
-
-void imm_wakeup(void *ref)
+static inline imm_struct *imm_dev(struct Scsi_Host *host)
 {
-    imm_struct *imm_dev = (imm_struct *) ref;
-
-    if (!imm_dev->p_busy)
-       return;
-
-    if (parport_claim(imm_dev->dev)) {
-       printk("imm: bug in imm_wakeup\n");
-       return;
-    }
-    imm_dev->p_busy = 0;
-    imm_dev->base = imm_dev->dev->port->base;
-    if (imm_dev->cur_cmd)
-       imm_dev->cur_cmd->SCp.phase++;
-    return;
+       return *(imm_struct **)&host->hostdata;
 }
 
-int imm_release(struct Scsi_Host *host)
-{
-    int host_no = host->unique_id;
-
-    printk("Releasing imm%i\n", host_no);
-    scsi_unregister(host);
-    parport_unregister_device(imm_hosts[host_no].dev);
-    return 0;
-}
+static spinlock_t arbitration_lock = SPIN_LOCK_UNLOCKED;
 
-static int imm_pb_claim(int host_no)
+static void got_it(imm_struct *dev)
 {
-    if (parport_claim(imm_hosts[host_no].dev)) {
-       imm_hosts[host_no].p_busy = 1;
-       return 1;
-    }
-    if (imm_hosts[host_no].cur_cmd)
-       imm_hosts[host_no].cur_cmd->SCp.phase++;
-    return 0;
+       dev->base = dev->dev->port->base;
+       if (dev->cur_cmd)
+               dev->cur_cmd->SCp.phase = 1;
+       else
+               wake_up(dev->waiting);
 }
 
-#define imm_pb_release(x) parport_release(imm_hosts[(x)].dev)
-
-/***************************************************************************
- *                   Parallel port probing routines                        *
- ***************************************************************************/
-
-static Scsi_Host_Template driver_template = {
-       .proc_name                      = "imm",
-       .proc_info                      = imm_proc_info,
-       .name                           = "Iomega VPI2 (imm) interface",
-       .detect                         = imm_detect,
-       .release                        = imm_release,
-       .queuecommand                   = imm_queuecommand,
-       .eh_abort_handler               = imm_abort,
-       .eh_bus_reset_handler           = imm_reset,
-       .eh_host_reset_handler          = imm_reset, 
-       .bios_param                     = imm_biosparam,
-       .this_id                        = 7,
-       .sg_tablesize                   = SG_ALL,
-       .cmd_per_lun                    = 1,
-       .use_clustering                 = ENABLE_CLUSTERING,
-};
-#include  "scsi_module.c"
-
-int imm_detect(Scsi_Host_Template * host)
+static void imm_wakeup(void *ref)
 {
-    struct Scsi_Host *hreg;
-    int ports;
-    int i, nhosts, try_again;
-    struct parport *pb;
-
-    pb = parport_enumerate();
-
-    printk("imm: Version %s\n", IMM_VERSION);
-    nhosts = 0;
-    try_again = 0;
-
-    if (!pb) {
-       printk("imm: parport reports no devices.\n");
-       return 0;
-    }
-  retry_entry:
-    for (i = 0; pb; i++, pb = pb->next) {
-       int modes, ppb;
-
-       imm_hosts[i].dev =
-           parport_register_device(pb, "imm", NULL, imm_wakeup,
-                                   NULL, 0, (void *) &imm_hosts[i]);
-
-       if (!imm_hosts[i].dev)
-           continue;
-
-       /* Claim the bus so it remembers what we do to the control
-        * registers. [ CTR and ECP ]
-        */
-       if (imm_pb_claim(i)) {
-           unsigned long now = jiffies;
-           while (imm_hosts[i].p_busy) {
-               schedule();     /* We are safe to schedule here */
-               if (time_after(jiffies, now + 3 * HZ)) {
-                   printk(KERN_ERR "imm%d: failed to claim parport because a "
-                     "pardevice is owning the port for too longtime!\n",
-                          i);
-                   parport_unregister_device (imm_hosts[i].dev);
-                   return 0;
-               }
-           }
+       imm_struct *dev = (imm_struct *) ref;
+       unsigned long flags;
+
+       spin_lock_irqsave(&arbitration_lock, flags);
+       if (dev->wanted) {
+               parport_claim(dev->dev);
+               got_it(dev);
+               dev->wanted = 0;
        }
-       ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base;
-       IMM_BASE_HI(i) = imm_hosts[i].dev->port->base_hi;
-       w_ctr(ppb, 0x0c);
-       modes = imm_hosts[i].dev->port->modes;
-
-       /* Mode detection works up the chain of speed
-        * This avoids a nasty if-then-else-if-... tree
-        */
-       imm_hosts[i].mode = IMM_NIBBLE;
-
-       if (modes & PARPORT_MODE_TRISTATE)
-           imm_hosts[i].mode = IMM_PS2;
-
-       /* Done configuration */
-       imm_pb_release(i);
+       spin_unlock_irqrestore(&arbitration_lock, flags);
+}
 
-       if (imm_init(i)) {
-           parport_unregister_device(imm_hosts[i].dev);
-           continue;
+static int imm_pb_claim(imm_struct *dev)
+{
+       unsigned long flags;
+       int res = 1;
+       spin_lock_irqsave(&arbitration_lock, flags);
+       if (parport_claim(dev->dev) == 0) {
+               got_it(dev);
+               res = 0;
        }
+       dev->wanted = res;
+       spin_unlock_irqrestore(&arbitration_lock, flags);
+       return res;
+}
 
-       /* now the glue ... */
-       switch (imm_hosts[i].mode) {
-       case IMM_NIBBLE:
-           ports = 3;
-           break;
-       case IMM_PS2:
-           ports = 3;
-           break;
-       case IMM_EPP_8:
-       case IMM_EPP_16:
-       case IMM_EPP_32:
-           ports = 8;
-           break;
-       default:                /* Never gets here */
-           continue;
-       }
+static void imm_pb_dismiss(imm_struct *dev)
+{
+       unsigned long flags;
+       int wanted;
+       spin_lock_irqsave(&arbitration_lock, flags);
+       wanted = dev->wanted;
+       dev->wanted = 0;
+       spin_unlock_irqrestore(&arbitration_lock, flags);
+       if (!wanted)
+               parport_release(dev->dev);
+}
 
-       INIT_WORK(&imm_hosts[i].imm_tq, imm_interrupt, &imm_hosts[i]);
-       
-       host->can_queue = IMM_CAN_QUEUE;
-       host->sg_tablesize = imm_sg;
-       hreg = scsi_register(host, 0);
-       if(hreg == NULL)
-               continue;
-       hreg->io_port = pb->base;
-       hreg->n_io_port = ports;
-       hreg->dma_channel = -1;
-       hreg->unique_id = i;
-       imm_hosts[i].host = hreg->host_no;
-       nhosts++;
-    }
-    if (nhosts == 0) {
-       if (try_again == 1) {
-           return 0;
-       }
-       try_again = 1;
-       goto retry_entry;
-    } else {
-       return 1;               /* return number of hosts detected */
-    }
+static inline void imm_pb_release(imm_struct *dev)
+{
+       parport_release(dev->dev);
 }
 
 /* This is to give the imm driver a way to modify the timings (and other
@@ -240,60 +120,62 @@ int imm_detect(Scsi_Host_Template * host)
  * testing...
  * Also gives a method to use a script to obtain optimum timings (TODO)
  */
-static inline int imm_proc_write(int hostno, char *buffer, int length)
+static inline int imm_proc_write(imm_struct *dev, char *buffer, int length)
 {
-    unsigned long x;
-
-    if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
-       x = simple_strtoul(buffer + 5, NULL, 0);
-       imm_hosts[hostno].mode = x;
-       return length;
-    }
-    printk("imm /proc: invalid variable\n");
-    return (-EINVAL);
+       unsigned long x;
+
+       if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
+               x = simple_strtoul(buffer + 5, NULL, 0);
+               dev->mode = x;
+               return length;
+       }
+       printk("imm /proc: invalid variable\n");
+       return (-EINVAL);
 }
 
-int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                 int length, int inout)
+static int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start,
+                       off_t offset, int length, int inout)
 {
-    int i;
-    int len = 0;
-
-    for (i = 0; i < 4; i++)
-       if (imm_hosts[i].host == host->host_no)
-           break;
-
-    if (inout)
-       return imm_proc_write(i, buffer, length);
-
-    len += sprintf(buffer + len, "Version : %s\n", IMM_VERSION);
-    len += sprintf(buffer + len, "Parport : %s\n", imm_hosts[i].dev->port->name);
-    len += sprintf(buffer + len, "Mode    : %s\n", IMM_MODE_STRING[imm_hosts[i].mode]);
-
-    /* Request for beyond end of buffer */
-    if (offset > len)
-       return 0;
+       imm_struct *dev = imm_dev(host);
+       int len = 0;
+
+       if (inout)
+               return imm_proc_write(dev, buffer, length);
+
+       len += sprintf(buffer + len, "Version : %s\n", IMM_VERSION);
+       len +=
+           sprintf(buffer + len, "Parport : %s\n",
+                   dev->dev->port->name);
+       len +=
+           sprintf(buffer + len, "Mode    : %s\n",
+                   IMM_MODE_STRING[dev->mode]);
+
+       /* Request for beyond end of buffer */
+       if (offset > len)
+               return 0;
 
-    *start = buffer + offset;
-    len -= offset;
-    if (len > length)
-       len = length;
-    return len;
+       *start = buffer + offset;
+       len -= offset;
+       if (len > length)
+               len = length;
+       return len;
 }
 
 #if IMM_DEBUG > 0
 #define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\
           y, __FUNCTION__, __LINE__); imm_fail_func(x,y);
-static inline void imm_fail_func(int host_no, int error_code)
+static inline void
+imm_fail_func(imm_struct *dev, int error_code)
 #else
-static inline void imm_fail(int host_no, int error_code)
+static inline void
+imm_fail(imm_struct *dev, int error_code)
 #endif
 {
-    /* If we fail a device then we trash status / message bytes */
-    if (imm_hosts[host_no].cur_cmd) {
-       imm_hosts[host_no].cur_cmd->result = error_code << 16;
-       imm_hosts[host_no].failed = 1;
-    }
+       /* If we fail a device then we trash status / message bytes */
+       if (dev->cur_cmd) {
+               dev->cur_cmd->result = error_code << 16;
+               dev->failed = 1;
+       }
 }
 
 /*
@@ -303,96 +185,97 @@ static inline void imm_fail(int host_no, int error_code)
  * doesn't appear to be designed to support interrupts.  We spin on
  * the 0x80 ready bit. 
  */
-static unsigned char imm_wait(int host_no)
+static unsigned char imm_wait(imm_struct *dev)
 {
-    int k;
-    unsigned short ppb = IMM_BASE(host_no);
-    unsigned char r;
+       int k;
+       unsigned short ppb = dev->base;
+       unsigned char r;
 
-    w_ctr(ppb, 0x0c);
+       w_ctr(ppb, 0x0c);
 
-    k = IMM_SPIN_TMO;
-    do {
-       r = r_str(ppb);
-       k--;
-       udelay(1);
-    }
-    while (!(r & 0x80) && (k));
-
-    /*
-     * STR register (LPT base+1) to SCSI mapping:
-     *
-     * STR      imm     imm
-     * ===================================
-     * 0x80     S_REQ   S_REQ
-     * 0x40     !S_BSY  (????)
-     * 0x20     !S_CD   !S_CD
-     * 0x10     !S_IO   !S_IO
-     * 0x08     (????)  !S_BSY
-     *
-     * imm      imm     meaning
-     * ==================================
-     * 0xf0     0xb8    Bit mask
-     * 0xc0     0x88    ZIP wants more data
-     * 0xd0     0x98    ZIP wants to send more data
-     * 0xe0     0xa8    ZIP is expecting SCSI command data
-     * 0xf0     0xb8    end of transfer, ZIP is sending status
-     */
-    w_ctr(ppb, 0x04);
-    if (k)
-       return (r & 0xb8);
-
-    /* Counter expired - Time out occurred */
-    imm_fail(host_no, DID_TIME_OUT);
-    printk("imm timeout in imm_wait\n");
-    return 0;                  /* command timed out */
+       k = IMM_SPIN_TMO;
+       do {
+               r = r_str(ppb);
+               k--;
+               udelay(1);
+       }
+       while (!(r & 0x80) && (k));
+
+       /*
+        * STR register (LPT base+1) to SCSI mapping:
+        *
+        * STR      imm     imm
+        * ===================================
+        * 0x80     S_REQ   S_REQ
+        * 0x40     !S_BSY  (????)
+        * 0x20     !S_CD   !S_CD
+        * 0x10     !S_IO   !S_IO
+        * 0x08     (????)  !S_BSY
+        *
+        * imm      imm     meaning
+        * ==================================
+        * 0xf0     0xb8    Bit mask
+        * 0xc0     0x88    ZIP wants more data
+        * 0xd0     0x98    ZIP wants to send more data
+        * 0xe0     0xa8    ZIP is expecting SCSI command data
+        * 0xf0     0xb8    end of transfer, ZIP is sending status
+        */
+       w_ctr(ppb, 0x04);
+       if (k)
+               return (r & 0xb8);
+
+       /* Counter expired - Time out occurred */
+       imm_fail(dev, DID_TIME_OUT);
+       printk("imm timeout in imm_wait\n");
+       return 0;               /* command timed out */
 }
 
 static int imm_negotiate(imm_struct * tmp)
 {
-    /*
-     * The following is supposedly the IEEE 1284-1994 negotiate
-     * sequence. I have yet to obtain a copy of the above standard
-     * so this is a bit of a guess...
-     *
-     * A fair chunk of this is based on the Linux parport implementation
-     * of IEEE 1284.
-     *
-     * Return 0 if data available
-     *        1 if no data available
-     */
-
-    unsigned short base = tmp->base;
-    unsigned char a, mode;
-
-    switch (tmp->mode) {
-    case IMM_NIBBLE:
-       mode = 0x00;
-       break;
-    case IMM_PS2:
-       mode = 0x01;
-       break;
-    default:
-       return 0;
-    }
-
-    w_ctr(base, 0x04);
-    udelay(5);
-    w_dtr(base, mode);
-    udelay(100);
-    w_ctr(base, 0x06);
-    udelay(5);
-    a = (r_str(base) & 0x20) ? 0 : 1;
-    udelay(5);
-    w_ctr(base, 0x07);
-    udelay(5);
-    w_ctr(base, 0x06);
-
-    if (a) {
-       printk("IMM: IEEE1284 negotiate indicates no data available.\n");
-       imm_fail(tmp->host, DID_ERROR);
-    }
-    return a;
+       /*
+        * The following is supposedly the IEEE 1284-1994 negotiate
+        * sequence. I have yet to obtain a copy of the above standard
+        * so this is a bit of a guess...
+        *
+        * A fair chunk of this is based on the Linux parport implementation
+        * of IEEE 1284.
+        *
+        * Return 0 if data available
+        *        1 if no data available
+        */
+
+       unsigned short base = tmp->base;
+       unsigned char a, mode;
+
+       switch (tmp->mode) {
+       case IMM_NIBBLE:
+               mode = 0x00;
+               break;
+       case IMM_PS2:
+               mode = 0x01;
+               break;
+       default:
+               return 0;
+       }
+
+       w_ctr(base, 0x04);
+       udelay(5);
+       w_dtr(base, mode);
+       udelay(100);
+       w_ctr(base, 0x06);
+       udelay(5);
+       a = (r_str(base) & 0x20) ? 0 : 1;
+       udelay(5);
+       w_ctr(base, 0x07);
+       udelay(5);
+       w_ctr(base, 0x06);
+
+       if (a) {
+               printk
+                   ("IMM: IEEE1284 negotiate indicates no data available.\n");
+               imm_fail(tmp, DID_ERROR);
+       }
+       return a;
 }
 
 /* 
@@ -400,364 +283,346 @@ static int imm_negotiate(imm_struct * tmp)
  */
 static inline void epp_reset(unsigned short ppb)
 {
-    int i;
+       int i;
 
-    i = r_str(ppb);
-    w_str(ppb, i);
-    w_str(ppb, i & 0xfe);
+       i = r_str(ppb);
+       w_str(ppb, i);
+       w_str(ppb, i & 0xfe);
 }
 
 /* 
  * Wait for empty ECP fifo (if we are in ECP fifo mode only)
  */
-static inline void ecp_sync(unsigned short hostno)
+static inline void ecp_sync(imm_struct *dev)
 {
-    int i, ppb_hi=IMM_BASE_HI(hostno);
+       int i, ppb_hi = dev->base_hi;
 
-    if (ppb_hi == 0) return;
+       if (ppb_hi == 0)
+               return;
 
-    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
-        for (i = 0; i < 100; i++) {
-           if (r_ecr(ppb_hi) & 0x01)
-               return;
-           udelay(5);
+       if ((r_ecr(ppb_hi) & 0xe0) == 0x60) {   /* mode 011 == ECP fifo mode */
+               for (i = 0; i < 100; i++) {
+                       if (r_ecr(ppb_hi) & 0x01)
+                               return;
+                       udelay(5);
+               }
+               printk("imm: ECP sync failed as data still present in FIFO.\n");
        }
-        printk("imm: ECP sync failed as data still present in FIFO.\n");
-    }
 }
 
 static int imm_byte_out(unsigned short base, const char *buffer, int len)
 {
-    int i;
-
-    w_ctr(base, 0x4);          /* apparently a sane mode */
-    for (i = len >> 1; i; i--) {
-       w_dtr(base, *buffer++);
-       w_ctr(base, 0x5);       /* Drop STROBE low */
-       w_dtr(base, *buffer++);
-       w_ctr(base, 0x0);       /* STROBE high + INIT low */
-    }
-    w_ctr(base, 0x4);          /* apparently a sane mode */
-    return 1;                  /* All went well - we hope! */
+       int i;
+
+       w_ctr(base, 0x4);       /* apparently a sane mode */
+       for (i = len >> 1; i; i--) {
+               w_dtr(base, *buffer++);
+               w_ctr(base, 0x5);       /* Drop STROBE low */
+               w_dtr(base, *buffer++);
+               w_ctr(base, 0x0);       /* STROBE high + INIT low */
+       }
+       w_ctr(base, 0x4);       /* apparently a sane mode */
+       return 1;               /* All went well - we hope! */
 }
 
 static int imm_nibble_in(unsigned short base, char *buffer, int len)
 {
-    unsigned char l;
-    int i;
-
-    /*
-     * The following is based on documented timing signals
-     */
-    w_ctr(base, 0x4);
-    for (i = len; i; i--) {
-       w_ctr(base, 0x6);
-       l = (r_str(base) & 0xf0) >> 4;
-       w_ctr(base, 0x5);
-       *buffer++ = (r_str(base) & 0xf0) | l;
+       unsigned char l;
+       int i;
+
+       /*
+        * The following is based on documented timing signals
+        */
        w_ctr(base, 0x4);
-    }
-    return 1;                  /* All went well - we hope! */
+       for (i = len; i; i--) {
+               w_ctr(base, 0x6);
+               l = (r_str(base) & 0xf0) >> 4;
+               w_ctr(base, 0x5);
+               *buffer++ = (r_str(base) & 0xf0) | l;
+               w_ctr(base, 0x4);
+       }
+       return 1;               /* All went well - we hope! */
 }
 
 static int imm_byte_in(unsigned short base, char *buffer, int len)
 {
-    int i;
-
-    /*
-     * The following is based on documented timing signals
-     */
-    w_ctr(base, 0x4);
-    for (i = len; i; i--) {
-       w_ctr(base, 0x26);
-       *buffer++ = r_dtr(base);
-       w_ctr(base, 0x25);
-    }
-    return 1;                  /* All went well - we hope! */
+       int i;
+
+       /*
+        * The following is based on documented timing signals
+        */
+       w_ctr(base, 0x4);
+       for (i = len; i; i--) {
+               w_ctr(base, 0x26);
+               *buffer++ = r_dtr(base);
+               w_ctr(base, 0x25);
+       }
+       return 1;               /* All went well - we hope! */
 }
 
-static int imm_out(int host_no, char *buffer, int len)
+static int imm_out(imm_struct *dev, char *buffer, int len)
 {
-    int r;
-    unsigned short ppb = IMM_BASE(host_no);
-
-    r = imm_wait(host_no);
-
-    /*
-     * Make sure that:
-     * a) the SCSI bus is BUSY (device still listening)
-     * b) the device is listening
-     */
-    if ((r & 0x18) != 0x08) {
-       imm_fail(host_no, DID_ERROR);
-       printk("IMM: returned SCSI status %2x\n", r);
-       return 0;
-    }
-    switch (imm_hosts[host_no].mode) {
-    case IMM_EPP_32:
-    case IMM_EPP_16:
-    case IMM_EPP_8:
-       epp_reset(ppb);
-       w_ctr(ppb, 0x4);
+       unsigned short ppb = dev->base;
+       int r = imm_wait(dev);
+
+       /*
+        * Make sure that:
+        * a) the SCSI bus is BUSY (device still listening)
+        * b) the device is listening
+        */
+       if ((r & 0x18) != 0x08) {
+               imm_fail(dev, DID_ERROR);
+               printk("IMM: returned SCSI status %2x\n", r);
+               return 0;
+       }
+       switch (dev->mode) {
+       case IMM_EPP_32:
+       case IMM_EPP_16:
+       case IMM_EPP_8:
+               epp_reset(ppb);
+               w_ctr(ppb, 0x4);
 #ifdef CONFIG_SCSI_IZIP_EPP16
-       if (!(((long) buffer | len) & 0x01))
-           outsw(ppb + 4, buffer, len >> 1);
+               if (!(((long) buffer | len) & 0x01))
+                       outsw(ppb + 4, buffer, len >> 1);
 #else
-       if (!(((long) buffer | len) & 0x03))
-           outsl(ppb + 4, buffer, len >> 2);
+               if (!(((long) buffer | len) & 0x03))
+                       outsl(ppb + 4, buffer, len >> 2);
 #endif
-       else
-           outsb(ppb + 4, buffer, len);
-       w_ctr(ppb, 0xc);
-       r = !(r_str(ppb) & 0x01);
-       w_ctr(ppb, 0xc);
-       ecp_sync(host_no);
-       break;
-
-    case IMM_NIBBLE:
-    case IMM_PS2:
-       /* 8 bit output, with a loop */
-       r = imm_byte_out(ppb, buffer, len);
-       break;
-
-    default:
-       printk("IMM: bug in imm_out()\n");
-       r = 0;
-    }
-    return r;
+               else
+                       outsb(ppb + 4, buffer, len);
+               w_ctr(ppb, 0xc);
+               r = !(r_str(ppb) & 0x01);
+               w_ctr(ppb, 0xc);
+               ecp_sync(dev);
+               break;
+
+       case IMM_NIBBLE:
+       case IMM_PS2:
+               /* 8 bit output, with a loop */
+               r = imm_byte_out(ppb, buffer, len);
+               break;
+
+       default:
+               printk("IMM: bug in imm_out()\n");
+               r = 0;
+       }
+       return r;
 }
 
-static int imm_in(int host_no, char *buffer, int len)
+static int imm_in(imm_struct *dev, char *buffer, int len)
 {
-    int r;
-    unsigned short ppb = IMM_BASE(host_no);
-
-    r = imm_wait(host_no);
-
-    /*
-     * Make sure that:
-     * a) the SCSI bus is BUSY (device still listening)
-     * b) the device is sending data
-     */
-    if ((r & 0x18) != 0x18) {
-       imm_fail(host_no, DID_ERROR);
-       return 0;
-    }
-    switch (imm_hosts[host_no].mode) {
-    case IMM_NIBBLE:
-       /* 4 bit input, with a loop */
-       r = imm_nibble_in(ppb, buffer, len);
-       w_ctr(ppb, 0xc);
-       break;
+       unsigned short ppb = dev->base;
+       int r = imm_wait(dev);
 
-    case IMM_PS2:
-       /* 8 bit input, with a loop */
-       r = imm_byte_in(ppb, buffer, len);
-       w_ctr(ppb, 0xc);
-       break;
+       /*
+        * Make sure that:
+        * a) the SCSI bus is BUSY (device still listening)
+        * b) the device is sending data
+        */
+       if ((r & 0x18) != 0x18) {
+               imm_fail(dev, DID_ERROR);
+               return 0;
+       }
+       switch (dev->mode) {
+       case IMM_NIBBLE:
+               /* 4 bit input, with a loop */
+               r = imm_nibble_in(ppb, buffer, len);
+               w_ctr(ppb, 0xc);
+               break;
 
-    case IMM_EPP_32:
-    case IMM_EPP_16:
-    case IMM_EPP_8:
-       epp_reset(ppb);
-       w_ctr(ppb, 0x24);
+       case IMM_PS2:
+               /* 8 bit input, with a loop */
+               r = imm_byte_in(ppb, buffer, len);
+               w_ctr(ppb, 0xc);
+               break;
+
+       case IMM_EPP_32:
+       case IMM_EPP_16:
+       case IMM_EPP_8:
+               epp_reset(ppb);
+               w_ctr(ppb, 0x24);
 #ifdef CONFIG_SCSI_IZIP_EPP16
-       if (!(((long) buffer | len) & 0x01))
-           insw(ppb + 4, buffer, len >> 1);
+               if (!(((long) buffer | len) & 0x01))
+                       insw(ppb + 4, buffer, len >> 1);
 #else
-       if (!(((long) buffer | len) & 0x03))
-           insl(ppb + 4, buffer, len >> 2);
+               if (!(((long) buffer | len) & 0x03))
+                       insl(ppb + 4, buffer, len >> 2);
 #endif
-       else
-           insb(ppb + 4, buffer, len);
-       w_ctr(ppb, 0x2c);
-       r = !(r_str(ppb) & 0x01);
-       w_ctr(ppb, 0x2c);
-       ecp_sync(host_no);
-       break;
-
-    default:
-       printk("IMM: bug in imm_ins()\n");
-       r = 0;
-       break;
-    }
-    return r;
+               else
+                       insb(ppb + 4, buffer, len);
+               w_ctr(ppb, 0x2c);
+               r = !(r_str(ppb) & 0x01);
+               w_ctr(ppb, 0x2c);
+               ecp_sync(dev);
+               break;
+
+       default:
+               printk("IMM: bug in imm_ins()\n");
+               r = 0;
+               break;
+       }
+       return r;
 }
 
 static int imm_cpp(unsigned short ppb, unsigned char b)
 {
-    /*
-     * Comments on udelay values refer to the
-     * Command Packet Protocol (CPP) timing diagram.
-     */
-
-    unsigned char s1, s2, s3;
-    w_ctr(ppb, 0x0c);
-    udelay(2);                 /* 1 usec - infinite */
-    w_dtr(ppb, 0xaa);
-    udelay(10);                        /* 7 usec - infinite */
-    w_dtr(ppb, 0x55);
-    udelay(10);                        /* 7 usec - infinite */
-    w_dtr(ppb, 0x00);
-    udelay(10);                        /* 7 usec - infinite */
-    w_dtr(ppb, 0xff);
-    udelay(10);                        /* 7 usec - infinite */
-    s1 = r_str(ppb) & 0xb8;
-    w_dtr(ppb, 0x87);
-    udelay(10);                        /* 7 usec - infinite */
-    s2 = r_str(ppb) & 0xb8;
-    w_dtr(ppb, 0x78);
-    udelay(10);                        /* 7 usec - infinite */
-    s3 = r_str(ppb) & 0x38;
-    /*
-     * Values for b are:
-     * 0000 00aa    Assign address aa to current device
-     * 0010 00aa    Select device aa in EPP Winbond mode
-     * 0010 10aa    Select device aa in EPP mode
-     * 0011 xxxx    Deselect all devices
-     * 0110 00aa    Test device aa
-     * 1101 00aa    Select device aa in ECP mode
-     * 1110 00aa    Select device aa in Compatible mode
-     */
-    w_dtr(ppb, b);
-    udelay(2);                 /* 1 usec - infinite */
-    w_ctr(ppb, 0x0c);
-    udelay(10);                        /* 7 usec - infinite */
-    w_ctr(ppb, 0x0d);
-    udelay(2);                 /* 1 usec - infinite */
-    w_ctr(ppb, 0x0c);
-    udelay(10);                        /* 7 usec - infinite */
-    w_dtr(ppb, 0xff);
-    udelay(10);                        /* 7 usec - infinite */
-
-    /*
-     * The following table is electrical pin values.
-     * (BSY is inverted at the CTR register)
-     *
-     *       BSY  ACK  POut SEL  Fault
-     * S1    0    X    1    1    1
-     * S2    1    X    0    1    1
-     * S3    L    X    1    1    S
-     *
-     * L => Last device in chain
-     * S => Selected
-     *
-     * Observered values for S1,S2,S3 are:
-     * Disconnect => f8/58/78
-     * Connect    => f8/58/70
-     */
-    if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30))
-       return 1;               /* Connected */
-    if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38))
-       return 0;               /* Disconnected */
-
-    return -1;                 /* No device present */
+       /*
+        * Comments on udelay values refer to the
+        * Command Packet Protocol (CPP) timing diagram.
+        */
+
+       unsigned char s1, s2, s3;
+       w_ctr(ppb, 0x0c);
+       udelay(2);              /* 1 usec - infinite */
+       w_dtr(ppb, 0xaa);
+       udelay(10);             /* 7 usec - infinite */
+       w_dtr(ppb, 0x55);
+       udelay(10);             /* 7 usec - infinite */
+       w_dtr(ppb, 0x00);
+       udelay(10);             /* 7 usec - infinite */
+       w_dtr(ppb, 0xff);
+       udelay(10);             /* 7 usec - infinite */
+       s1 = r_str(ppb) & 0xb8;
+       w_dtr(ppb, 0x87);
+       udelay(10);             /* 7 usec - infinite */
+       s2 = r_str(ppb) & 0xb8;
+       w_dtr(ppb, 0x78);
+       udelay(10);             /* 7 usec - infinite */
+       s3 = r_str(ppb) & 0x38;
+       /*
+        * Values for b are:
+        * 0000 00aa    Assign address aa to current device
+        * 0010 00aa    Select device aa in EPP Winbond mode
+        * 0010 10aa    Select device aa in EPP mode
+        * 0011 xxxx    Deselect all devices
+        * 0110 00aa    Test device aa
+        * 1101 00aa    Select device aa in ECP mode
+        * 1110 00aa    Select device aa in Compatible mode
+        */
+       w_dtr(ppb, b);
+       udelay(2);              /* 1 usec - infinite */
+       w_ctr(ppb, 0x0c);
+       udelay(10);             /* 7 usec - infinite */
+       w_ctr(ppb, 0x0d);
+       udelay(2);              /* 1 usec - infinite */
+       w_ctr(ppb, 0x0c);
+       udelay(10);             /* 7 usec - infinite */
+       w_dtr(ppb, 0xff);
+       udelay(10);             /* 7 usec - infinite */
+
+       /*
+        * The following table is electrical pin values.
+        * (BSY is inverted at the CTR register)
+        *
+        *       BSY  ACK  POut SEL  Fault
+        * S1    0    X    1    1    1
+        * S2    1    X    0    1    1
+        * S3    L    X    1    1    S
+        *
+        * L => Last device in chain
+        * S => Selected
+        *
+        * Observered values for S1,S2,S3 are:
+        * Disconnect => f8/58/78
+        * Connect    => f8/58/70
+        */
+       if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30))
+               return 1;       /* Connected */
+       if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38))
+               return 0;       /* Disconnected */
+
+       return -1;              /* No device present */
 }
 
-static inline int imm_connect(int host_no, int flag)
+static inline int imm_connect(imm_struct *dev, int flag)
 {
-    unsigned short ppb = IMM_BASE(host_no);
+       unsigned short ppb = dev->base;
 
-    imm_cpp(ppb, 0xe0);                /* Select device 0 in compatible mode */
-    imm_cpp(ppb, 0x30);                /* Disconnect all devices */
+       imm_cpp(ppb, 0xe0);     /* Select device 0 in compatible mode */
+       imm_cpp(ppb, 0x30);     /* Disconnect all devices */
 
-    if ((imm_hosts[host_no].mode == IMM_EPP_8) ||
-       (imm_hosts[host_no].mode == IMM_EPP_16) ||
-       (imm_hosts[host_no].mode == IMM_EPP_32))
-       return imm_cpp(ppb, 0x28);      /* Select device 0 in EPP mode */
-    return imm_cpp(ppb, 0xe0); /* Select device 0 in compatible mode */
+       if ((dev->mode == IMM_EPP_8) ||
+           (dev->mode == IMM_EPP_16) ||
+           (dev->mode == IMM_EPP_32))
+               return imm_cpp(ppb, 0x28);      /* Select device 0 in EPP mode */
+       return imm_cpp(ppb, 0xe0);      /* Select device 0 in compatible mode */
 }
 
-static void imm_disconnect(int host_no)
+static void imm_disconnect(imm_struct *dev)
 {
-    unsigned short ppb = IMM_BASE(host_no);
-
-    imm_cpp(ppb, 0x30);                /* Disconnect all devices */
+       imm_cpp(dev->base, 0x30);       /* Disconnect all devices */
 }
 
-static int imm_select(int host_no, int target)
+static int imm_select(imm_struct *dev, int target)
 {
-    int k;
-    unsigned short ppb = IMM_BASE(host_no);
+       int k;
+       unsigned short ppb = dev->base;
 
-    /*
-     * Firstly we want to make sure there is nothing
-     * holding onto the SCSI bus.
-     */
-    w_ctr(ppb, 0xc);
+       /*
+        * Firstly we want to make sure there is nothing
+        * holding onto the SCSI bus.
+        */
+       w_ctr(ppb, 0xc);
 
-    k = IMM_SELECT_TMO;
-    do {
-       k--;
-    } while ((r_str(ppb) & 0x08) && (k));
+       k = IMM_SELECT_TMO;
+       do {
+               k--;
+       } while ((r_str(ppb) & 0x08) && (k));
 
-    if (!k)
-       return 0;
+       if (!k)
+               return 0;
+
+       /*
+        * Now assert the SCSI ID (HOST and TARGET) on the data bus
+        */
+       w_ctr(ppb, 0x4);
+       w_dtr(ppb, 0x80 | (1 << target));
+       udelay(1);
 
-    /*
-     * Now assert the SCSI ID (HOST and TARGET) on the data bus
-     */
-    w_ctr(ppb, 0x4);
-    w_dtr(ppb, 0x80 | (1 << target));
-    udelay(1);
-
-    /*
-     * Deassert SELIN first followed by STROBE
-     */
-    w_ctr(ppb, 0xc);
-    w_ctr(ppb, 0xd);
-
-    /*
-     * ACK should drop low while SELIN is deasserted.
-     * FAULT should drop low when the SCSI device latches the bus.
-     */
-    k = IMM_SELECT_TMO;
-    do {
-       k--;
-    }
-    while (!(r_str(ppb) & 0x08) && (k));
-
-    /*
-     * Place the interface back into a sane state (status mode)
-     */
-    w_ctr(ppb, 0xc);
-    return (k) ? 1 : 0;
+       /*
+        * Deassert SELIN first followed by STROBE
+        */
+       w_ctr(ppb, 0xc);
+       w_ctr(ppb, 0xd);
+
+       /*
+        * ACK should drop low while SELIN is deasserted.
+        * FAULT should drop low when the SCSI device latches the bus.
+        */
+       k = IMM_SELECT_TMO;
+       do {
+               k--;
+       }
+       while (!(r_str(ppb) & 0x08) && (k));
+
+       /*
+        * Place the interface back into a sane state (status mode)
+        */
+       w_ctr(ppb, 0xc);
+       return (k) ? 1 : 0;
 }
 
-static int imm_init(int host_no)
+static int imm_init(imm_struct *dev)
 {
-    int retv;
-
-#if defined(CONFIG_PARPORT) || defined(CONFIG_PARPORT_MODULE)
-    if (imm_pb_claim(host_no))
-       while (imm_hosts[host_no].p_busy)
-           schedule();         /* We can safe schedule here */
-#endif
-    retv = imm_connect(host_no, 0);
-
-    if (retv == 1) {
-       imm_reset_pulse(IMM_BASE(host_no));
-       udelay(1000);           /* Delay to allow devices to settle */
-       imm_disconnect(host_no);
-       udelay(1000);           /* Another delay to allow devices to settle */
-       retv = device_check(host_no);
-       imm_pb_release(host_no);
-       return retv;
-    }
-    imm_pb_release(host_no);
-    return 1;
+       if (imm_connect(dev, 0) != 1)
+               return -EIO;
+       imm_reset_pulse(dev->base);
+       udelay(1000);   /* Delay to allow devices to settle */
+       imm_disconnect(dev);
+       udelay(1000);   /* Another delay to allow devices to settle */
+       return device_check(dev);
 }
 
-static inline int imm_send_command(Scsi_Cmnd * cmd)
+static inline int imm_send_command(Scsi_Cmnd *cmd)
 {
-    int host_no = cmd->device->host->unique_id;
-    int k;
-
-    /* NOTE: IMM uses byte pairs */
-    for (k = 0; k < cmd->cmd_len; k += 2)
-       if (!imm_out(host_no, &cmd->cmnd[k], 2))
-           return 0;
-    return 1;
+       imm_struct *dev = imm_dev(cmd->device->host);
+       int k;
+
+       /* NOTE: IMM uses byte pairs */
+       for (k = 0; k < cmd->cmd_len; k += 2)
+               if (!imm_out(dev, &cmd->cmnd[k], 2))
+                       return 0;
+       return 1;
 }
 
 /*
@@ -768,94 +633,99 @@ static inline int imm_send_command(Scsi_Cmnd * cmd)
  * The driver appears to remain stable if we speed up the parallel port
  * i/o in this function, but not elsewhere.
  */
-static int imm_completion(Scsi_Cmnd * cmd)
+static int imm_completion(Scsi_Cmnd *cmd)
 {
-    /* Return codes:
-     * -1     Error
-     *  0     Told to schedule
-     *  1     Finished data transfer
-     */
-    int host_no = cmd->device->host->unique_id;
-    unsigned short ppb = IMM_BASE(host_no);
-    unsigned long start_jiffies = jiffies;
-
-    unsigned char r, v;
-    int fast, bulk, status;
-
-    v = cmd->cmnd[0];
-    bulk = ((v == READ_6) ||
-           (v == READ_10) ||
-           (v == WRITE_6) ||
-           (v == WRITE_10));
-
-    /*
-     * We only get here if the drive is ready to comunicate,
-     * hence no need for a full imm_wait.
-     */
-    w_ctr(ppb, 0x0c);
-    r = (r_str(ppb) & 0xb8);
-
-    /*
-     * while (device is not ready to send status byte)
-     *     loop;
-     */
-    while (r != (unsigned char) 0xb8) {
-       /*
-        * If we have been running for more than a full timer tick
-        * then take a rest.
+       /* Return codes:
+        * -1     Error
+        *  0     Told to schedule
+        *  1     Finished data transfer
         */
-       if (time_after(jiffies, start_jiffies + 1))
-           return 0;
+       imm_struct *dev = imm_dev(cmd->device->host);
+       unsigned short ppb = dev->base;
+       unsigned long start_jiffies = jiffies;
+
+       unsigned char r, v;
+       int fast, bulk, status;
+
+       v = cmd->cmnd[0];
+       bulk = ((v == READ_6) ||
+               (v == READ_10) || (v == WRITE_6) || (v == WRITE_10));
 
        /*
-        * FAIL if:
-        * a) Drive status is screwy (!ready && !present)
-        * b) Drive is requesting/sending more data than expected
+        * We only get here if the drive is ready to comunicate,
+        * hence no need for a full imm_wait.
         */
-       if (((r & 0x88) != 0x88) || (cmd->SCp.this_residual <= 0)) {
-           imm_fail(host_no, DID_ERROR);
-           return -1;          /* ERROR_RETURN */
-       }
-       /* determine if we should use burst I/O */
-       if (imm_hosts[host_no].rd == 0) {
-           fast = (bulk && (cmd->SCp.this_residual >= IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 2;
-           status = imm_out(host_no, cmd->SCp.ptr, fast);
-       } else {
-           fast = (bulk && (cmd->SCp.this_residual >= IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 1;
-           status = imm_in(host_no, cmd->SCp.ptr, fast);
-       }
-
-       cmd->SCp.ptr += fast;
-       cmd->SCp.this_residual -= fast;
+       w_ctr(ppb, 0x0c);
+       r = (r_str(ppb) & 0xb8);
 
-       if (!status) {
-           imm_fail(host_no, DID_BUS_BUSY);
-           return -1;          /* ERROR_RETURN */
-       }
-       if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
-           /* if scatter/gather, advance to the next segment */
-           if (cmd->SCp.buffers_residual--) {
-               cmd->SCp.buffer++;
-               cmd->SCp.this_residual = cmd->SCp.buffer->length;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+       /*
+        * while (device is not ready to send status byte)
+        *     loop;
+        */
+       while (r != (unsigned char) 0xb8) {
+               /*
+                * If we have been running for more than a full timer tick
+                * then take a rest.
+                */
+               if (time_after(jiffies, start_jiffies + 1))
+                       return 0;
 
                /*
-                * Make sure that we transfer even number of bytes
-                * otherwise it makes imm_byte_out() messy.
+                * FAIL if:
+                * a) Drive status is screwy (!ready && !present)
+                * b) Drive is requesting/sending more data than expected
                 */
-               if (cmd->SCp.this_residual & 0x01)
-                   cmd->SCp.this_residual++;
-           }
-       }
-       /* Now check to see if the drive is ready to comunicate */
-       w_ctr(ppb, 0x0c);
-       r = (r_str(ppb) & 0xb8);
+               if (((r & 0x88) != 0x88) || (cmd->SCp.this_residual <= 0)) {
+                       imm_fail(dev, DID_ERROR);
+                       return -1;      /* ERROR_RETURN */
+               }
+               /* determine if we should use burst I/O */
+               if (dev->rd == 0) {
+                       fast = (bulk
+                               && (cmd->SCp.this_residual >=
+                                   IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 2;
+                       status = imm_out(dev, cmd->SCp.ptr, fast);
+               } else {
+                       fast = (bulk
+                               && (cmd->SCp.this_residual >=
+                                   IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 1;
+                       status = imm_in(dev, cmd->SCp.ptr, fast);
+               }
+
+               cmd->SCp.ptr += fast;
+               cmd->SCp.this_residual -= fast;
+
+               if (!status) {
+                       imm_fail(dev, DID_BUS_BUSY);
+                       return -1;      /* ERROR_RETURN */
+               }
+               if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
+                       /* if scatter/gather, advance to the next segment */
+                       if (cmd->SCp.buffers_residual--) {
+                               cmd->SCp.buffer++;
+                               cmd->SCp.this_residual =
+                                   cmd->SCp.buffer->length;
+                               cmd->SCp.ptr =
+                                   page_address(cmd->SCp.buffer->page) +
+                                   cmd->SCp.buffer->offset;
+
+                               /*
+                                * Make sure that we transfer even number of bytes
+                                * otherwise it makes imm_byte_out() messy.
+                                */
+                               if (cmd->SCp.this_residual & 0x01)
+                                       cmd->SCp.this_residual++;
+                       }
+               }
+               /* Now check to see if the drive is ready to comunicate */
+               w_ctr(ppb, 0x0c);
+               r = (r_str(ppb) & 0xb8);
 
-       /* If not, drop back down to the scheduler and wait a timer tick */
-       if (!(r & 0x80))
-           return 0;
-    }
-    return 1;                  /* FINISH_RETURN */
+               /* If not, drop back down to the scheduler and wait a timer tick */
+               if (!(r & 0x80))
+                       return 0;
+       }
+       return 1;               /* FINISH_RETURN */
 }
 
 /*
@@ -865,226 +735,229 @@ static int imm_completion(Scsi_Cmnd * cmd)
  */
 static void imm_interrupt(void *data)
 {
-    imm_struct *tmp = (imm_struct *) data;
-    Scsi_Cmnd *cmd = tmp->cur_cmd;
-    struct Scsi_Host *host = cmd->device->host;
-    unsigned long flags;
-
-    if (!cmd) {
-       printk("IMM: bug in imm_interrupt\n");
-       return;
-    }
-    if (imm_engine(tmp, cmd)) {
-       INIT_WORK(&tmp->imm_tq, imm_interrupt, (void *)tmp);
-       schedule_delayed_work(&tmp->imm_tq, 1);
-       return;
-    }
-    /* Command must of completed hence it is safe to let go... */
+       imm_struct *dev = (imm_struct *) data;
+       Scsi_Cmnd *cmd = dev->cur_cmd;
+       struct Scsi_Host *host = cmd->device->host;
+       unsigned long flags;
+
+       if (!cmd) {
+               printk("IMM: bug in imm_interrupt\n");
+               return;
+       }
+       if (imm_engine(dev, cmd)) {
+               INIT_WORK(&dev->imm_tq, imm_interrupt, (void *) dev);
+               schedule_delayed_work(&dev->imm_tq, 1);
+               return;
+       }
+       /* Command must of completed hence it is safe to let go... */
 #if IMM_DEBUG > 0
-    switch ((cmd->result >> 16) & 0xff) {
-    case DID_OK:
-       break;
-    case DID_NO_CONNECT:
-       printk("imm: no device at SCSI ID %i\n", cmd->target);
-       break;
-    case DID_BUS_BUSY:
-       printk("imm: BUS BUSY - EPP timeout detected\n");
-       break;
-    case DID_TIME_OUT:
-       printk("imm: unknown timeout\n");
-       break;
-    case DID_ABORT:
-       printk("imm: told to abort\n");
-       break;
-    case DID_PARITY:
-       printk("imm: parity error (???)\n");
-       break;
-    case DID_ERROR:
-       printk("imm: internal driver error\n");
-       break;
-    case DID_RESET:
-       printk("imm: told to reset device\n");
-       break;
-    case DID_BAD_INTR:
-       printk("imm: bad interrupt (???)\n");
-       break;
-    default:
-       printk("imm: bad return code (%02x)\n", (cmd->result >> 16) & 0xff);
-    }
+       switch ((cmd->result >> 16) & 0xff) {
+       case DID_OK:
+               break;
+       case DID_NO_CONNECT:
+               printk("imm: no device at SCSI ID %i\n", cmd->target);
+               break;
+       case DID_BUS_BUSY:
+               printk("imm: BUS BUSY - EPP timeout detected\n");
+               break;
+       case DID_TIME_OUT:
+               printk("imm: unknown timeout\n");
+               break;
+       case DID_ABORT:
+               printk("imm: told to abort\n");
+               break;
+       case DID_PARITY:
+               printk("imm: parity error (???)\n");
+               break;
+       case DID_ERROR:
+               printk("imm: internal driver error\n");
+               break;
+       case DID_RESET:
+               printk("imm: told to reset device\n");
+               break;
+       case DID_BAD_INTR:
+               printk("imm: bad interrupt (???)\n");
+               break;
+       default:
+               printk("imm: bad return code (%02x)\n",
+                      (cmd->result >> 16) & 0xff);
+       }
 #endif
 
-    if (cmd->SCp.phase > 1)
-       imm_disconnect(cmd->device->host->unique_id);
-    if (cmd->SCp.phase > 0)
-       imm_pb_release(cmd->device->host->unique_id);
+       if (cmd->SCp.phase > 1)
+               imm_disconnect(dev);
+
+       imm_pb_dismiss(dev);
 
-    spin_lock_irqsave(host->host_lock, flags);
-    tmp->cur_cmd = 0;
-    cmd->scsi_done(cmd);
-    spin_unlock_irqrestore(host->host_lock, flags);
-    return;
+       spin_lock_irqsave(host->host_lock, flags);
+       dev->cur_cmd = 0;
+       cmd->scsi_done(cmd);
+       spin_unlock_irqrestore(host->host_lock, flags);
+       return;
 }
 
-static int imm_engine(imm_struct * tmp, Scsi_Cmnd * cmd)
+static int imm_engine(imm_struct *dev, Scsi_Cmnd *cmd)
 {
-    int host_no = cmd->device->host->unique_id;
-    unsigned short ppb = IMM_BASE(host_no);
-    unsigned char l = 0, h = 0;
-    int retv, x;
-
-    /* First check for any errors that may have occurred
-     * Here we check for internal errors
-     */
-    if (tmp->failed)
-       return 0;
+       unsigned short ppb = dev->base;
+       unsigned char l = 0, h = 0;
+       int retv, x;
 
-    switch (cmd->SCp.phase) {
-    case 0:                    /* Phase 0 - Waiting for parport */
-       if ((jiffies - tmp->jstart) > HZ) {
-           /*
-            * We waited more than a second
-            * for parport to call us
-            */
-           imm_fail(host_no, DID_BUS_BUSY);
-           return 0;
-       }
-       return 1;               /* wait until imm_wakeup claims parport */
-       /* Phase 1 - Connected */
-    case 1:
-       imm_connect(host_no, CONNECT_EPP_MAYBE);
-       cmd->SCp.phase++;
-
-       /* Phase 2 - We are now talking to the scsi bus */
-    case 2:
-       if (!imm_select(host_no, cmd->device->id)) {
-           imm_fail(host_no, DID_NO_CONNECT);
-           return 0;
-       }
-       cmd->SCp.phase++;
-
-       /* Phase 3 - Ready to accept a command */
-    case 3:
-       w_ctr(ppb, 0x0c);
-       if (!(r_str(ppb) & 0x80))
-           return 1;
-
-       if (!imm_send_command(cmd))
-           return 0;
-       cmd->SCp.phase++;
-
-       /* Phase 4 - Setup scatter/gather buffers */
-    case 4:
-       if (cmd->use_sg) {
-           /* if many buffers are available, start filling the first */
-           cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
-           cmd->SCp.this_residual = cmd->SCp.buffer->length;
-           cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
-       } else {
-           /* else fill the only available buffer */
-           cmd->SCp.buffer = NULL;
-           cmd->SCp.this_residual = cmd->request_bufflen;
-           cmd->SCp.ptr = cmd->request_buffer;
-       }
-       cmd->SCp.buffers_residual = cmd->use_sg - 1;
-       cmd->SCp.phase++;
-       if (cmd->SCp.this_residual & 0x01)
-           cmd->SCp.this_residual++;
-       /* Phase 5 - Pre-Data transfer stage */
-    case 5:
-       /* Spin lock for BUSY */
-       w_ctr(ppb, 0x0c);
-       if (!(r_str(ppb) & 0x80))
-           return 1;
-
-       /* Require negotiation for read requests */
-       x = (r_str(ppb) & 0xb8);
-       tmp->rd = (x & 0x10) ? 1 : 0;
-       tmp->dp = (x & 0x20) ? 0 : 1;
-
-       if ((tmp->dp) && (tmp->rd))
-           if (imm_negotiate(tmp))
+       /* First check for any errors that may have occurred
+        * Here we check for internal errors
+        */
+       if (dev->failed)
                return 0;
-       cmd->SCp.phase++;
 
-       /* Phase 6 - Data transfer stage */
-    case 6:
-       /* Spin lock for BUSY */
-       w_ctr(ppb, 0x0c);
-       if (!(r_str(ppb) & 0x80))
-           return 1;
-
-       if (tmp->dp) {
-           retv = imm_completion(cmd);
-           if (retv == -1)
-               return 0;
-           if (retv == 0)
-               return 1;
-       }
-       cmd->SCp.phase++;
+       switch (cmd->SCp.phase) {
+       case 0:         /* Phase 0 - Waiting for parport */
+               if (time_after(jiffies, dev->jstart + HZ)) {
+                       /*
+                        * We waited more than a second
+                        * for parport to call us
+                        */
+                       imm_fail(dev, DID_BUS_BUSY);
+                       return 0;
+               }
+               return 1;       /* wait until imm_wakeup claims parport */
+               /* Phase 1 - Connected */
+       case 1:
+               imm_connect(dev, CONNECT_EPP_MAYBE);
+               cmd->SCp.phase++;
+
+               /* Phase 2 - We are now talking to the scsi bus */
+       case 2:
+               if (!imm_select(dev, cmd->device->id)) {
+                       imm_fail(dev, DID_NO_CONNECT);
+                       return 0;
+               }
+               cmd->SCp.phase++;
+
+               /* Phase 3 - Ready to accept a command */
+       case 3:
+               w_ctr(ppb, 0x0c);
+               if (!(r_str(ppb) & 0x80))
+                       return 1;
+
+               if (!imm_send_command(cmd))
+                       return 0;
+               cmd->SCp.phase++;
+
+               /* Phase 4 - Setup scatter/gather buffers */
+       case 4:
+               if (cmd->use_sg) {
+                       /* if many buffers are available, start filling the first */
+                       cmd->SCp.buffer =
+                           (struct scatterlist *) cmd->request_buffer;
+                       cmd->SCp.this_residual = cmd->SCp.buffer->length;
+                       cmd->SCp.ptr =
+                           page_address(cmd->SCp.buffer->page) +
+                           cmd->SCp.buffer->offset;
+               } else {
+                       /* else fill the only available buffer */
+                       cmd->SCp.buffer = NULL;
+                       cmd->SCp.this_residual = cmd->request_bufflen;
+                       cmd->SCp.ptr = cmd->request_buffer;
+               }
+               cmd->SCp.buffers_residual = cmd->use_sg - 1;
+               cmd->SCp.phase++;
+               if (cmd->SCp.this_residual & 0x01)
+                       cmd->SCp.this_residual++;
+               /* Phase 5 - Pre-Data transfer stage */
+       case 5:
+               /* Spin lock for BUSY */
+               w_ctr(ppb, 0x0c);
+               if (!(r_str(ppb) & 0x80))
+                       return 1;
+
+               /* Require negotiation for read requests */
+               x = (r_str(ppb) & 0xb8);
+               dev->rd = (x & 0x10) ? 1 : 0;
+               dev->dp = (x & 0x20) ? 0 : 1;
+
+               if ((dev->dp) && (dev->rd))
+                       if (imm_negotiate(dev))
+                               return 0;
+               cmd->SCp.phase++;
+
+               /* Phase 6 - Data transfer stage */
+       case 6:
+               /* Spin lock for BUSY */
+               w_ctr(ppb, 0x0c);
+               if (!(r_str(ppb) & 0x80))
+                       return 1;
+
+               if (dev->dp) {
+                       retv = imm_completion(cmd);
+                       if (retv == -1)
+                               return 0;
+                       if (retv == 0)
+                               return 1;
+               }
+               cmd->SCp.phase++;
+
+               /* Phase 7 - Post data transfer stage */
+       case 7:
+               if ((dev->dp) && (dev->rd)) {
+                       if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) {
+                               w_ctr(ppb, 0x4);
+                               w_ctr(ppb, 0xc);
+                               w_ctr(ppb, 0xe);
+                               w_ctr(ppb, 0x4);
+                       }
+               }
+               cmd->SCp.phase++;
+
+               /* Phase 8 - Read status/message */
+       case 8:
+               /* Check for data overrun */
+               if (imm_wait(dev) != (unsigned char) 0xb8) {
+                       imm_fail(dev, DID_ERROR);
+                       return 0;
+               }
+               if (imm_negotiate(dev))
+                       return 0;
+               if (imm_in(dev, &l, 1)) {       /* read status byte */
+                       /* Check for optional message byte */
+                       if (imm_wait(dev) == (unsigned char) 0xb8)
+                               imm_in(dev, &h, 1);
+                       cmd->result = (DID_OK << 16) + (l & STATUS_MASK);
+               }
+               if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) {
+                       w_ctr(ppb, 0x4);
+                       w_ctr(ppb, 0xc);
+                       w_ctr(ppb, 0xe);
+                       w_ctr(ppb, 0x4);
+               }
+               return 0;       /* Finished */
+               break;
 
-       /* Phase 7 - Post data transfer stage */
-    case 7:
-       if ((tmp->dp) && (tmp->rd)) {
-           if ((tmp->mode == IMM_NIBBLE) || (tmp->mode == IMM_PS2)) {
-               w_ctr(ppb, 0x4);
-               w_ctr(ppb, 0xc);
-               w_ctr(ppb, 0xe);
-               w_ctr(ppb, 0x4);
-           }
-       }
-       cmd->SCp.phase++;
-
-       /* Phase 8 - Read status/message */
-    case 8:
-       /* Check for data overrun */
-       if (imm_wait(host_no) != (unsigned char) 0xb8) {
-           imm_fail(host_no, DID_ERROR);
-           return 0;
-       }
-       if (imm_negotiate(tmp))
-           return 0;
-       if (imm_in(host_no, &l, 1)) {   /* read status byte */
-           /* Check for optional message byte */
-           if (imm_wait(host_no) == (unsigned char) 0xb8)
-               imm_in(host_no, &h, 1);
-           cmd->result = (DID_OK << 16) + (l & STATUS_MASK);
-       }
-       if ((tmp->mode == IMM_NIBBLE) || (tmp->mode == IMM_PS2)) {
-           w_ctr(ppb, 0x4);
-           w_ctr(ppb, 0xc);
-           w_ctr(ppb, 0xe);
-           w_ctr(ppb, 0x4);
+       default:
+               printk("imm: Invalid scsi phase\n");
        }
-       return 0;               /* Finished */
-       break;
-
-    default:
-       printk("imm: Invalid scsi phase\n");
-    }
-    return 0;
+       return 0;
 }
 
-int imm_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int imm_queuecommand(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
-    int host_no = cmd->device->host->unique_id;
+       imm_struct *dev = imm_dev(cmd->device->host);
 
-    if (imm_hosts[host_no].cur_cmd) {
-       printk("IMM: bug in imm_queuecommand\n");
-       return 0;
-    }
-    imm_hosts[host_no].failed = 0;
-    imm_hosts[host_no].jstart = jiffies;
-    imm_hosts[host_no].cur_cmd = cmd;
-    cmd->scsi_done = done;
-    cmd->result = DID_ERROR << 16;     /* default return code */
-    cmd->SCp.phase = 0;                /* bus free */
+       if (dev->cur_cmd) {
+               printk("IMM: bug in imm_queuecommand\n");
+               return 0;
+       }
+       dev->failed = 0;
+       dev->jstart = jiffies;
+       dev->cur_cmd = cmd;
+       cmd->scsi_done = done;
+       cmd->result = DID_ERROR << 16;  /* default return code */
+       cmd->SCp.phase = 0;     /* bus free */
 
-    imm_pb_claim(host_no);
+       INIT_WORK(&dev->imm_tq, imm_interrupt, dev);
+       schedule_work(&dev->imm_tq);
 
-    INIT_WORK(&imm_hosts[host_no].imm_tq, imm_interrupt, imm_hosts + host_no);
-    schedule_work(&imm_hosts[host_no].imm_tq);
+       imm_pb_claim(dev);
 
-    return 0;
+       return 0;
 }
 
 /*
@@ -1093,150 +966,320 @@ int imm_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
  * be done in sd.c.  Even if it gets fixed there, this will still
  * work.
  */
-int imm_biosparam(struct scsi_device *sdev, struct block_device *dev,
-               sector_t capacity, int ip[])
+static int imm_biosparam(struct scsi_device *sdev, struct block_device *dev,
+                        sector_t capacity, int ip[])
 {
-    ip[0] = 0x40;
-    ip[1] = 0x20;
-    ip[2] = ((unsigned long)capacity + 1) / (ip[0] * ip[1]);
-    if (ip[2] > 1024) {
-       ip[0] = 0xff;
-       ip[1] = 0x3f;
-       ip[2] = ((unsigned long)capacity + 1) / (ip[0] * ip[1]);
-    }
-    return 0;
+       ip[0] = 0x40;
+       ip[1] = 0x20;
+       ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
+       if (ip[2] > 1024) {
+               ip[0] = 0xff;
+               ip[1] = 0x3f;
+               ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
+       }
+       return 0;
 }
 
-int imm_abort(Scsi_Cmnd * cmd)
+static int imm_abort(Scsi_Cmnd *cmd)
 {
-    int host_no = cmd->device->host->unique_id;
-    /*
-     * There is no method for aborting commands since Iomega
-     * have tied the SCSI_MESSAGE line high in the interface
-     */
-
-    switch (cmd->SCp.phase) {
-    case 0:                    /* Do not have access to parport */
-    case 1:                    /* Have not connected to interface */
-       imm_hosts[host_no].cur_cmd = NULL;      /* Forget the problem */
-       return SUCCESS;
-       break;
-    default:                   /* SCSI command sent, can not abort */
-       return FAILED;
-       break;
-    }
+       imm_struct *dev = imm_dev(cmd->device->host);
+       /*
+        * There is no method for aborting commands since Iomega
+        * have tied the SCSI_MESSAGE line high in the interface
+        */
+
+       switch (cmd->SCp.phase) {
+       case 0:         /* Do not have access to parport */
+       case 1:         /* Have not connected to interface */
+               dev->cur_cmd = NULL;    /* Forget the problem */
+               return SUCCESS;
+               break;
+       default:                /* SCSI command sent, can not abort */
+               return FAILED;
+               break;
+       }
 }
 
-void imm_reset_pulse(unsigned int base)
+static void imm_reset_pulse(unsigned int base)
 {
-    w_ctr(base, 0x04);
-    w_dtr(base, 0x40);
-    udelay(1);
-    w_ctr(base, 0x0c);
-    w_ctr(base, 0x0d);
-    udelay(50);
-    w_ctr(base, 0x0c);
-    w_ctr(base, 0x04);
+       w_ctr(base, 0x04);
+       w_dtr(base, 0x40);
+       udelay(1);
+       w_ctr(base, 0x0c);
+       w_ctr(base, 0x0d);
+       udelay(50);
+       w_ctr(base, 0x0c);
+       w_ctr(base, 0x04);
 }
 
-int imm_reset(Scsi_Cmnd * cmd)
+static int imm_reset(Scsi_Cmnd *cmd)
 {
-    int host_no = cmd->device->host->unique_id;
-
-    if (cmd->SCp.phase)
-       imm_disconnect(host_no);
-    imm_hosts[host_no].cur_cmd = NULL; /* Forget the problem */
-
-    imm_connect(host_no, CONNECT_NORMAL);
-    imm_reset_pulse(IMM_BASE(host_no));
-    udelay(1000);              /* device settle delay */
-    imm_disconnect(host_no);
-    udelay(1000);              /* device settle delay */
-    return SUCCESS;
+       imm_struct *dev = imm_dev(cmd->device->host);
+
+       if (cmd->SCp.phase)
+               imm_disconnect(dev);
+       dev->cur_cmd = NULL;    /* Forget the problem */
+
+       imm_connect(dev, CONNECT_NORMAL);
+       imm_reset_pulse(dev->base);
+       udelay(1000);           /* device settle delay */
+       imm_disconnect(dev);
+       udelay(1000);           /* device settle delay */
+       return SUCCESS;
 }
 
-static int device_check(int host_no)
+static int device_check(imm_struct *dev)
 {
-    /* This routine looks for a device and then attempts to use EPP
-       to send a command. If all goes as planned then EPP is available. */
-
-    static char cmd[6] =
-    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-    int loop, old_mode, status, k, ppb = IMM_BASE(host_no);
-    unsigned char l;
-
-    old_mode = imm_hosts[host_no].mode;
-    for (loop = 0; loop < 8; loop++) {
-       /* Attempt to use EPP for Test Unit Ready */
-       if ((ppb & 0x0007) == 0x0000)
-           imm_hosts[host_no].mode = IMM_EPP_32;
-
-      second_pass:
-       imm_connect(host_no, CONNECT_EPP_MAYBE);
-       /* Select SCSI device */
-       if (!imm_select(host_no, loop)) {
-           imm_disconnect(host_no);
-           continue;
+       /* This routine looks for a device and then attempts to use EPP
+          to send a command. If all goes as planned then EPP is available. */
+
+       static char cmd[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       int loop, old_mode, status, k, ppb = dev->base;
+       unsigned char l;
+
+       old_mode = dev->mode;
+       for (loop = 0; loop < 8; loop++) {
+               /* Attempt to use EPP for Test Unit Ready */
+               if ((ppb & 0x0007) == 0x0000)
+                       dev->mode = IMM_EPP_32;
+
+             second_pass:
+               imm_connect(dev, CONNECT_EPP_MAYBE);
+               /* Select SCSI device */
+               if (!imm_select(dev, loop)) {
+                       imm_disconnect(dev);
+                       continue;
+               }
+               printk("imm: Found device at ID %i, Attempting to use %s\n",
+                      loop, IMM_MODE_STRING[dev->mode]);
+
+               /* Send SCSI command */
+               status = 1;
+               w_ctr(ppb, 0x0c);
+               for (l = 0; (l < 3) && (status); l++)
+                       status = imm_out(dev, &cmd[l << 1], 2);
+
+               if (!status) {
+                       imm_disconnect(dev);
+                       imm_connect(dev, CONNECT_EPP_MAYBE);
+                       imm_reset_pulse(dev->base);
+                       udelay(1000);
+                       imm_disconnect(dev);
+                       udelay(1000);
+                       if (dev->mode == IMM_EPP_32) {
+                               dev->mode = old_mode;
+                               goto second_pass;
+                       }
+                       printk("imm: Unable to establish communication\n");
+                       return -EIO;
+               }
+               w_ctr(ppb, 0x0c);
+
+               k = 1000000;    /* 1 Second */
+               do {
+                       l = r_str(ppb);
+                       k--;
+                       udelay(1);
+               } while (!(l & 0x80) && (k));
+
+               l &= 0xb8;
+
+               if (l != 0xb8) {
+                       imm_disconnect(dev);
+                       imm_connect(dev, CONNECT_EPP_MAYBE);
+                       imm_reset_pulse(dev->base);
+                       udelay(1000);
+                       imm_disconnect(dev);
+                       udelay(1000);
+                       if (dev->mode == IMM_EPP_32) {
+                               dev->mode = old_mode;
+                               goto second_pass;
+                       }
+                       printk
+                           ("imm: Unable to establish communication\n");
+                       return -EIO;
+               }
+               imm_disconnect(dev);
+               printk
+                   ("imm: Communication established at 0x%x with ID %i using %s\n",
+                    ppb, loop, IMM_MODE_STRING[dev->mode]);
+               imm_connect(dev, CONNECT_EPP_MAYBE);
+               imm_reset_pulse(dev->base);
+               udelay(1000);
+               imm_disconnect(dev);
+               udelay(1000);
+               return 0;
        }
-       printk("imm: Found device at ID %i, Attempting to use %s\n", loop,
-              IMM_MODE_STRING[imm_hosts[host_no].mode]);
+       printk("imm: No devices found\n");
+       return -ENODEV;
+}
 
-       /* Send SCSI command */
-       status = 1;
-       w_ctr(ppb, 0x0c);
-       for (l = 0; (l < 3) && (status); l++)
-           status = imm_out(host_no, &cmd[l << 1], 2);
-
-       if (!status) {
-            imm_disconnect(host_no);
-            imm_connect(host_no, CONNECT_EPP_MAYBE);
-            imm_reset_pulse(IMM_BASE(host_no));
-            udelay(1000);
-            imm_disconnect(host_no);
-            udelay(1000);
-            if (imm_hosts[host_no].mode == IMM_EPP_32) {
-                imm_hosts[host_no].mode = old_mode;
-                goto second_pass;
-            }
-           printk("imm: Unable to establish communication, aborting driver load.\n");
-           return 1;
+static Scsi_Host_Template imm_template = {
+       .module                 = THIS_MODULE,
+       .proc_name              = "imm",
+       .proc_info              = imm_proc_info,
+       .name                   = "Iomega VPI2 (imm) interface",
+       .queuecommand           = imm_queuecommand,
+       .eh_abort_handler       = imm_abort,
+       .eh_bus_reset_handler   = imm_reset,
+       .eh_host_reset_handler  = imm_reset,
+       .bios_param             = imm_biosparam,
+       .this_id                = 7,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 1,
+       .use_clustering         = ENABLE_CLUSTERING,
+       .can_queue              = 1,
+};
+
+/***************************************************************************
+ *                   Parallel port probing routines                        *
+ ***************************************************************************/
+
+static LIST_HEAD(imm_hosts);
+
+static int __imm_attach(struct parport *pb)
+{
+       struct Scsi_Host *host;
+       imm_struct *dev;
+       DECLARE_WAIT_QUEUE_HEAD(waiting);
+       DEFINE_WAIT(wait);
+       int ports;
+       int modes, ppb;
+       int err = -ENOMEM;
+
+       init_waitqueue_head(&waiting);
+
+       dev = kmalloc(sizeof(imm_struct), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       memset(dev, 0, sizeof(imm_struct));
+
+       dev->base = -1;
+       dev->mode = IMM_AUTODETECT;
+       INIT_LIST_HEAD(&dev->list);
+
+       dev->dev = parport_register_device(pb, "imm", NULL, imm_wakeup,
+                                               NULL, 0, dev);
+
+       if (!dev->dev)
+               goto out;
+
+
+       /* Claim the bus so it remembers what we do to the control
+        * registers. [ CTR and ECP ]
+        */
+       err = -EBUSY;
+       dev->waiting = &waiting;
+       prepare_to_wait(&waiting, &wait, TASK_UNINTERRUPTIBLE);
+       if (imm_pb_claim(dev))
+               schedule_timeout(3 * HZ);
+       if (dev->wanted) {
+               printk(KERN_ERR "imm%d: failed to claim parport because "
+                       "a pardevice is owning the port for too long "
+                       "time!\n", pb->number);
+               imm_pb_dismiss(dev);
+               dev->waiting = NULL;
+               finish_wait(&waiting, &wait);
+               goto out1;
        }
+       dev->waiting = NULL;
+       finish_wait(&waiting, &wait);
+       ppb = dev->base = dev->dev->port->base;
+       dev->base_hi = dev->dev->port->base_hi;
        w_ctr(ppb, 0x0c);
+       modes = dev->dev->port->modes;
 
-       k = 1000000;            /* 1 Second */
-       do {
-           l = r_str(ppb);
-           k--;
-           udelay(1);
-       } while (!(l & 0x80) && (k));
-
-       l &= 0xb8;
-
-       if (l != 0xb8) {
-           imm_disconnect(host_no);
-           imm_connect(host_no, CONNECT_EPP_MAYBE);
-           imm_reset_pulse(IMM_BASE(host_no));
-           udelay(1000);
-           imm_disconnect(host_no);
-           udelay(1000);
-           if (imm_hosts[host_no].mode == IMM_EPP_32) {
-               imm_hosts[host_no].mode = old_mode;
-               goto second_pass;
-           }
-           printk("imm: Unable to establish communication, aborting driver load.\n");
-           return 1;
-       }
-       imm_disconnect(host_no);
-       printk("imm: Communication established at 0x%x with ID %i using %s\n", ppb, loop,
-              IMM_MODE_STRING[imm_hosts[host_no].mode]);
-       imm_connect(host_no, CONNECT_EPP_MAYBE);
-       imm_reset_pulse(IMM_BASE(host_no));
-       udelay(1000);
-       imm_disconnect(host_no);
-       udelay(1000);
+       /* Mode detection works up the chain of speed
+        * This avoids a nasty if-then-else-if-... tree
+        */
+       dev->mode = IMM_NIBBLE;
+
+       if (modes & PARPORT_MODE_TRISTATE)
+               dev->mode = IMM_PS2;
+
+       /* Done configuration */
+
+       err = imm_init(dev);
+
+       imm_pb_release(dev);
+
+       if (err)
+               goto out1;
+
+       /* now the glue ... */
+       if (dev->mode == IMM_NIBBLE || dev->mode == IMM_PS2)
+               ports = 3;
+       else
+               ports = 8;
+
+       INIT_WORK(&dev->imm_tq, imm_interrupt, dev);
+
+       err = -ENOMEM;
+       host = scsi_host_alloc(&imm_template, sizeof(imm_struct *));
+       if (!host)
+               goto out1;
+       host->io_port = pb->base;
+       host->n_io_port = ports;
+       host->dma_channel = -1;
+       host->unique_id = pb->number;
+       *(imm_struct **)&host->hostdata = dev;
+       dev->host = host;
+       list_add_tail(&dev->list, &imm_hosts);
+       err = scsi_add_host(host, NULL);
+       if (err)
+               goto out2;
+       scsi_scan_host(host);
        return 0;
-    }
-    printk("imm: No devices found, aborting driver load.\n");
-    return 1;
+
+out2:
+       list_del_init(&dev->list);
+       scsi_host_put(host);
+out1:
+       parport_unregister_device(dev->dev);
+out:
+       kfree(dev);
+       return err;
+}
+
+static void imm_attach(struct parport *pb)
+{
+       __imm_attach(pb);
+}
+
+static void imm_detach(struct parport *pb)
+{
+       imm_struct *dev;
+       list_for_each_entry(dev, &imm_hosts, list) {
+               if (dev->dev->port == pb) {
+                       list_del_init(&dev->list);
+                       scsi_remove_host(dev->host);
+                       scsi_host_put(dev->host);
+                       parport_unregister_device(dev->dev);
+                       kfree(dev);
+                       break;
+               }
+       }
 }
+
+static struct parport_driver imm_driver = {
+       .name   = "imm",
+       .attach = imm_attach,
+       .detach = imm_detach,
+};
+
+static int __init imm_driver_init(void)
+{
+       printk("imm: Version %s\n", IMM_VERSION);
+       return parport_register_driver(&imm_driver);
+}
+
+static void __exit imm_driver_exit(void)
+{
+       parport_unregister_driver(&imm_driver);
+}
+
+module_init(imm_driver_init);
+module_exit(imm_driver_exit);
+
 MODULE_LICENSE("GPL");
index 800d38f..434a57e 100644 (file)
@@ -66,7 +66,6 @@
  */
 /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */
 
-#ifdef IMM_CODE
 #include  <linux/config.h>
 #include  <linux/stddef.h>
 #include  <linux/module.h>
@@ -109,11 +108,7 @@ static char *IMM_MODE_STRING[] =
        [IMM_UNKNOWN]    = "Unknown",
 };
 
-/* This is a global option */
-int imm_sg = SG_ALL;           /* enable/disable scatter-gather. */
-
 /* other options */
-#define IMM_CAN_QUEUE   1      /* use "queueing" interface */
 #define IMM_BURST_SIZE 512     /* data burst size */
 #define IMM_SELECT_TMO  500    /* 500 how long to wait for target ? */
 #define IMM_SPIN_TMO    5000   /* 50000 imm_wait loop limiter */
@@ -145,23 +140,5 @@ int imm_sg = SG_ALL;               /* enable/disable scatter-gather. */
 #endif
 
 static int imm_engine(imm_struct *, Scsi_Cmnd *);
-static int imm_in(int, char *, int);
-static int imm_init(int);
-static void imm_interrupt(void *);
-static int imm_out(int, char *, int);
-
-#else
-#define imm_release 0
-#endif
-
-int imm_detect(Scsi_Host_Template *);
-const char *imm_info(struct Scsi_Host *);
-int imm_command(Scsi_Cmnd *);
-int imm_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-int imm_abort(Scsi_Cmnd *);
-int imm_reset(Scsi_Cmnd *);
-int imm_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
-int imm_biosparam(struct scsi_device *, struct block_device *,
-               sector_t, int *);
 
 #endif                         /* _IMM_H */
index cc51537..28585bf 100644 (file)
@@ -39,6 +39,7 @@
 #include "hosts.h"
 #include <linux/libata.h>
 #include <asm/io.h>
+#include <linux/ide.h>
 #include <asm/semaphore.h>
 
 #include "libata.h"
@@ -969,7 +970,7 @@ retry:
                printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors%s\n",
                       ap->id, device,
                       ata_udma_string(udma_modes),
-                      dev->n_sectors,
+                      (unsigned long long)dev->n_sectors,
                       dev->flags & ATA_DFLAG_LBA48 ? " (lba48)" : "");
        }
 
index d2088d3..b3b976e 100644 (file)
  */
 
 #include <linux/config.h>
-
-/* The following #define is to avoid a clash with hosts.c */
-#define PPA_CODE 1
-
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/blkdev.h>
 #include <asm/io.h>
 #include <linux/parport.h>
 #include <linux/workqueue.h>
 #include "scsi.h"
 #include "hosts.h"
-int ppa_release(struct Scsi_Host *);
 static void ppa_reset_pulse(unsigned int base);
 
 typedef struct {
-    struct pardevice *dev;     /* Parport device entry         */
-    int base;                  /* Actual port address          */
-    int mode;                  /* Transfer mode                */
-    int host;                  /* Host number (for proc)       */
-    Scsi_Cmnd *cur_cmd;                /* Current queued command       */
-    struct work_struct ppa_tq; /* Polling interrupt stuff       */
-    unsigned long jstart;      /* Jiffies at start             */
-    unsigned long recon_tmo;    /* How many usecs to wait for reconnection (6th bit) */
-    unsigned int failed:1;     /* Failure flag                 */
-    unsigned int p_busy:1;     /* Parport sharing busy flag    */
+       struct pardevice *dev;  /* Parport device entry         */
+       int base;               /* Actual port address          */
+       int mode;               /* Transfer mode                */
+       Scsi_Cmnd *cur_cmd;     /* Current queued command       */
+       struct work_struct ppa_tq;      /* Polling interrupt stuff       */
+       unsigned long jstart;   /* Jiffies at start             */
+       unsigned long recon_tmo;        /* How many usecs to wait for reconnection (6th bit) */
+       unsigned int failed:1;  /* Failure flag                 */
+       unsigned wanted:1;      /* Parport sharing busy flag    */
+       wait_queue_head_t *waiting;
+       struct Scsi_Host *host;
+       struct list_head list;
 } ppa_struct;
 
-#define PPA_EMPTY      \
-{      .base           = -1,           \
-       .mode           = PPA_AUTODETECT,       \
-       .host           = -1,           \
-       .ppa_tq         = { .func = ppa_interrupt },    \
-       .recon_tmo      = PPA_RECON_TMO,        \
-}
-
 #include  "ppa.h"
 
-#define NO_HOSTS 4
-static ppa_struct ppa_hosts[NO_HOSTS] =
-{PPA_EMPTY, PPA_EMPTY, PPA_EMPTY, PPA_EMPTY};
+static inline ppa_struct *ppa_dev(struct Scsi_Host *host)
+{
+       return *(ppa_struct **)&host->hostdata;
+}
 
-#define PPA_BASE(x)    ppa_hosts[(x)].base
+static spinlock_t arbitration_lock = SPIN_LOCK_UNLOCKED;
 
-void ppa_wakeup(void *ref)
+static void got_it(ppa_struct *dev)
 {
-    ppa_struct *ppa_dev = (ppa_struct *) ref;
-
-    if (!ppa_dev->p_busy)
-       return;
+       dev->base = dev->dev->port->base;
+       if (dev->cur_cmd)
+               dev->cur_cmd->SCp.phase = 1;
+       else
+               wake_up(dev->waiting);
+}
 
-    if (parport_claim(ppa_dev->dev)) {
-       printk("ppa: bug in ppa_wakeup\n");
+static void ppa_wakeup(void *ref)
+{
+       ppa_struct *dev = (ppa_struct *) ref;
+       unsigned long flags;
+
+       spin_lock_irqsave(&arbitration_lock, flags);
+       if (dev->wanted) {
+               parport_claim(dev->dev);
+               got_it(dev);
+               dev->wanted = 0;
+       }
+       spin_unlock_irqrestore(&arbitration_lock, flags);
        return;
-    }
-    ppa_dev->p_busy = 0;
-    ppa_dev->base = ppa_dev->dev->port->base;
-    if (ppa_dev->cur_cmd)
-       ppa_dev->cur_cmd->SCp.phase++;
-    return;
 }
 
-int ppa_release(struct Scsi_Host *host)
+static int ppa_pb_claim(ppa_struct *dev)
 {
-    int host_no = host->unique_id;
-
-    printk("Releasing ppa%i\n", host_no);
-    scsi_unregister(host);
-    parport_unregister_device(ppa_hosts[host_no].dev);
-    return 0;
+       unsigned long flags;
+       int res = 1;
+       spin_lock_irqsave(&arbitration_lock, flags);
+       if (parport_claim(dev->dev) == 0) {
+               got_it(dev);
+               res = 0;
+       }
+       dev->wanted = res;
+       spin_unlock_irqrestore(&arbitration_lock, flags);
+       return res;
 }
 
-static int ppa_pb_claim(int host_no)
+static void ppa_pb_dismiss(ppa_struct *dev)
 {
-    if (parport_claim(ppa_hosts[host_no].dev)) {
-       ppa_hosts[host_no].p_busy = 1;
-       return 1;
-    }
-    if (ppa_hosts[host_no].cur_cmd)
-       ppa_hosts[host_no].cur_cmd->SCp.phase++;
-    return 0;
+       unsigned long flags;
+       int wanted;
+       spin_lock_irqsave(&arbitration_lock, flags);
+       wanted = dev->wanted;
+       dev->wanted = 0;
+       spin_unlock_irqrestore(&arbitration_lock, flags);
+       if (!wanted)
+               parport_release(dev->dev);
 }
 
-#define ppa_pb_release(x) parport_release(ppa_hosts[(x)].dev)
-
-/***************************************************************************
- *                   Parallel port probing routines                        *
- ***************************************************************************/
-
-static Scsi_Host_Template driver_template = {
-       .proc_name                      = "ppa",
-       .proc_info                      = ppa_proc_info,
-       .name                           = "Iomega VPI0 (ppa) interface",
-       .detect                         = ppa_detect,
-       .release                        = ppa_release,
-       .queuecommand                   = ppa_queuecommand,
-       .eh_abort_handler               = ppa_abort,
-       .eh_bus_reset_handler           = ppa_reset,
-       .eh_host_reset_handler          = ppa_reset,
-       .bios_param                     = ppa_biosparam,
-       .this_id                        = -1,
-       .sg_tablesize                   = SG_ALL,
-       .cmd_per_lun                    = 1,
-       .use_clustering                 = ENABLE_CLUSTERING,
-};
-#include  "scsi_module.c"
+static inline void ppa_pb_release(ppa_struct *dev)
+{
+       parport_release(dev->dev);
+}
 
 /*
  * Start of Chipset kludges
  */
 
-int ppa_detect(Scsi_Host_Template * host)
-{
-    struct Scsi_Host *hreg = NULL;
-    int ports;
-    int i, nhosts, try_again;
-    struct parport *pb;
-
-    /*
-     * unlock to allow the lowlevel parport driver to probe
-     * the irqs
-     */
-    pb = parport_enumerate();
-
-    printk("ppa: Version %s\n", PPA_VERSION);
-    nhosts = 0;
-    try_again = 0;
-
-    if (!pb) {
-       printk("ppa: parport reports no devices.\n");
-       return 0;
-    }
-  retry_entry:
-    for (i = 0; pb; i++, pb = pb->next) {
-       int modes, ppb, ppb_hi;
-
-       ppa_hosts[i].dev =
-           parport_register_device(pb, "ppa", NULL, ppa_wakeup,
-                                   NULL, 0, (void *) &ppa_hosts[i]);
-
-       if (!ppa_hosts[i].dev)
-           continue;
-
-       /* Claim the bus so it remembers what we do to the control
-        * registers. [ CTR and ECP ]
-        */
-       if (ppa_pb_claim(i)) {
-           unsigned long now = jiffies;
-           while (ppa_hosts[i].p_busy) {
-               schedule();     /* We are safe to schedule here */
-               if (time_after(jiffies, now + 3 * HZ)) {
-                   printk(KERN_ERR "ppa%d: failed to claim parport because a "
-                     "pardevice is owning the port for too longtime!\n",
-                          i);
-                   parport_unregister_device(ppa_hosts[i].dev);
-                   spin_lock_irq(ppa_hosts[i].cur_cmd->device->host->host_lock);
-                   return 0;
-               }
-           }
-       }
-       ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base;
-       ppb_hi =  ppa_hosts[i].dev->port->base_hi;
-       w_ctr(ppb, 0x0c);
-       modes = ppa_hosts[i].dev->port->modes;
-
-       /* Mode detection works up the chain of speed
-        * This avoids a nasty if-then-else-if-... tree
-        */
-       ppa_hosts[i].mode = PPA_NIBBLE;
-
-       if (modes & PARPORT_MODE_TRISTATE)
-           ppa_hosts[i].mode = PPA_PS2;
-
-       if (modes & PARPORT_MODE_ECP) {
-           w_ecr(ppb_hi, 0x20);
-           ppa_hosts[i].mode = PPA_PS2;
-       }
-       if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP))
-           w_ecr(ppb_hi, 0x80);
-
-       /* Done configuration */
-       ppa_pb_release(i);
-
-       if (ppa_init(i)) {
-           parport_unregister_device(ppa_hosts[i].dev);
-           continue;
-       }
-       /* now the glue ... */
-       switch (ppa_hosts[i].mode) {
-       case PPA_NIBBLE:
-           ports = 3;
-           break;
-       case PPA_PS2:
-           ports = 3;
-           break;
-       case PPA_EPP_8:
-       case PPA_EPP_16:
-       case PPA_EPP_32:
-           ports = 8;
-           break;
-       default:                /* Never gets here */
-           continue;
-       }
-       
-       INIT_WORK(&ppa_hosts[i].ppa_tq, ppa_interrupt, &ppa_hosts[i]);
-
-       host->can_queue = PPA_CAN_QUEUE;
-       host->sg_tablesize = ppa_sg;
-       hreg = scsi_register(host, 0);
-       if(hreg == NULL)
-               continue;
-       hreg->io_port = pb->base;
-       hreg->n_io_port = ports;
-       hreg->dma_channel = -1;
-       hreg->unique_id = i;
-       ppa_hosts[i].host = hreg->host_no;
-       nhosts++;
-    }
-    if (nhosts == 0) {
-       if (try_again == 1) {
-           printk("WARNING - no ppa compatible devices found.\n");
-           printk("  As of 31/Aug/1998 Iomega started shipping parallel\n");
-           printk("  port ZIP drives with a different interface which is\n");
-           printk("  supported by the imm (ZIP Plus) driver. If the\n");
-           printk("  cable is marked with \"AutoDetect\", this is what has\n");
-           printk("  happened.\n");
-           return 0;
-       }
-       try_again = 1;
-       goto retry_entry;
-    } else
-       return 1;               /* return number of hosts detected */
-}
-
 /* This is to give the ppa driver a way to modify the timings (and other
  * parameters) by writing to the /proc/scsi/ppa/0 file.
  * Very simple method really... (To simple, no error checking :( )
@@ -251,71 +113,71 @@ int ppa_detect(Scsi_Host_Template * host)
  * Also gives a method to use a script to obtain optimum timings (TODO)
  */
 
-static inline int ppa_proc_write(int hostno, char *buffer, int length)
+static inline int ppa_proc_write(ppa_struct *dev, char *buffer, int length)
 {
-    unsigned long x;
-
-    if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
-       x = simple_strtoul(buffer + 5, NULL, 0);
-       ppa_hosts[hostno].mode = x;
-       return length;
-    }
-    if ((length > 10) && (strncmp(buffer, "recon_tmo=", 10) == 0)) {
-       x = simple_strtoul(buffer + 10, NULL, 0);
-       ppa_hosts[hostno].recon_tmo = x;
-        printk("ppa: recon_tmo set to %ld\n", x);
-       return length;
-    }
-    printk("ppa /proc: invalid variable\n");
-    return (-EINVAL);
+       unsigned long x;
+
+       if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
+               x = simple_strtoul(buffer + 5, NULL, 0);
+               dev->mode = x;
+               return length;
+       }
+       if ((length > 10) && (strncmp(buffer, "recon_tmo=", 10) == 0)) {
+               x = simple_strtoul(buffer + 10, NULL, 0);
+               dev->recon_tmo = x;
+               printk("ppa: recon_tmo set to %ld\n", x);
+               return length;
+       }
+       printk("ppa /proc: invalid variable\n");
+       return (-EINVAL);
 }
 
-int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
-                 int length, int inout)
+static int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout)
 {
-    int i;
-    int len = 0;
-
-    for (i = 0; i < 4; i++)
-       if (ppa_hosts[i].host == host->host_no)
-           break;
-
-    if (inout)
-       return ppa_proc_write(i, buffer, length);
-
-    len += sprintf(buffer + len, "Version : %s\n", PPA_VERSION);
-    len += sprintf(buffer + len, "Parport : %s\n", ppa_hosts[i].dev->port->name);
-    len += sprintf(buffer + len, "Mode    : %s\n", PPA_MODE_STRING[ppa_hosts[i].mode]);
+       int len = 0;
+       ppa_struct *dev = ppa_dev(host);
+
+       if (inout)
+               return ppa_proc_write(dev, buffer, length);
+
+       len += sprintf(buffer + len, "Version : %s\n", PPA_VERSION);
+       len +=
+           sprintf(buffer + len, "Parport : %s\n",
+                   dev->dev->port->name);
+       len +=
+           sprintf(buffer + len, "Mode    : %s\n",
+                   PPA_MODE_STRING[dev->mode]);
 #if PPA_DEBUG > 0
-    len += sprintf(buffer + len, "recon_tmo : %lu\n", ppa_hosts[i].recon_tmo);
+       len +=
+           sprintf(buffer + len, "recon_tmo : %lu\n", dev->recon_tmo);
 #endif
 
-    /* Request for beyond end of buffer */
-    if (offset > length)
-       return 0;
+       /* Request for beyond end of buffer */
+       if (offset > length)
+               return 0;
 
-    *start = buffer + offset;
-    len -= offset;
-    if (len > length)
-       len = length;
-    return len;
+       *start = buffer + offset;
+       len -= offset;
+       if (len > length)
+               len = length;
+       return len;
 }
 
-static int device_check(int host_no);
+static int device_check(ppa_struct *dev);
 
 #if PPA_DEBUG > 0
 #define ppa_fail(x,y) printk("ppa: ppa_fail(%i) from %s at line %d\n",\
           y, __FUNCTION__, __LINE__); ppa_fail_func(x,y);
-static inline void ppa_fail_func(int host_no, int error_code)
+static inline void ppa_fail_func(ppa_struct *dev, int error_code)
 #else
-static inline void ppa_fail(int host_no, int error_code)
+static inline void ppa_fail(ppa_struct *dev, int error_code)
 #endif
 {
-    /* If we fail a device then we trash status / message bytes */
-    if (ppa_hosts[host_no].cur_cmd) {
-       ppa_hosts[host_no].cur_cmd->result = error_code << 16;
-       ppa_hosts[host_no].failed = 1;
-    }
+       /* If we fail a device then we trash status / message bytes */
+       if (dev->cur_cmd) {
+               dev->cur_cmd->result = error_code << 16;
+               dev->failed = 1;
+       }
 }
 
 /*
@@ -325,33 +187,33 @@ static inline void ppa_fail(int host_no, int error_code)
  * doesn't appear to be designed to support interrupts.  We spin on
  * the 0x80 ready bit. 
  */
-static unsigned char ppa_wait(int host_no)
+static unsigned char ppa_wait(ppa_struct *dev)
 {
-    int k;
-    unsigned short ppb = PPA_BASE(host_no);
-    unsigned char r;
-
-    k = PPA_SPIN_TMO;
-    /* Wait for bit 6 and 7 - PJC */
-    for (r = r_str (ppb); ((r & 0xc0)!=0xc0) && (k); k--) {
-           udelay (1);
-           r = r_str (ppb);
-    }
-
-    /*
-     * return some status information.
-     * Semantics: 0xc0 = ZIP wants more data
-     *            0xd0 = ZIP wants to send more data
-     *            0xe0 = ZIP is expecting SCSI command data
-     *            0xf0 = end of transfer, ZIP is sending status
-     */
-    if (k)
-       return (r & 0xf0);
-
-    /* Counter expired - Time out occurred */
-    ppa_fail(host_no, DID_TIME_OUT);
-    printk("ppa timeout in ppa_wait\n");
-    return 0;                  /* command timed out */
+       int k;
+       unsigned short ppb = dev->base;
+       unsigned char r;
+
+       k = PPA_SPIN_TMO;
+       /* Wait for bit 6 and 7 - PJC */
+       for (r = r_str(ppb); ((r & 0xc0) != 0xc0) && (k); k--) {
+               udelay(1);
+               r = r_str(ppb);
+       }
+
+       /*
+        * return some status information.
+        * Semantics: 0xc0 = ZIP wants more data
+        *            0xd0 = ZIP wants to send more data
+        *            0xe0 = ZIP is expecting SCSI command data
+        *            0xf0 = end of transfer, ZIP is sending status
+        */
+       if (k)
+               return (r & 0xf0);
+
+       /* Counter expired - Time out occurred */
+       ppa_fail(dev, DID_TIME_OUT);
+       printk("ppa timeout in ppa_wait\n");
+       return 0;               /* command timed out */
 }
 
 /*
@@ -359,245 +221,245 @@ static unsigned char ppa_wait(int host_no)
  */
 static inline void epp_reset(unsigned short ppb)
 {
-    int i;
+       int i;
 
-    i = r_str(ppb);
-    w_str(ppb, i);
-    w_str(ppb, i & 0xfe);
+       i = r_str(ppb);
+       w_str(ppb, i);
+       w_str(ppb, i & 0xfe);
 }
 
 /* 
  * Wait for empty ECP fifo (if we are in ECP fifo mode only)
  */
-static inline void ecp_sync(unsigned short hostno)
+static inline void ecp_sync(ppa_struct *dev)
 {
-    int i, ppb_hi=ppa_hosts[hostno].dev->port->base_hi;
-
-    if (ppb_hi == 0) return;
-
-    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
-        for (i = 0; i < 100; i++) {
-            if (r_ecr(ppb_hi) & 0x01)
-                return;
-            udelay(5);
-        }
-        printk("ppa: ECP sync failed as data still present in FIFO.\n");
-    }
+       int i, ppb_hi = dev->dev->port->base_hi;
+
+       if (ppb_hi == 0)
+               return;
+
+       if ((r_ecr(ppb_hi) & 0xe0) == 0x60) {   /* mode 011 == ECP fifo mode */
+               for (i = 0; i < 100; i++) {
+                       if (r_ecr(ppb_hi) & 0x01)
+                               return;
+                       udelay(5);
+               }
+               printk("ppa: ECP sync failed as data still present in FIFO.\n");
+       }
 }
 
 static int ppa_byte_out(unsigned short base, const char *buffer, int len)
 {
-    int i;
+       int i;
 
-    for (i = len; i; i--) {
-       w_dtr(base, *buffer++);
-       w_ctr(base, 0xe);
-       w_ctr(base, 0xc);
-    }
-    return 1;                  /* All went well - we hope! */
+       for (i = len; i; i--) {
+               w_dtr(base, *buffer++);
+               w_ctr(base, 0xe);
+               w_ctr(base, 0xc);
+       }
+       return 1;               /* All went well - we hope! */
 }
 
 static int ppa_byte_in(unsigned short base, char *buffer, int len)
 {
-    int i;
-
-    for (i = len; i; i--) {
-       *buffer++ = r_dtr(base);
-       w_ctr(base, 0x27);
-       w_ctr(base, 0x25);
-    }
-    return 1;                  /* All went well - we hope! */
+       int i;
+
+       for (i = len; i; i--) {
+               *buffer++ = r_dtr(base);
+               w_ctr(base, 0x27);
+               w_ctr(base, 0x25);
+       }
+       return 1;               /* All went well - we hope! */
 }
 
 static int ppa_nibble_in(unsigned short base, char *buffer, int len)
 {
-    for (; len; len--) {
-       unsigned char h;
-
-       w_ctr(base, 0x4);
-       h = r_str(base) & 0xf0;
-       w_ctr(base, 0x6);
-       *buffer++ = h | ((r_str(base) & 0xf0) >> 4);
-    }
-    return 1;                  /* All went well - we hope! */
+       for (; len; len--) {
+               unsigned char h;
+
+               w_ctr(base, 0x4);
+               h = r_str(base) & 0xf0;
+               w_ctr(base, 0x6);
+               *buffer++ = h | ((r_str(base) & 0xf0) >> 4);
+       }
+       return 1;               /* All went well - we hope! */
 }
 
-static int ppa_out(int host_no, char *buffer, int len)
+static int ppa_out(ppa_struct *dev, char *buffer, int len)
 {
-    int r;
-    unsigned short ppb = PPA_BASE(host_no);
+       int r;
+       unsigned short ppb = dev->base;
 
-    r = ppa_wait(host_no);
+       r = ppa_wait(dev);
 
-    if ((r & 0x50) != 0x40) {
-       ppa_fail(host_no, DID_ERROR);
-       return 0;
-    }
-    switch (ppa_hosts[host_no].mode) {
-    case PPA_NIBBLE:
-    case PPA_PS2:
-       /* 8 bit output, with a loop */
-       r = ppa_byte_out(ppb, buffer, len);
-       break;
-
-    case PPA_EPP_32:
-    case PPA_EPP_16:
-    case PPA_EPP_8:
-       epp_reset(ppb);
-       w_ctr(ppb, 0x4);
+       if ((r & 0x50) != 0x40) {
+               ppa_fail(dev, DID_ERROR);
+               return 0;
+       }
+       switch (dev->mode) {
+       case PPA_NIBBLE:
+       case PPA_PS2:
+               /* 8 bit output, with a loop */
+               r = ppa_byte_out(ppb, buffer, len);
+               break;
+
+       case PPA_EPP_32:
+       case PPA_EPP_16:
+       case PPA_EPP_8:
+               epp_reset(ppb);
+               w_ctr(ppb, 0x4);
 #ifdef CONFIG_SCSI_IZIP_EPP16
-       if (!(((long) buffer | len) & 0x01))
-           outsw(ppb + 4, buffer, len >> 1);
+               if (!(((long) buffer | len) & 0x01))
+                       outsw(ppb + 4, buffer, len >> 1);
 #else
-       if (!(((long) buffer | len) & 0x03))
-           outsl(ppb + 4, buffer, len >> 2);
+               if (!(((long) buffer | len) & 0x03))
+                       outsl(ppb + 4, buffer, len >> 2);
 #endif
-       else
-           outsb(ppb + 4, buffer, len);
-       w_ctr(ppb, 0xc);
-       r = !(r_str(ppb) & 0x01);
-       w_ctr(ppb, 0xc);
-       ecp_sync(host_no);
-       break;
-
-    default:
-       printk("PPA: bug in ppa_out()\n");
-       r = 0;
-    }
-    return r;
+               else
+                       outsb(ppb + 4, buffer, len);
+               w_ctr(ppb, 0xc);
+               r = !(r_str(ppb) & 0x01);
+               w_ctr(ppb, 0xc);
+               ecp_sync(dev);
+               break;
+
+       default:
+               printk("PPA: bug in ppa_out()\n");
+               r = 0;
+       }
+       return r;
 }
 
-static int ppa_in(int host_no, char *buffer, int len)
+static int ppa_in(ppa_struct *dev, char *buffer, int len)
 {
-    int r;
-    unsigned short ppb = PPA_BASE(host_no);
+       int r;
+       unsigned short ppb = dev->base;
 
-    r = ppa_wait(host_no);
+       r = ppa_wait(dev);
 
-    if ((r & 0x50) != 0x50) {
-       ppa_fail(host_no, DID_ERROR);
-       return 0;
-    }
-    switch (ppa_hosts[host_no].mode) {
-    case PPA_NIBBLE:
-       /* 4 bit input, with a loop */
-       r = ppa_nibble_in(ppb, buffer, len);
-       w_ctr(ppb, 0xc);
-       break;
+       if ((r & 0x50) != 0x50) {
+               ppa_fail(dev, DID_ERROR);
+               return 0;
+       }
+       switch (dev->mode) {
+       case PPA_NIBBLE:
+               /* 4 bit input, with a loop */
+               r = ppa_nibble_in(ppb, buffer, len);
+               w_ctr(ppb, 0xc);
+               break;
 
-    case PPA_PS2:
-       /* 8 bit input, with a loop */
-       w_ctr(ppb, 0x25);
-       r = ppa_byte_in(ppb, buffer, len);
-       w_ctr(ppb, 0x4);
-       w_ctr(ppb, 0xc);
-       break;
+       case PPA_PS2:
+               /* 8 bit input, with a loop */
+               w_ctr(ppb, 0x25);
+               r = ppa_byte_in(ppb, buffer, len);
+               w_ctr(ppb, 0x4);
+               w_ctr(ppb, 0xc);
+               break;
 
-    case PPA_EPP_32:
-    case PPA_EPP_16:
-    case PPA_EPP_8:
-       epp_reset(ppb);
-       w_ctr(ppb, 0x24);
+       case PPA_EPP_32:
+       case PPA_EPP_16:
+       case PPA_EPP_8:
+               epp_reset(ppb);
+               w_ctr(ppb, 0x24);
 #ifdef CONFIG_SCSI_IZIP_EPP16
-       if (!(((long) buffer | len) & 0x01))
-           insw(ppb + 4, buffer, len >> 1);
+               if (!(((long) buffer | len) & 0x01))
+                       insw(ppb + 4, buffer, len >> 1);
 #else
-       if (!(((long) buffer | len) & 0x03))
-           insl(ppb + 4, buffer, len >> 2);
+               if (!(((long) buffer | len) & 0x03))
+                       insl(ppb + 4, buffer, len >> 2);
 #endif
-       else
-           insb(ppb + 4, buffer, len);
-       w_ctr(ppb, 0x2c);
-       r = !(r_str(ppb) & 0x01);
-       w_ctr(ppb, 0x2c);
-       ecp_sync(host_no);
-       break;
-
-    default:
-       printk("PPA: bug in ppa_ins()\n");
-       r = 0;
-       break;
-    }
-    return r;
+               else
+                       insb(ppb + 4, buffer, len);
+               w_ctr(ppb, 0x2c);
+               r = !(r_str(ppb) & 0x01);
+               w_ctr(ppb, 0x2c);
+               ecp_sync(dev);
+               break;
+
+       default:
+               printk("PPA: bug in ppa_ins()\n");
+               r = 0;
+               break;
+       }
+       return r;
 }
 
 /* end of ppa_io.h */
 static inline void ppa_d_pulse(unsigned short ppb, unsigned char b)
 {
-    w_dtr(ppb, b);
-    w_ctr(ppb, 0xc);
-    w_ctr(ppb, 0xe);
-    w_ctr(ppb, 0xc);
-    w_ctr(ppb, 0x4);
-    w_ctr(ppb, 0xc);
+       w_dtr(ppb, b);
+       w_ctr(ppb, 0xc);
+       w_ctr(ppb, 0xe);
+       w_ctr(ppb, 0xc);
+       w_ctr(ppb, 0x4);
+       w_ctr(ppb, 0xc);
 }
 
-static void ppa_disconnect(int host_no)
+static void ppa_disconnect(ppa_struct *dev)
 {
-    unsigned short ppb = PPA_BASE(host_no);
+       unsigned short ppb = dev->base;
 
-    ppa_d_pulse(ppb, 0);
-    ppa_d_pulse(ppb, 0x3c);
-    ppa_d_pulse(ppb, 0x20);
-    ppa_d_pulse(ppb, 0xf);
+       ppa_d_pulse(ppb, 0);
+       ppa_d_pulse(ppb, 0x3c);
+       ppa_d_pulse(ppb, 0x20);
+       ppa_d_pulse(ppb, 0xf);
 }
 
 static inline void ppa_c_pulse(unsigned short ppb, unsigned char b)
 {
-    w_dtr(ppb, b);
-    w_ctr(ppb, 0x4);
-    w_ctr(ppb, 0x6);
-    w_ctr(ppb, 0x4);
-    w_ctr(ppb, 0xc);
+       w_dtr(ppb, b);
+       w_ctr(ppb, 0x4);
+       w_ctr(ppb, 0x6);
+       w_ctr(ppb, 0x4);
+       w_ctr(ppb, 0xc);
 }
 
-static inline void ppa_connect(int host_no, int flag)
+static inline void ppa_connect(ppa_struct *dev, int flag)
 {
-    unsigned short ppb = PPA_BASE(host_no);
-
-    ppa_c_pulse(ppb, 0);
-    ppa_c_pulse(ppb, 0x3c);
-    ppa_c_pulse(ppb, 0x20);
-    if ((flag == CONNECT_EPP_MAYBE) &&
-       IN_EPP_MODE(ppa_hosts[host_no].mode))
-       ppa_c_pulse(ppb, 0xcf);
-    else
-       ppa_c_pulse(ppb, 0x8f);
+       unsigned short ppb = dev->base;
+
+       ppa_c_pulse(ppb, 0);
+       ppa_c_pulse(ppb, 0x3c);
+       ppa_c_pulse(ppb, 0x20);
+       if ((flag == CONNECT_EPP_MAYBE) && IN_EPP_MODE(dev->mode))
+               ppa_c_pulse(ppb, 0xcf);
+       else
+               ppa_c_pulse(ppb, 0x8f);
 }
 
-static int ppa_select(int host_no, int target)
+static int ppa_select(ppa_struct *dev, int target)
 {
-    int k;
-    unsigned short ppb = PPA_BASE(host_no);
-
-    /*
-     * Bit 6 (0x40) is the device selected bit.
-     * First we must wait till the current device goes off line...
-     */
-    k = PPA_SELECT_TMO;
-    do {
-       k--;
-       udelay(1);
-    } while ((r_str(ppb) & 0x40) && (k));
-    if (!k)
-       return 0;
+       int k;
+       unsigned short ppb = dev->base;
 
-    w_dtr(ppb, (1 << target));
-    w_ctr(ppb, 0xe);
-    w_ctr(ppb, 0xc);
-    w_dtr(ppb, 0x80);          /* This is NOT the initator */
-    w_ctr(ppb, 0x8);
-
-    k = PPA_SELECT_TMO;
-    do {
-       k--;
-       udelay(1);
-    }
-    while (!(r_str(ppb) & 0x40) && (k));
-    if (!k)
-       return 0;
+       /*
+        * Bit 6 (0x40) is the device selected bit.
+        * First we must wait till the current device goes off line...
+        */
+       k = PPA_SELECT_TMO;
+       do {
+               k--;
+               udelay(1);
+       } while ((r_str(ppb) & 0x40) && (k));
+       if (!k)
+               return 0;
+
+       w_dtr(ppb, (1 << target));
+       w_ctr(ppb, 0xe);
+       w_ctr(ppb, 0xc);
+       w_dtr(ppb, 0x80);       /* This is NOT the initator */
+       w_ctr(ppb, 0x8);
 
-    return 1;
+       k = PPA_SELECT_TMO;
+       do {
+               k--;
+               udelay(1);
+       }
+       while (!(r_str(ppb) & 0x40) && (k));
+       if (!k)
+               return 0;
+
+       return 1;
 }
 
 /* 
@@ -609,54 +471,47 @@ static int ppa_select(int host_no, int target)
  * handshaking failed.
  * 
  */
-static int ppa_init(int host_no)
+static int ppa_init(ppa_struct *dev)
 {
-    int retv;
-    unsigned short ppb = PPA_BASE(host_no);
+       int retv;
+       unsigned short ppb = dev->base;
 
-#if defined(CONFIG_PARPORT) || defined(CONFIG_PARPORT_MODULE)
-    if (ppa_pb_claim(host_no))
-       while (ppa_hosts[host_no].p_busy)
-           schedule();         /* We can safe schedule here */
-#endif
-
-    ppa_disconnect(host_no);
-    ppa_connect(host_no, CONNECT_NORMAL);
+       ppa_disconnect(dev);
+       ppa_connect(dev, CONNECT_NORMAL);
 
-    retv = 2;                  /* Failed */
+       retv = 2;               /* Failed */
 
-    w_ctr(ppb, 0xe);
-    if ((r_str(ppb) & 0x08) == 0x08)
-       retv--;
+       w_ctr(ppb, 0xe);
+       if ((r_str(ppb) & 0x08) == 0x08)
+               retv--;
 
-    w_ctr(ppb, 0xc);
-    if ((r_str(ppb) & 0x08) == 0x00)
-       retv--;
+       w_ctr(ppb, 0xc);
+       if ((r_str(ppb) & 0x08) == 0x00)
+               retv--;
 
-    if (!retv)
-       ppa_reset_pulse(ppb);
-    udelay(1000);              /* Allow devices to settle down */
-    ppa_disconnect(host_no);
-    udelay(1000);              /* Another delay to allow devices to settle */
+       if (!retv)
+               ppa_reset_pulse(ppb);
+       udelay(1000);           /* Allow devices to settle down */
+       ppa_disconnect(dev);
+       udelay(1000);           /* Another delay to allow devices to settle */
 
-    if (!retv)
-       retv = device_check(host_no);
+       if (retv)
+               return -EIO;
 
-    ppa_pb_release(host_no);
-    return retv;
+       return device_check(dev);
 }
 
-static inline int ppa_send_command(Scsi_Cmnd * cmd)
+static inline int ppa_send_command(Scsi_Cmnd *cmd)
 {
-    int host_no = cmd->device->host->unique_id;
-    int k;
+       ppa_struct *dev = ppa_dev(cmd->device->host);
+       int k;
 
-    w_ctr(PPA_BASE(host_no), 0x0c);
+       w_ctr(dev->base, 0x0c);
 
-    for (k = 0; k < cmd->cmd_len; k++)
-       if (!ppa_out(host_no, &cmd->cmnd[k], 1))
-           return 0;
-    return 1;
+       for (k = 0; k < cmd->cmd_len; k++)
+               if (!ppa_out(dev, &cmd->cmnd[k], 1))
+                       return 0;
+       return 1;
 }
 
 /*
@@ -667,98 +522,100 @@ static inline int ppa_send_command(Scsi_Cmnd * cmd)
  * The driver appears to remain stable if we speed up the parallel port
  * i/o in this function, but not elsewhere.
  */
-static int ppa_completion(Scsi_Cmnd * cmd)
+static int ppa_completion(Scsi_Cmnd *cmd)
 {
-    /* Return codes:
-     * -1     Error
-     *  0     Told to schedule
-     *  1     Finished data transfer
-     */
-    int host_no = cmd->device->host->unique_id;
-    unsigned short ppb = PPA_BASE(host_no);
-    unsigned long start_jiffies = jiffies;
-
-    unsigned char r, v;
-    int fast, bulk, status;
-
-    v = cmd->cmnd[0];
-    bulk = ((v == READ_6) ||
-           (v == READ_10) ||
-           (v == WRITE_6) ||
-           (v == WRITE_10));
-
-    /*
-     * We only get here if the drive is ready to comunicate,
-     * hence no need for a full ppa_wait.
-     */
-    r = (r_str(ppb) & 0xf0);
-
-    while (r != (unsigned char) 0xf0) {
-       /*
-        * If we have been running for more than a full timer tick
-        * then take a rest.
+       /* Return codes:
+        * -1     Error
+        *  0     Told to schedule
+        *  1     Finished data transfer
         */
-       if (time_after(jiffies, start_jiffies + 1))
-           return 0;
+       ppa_struct *dev = ppa_dev(cmd->device->host);
+       unsigned short ppb = dev->base;
+       unsigned long start_jiffies = jiffies;
 
-       if ((cmd->SCp.this_residual <= 0)) {
-           ppa_fail(host_no, DID_ERROR);
-           return -1;          /* ERROR_RETURN */
-       }
+       unsigned char r, v;
+       int fast, bulk, status;
 
-       /* On some hardware we have SCSI disconnected (6th bit low)
-        * for about 100usecs. It is too expensive to wait a 
-        * tick on every loop so we busy wait for no more than
-        * 500usecs to give the drive a chance first. We do not 
-        * change things for "normal" hardware since generally 
-        * the 6th bit is always high.
-        * This makes the CPU load higher on some hardware 
-        * but otherwise we can not get more than 50K/secs 
-        * on this problem hardware.
+       v = cmd->cmnd[0];
+       bulk = ((v == READ_6) ||
+               (v == READ_10) || (v == WRITE_6) || (v == WRITE_10));
+
+       /*
+        * We only get here if the drive is ready to comunicate,
+        * hence no need for a full ppa_wait.
         */
-       if ((r & 0xc0) != 0xc0) {
-          /* Wait for reconnection should be no more than 
-           * jiffy/2 = 5ms = 5000 loops
-           */
-          unsigned long k = ppa_hosts[host_no].recon_tmo; 
-          for (; k && ((r = (r_str(ppb) & 0xf0)) & 0xc0) != 0xc0; k--)
-            udelay(1);
-
-          if(!k) 
-            return 0;
-       }          
-
-       /* determine if we should use burst I/O */ 
-       fast = (bulk && (cmd->SCp.this_residual >= PPA_BURST_SIZE)) 
-            ? PPA_BURST_SIZE : 1;
-
-       if (r == (unsigned char) 0xc0)
-           status = ppa_out(host_no, cmd->SCp.ptr, fast);
-       else
-           status = ppa_in(host_no, cmd->SCp.ptr, fast);
+       r = (r_str(ppb) & 0xf0);
 
-       cmd->SCp.ptr += fast;
-       cmd->SCp.this_residual -= fast;
+       while (r != (unsigned char) 0xf0) {
+               /*
+                * If we have been running for more than a full timer tick
+                * then take a rest.
+                */
+               if (time_after(jiffies, start_jiffies + 1))
+                       return 0;
+
+               if ((cmd->SCp.this_residual <= 0)) {
+                       ppa_fail(dev, DID_ERROR);
+                       return -1;      /* ERROR_RETURN */
+               }
 
-       if (!status) {
-           ppa_fail(host_no, DID_BUS_BUSY);
-           return -1;          /* ERROR_RETURN */
-       }
-       if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
-           /* if scatter/gather, advance to the next segment */
-           if (cmd->SCp.buffers_residual--) {
-               cmd->SCp.buffer++;
-               cmd->SCp.this_residual = cmd->SCp.buffer->length;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
-           }
+               /* On some hardware we have SCSI disconnected (6th bit low)
+                * for about 100usecs. It is too expensive to wait a 
+                * tick on every loop so we busy wait for no more than
+                * 500usecs to give the drive a chance first. We do not 
+                * change things for "normal" hardware since generally 
+                * the 6th bit is always high.
+                * This makes the CPU load higher on some hardware 
+                * but otherwise we can not get more than 50K/secs 
+                * on this problem hardware.
+                */
+               if ((r & 0xc0) != 0xc0) {
+                       /* Wait for reconnection should be no more than 
+                        * jiffy/2 = 5ms = 5000 loops
+                        */
+                       unsigned long k = dev->recon_tmo;
+                       for (; k && ((r = (r_str(ppb) & 0xf0)) & 0xc0) != 0xc0;
+                            k--)
+                               udelay(1);
+
+                       if (!k)
+                               return 0;
+               }
+
+               /* determine if we should use burst I/O */
+               fast = (bulk && (cmd->SCp.this_residual >= PPA_BURST_SIZE))
+                   ? PPA_BURST_SIZE : 1;
+
+               if (r == (unsigned char) 0xc0)
+                       status = ppa_out(dev, cmd->SCp.ptr, fast);
+               else
+                       status = ppa_in(dev, cmd->SCp.ptr, fast);
+
+               cmd->SCp.ptr += fast;
+               cmd->SCp.this_residual -= fast;
+
+               if (!status) {
+                       ppa_fail(dev, DID_BUS_BUSY);
+                       return -1;      /* ERROR_RETURN */
+               }
+               if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
+                       /* if scatter/gather, advance to the next segment */
+                       if (cmd->SCp.buffers_residual--) {
+                               cmd->SCp.buffer++;
+                               cmd->SCp.this_residual =
+                                   cmd->SCp.buffer->length;
+                               cmd->SCp.ptr =
+                                   page_address(cmd->SCp.buffer->page) +
+                                   cmd->SCp.buffer->offset;
+                       }
+               }
+               /* Now check to see if the drive is ready to comunicate */
+               r = (r_str(ppb) & 0xf0);
+               /* If not, drop back down to the scheduler and wait a timer tick */
+               if (!(r & 0x80))
+                       return 0;
        }
-       /* Now check to see if the drive is ready to comunicate */
-       r = (r_str(ppb) & 0xf0);
-       /* If not, drop back down to the scheduler and wait a timer tick */
-       if (!(r & 0x80))
-           return 0;
-    }
-    return 1;                  /* FINISH_RETURN */
+       return 1;               /* FINISH_RETURN */
 }
 
 /*
@@ -768,203 +625,204 @@ static int ppa_completion(Scsi_Cmnd * cmd)
  */
 static void ppa_interrupt(void *data)
 {
-    ppa_struct *tmp = (ppa_struct *) data;
-    Scsi_Cmnd *cmd = tmp->cur_cmd;
-    unsigned long flags;
+       ppa_struct *dev = (ppa_struct *) data;
+       Scsi_Cmnd *cmd = dev->cur_cmd;
 
-    if (!cmd) {
-       printk("PPA: bug in ppa_interrupt\n");
-       return;
-    }
-    if (ppa_engine(tmp, cmd)) {
-       tmp->ppa_tq.data = (void *) tmp;
-       schedule_delayed_work(&tmp->ppa_tq, 1);
-       return;
-    }
-    /* Command must of completed hence it is safe to let go... */
+       if (!cmd) {
+               printk("PPA: bug in ppa_interrupt\n");
+               return;
+       }
+       if (ppa_engine(dev, cmd)) {
+               dev->ppa_tq.data = (void *) dev;
+               schedule_delayed_work(&dev->ppa_tq, 1);
+               return;
+       }
+       /* Command must of completed hence it is safe to let go... */
 #if PPA_DEBUG > 0
-    switch ((cmd->result >> 16) & 0xff) {
-    case DID_OK:
-       break;
-    case DID_NO_CONNECT:
-       printk("ppa: no device at SCSI ID %i\n", cmd->device->target);
-       break;
-    case DID_BUS_BUSY:
-       printk("ppa: BUS BUSY - EPP timeout detected\n");
-       break;
-    case DID_TIME_OUT:
-       printk("ppa: unknown timeout\n");
-       break;
-    case DID_ABORT:
-       printk("ppa: told to abort\n");
-       break;
-    case DID_PARITY:
-       printk("ppa: parity error (???)\n");
-       break;
-    case DID_ERROR:
-       printk("ppa: internal driver error\n");
-       break;
-    case DID_RESET:
-       printk("ppa: told to reset device\n");
-       break;
-    case DID_BAD_INTR:
-       printk("ppa: bad interrupt (???)\n");
-       break;
-    default:
-       printk("ppa: bad return code (%02x)\n", (cmd->result >> 16) & 0xff);
-    }
+       switch ((cmd->result >> 16) & 0xff) {
+       case DID_OK:
+               break;
+       case DID_NO_CONNECT:
+               printk("ppa: no device at SCSI ID %i\n", cmd->device->target);
+               break;
+       case DID_BUS_BUSY:
+               printk("ppa: BUS BUSY - EPP timeout detected\n");
+               break;
+       case DID_TIME_OUT:
+               printk("ppa: unknown timeout\n");
+               break;
+       case DID_ABORT:
+               printk("ppa: told to abort\n");
+               break;
+       case DID_PARITY:
+               printk("ppa: parity error (???)\n");
+               break;
+       case DID_ERROR:
+               printk("ppa: internal driver error\n");
+               break;
+       case DID_RESET:
+               printk("ppa: told to reset device\n");
+               break;
+       case DID_BAD_INTR:
+               printk("ppa: bad interrupt (???)\n");
+               break;
+       default:
+               printk("ppa: bad return code (%02x)\n",
+                      (cmd->result >> 16) & 0xff);
+       }
 #endif
 
-    if (cmd->SCp.phase > 1)
-       ppa_disconnect(cmd->device->host->unique_id);
-    if (cmd->SCp.phase > 0)
-       ppa_pb_release(cmd->device->host->unique_id);
-
-    tmp->cur_cmd = 0;
-    
-    spin_lock_irqsave(cmd->device->host->host_lock, flags);
-    cmd->scsi_done(cmd);
-    spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
-    return;
-}
+       if (cmd->SCp.phase > 1)
+               ppa_disconnect(dev);
 
-static int ppa_engine(ppa_struct * tmp, Scsi_Cmnd * cmd)
-{
-    int host_no = cmd->device->host->unique_id;
-    unsigned short ppb = PPA_BASE(host_no);
-    unsigned char l = 0, h = 0;
-    int retv;
-
-    /* First check for any errors that may of occurred
-     * Here we check for internal errors
-     */
-    if (tmp->failed)
-       return 0;
+       ppa_pb_dismiss(dev);
 
-    switch (cmd->SCp.phase) {
-    case 0:                    /* Phase 0 - Waiting for parport */
-       if ((jiffies - tmp->jstart) > HZ) {
-           /*
-            * We waited more than a second
-            * for parport to call us
-            */
-           ppa_fail(host_no, DID_BUS_BUSY);
-           return 0;
-       }
-       return 1;               /* wait until ppa_wakeup claims parport */
-    case 1:                    /* Phase 1 - Connected */
-       {                       /* Perform a sanity check for cable unplugged */
-           int retv = 2;       /* Failed */
+       dev->cur_cmd = 0;
 
-           ppa_connect(host_no, CONNECT_EPP_MAYBE);
+       cmd->scsi_done(cmd);
+}
 
-           w_ctr(ppb, 0xe);
-           if ((r_str(ppb) & 0x08) == 0x08)
-               retv--;
+static int ppa_engine(ppa_struct *dev, Scsi_Cmnd *cmd)
+{
+       unsigned short ppb = dev->base;
+       unsigned char l = 0, h = 0;
+       int retv;
 
-           w_ctr(ppb, 0xc);
-           if ((r_str(ppb) & 0x08) == 0x00)
-               retv--;
+       /* First check for any errors that may of occurred
+        * Here we check for internal errors
+        */
+       if (dev->failed)
+               return 0;
+
+       switch (cmd->SCp.phase) {
+       case 0:         /* Phase 0 - Waiting for parport */
+               if (time_after(jiffies, dev->jstart + HZ)) {
+                       /*
+                        * We waited more than a second
+                        * for parport to call us
+                        */
+                       ppa_fail(dev, DID_BUS_BUSY);
+                       return 0;
+               }
+               return 1;       /* wait until ppa_wakeup claims parport */
+       case 1:         /* Phase 1 - Connected */
+               {               /* Perform a sanity check for cable unplugged */
+                       int retv = 2;   /* Failed */
+
+                       ppa_connect(dev, CONNECT_EPP_MAYBE);
+
+                       w_ctr(ppb, 0xe);
+                       if ((r_str(ppb) & 0x08) == 0x08)
+                               retv--;
+
+                       w_ctr(ppb, 0xc);
+                       if ((r_str(ppb) & 0x08) == 0x00)
+                               retv--;
+
+                       if (retv) {
+                               if ((jiffies - dev->jstart) > (1 * HZ)) {
+                                       printk
+                                           ("ppa: Parallel port cable is unplugged!!\n");
+                                       ppa_fail(dev, DID_BUS_BUSY);
+                                       return 0;
+                               } else {
+                                       ppa_disconnect(dev);
+                                       return 1;       /* Try again in a jiffy */
+                               }
+                       }
+                       cmd->SCp.phase++;
+               }
 
-           if (retv) {
-               if ((jiffies - tmp->jstart) > (1 * HZ)) {
-                   printk("ppa: Parallel port cable is unplugged!!\n");
-                   ppa_fail(host_no, DID_BUS_BUSY);
-                   return 0;
+       case 2:         /* Phase 2 - We are now talking to the scsi bus */
+               if (!ppa_select(dev, cmd->device->id)) {
+                       ppa_fail(dev, DID_NO_CONNECT);
+                       return 0;
+               }
+               cmd->SCp.phase++;
+
+       case 3:         /* Phase 3 - Ready to accept a command */
+               w_ctr(ppb, 0x0c);
+               if (!(r_str(ppb) & 0x80))
+                       return 1;
+
+               if (!ppa_send_command(cmd))
+                       return 0;
+               cmd->SCp.phase++;
+
+       case 4:         /* Phase 4 - Setup scatter/gather buffers */
+               if (cmd->use_sg) {
+                       /* if many buffers are available, start filling the first */
+                       cmd->SCp.buffer =
+                           (struct scatterlist *) cmd->request_buffer;
+                       cmd->SCp.this_residual = cmd->SCp.buffer->length;
+                       cmd->SCp.ptr =
+                           page_address(cmd->SCp.buffer->page) +
+                           cmd->SCp.buffer->offset;
                } else {
-                   ppa_disconnect(host_no);
-                   return 1;   /* Try again in a jiffy */
+                       /* else fill the only available buffer */
+                       cmd->SCp.buffer = NULL;
+                       cmd->SCp.this_residual = cmd->request_bufflen;
+                       cmd->SCp.ptr = cmd->request_buffer;
                }
-           }
-           cmd->SCp.phase++;
-       }
-
-    case 2:                    /* Phase 2 - We are now talking to the scsi bus */
-       if (!ppa_select(host_no, cmd->device->id)) {
-           ppa_fail(host_no, DID_NO_CONNECT);
-           return 0;
-       }
-       cmd->SCp.phase++;
-
-    case 3:                    /* Phase 3 - Ready to accept a command */
-       w_ctr(ppb, 0x0c);
-       if (!(r_str(ppb) & 0x80))
-           return 1;
-
-       if (!ppa_send_command(cmd))
-           return 0;
-       cmd->SCp.phase++;
-
-    case 4:                    /* Phase 4 - Setup scatter/gather buffers */
-       if (cmd->use_sg) {
-           /* if many buffers are available, start filling the first */
-           cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
-           cmd->SCp.this_residual = cmd->SCp.buffer->length;
-           cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
-       } else {
-           /* else fill the only available buffer */
-           cmd->SCp.buffer = NULL;
-           cmd->SCp.this_residual = cmd->request_bufflen;
-           cmd->SCp.ptr = cmd->request_buffer;
-       }
-       cmd->SCp.buffers_residual = cmd->use_sg - 1;
-       cmd->SCp.phase++;
+               cmd->SCp.buffers_residual = cmd->use_sg - 1;
+               cmd->SCp.phase++;
+
+       case 5:         /* Phase 5 - Data transfer stage */
+               w_ctr(ppb, 0x0c);
+               if (!(r_str(ppb) & 0x80))
+                       return 1;
+
+               retv = ppa_completion(cmd);
+               if (retv == -1)
+                       return 0;
+               if (retv == 0)
+                       return 1;
+               cmd->SCp.phase++;
+
+       case 6:         /* Phase 6 - Read status/message */
+               cmd->result = DID_OK << 16;
+               /* Check for data overrun */
+               if (ppa_wait(dev) != (unsigned char) 0xf0) {
+                       ppa_fail(dev, DID_ERROR);
+                       return 0;
+               }
+               if (ppa_in(dev, &l, 1)) {       /* read status byte */
+                       /* Check for optional message byte */
+                       if (ppa_wait(dev) == (unsigned char) 0xf0)
+                               ppa_in(dev, &h, 1);
+                       cmd->result =
+                           (DID_OK << 16) + (h << 8) + (l & STATUS_MASK);
+               }
+               return 0;       /* Finished */
+               break;
 
-    case 5:                    /* Phase 5 - Data transfer stage */
-       w_ctr(ppb, 0x0c);
-       if (!(r_str(ppb) & 0x80))
-           return 1;
-
-       retv = ppa_completion(cmd);
-       if (retv == -1)
-           return 0;
-       if (retv == 0)
-           return 1;
-       cmd->SCp.phase++;
-
-    case 6:                    /* Phase 6 - Read status/message */
-       cmd->result = DID_OK << 16;
-       /* Check for data overrun */
-       if (ppa_wait(host_no) != (unsigned char) 0xf0) {
-           ppa_fail(host_no, DID_ERROR);
-           return 0;
+       default:
+               printk("ppa: Invalid scsi phase\n");
        }
-       if (ppa_in(host_no, &l, 1)) {   /* read status byte */
-           /* Check for optional message byte */
-           if (ppa_wait(host_no) == (unsigned char) 0xf0)
-               ppa_in(host_no, &h, 1);
-           cmd->result = (DID_OK << 16) + (h << 8) + (l & STATUS_MASK);
-       }
-       return 0;               /* Finished */
-       break;
-
-    default:
-       printk("ppa: Invalid scsi phase\n");
-    }
-    return 0;
+       return 0;
 }
 
-int ppa_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int ppa_queuecommand(Scsi_Cmnd *cmd, void (*done) (Scsi_Cmnd *))
 {
-    int host_no = cmd->device->host->unique_id;
+       ppa_struct *dev = ppa_dev(cmd->device->host);
 
-    if (ppa_hosts[host_no].cur_cmd) {
-       printk("PPA: bug in ppa_queuecommand\n");
-       return 0;
-    }
-    ppa_hosts[host_no].failed = 0;
-    ppa_hosts[host_no].jstart = jiffies;
-    ppa_hosts[host_no].cur_cmd = cmd;
-    cmd->scsi_done = done;
-    cmd->result = DID_ERROR << 16;     /* default return code */
-    cmd->SCp.phase = 0;                /* bus free */
+       if (dev->cur_cmd) {
+               printk("PPA: bug in ppa_queuecommand\n");
+               return 0;
+       }
+       dev->failed = 0;
+       dev->jstart = jiffies;
+       dev->cur_cmd = cmd;
+       cmd->scsi_done = done;
+       cmd->result = DID_ERROR << 16;  /* default return code */
+       cmd->SCp.phase = 0;     /* bus free */
 
-    ppa_pb_claim(host_no);
+       dev->ppa_tq.data = dev;
+       schedule_work(&dev->ppa_tq);
 
-    ppa_hosts[host_no].ppa_tq.data = ppa_hosts + host_no;
-    schedule_work(&ppa_hosts[host_no].ppa_tq);
+       ppa_pb_claim(dev);
 
-    return 0;
+       return 0;
 }
 
 /*
@@ -973,150 +831,314 @@ int ppa_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
  * be done in sd.c.  Even if it gets fixed there, this will still
  * work.
  */
-int ppa_biosparam(struct scsi_device *sdev, struct block_device *dev,
-               sector_t capacity, int ip[])
+static int ppa_biosparam(struct scsi_device *sdev, struct block_device *dev,
+             sector_t capacity, int ip[])
 {
-    ip[0] = 0x40;
-    ip[1] = 0x20;
-    ip[2] = ((unsigned long)capacity + 1) / (ip[0] * ip[1]);
-    if (ip[2] > 1024) {
-       ip[0] = 0xff;
-       ip[1] = 0x3f;
-       ip[2] = ((unsigned long)capacity + 1) / (ip[0] * ip[1]);
-       if (ip[2] > 1023)
-           ip[2] = 1023;
-    }
-    return 0;
+       ip[0] = 0x40;
+       ip[1] = 0x20;
+       ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
+       if (ip[2] > 1024) {
+               ip[0] = 0xff;
+               ip[1] = 0x3f;
+               ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
+               if (ip[2] > 1023)
+                       ip[2] = 1023;
+       }
+       return 0;
 }
 
-int ppa_abort(Scsi_Cmnd * cmd)
+static int ppa_abort(Scsi_Cmnd *cmd)
 {
-    int host_no = cmd->device->host->unique_id;
-    /*
-     * There is no method for aborting commands since Iomega
-     * have tied the SCSI_MESSAGE line high in the interface
-     */
-
-    switch (cmd->SCp.phase) {
-    case 0:                    /* Do not have access to parport */
-    case 1:                    /* Have not connected to interface */
-       ppa_hosts[host_no].cur_cmd = NULL;      /* Forget the problem */
-       return SUCCESS;
-       break;
-    default:                   /* SCSI command sent, can not abort */
-       return FAILED;
-       break;
-    }
+       ppa_struct *dev = ppa_dev(cmd->device->host);
+       /*
+        * There is no method for aborting commands since Iomega
+        * have tied the SCSI_MESSAGE line high in the interface
+        */
+
+       switch (cmd->SCp.phase) {
+       case 0:         /* Do not have access to parport */
+       case 1:         /* Have not connected to interface */
+               dev->cur_cmd = NULL;    /* Forget the problem */
+               return SUCCESS;
+               break;
+       default:                /* SCSI command sent, can not abort */
+               return FAILED;
+               break;
+       }
 }
 
 static void ppa_reset_pulse(unsigned int base)
 {
-    w_dtr(base, 0x40);
-    w_ctr(base, 0x8);
-    udelay(30);
-    w_ctr(base, 0xc);
+       w_dtr(base, 0x40);
+       w_ctr(base, 0x8);
+       udelay(30);
+       w_ctr(base, 0xc);
 }
 
-int ppa_reset(Scsi_Cmnd * cmd)
+static int ppa_reset(Scsi_Cmnd *cmd)
 {
-    int host_no = cmd->device->host->unique_id;
-
-    if (cmd->SCp.phase)
-       ppa_disconnect(host_no);
-    ppa_hosts[host_no].cur_cmd = NULL; /* Forget the problem */
-
-    ppa_connect(host_no, CONNECT_NORMAL);
-    ppa_reset_pulse(PPA_BASE(host_no));
-    udelay(1000);              /* device settle delay */
-    ppa_disconnect(host_no);
-    udelay(1000);              /* device settle delay */
-    return SUCCESS;
+       ppa_struct *dev = ppa_dev(cmd->device->host);
+
+       if (cmd->SCp.phase)
+               ppa_disconnect(dev);
+       dev->cur_cmd = NULL;    /* Forget the problem */
+
+       ppa_connect(dev, CONNECT_NORMAL);
+       ppa_reset_pulse(dev->base);
+       udelay(1000);           /* device settle delay */
+       ppa_disconnect(dev);
+       udelay(1000);           /* device settle delay */
+       return SUCCESS;
 }
 
-static int device_check(int host_no)
+static int device_check(ppa_struct *dev)
 {
-    /* This routine looks for a device and then attempts to use EPP
-       to send a command. If all goes as planned then EPP is available. */
-
-    static char cmd[6] =
-    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-    int loop, old_mode, status, k, ppb = PPA_BASE(host_no);
-    unsigned char l;
-
-    old_mode = ppa_hosts[host_no].mode;
-    for (loop = 0; loop < 8; loop++) {
-       /* Attempt to use EPP for Test Unit Ready */
-       if ((ppb & 0x0007) == 0x0000)
-           ppa_hosts[host_no].mode = PPA_EPP_32;
-
-      second_pass:
-       ppa_connect(host_no, CONNECT_EPP_MAYBE);
-       /* Select SCSI device */
-       if (!ppa_select(host_no, loop)) {
-           ppa_disconnect(host_no);
-           continue;
+       /* This routine looks for a device and then attempts to use EPP
+          to send a command. If all goes as planned then EPP is available. */
+
+       static char cmd[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       int loop, old_mode, status, k, ppb = dev->base;
+       unsigned char l;
+
+       old_mode = dev->mode;
+       for (loop = 0; loop < 8; loop++) {
+               /* Attempt to use EPP for Test Unit Ready */
+               if ((ppb & 0x0007) == 0x0000)
+                       dev->mode = PPA_EPP_32;
+
+             second_pass:
+               ppa_connect(dev, CONNECT_EPP_MAYBE);
+               /* Select SCSI device */
+               if (!ppa_select(dev, loop)) {
+                       ppa_disconnect(dev);
+                       continue;
+               }
+               printk("ppa: Found device at ID %i, Attempting to use %s\n",
+                      loop, PPA_MODE_STRING[dev->mode]);
+
+               /* Send SCSI command */
+               status = 1;
+               w_ctr(ppb, 0x0c);
+               for (l = 0; (l < 6) && (status); l++)
+                       status = ppa_out(dev, cmd, 1);
+
+               if (!status) {
+                       ppa_disconnect(dev);
+                       ppa_connect(dev, CONNECT_EPP_MAYBE);
+                       w_dtr(ppb, 0x40);
+                       w_ctr(ppb, 0x08);
+                       udelay(30);
+                       w_ctr(ppb, 0x0c);
+                       udelay(1000);
+                       ppa_disconnect(dev);
+                       udelay(1000);
+                       if (dev->mode == PPA_EPP_32) {
+                               dev->mode = old_mode;
+                               goto second_pass;
+                       }
+                       return -EIO;
+               }
+               w_ctr(ppb, 0x0c);
+               k = 1000000;    /* 1 Second */
+               do {
+                       l = r_str(ppb);
+                       k--;
+                       udelay(1);
+               } while (!(l & 0x80) && (k));
+
+               l &= 0xf0;
+
+               if (l != 0xf0) {
+                       ppa_disconnect(dev);
+                       ppa_connect(dev, CONNECT_EPP_MAYBE);
+                       ppa_reset_pulse(ppb);
+                       udelay(1000);
+                       ppa_disconnect(dev);
+                       udelay(1000);
+                       if (dev->mode == PPA_EPP_32) {
+                               dev->mode = old_mode;
+                               goto second_pass;
+                       }
+                       return -EIO;
+               }
+               ppa_disconnect(dev);
+               printk("ppa: Communication established with ID %i using %s\n",
+                      loop, PPA_MODE_STRING[dev->mode]);
+               ppa_connect(dev, CONNECT_EPP_MAYBE);
+               ppa_reset_pulse(ppb);
+               udelay(1000);
+               ppa_disconnect(dev);
+               udelay(1000);
+               return 0;
        }
-       printk("ppa: Found device at ID %i, Attempting to use %s\n", loop,
-              PPA_MODE_STRING[ppa_hosts[host_no].mode]);
+       return -ENODEV;
+}
 
-       /* Send SCSI command */
-       status = 1;
-       w_ctr(ppb, 0x0c);
-       for (l = 0; (l < 6) && (status); l++)
-           status = ppa_out(host_no, cmd, 1);
-
-       if (!status) {
-           ppa_disconnect(host_no);
-           ppa_connect(host_no, CONNECT_EPP_MAYBE);
-           w_dtr(ppb, 0x40);
-           w_ctr(ppb, 0x08);
-           udelay(30);
-           w_ctr(ppb, 0x0c);
-           udelay(1000);
-           ppa_disconnect(host_no);
-           udelay(1000);
-           if (ppa_hosts[host_no].mode == PPA_EPP_32) {
-               ppa_hosts[host_no].mode = old_mode;
-               goto second_pass;
-           }
-           printk("ppa: Unable to establish communication, aborting driver load.\n");
-           return 1;
+static Scsi_Host_Template ppa_template = {
+       .module                 = THIS_MODULE,
+       .proc_name              = "ppa",
+       .proc_info              = ppa_proc_info,
+       .name                   = "Iomega VPI0 (ppa) interface",
+       .queuecommand           = ppa_queuecommand,
+       .eh_abort_handler       = ppa_abort,
+       .eh_bus_reset_handler   = ppa_reset,
+       .eh_host_reset_handler  = ppa_reset,
+       .bios_param             = ppa_biosparam,
+       .this_id                = -1,
+       .sg_tablesize           = SG_ALL,
+       .cmd_per_lun            = 1,
+       .use_clustering         = ENABLE_CLUSTERING,
+       .can_queue              = 1,
+};
+
+/***************************************************************************
+ *                   Parallel port probing routines                        *
+ ***************************************************************************/
+
+static LIST_HEAD(ppa_hosts);
+
+static int __ppa_attach(struct parport *pb)
+{
+       struct Scsi_Host *host;
+       DECLARE_WAIT_QUEUE_HEAD(waiting);
+       DEFINE_WAIT(wait);
+       ppa_struct *dev;
+       int ports;
+       int modes, ppb, ppb_hi;
+       int err = -ENOMEM;
+
+       dev = kmalloc(sizeof(ppa_struct), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+       memset(dev, 0, sizeof(ppa_struct));
+       dev->base = -1;
+       dev->mode = PPA_AUTODETECT;
+       dev->recon_tmo = PPA_RECON_TMO;
+       init_waitqueue_head(&waiting);
+       dev->dev = parport_register_device(pb, "ppa", NULL, ppa_wakeup,
+                                           NULL, 0, dev);
+
+       if (!dev->dev)
+               goto out;
+
+       /* Claim the bus so it remembers what we do to the control
+        * registers. [ CTR and ECP ]
+        */
+       err = -EBUSY;
+       dev->waiting = &waiting;
+       prepare_to_wait(&waiting, &wait, TASK_UNINTERRUPTIBLE);
+       if (ppa_pb_claim(dev))
+               schedule_timeout(3 * HZ);
+       if (dev->wanted) {
+               printk(KERN_ERR "ppa%d: failed to claim parport because "
+                               "a pardevice is owning the port for too long "
+                               "time!\n", pb->number);
+               ppa_pb_dismiss(dev);
+               dev->waiting = NULL;
+               finish_wait(&waiting, &wait);
+               goto out1;
        }
+       dev->waiting = NULL;
+       finish_wait(&waiting, &wait);
+       ppb = dev->base = dev->dev->port->base;
+       ppb_hi = dev->dev->port->base_hi;
        w_ctr(ppb, 0x0c);
-       k = 1000000;            /* 1 Second */
-       do {
-           l = r_str(ppb);
-           k--;
-           udelay(1);
-       } while (!(l & 0x80) && (k));
-
-       l &= 0xf0;
-
-       if (l != 0xf0) {
-           ppa_disconnect(host_no);
-           ppa_connect(host_no, CONNECT_EPP_MAYBE);
-           ppa_reset_pulse(ppb);
-           udelay(1000);
-           ppa_disconnect(host_no);
-           udelay(1000);
-           if (ppa_hosts[host_no].mode == PPA_EPP_32) {
-               ppa_hosts[host_no].mode = old_mode;
-               goto second_pass;
-           }
-           printk("ppa: Unable to establish communication, aborting driver load.\n");
-           return 1;
+       modes = dev->dev->port->modes;
+
+       /* Mode detection works up the chain of speed
+        * This avoids a nasty if-then-else-if-... tree
+        */
+       dev->mode = PPA_NIBBLE;
+
+       if (modes & PARPORT_MODE_TRISTATE)
+               dev->mode = PPA_PS2;
+
+       if (modes & PARPORT_MODE_ECP) {
+               w_ecr(ppb_hi, 0x20);
+               dev->mode = PPA_PS2;
        }
-       ppa_disconnect(host_no);
-       printk("ppa: Communication established with ID %i using %s\n", loop,
-              PPA_MODE_STRING[ppa_hosts[host_no].mode]);
-       ppa_connect(host_no, CONNECT_EPP_MAYBE);
-       ppa_reset_pulse(ppb);
-       udelay(1000);
-       ppa_disconnect(host_no);
-       udelay(1000);
+       if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP))
+               w_ecr(ppb_hi, 0x80);
+
+       /* Done configuration */
+
+       err = ppa_init(dev);
+       ppa_pb_release(dev);
+
+       if (err)
+               goto out1;
+
+       /* now the glue ... */
+       if (dev->mode == PPA_NIBBLE || dev->mode == PPA_PS2)
+               ports = 3;
+       else
+               ports = 8;
+
+       INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev);
+
+       err = -ENOMEM;
+       host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *));
+       if (!host)
+               goto out1;
+       host->io_port = pb->base;
+       host->n_io_port = ports;
+       host->dma_channel = -1;
+       host->unique_id = pb->number;
+       *(ppa_struct **)&host->hostdata = dev;
+       dev->host = host;
+       list_add_tail(&dev->list, &ppa_hosts);
+       err = scsi_add_host(host, NULL);
+       if (err)
+               goto out2;
+       scsi_scan_host(host);
        return 0;
-    }
-    printk("ppa: No devices found, aborting driver load.\n");
-    return 1;
+out2:
+       list_del_init(&dev->list);
+       scsi_host_put(host);
+out1:
+       parport_unregister_device(dev->dev);
+out:
+       kfree(dev);
+       return err;
+}
+
+static void ppa_attach(struct parport *pb)
+{
+       __ppa_attach(pb);
+}
+
+static void ppa_detach(struct parport *pb)
+{
+       ppa_struct *dev;
+       list_for_each_entry(dev, &ppa_hosts, list) {
+               if (dev->dev->port == pb) {
+                       list_del_init(&dev->list);
+                       scsi_remove_host(dev->host);
+                       scsi_host_put(dev->host);
+                       parport_unregister_device(dev->dev);
+                       kfree(dev);
+                       break;
+               }
+       }
 }
+
+static struct parport_driver ppa_driver = {
+       .name   = "ppa",
+       .attach = ppa_attach,
+       .detach = ppa_detach,
+};
+
+static int __init ppa_driver_init(void)
+{
+       printk("ppa: Version %s\n", PPA_VERSION);
+       return parport_register_driver(&ppa_driver);
+}
+
+static void __exit ppa_driver_exit(void)
+{
+       parport_unregister_driver(&ppa_driver);
+}
+
+module_init(ppa_driver_init);
+module_exit(ppa_driver_exit);
 MODULE_LICENSE("GPL");
index c59f9a0..7bb2776 100644 (file)
@@ -73,7 +73,6 @@
  */
 /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */
 
-#ifdef PPA_CODE
 #include  <linux/config.h>
 #include  <linux/stddef.h>
 #include  <linux/module.h>
@@ -115,11 +114,7 @@ static char *PPA_MODE_STRING[] =
 #endif
     "Unknown"};
 
-/* This is a global option */
-int ppa_sg = SG_ALL;           /* enable/disable scatter-gather. */
-
 /* other options */
-#define PPA_CAN_QUEUE   1      /* use "queueing" interface */
 #define PPA_BURST_SIZE 512     /* data burst size */
 #define PPA_SELECT_TMO  5000   /* how long to wait for target ? */
 #define PPA_SPIN_TMO    50000  /* ppa_wait loop limiter */
@@ -152,23 +147,5 @@ int ppa_sg = SG_ALL;               /* enable/disable scatter-gather. */
 #endif
 
 static int ppa_engine(ppa_struct *, Scsi_Cmnd *);
-static int ppa_in(int, char *, int);
-static int ppa_init(int);
-static void ppa_interrupt(void *);
-static int ppa_out(int, char *, int);
-
-#else
-#define ppa_release 0
-#endif
-
-int ppa_detect(Scsi_Host_Template *);
-const char *ppa_info(struct Scsi_Host *);
-int ppa_command(Scsi_Cmnd *);
-int ppa_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-int ppa_abort(Scsi_Cmnd *);
-int ppa_reset(Scsi_Cmnd *);
-int ppa_proc_info(struct Scsi_Host *host, char *, char **, off_t, int, int);
-int ppa_biosparam(struct scsi_device *, struct block_device *,
-               sector_t, int *);
 
 #endif                         /* _PPA_H */
index b03db26..e8187f3 100644 (file)
@@ -1,41 +1,41 @@
-config SCSI_QLA2XXX_CONFIG
+config SCSI_QLA2XXX
        tristate
        default (SCSI && PCI)
        depends on SCSI && PCI
 
 config SCSI_QLA21XX
        tristate "QLogic ISP2100 host adapter family support"
-       depends on SCSI_QLA2XXX_CONFIG
+       depends on SCSI_QLA2XXX
        ---help---
        This driver supports the QLogic 21xx (ISP2100) host adapter family.
 
 config SCSI_QLA22XX
        tristate "QLogic ISP2200 host adapter family support"
-       depends on SCSI_QLA2XXX_CONFIG
+       depends on SCSI_QLA2XXX
        ---help---
        This driver supports the QLogic 22xx (ISP2200) host adapter family.
 
 config SCSI_QLA2300
        tristate "QLogic ISP2300 host adapter family support"
-       depends on SCSI_QLA2XXX_CONFIG
+       depends on SCSI_QLA2XXX
        ---help---
        This driver supports the QLogic 2300 (ISP2300, and ISP2312) host
        adapter family.
 
 config SCSI_QLA2322
        tristate "QLogic ISP2322 host adapter family support"
-       depends on SCSI_QLA2XXX_CONFIG
+       depends on SCSI_QLA2XXX
        ---help---
        This driver supports the QLogic 2322 (ISP2322) host adapter family.
 
 config SCSI_QLA6312
        tristate "QLogic ISP6312 host adapter family support"
-       depends on SCSI_QLA2XXX_CONFIG
+       depends on SCSI_QLA2XXX
        ---help---
        This driver supports the QLogic 6312 (ISP6312) host adapter family.
 
 config SCSI_QLA6322
        tristate "QLogic ISP6322 host adapter family support"
-       depends on SCSI_QLA2XXX_CONFIG
+       depends on SCSI_QLA2XXX
        ---help---
        This driver supports the QLogic 6322 (ISP6322) host adapter family.
index 9e19f07..02bbfa4 100644 (file)
@@ -62,7 +62,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
            ha->fw_dump_order);
        if (ha->fw_dump == NULL) {
                qla_printk(KERN_WARNING, ha,
-                   "Unable to allocated memory for firmware dump (%d/%d).\n",
+                   "Unable to allocated memory for firmware dump (%d/%Zd).\n",
                    ha->fw_dump_order, sizeof(struct qla2300_fw_dump));
                return;
        }
@@ -598,7 +598,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
            ha->fw_dump_order);
        if (ha->fw_dump == NULL) {
                qla_printk(KERN_WARNING, ha,
-                   "Unable to allocated memory for firmware dump (%d/%d).\n",
+                   "Unable to allocated memory for firmware dump (%d/%Zd).\n",
                    ha->fw_dump_order, sizeof(struct qla2100_fw_dump));
                return;
        }
index acde58d..3740771 100644 (file)
@@ -2382,8 +2382,9 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer,
            ha->brd_info->isp_name, ('A' + tmp_sn/100000), (tmp_sn%100000));
 
        copy_info(&info,
-           "Request Queue = 0x%p, Response Queue = 0x%p\n",
-           (void *)ha->request_dma, (void *)ha->response_dma);
+           "Request Queue = 0x%llx, Response Queue = 0x%llx\n",
+               (unsigned long long)ha->request_dma,
+               (unsigned long long)ha->response_dma);
 
        copy_info(&info,
            "Request Queue count = %ld, Response Queue count = %ld\n",
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
new file mode 100644 (file)
index 0000000..02da967
--- /dev/null
@@ -0,0 +1,2236 @@
+/*
+ * QLogic ISP2x00 SCSI-FCP
+ * Written by Erik H. Moe, ehm@cris.com
+ * Copyright 1995, Erik H. Moe
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+/* Renamed and updated to 1.3.x by Michael Griffith <grif@cs.ucr.edu> */
+
+/* This is a version of the isp1020 driver which was modified by
+ * Chris Loveland <cwl@iol.unh.edu> to support the isp2100 and isp2200
+ *
+ * Big endian support and dynamic DMA mapping added
+ * by Jakub Jelinek <jakub@redhat.com>.
+ *
+ * Conversion to final pci64 DMA interfaces
+ * by David S. Miller <davem@redhat.com>.
+ */
+
+/*
+ * $Date: 1995/09/22 02:23:15 $
+ * $Revision: 0.5 $
+ *
+ * $Log: isp1020.c,v $
+ * Revision 0.5  1995/09/22  02:23:15  root
+ * do auto request sense
+ *
+ * Revision 0.4  1995/08/07  04:44:33  root
+ * supply firmware with driver.
+ * numerous bug fixes/general cleanup of code.
+ *
+ * Revision 0.3  1995/07/16  16:15:39  root
+ * added reset/abort code.
+ *
+ * Revision 0.2  1995/06/29  03:14:19  root
+ * fixed biosparam.
+ * added queue protocol.
+ *
+ * Revision 0.1  1995/06/25  01:55:45  root
+ * Initial release.
+ *
+ */
+
+#include <linux/blkdev.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/unistd.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#define pci64_dma_hi32(a) ((u32) (0xffffffff & (((u64)(a))>>32)))
+#define pci64_dma_lo32(a) ((u32) (0xffffffff & (((u64)(a)))))
+#define pci64_dma_build(hi,lo) \
+       ((dma_addr_t)(((u64)(lo))|(((u64)(hi))<<32)))
+
+#include "qlogicfc.h"
+
+/* Configuration section **************************************************** */
+
+/* Set the following macro to 1 to reload the ISP2x00's firmware.  This is
+   version 1.17.30 of the isp2100's firmware and version 2.00.40 of the 
+   isp2200's firmware. 
+*/
+
+#define USE_NVRAM_DEFAULTS      1
+
+#define ISP2x00_PORTDB          1
+
+/* 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          1
+
+/*  Macros used for debugging */
+#define DEBUG_ISP2x00          0
+#define DEBUG_ISP2x00_INT      0
+#define DEBUG_ISP2x00_INTR     0
+#define DEBUG_ISP2x00_SETUP    0
+#define DEBUG_ISP2x00_FABRIC    0
+#define TRACE_ISP              0 
+
+
+#define DEFAULT_LOOP_COUNT     1000000000
+
+/* End Configuration section ************************************************ */
+
+#include <linux/module.h>
+
+#if TRACE_ISP
+
+#define TRACE_BUF_LEN  (32*1024)
+
+struct {
+       u_long next;
+       struct {
+               u_long time;
+               u_int index;
+               u_int addr;
+               u_char *name;
+       } buf[TRACE_BUF_LEN];
+} trace;
+
+#define TRACE(w, i, a)                                         \
+{                                                              \
+       unsigned long flags;                                    \
+                                                               \
+       save_flags(flags);                                      \
+       cli();                                                  \
+       trace.buf[trace.next].name  = (w);                      \
+       trace.buf[trace.next].time  = jiffies;                  \
+       trace.buf[trace.next].index = (i);                      \
+       trace.buf[trace.next].addr  = (long) (a);               \
+       trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1);    \
+       restore_flags(flags);                                   \
+}
+
+#else
+#define TRACE(w, i, a)
+#endif
+
+#if DEBUG_ISP2x00_FABRIC
+#define DEBUG_FABRIC(x)        x
+#else
+#define DEBUG_FABRIC(x)
+#endif                         /* DEBUG_ISP2x00_FABRIC */
+
+
+#if DEBUG_ISP2x00
+#define ENTER(x)       printk("isp2x00 : entering %s()\n", x);
+#define LEAVE(x)       printk("isp2x00 : leaving %s()\n", x);
+#define DEBUG(x)       x
+#else
+#define ENTER(x)
+#define LEAVE(x)
+#define DEBUG(x)
+#endif                         /* DEBUG_ISP2x00 */
+
+#if DEBUG_ISP2x00_INTR
+#define ENTER_INTR(x)  printk("isp2x00 : entering %s()\n", x);
+#define LEAVE_INTR(x)  printk("isp2x00 : leaving %s()\n", x);
+#define DEBUG_INTR(x)  x
+#else
+#define ENTER_INTR(x)
+#define LEAVE_INTR(x)
+#define DEBUG_INTR(x)
+#endif                         /* DEBUG ISP2x00_INTR */
+
+
+#define ISP2100_REV_ID1               1
+#define ISP2100_REV_ID3        3
+#define ISP2200_REV_ID5        5
+
+/* host configuration and control registers */
+#define HOST_HCCR      0xc0    /* host command and control */
+
+/* pci bus interface registers */
+#define FLASH_BIOS_ADDR        0x00
+#define FLASH_BIOS_DATA        0x02
+#define ISP_CTRL_STATUS        0x06    /* configuration register #1 */
+#define PCI_INTER_CTL  0x08    /* pci interrupt control */
+#define PCI_INTER_STS  0x0a    /* pci interrupt status */
+#define PCI_SEMAPHORE  0x0c    /* pci semaphore */
+#define PCI_NVRAM      0x0e    /* pci nvram interface */
+
+/* mailbox registers */
+#define MBOX0          0x10    /* mailbox 0 */
+#define MBOX1          0x12    /* mailbox 1 */
+#define MBOX2          0x14    /* mailbox 2 */
+#define MBOX3          0x16    /* mailbox 3 */
+#define MBOX4          0x18    /* mailbox 4 */
+#define MBOX5          0x1a    /* mailbox 5 */
+#define MBOX6          0x1c    /* mailbox 6 */
+#define MBOX7          0x1e    /* mailbox 7 */
+
+/* mailbox command complete status codes */
+#define MBOX_COMMAND_COMPLETE          0x4000
+#define INVALID_COMMAND                        0x4001
+#define HOST_INTERFACE_ERROR           0x4002
+#define TEST_FAILED                    0x4003
+#define COMMAND_ERROR                  0x4005
+#define COMMAND_PARAM_ERROR            0x4006
+#define PORT_ID_USED                    0x4007
+#define LOOP_ID_USED                    0x4008
+#define ALL_IDS_USED                    0x4009
+
+/* async event status codes */
+#define RESET_DETECTED                 0x8001
+#define SYSTEM_ERROR                   0x8002
+#define REQUEST_TRANSFER_ERROR         0x8003
+#define RESPONSE_TRANSFER_ERROR                0x8004
+#define REQUEST_QUEUE_WAKEUP           0x8005
+#define LIP_OCCURRED                     0x8010
+#define LOOP_UP                         0x8011
+#define LOOP_DOWN                       0x8012
+#define LIP_RECEIVED                    0x8013
+#define PORT_DB_CHANGED                 0x8014
+#define CHANGE_NOTIFICATION             0x8015
+#define SCSI_COMMAND_COMPLETE           0x8020
+#define POINT_TO_POINT_UP               0x8030
+#define CONNECTION_MODE                 0x8036
+
+struct Entry_header {
+       u_char entry_type;
+       u_char entry_cnt;
+       u_char sys_def_1;
+       u_char flags;
+};
+
+/* entry header type commands */
+#define ENTRY_COMMAND          0x19
+#define ENTRY_CONTINUATION     0x0a
+
+#define ENTRY_STATUS           0x03
+#define ENTRY_MARKER           0x04
+
+
+/* entry header flag definitions */
+#define EFLAG_BUSY             2
+#define EFLAG_BAD_HEADER       4
+#define EFLAG_BAD_PAYLOAD      8
+
+struct dataseg {
+       u_int d_base;
+       u_int d_base_hi;
+       u_int d_count;
+};
+
+struct Command_Entry {
+       struct Entry_header hdr;
+       u_int handle;
+       u_char target_lun;
+       u_char target_id;
+       u_short expanded_lun;
+       u_short control_flags;
+       u_short rsvd2;
+       u_short time_out;
+       u_short segment_cnt;
+       u_char cdb[16];
+       u_int total_byte_cnt;
+       struct dataseg dataseg[DATASEGS_PER_COMMAND];
+};
+
+/* command entry control flag definitions */
+#define CFLAG_NODISC           0x01
+#define CFLAG_HEAD_TAG         0x02
+#define CFLAG_ORDERED_TAG      0x04
+#define CFLAG_SIMPLE_TAG       0x08
+#define CFLAG_TAR_RTN          0x10
+#define CFLAG_READ             0x20
+#define CFLAG_WRITE            0x40
+
+struct Continuation_Entry {
+       struct Entry_header hdr;
+       struct dataseg dataseg[DATASEGS_PER_CONT];
+};
+
+struct Marker_Entry {
+       struct Entry_header hdr;
+       u_int reserved;
+       u_char target_lun;
+       u_char target_id;
+       u_char modifier;
+       u_char expanded_lun;
+       u_char rsvds[52];
+};
+
+/* marker entry modifier definitions */
+#define SYNC_DEVICE    0
+#define SYNC_TARGET    1
+#define SYNC_ALL       2
+
+struct Status_Entry {
+       struct Entry_header hdr;
+       u_int handle;
+       u_short scsi_status;
+       u_short completion_status;
+       u_short state_flags;
+       u_short status_flags;
+       u_short res_info_len;
+       u_short req_sense_len;
+       u_int residual;
+       u_char res_info[8];
+       u_char req_sense_data[32];
+};
+
+/* status entry completion status definitions */
+#define CS_COMPLETE                    0x0000
+#define CS_DMA_ERROR                   0x0002
+#define CS_RESET_OCCURRED              0x0004
+#define CS_ABORTED                     0x0005
+#define CS_TIMEOUT                     0x0006
+#define CS_DATA_OVERRUN                        0x0007
+#define CS_DATA_UNDERRUN               0x0015
+#define CS_QUEUE_FULL                  0x001c
+#define CS_PORT_UNAVAILABLE             0x0028
+#define CS_PORT_LOGGED_OUT              0x0029
+#define CS_PORT_CONFIG_CHANGED         0x002a
+
+/* status entry state flag definitions */
+#define SF_SENT_CDB                    0x0400
+#define SF_TRANSFERRED_DATA            0x0800
+#define SF_GOT_STATUS                  0x1000
+
+/* status entry status flag definitions */
+#define STF_BUS_RESET                  0x0008
+#define STF_DEVICE_RESET               0x0010
+#define STF_ABORTED                    0x0020
+#define STF_TIMEOUT                    0x0040
+
+/* interrupt control commands */
+#define ISP_EN_INT                     0x8000
+#define ISP_EN_RISC                    0x0008
+
+/* host control commands */
+#define HCCR_NOP                       0x0000
+#define HCCR_RESET                     0x1000
+#define HCCR_PAUSE                     0x2000
+#define HCCR_RELEASE                   0x3000
+#define HCCR_SINGLE_STEP               0x4000
+#define HCCR_SET_HOST_INTR             0x5000
+#define HCCR_CLEAR_HOST_INTR           0x6000
+#define HCCR_CLEAR_RISC_INTR           0x7000
+#define HCCR_BP_ENABLE                 0x8000
+#define HCCR_BIOS_DISABLE              0x9000
+#define HCCR_TEST_MODE                 0xf000
+
+#define RISC_BUSY                      0x0004
+
+/* mailbox commands */
+#define MBOX_NO_OP                     0x0000
+#define MBOX_LOAD_RAM                  0x0001
+#define MBOX_EXEC_FIRMWARE             0x0002
+#define MBOX_DUMP_RAM                  0x0003
+#define MBOX_WRITE_RAM_WORD            0x0004
+#define MBOX_READ_RAM_WORD             0x0005
+#define MBOX_MAILBOX_REG_TEST          0x0006
+#define MBOX_VERIFY_CHECKSUM           0x0007
+#define MBOX_ABOUT_FIRMWARE            0x0008
+#define MBOX_LOAD_RISC_RAM              0x0009
+#define MBOX_DUMP_RISC_RAM              0x000a
+#define MBOX_CHECK_FIRMWARE            0x000e
+#define MBOX_INIT_REQ_QUEUE            0x0010
+#define MBOX_INIT_RES_QUEUE            0x0011
+#define MBOX_EXECUTE_IOCB              0x0012
+#define MBOX_WAKE_UP                   0x0013
+#define MBOX_STOP_FIRMWARE             0x0014
+#define MBOX_ABORT_IOCB                        0x0015
+#define MBOX_ABORT_DEVICE              0x0016
+#define MBOX_ABORT_TARGET              0x0017
+#define MBOX_BUS_RESET                 0x0018
+#define MBOX_STOP_QUEUE                        0x0019
+#define MBOX_START_QUEUE               0x001a
+#define MBOX_SINGLE_STEP_QUEUE         0x001b
+#define MBOX_ABORT_QUEUE               0x001c
+#define MBOX_GET_DEV_QUEUE_STATUS      0x001d
+#define MBOX_GET_FIRMWARE_STATUS       0x001f
+#define MBOX_GET_INIT_SCSI_ID          0x0020
+#define MBOX_GET_RETRY_COUNT           0x0022
+#define MBOX_GET_TARGET_PARAMS         0x0028
+#define MBOX_GET_DEV_QUEUE_PARAMS      0x0029
+#define MBOX_SET_RETRY_COUNT           0x0032
+#define MBOX_SET_TARGET_PARAMS         0x0038
+#define MBOX_SET_DEV_QUEUE_PARAMS      0x0039
+#define MBOX_EXECUTE_IOCB64             0x0054
+#define MBOX_INIT_FIRMWARE              0x0060
+#define MBOX_GET_INIT_CB                0x0061
+#define MBOX_INIT_LIP                  0x0062
+#define MBOX_GET_POS_MAP                0x0063
+#define MBOX_GET_PORT_DB                0x0064
+#define MBOX_CLEAR_ACA                  0x0065
+#define MBOX_TARGET_RESET               0x0066
+#define MBOX_CLEAR_TASK_SET             0x0067
+#define MBOX_ABORT_TASK_SET             0x0068
+#define MBOX_GET_FIRMWARE_STATE         0x0069
+#define MBOX_GET_PORT_NAME              0x006a
+#define MBOX_SEND_SNS                   0x006e
+#define MBOX_PORT_LOGIN                 0x006f
+#define MBOX_SEND_CHANGE_REQUEST        0x0070
+#define MBOX_PORT_LOGOUT                0x0071
+
+/*
+ *     Firmware if needed (note this is a hack, it belongs in a separate
+ *     module.
+ */
+#ifdef CONFIG_SCSI_QLOGIC_FC_FIRMWARE
+#include "qlogicfc_asm.c"
+#else
+static unsigned short risc_code_addr01 = 0x1000 ;
+#endif
+
+/* Each element in mbox_param is an 8 bit bitmap where each bit indicates
+   if that mbox should be copied as input.  For example 0x2 would mean
+   only copy mbox1. */
+
+const u_char mbox_param[] =
+{
+       0x01,                   /* MBOX_NO_OP */
+       0x1f,                   /* MBOX_LOAD_RAM */
+       0x03,                   /* MBOX_EXEC_FIRMWARE */
+       0x1f,                   /* MBOX_DUMP_RAM */
+       0x07,                   /* MBOX_WRITE_RAM_WORD */
+       0x03,                   /* MBOX_READ_RAM_WORD */
+       0xff,                   /* MBOX_MAILBOX_REG_TEST */
+       0x03,                   /* MBOX_VERIFY_CHECKSUM */
+       0x01,                   /* MBOX_ABOUT_FIRMWARE */
+       0xff,                   /* MBOX_LOAD_RISC_RAM */
+       0xff,                   /* MBOX_DUMP_RISC_RAM */
+       0x00,                   /* 0x000b */
+       0x00,                   /* 0x000c */
+       0x00,                   /* 0x000d */
+       0x01,                   /* MBOX_CHECK_FIRMWARE */
+       0x00,                   /* 0x000f */
+       0x1f,                   /* MBOX_INIT_REQ_QUEUE */
+       0x2f,                   /* MBOX_INIT_RES_QUEUE */
+       0x0f,                   /* MBOX_EXECUTE_IOCB */
+       0x03,                   /* MBOX_WAKE_UP */
+       0x01,                   /* MBOX_STOP_FIRMWARE */
+       0x0f,                   /* MBOX_ABORT_IOCB */
+       0x03,                   /* MBOX_ABORT_DEVICE */
+       0x07,                   /* MBOX_ABORT_TARGET */
+       0x03,                   /* MBOX_BUS_RESET */
+       0x03,                   /* MBOX_STOP_QUEUE */
+       0x03,                   /* MBOX_START_QUEUE */
+       0x03,                   /* MBOX_SINGLE_STEP_QUEUE */
+       0x03,                   /* MBOX_ABORT_QUEUE */
+       0x03,                   /* MBOX_GET_DEV_QUEUE_STATUS */
+       0x00,                   /* 0x001e */
+       0x01,                   /* MBOX_GET_FIRMWARE_STATUS */
+       0x01,                   /* MBOX_GET_INIT_SCSI_ID */
+       0x00,                   /* 0x0021 */
+       0x01,                   /* MBOX_GET_RETRY_COUNT */
+       0x00,                   /* 0x0023 */
+       0x00,                   /* 0x0024 */
+       0x00,                   /* 0x0025 */
+       0x00,                   /* 0x0026 */
+       0x00,                   /* 0x0027 */
+       0x03,                   /* MBOX_GET_TARGET_PARAMS */
+       0x03,                   /* MBOX_GET_DEV_QUEUE_PARAMS */
+       0x00,                   /* 0x002a */
+       0x00,                   /* 0x002b */
+       0x00,                   /* 0x002c */
+       0x00,                   /* 0x002d */
+       0x00,                   /* 0x002e */
+       0x00,                   /* 0x002f */
+       0x00,                   /* 0x0030 */
+       0x00,                   /* 0x0031 */
+       0x07,                   /* MBOX_SET_RETRY_COUNT */
+       0x00,                   /* 0x0033 */
+       0x00,                   /* 0x0034 */
+       0x00,                   /* 0x0035 */
+       0x00,                   /* 0x0036 */
+       0x00,                   /* 0x0037 */
+       0x0f,                   /* MBOX_SET_TARGET_PARAMS */
+       0x0f,                   /* MBOX_SET_DEV_QUEUE_PARAMS */
+       0x00,                   /* 0x003a */
+       0x00,                   /* 0x003b */
+       0x00,                   /* 0x003c */
+       0x00,                   /* 0x003d */
+       0x00,                   /* 0x003e */
+       0x00,                   /* 0x003f */
+       0x00,                   /* 0x0040 */
+       0x00,                   /* 0x0041 */
+       0x00,                   /* 0x0042 */
+       0x00,                   /* 0x0043 */
+       0x00,                   /* 0x0044 */
+       0x00,                   /* 0x0045 */
+       0x00,                   /* 0x0046 */
+       0x00,                   /* 0x0047 */
+       0x00,                   /* 0x0048 */
+       0x00,                   /* 0x0049 */
+       0x00,                   /* 0x004a */
+       0x00,                   /* 0x004b */
+       0x00,                   /* 0x004c */
+       0x00,                   /* 0x004d */
+       0x00,                   /* 0x004e */
+       0x00,                   /* 0x004f */
+       0x00,                   /* 0x0050 */
+       0x00,                   /* 0x0051 */
+       0x00,                   /* 0x0052 */
+       0x00,                   /* 0x0053 */
+       0xcf,                   /* MBOX_EXECUTE_IOCB64 */
+       0x00,                   /* 0x0055 */
+       0x00,                   /* 0x0056 */
+       0x00,                   /* 0x0057 */
+       0x00,                   /* 0x0058 */
+       0x00,                   /* 0x0059 */
+       0x00,                   /* 0x005a */
+       0x00,                   /* 0x005b */
+       0x00,                   /* 0x005c */
+       0x00,                   /* 0x005d */
+       0x00,                   /* 0x005e */
+       0x00,                   /* 0x005f */
+       0xff,                   /* MBOX_INIT_FIRMWARE */
+       0xcd,                   /* MBOX_GET_INIT_CB */
+       0x01,                   /* MBOX_INIT_LIP */
+       0xcd,                   /* MBOX_GET_POS_MAP */
+       0xcf,                   /* MBOX_GET_PORT_DB */
+       0x03,                   /* MBOX_CLEAR_ACA */
+       0x03,                   /* MBOX_TARGET_RESET */
+       0x03,                   /* MBOX_CLEAR_TASK_SET */
+       0x03,                   /* MBOX_ABORT_TASK_SET */
+       0x01,                   /* MBOX_GET_FIRMWARE_STATE */
+       0x03,                   /* MBOX_GET_PORT_NAME */
+       0x00,                   /* 0x006b */
+       0x00,                   /* 0x006c */
+       0x00,                   /* 0x006d */
+       0xcf,                   /* MBOX_SEND_SNS */
+       0x0f,                   /* MBOX_PORT_LOGIN */
+       0x03,                   /* MBOX_SEND_CHANGE_REQUEST */
+       0x03,                   /* MBOX_PORT_LOGOUT */
+};
+
+#define MAX_MBOX_COMMAND       (sizeof(mbox_param)/sizeof(u_short))
+
+
+struct id_name_map {
+       u64 wwn;
+       u_char loop_id;
+};
+
+struct sns_cb {
+       u_short len;
+       u_short res1;
+       u_int response_low;
+       u_int response_high;
+       u_short sub_len;
+       u_short res2;
+       u_char data[44];
+};
+
+/* address of instance of this struct is passed to adapter to initialize things
+ */
+struct init_cb {
+       u_char version;
+       u_char reseverd1[1];
+       u_short firm_opts;
+       u_short max_frame_len;
+       u_short max_iocb;
+       u_short exec_throttle;
+       u_char retry_cnt;
+       u_char retry_delay;
+       u_short node_name[4];
+       u_short hard_addr;
+       u_char reserved2[10];
+       u_short req_queue_out;
+       u_short res_queue_in;
+       u_short req_queue_len;
+       u_short res_queue_len;
+       u_int req_queue_addr_lo;
+       u_int req_queue_addr_high;
+       u_int res_queue_addr_lo;
+       u_int res_queue_addr_high;
+        /* the rest of this structure only applies to the isp2200 */
+        u_short lun_enables;
+        u_char cmd_resource_cnt;
+        u_char notify_resource_cnt;
+        u_short timeout;
+        u_short reserved3;
+        u_short add_firm_opts;
+        u_char res_accum_timer;
+        u_char irq_delay_timer;
+        u_short special_options;
+        u_short reserved4[13];
+};
+
+/*
+ * The result queue can be quite a bit smaller since continuation entries
+ * do not show up there:
+ */
+#define RES_QUEUE_LEN          ((QLOGICFC_REQ_QUEUE_LEN + 1) / 8 - 1)
+#define QUEUE_ENTRY_LEN                64
+
+#if ISP2x00_FABRIC
+#define QLOGICFC_MAX_ID    0xff
+#else
+#define QLOGICFC_MAX_ID    0x7d
+#endif
+
+#define QLOGICFC_MAX_LUN       128
+#define QLOGICFC_MAX_LOOP_ID   0x7d
+
+/* the following connection options only apply to the 2200.  i have only
+ * had success with LOOP_ONLY and P2P_ONLY.
+ */
+
+#define LOOP_ONLY              0
+#define P2P_ONLY               1
+#define LOOP_PREFERED          2
+#define P2P_PREFERED           3
+
+#define CONNECTION_PREFERENCE  LOOP_ONLY
+
+/* adapter_state values */
+#define AS_FIRMWARE_DEAD      -1
+#define AS_LOOP_DOWN           0
+#define AS_LOOP_GOOD           1
+#define AS_REDO_FABRIC_PORTDB  2
+#define AS_REDO_LOOP_PORTDB    4
+
+#define RES_SIZE       ((RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN)
+#define REQ_SIZE       ((QLOGICFC_REQ_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN)
+
+struct isp2x00_hostdata {
+       u_char revision;
+       struct pci_dev *pci_dev;
+       /* result and request queues (shared with isp2x00): */
+       u_int req_in_ptr;       /* index of next request slot */
+       u_int res_out_ptr;      /* index of next result slot */
+
+       /* this is here so the queues are nicely aligned */
+       long send_marker;       /* do we need to send a marker? */
+
+       char * res;
+       char * req;
+       struct init_cb control_block;
+       int adapter_state;
+       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];
+       u_char mbox_done;
+       u64 wwn;
+       u_int port_id;
+       u_char queued;
+       u_char host_id;
+        struct timer_list explore_timer;
+       struct id_name_map tempmap[QLOGICFC_MAX_ID + 1];
+};
+
+
+/* queue length's _must_ be power of two: */
+#define QUEUE_DEPTH(in, out, ql)       ((in - out) & (ql))
+#define REQ_QUEUE_DEPTH(in, out)       QUEUE_DEPTH(in, out,                 \
+                                                   QLOGICFC_REQ_QUEUE_LEN)
+#define RES_QUEUE_DEPTH(in, out)       QUEUE_DEPTH(in, out, RES_QUEUE_LEN)
+
+static void isp2x00_enable_irqs(struct Scsi_Host *);
+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(Scsi_Cmnd *, struct Status_Entry *);
+static void isp2x00_intr_handler(int, void *, struct pt_regs *);
+static irqreturn_t do_isp2x00_intr_handler(int, void *, struct pt_regs *);
+static int isp2x00_make_portdb(struct Scsi_Host *);
+
+#if ISP2x00_FABRIC
+static int isp2x00_init_fabric(struct Scsi_Host *, struct id_name_map *, int);
+#endif
+
+#if USE_NVRAM_DEFAULTS
+static int isp2x00_get_nvram_defaults(struct Scsi_Host *, struct init_cb *);
+static u_short isp2x00_read_nvram_word(struct Scsi_Host *, u_short);
+#endif
+
+#if DEBUG_ISP2x00
+static void isp2x00_print_scsi_cmd(Scsi_Cmnd *);
+#endif
+
+#if DEBUG_ISP2x00_INTR
+static void isp2x00_print_status_entry(struct Status_Entry *);
+#endif
+
+static inline void isp2x00_enable_irqs(struct Scsi_Host *host)
+{
+       outw(ISP_EN_INT | ISP_EN_RISC, host->io_port + PCI_INTER_CTL);
+}
+
+
+static inline void isp2x00_disable_irqs(struct Scsi_Host *host)
+{
+       outw(0x0, host->io_port + PCI_INTER_CTL);
+}
+
+
+int isp2x00_detect(Scsi_Host_Template * tmpt)
+{
+       int hosts = 0;
+       unsigned long wait_time;
+       struct Scsi_Host *host = NULL;
+       struct isp2x00_hostdata *hostdata;
+       struct pci_dev *pdev;
+       unsigned short device_ids[2];
+       dma_addr_t busaddr;
+       int i;
+
+
+       ENTER("isp2x00_detect");
+
+               device_ids[0] = PCI_DEVICE_ID_QLOGIC_ISP2100;
+       device_ids[1] = PCI_DEVICE_ID_QLOGIC_ISP2200;
+
+       tmpt->proc_name = "isp2x00";
+
+       for (i=0; i<2; i++){
+               pdev = NULL;
+               while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, device_ids[i], pdev))) {
+                       if (pci_enable_device(pdev))
+                               continue;
+
+                       /* Try to configure DMA attributes. */
+                       if (pci_set_dma_mask(pdev, 0xffffffffffffffffULL) &&
+                           pci_set_dma_mask(pdev, 0xffffffffULL))
+                                       continue;
+
+                       host = scsi_register(tmpt, sizeof(struct isp2x00_hostdata));
+                       if (!host) {
+                               printk("qlogicfc%d : could not register host.\n", hosts);
+                               continue;
+                       }
+                       scsi_set_device(host, &pdev->dev);
+                       host->max_id = QLOGICFC_MAX_ID + 1;
+                       host->max_lun = QLOGICFC_MAX_LUN;
+                       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+
+                       memset(hostdata, 0, sizeof(struct isp2x00_hostdata));
+                       hostdata->pci_dev = pdev;
+                       hostdata->res = pci_alloc_consistent(pdev, RES_SIZE + REQ_SIZE, &busaddr);
+
+                       if (!hostdata->res){
+                               printk("qlogicfc%d : could not allocate memory for request and response queue.\n", hosts);
+                               scsi_unregister(host);
+                               continue;
+                       }
+                       hostdata->req = hostdata->res + (RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN;
+                       hostdata->queued = 0;
+                       /* set up the control block */
+                       hostdata->control_block.version = 0x1;
+                       hostdata->control_block.firm_opts = cpu_to_le16(0x800e);
+                       hostdata->control_block.max_frame_len = cpu_to_le16(2048);
+                       hostdata->control_block.max_iocb = cpu_to_le16(QLOGICFC_REQ_QUEUE_LEN);
+                       hostdata->control_block.exec_throttle = cpu_to_le16(QLOGICFC_CMD_PER_LUN);
+                       hostdata->control_block.retry_delay = 5;
+                       hostdata->control_block.retry_cnt = 1;
+                       hostdata->control_block.node_name[0] = cpu_to_le16(0x0020);
+                       hostdata->control_block.node_name[1] = cpu_to_le16(0xE000);
+                       hostdata->control_block.node_name[2] = cpu_to_le16(0x008B);
+                       hostdata->control_block.node_name[3] = cpu_to_le16(0x0000);
+                       hostdata->control_block.hard_addr = cpu_to_le16(0x0003);
+                       hostdata->control_block.req_queue_len = cpu_to_le16(QLOGICFC_REQ_QUEUE_LEN + 1);
+                       hostdata->control_block.res_queue_len = cpu_to_le16(RES_QUEUE_LEN + 1);
+                       hostdata->control_block.res_queue_addr_lo = cpu_to_le32(pci64_dma_lo32(busaddr));
+                       hostdata->control_block.res_queue_addr_high = cpu_to_le32(pci64_dma_hi32(busaddr));
+                       hostdata->control_block.req_queue_addr_lo = cpu_to_le32(pci64_dma_lo32(busaddr + RES_SIZE));
+                       hostdata->control_block.req_queue_addr_high = cpu_to_le32(pci64_dma_hi32(busaddr + RES_SIZE));
+
+
+                       hostdata->control_block.add_firm_opts |= cpu_to_le16(CONNECTION_PREFERENCE<<4);
+                       hostdata->adapter_state = AS_LOOP_DOWN;
+                       hostdata->explore_timer.data = 1;
+                       hostdata->host_id = hosts;
+
+                       if (isp2x00_init(host) || isp2x00_reset_hardware(host)) {
+                               pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+                               scsi_unregister(host);
+                               continue;
+                       }
+                       host->this_id = 0;
+
+                       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);
+                               pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+                               scsi_unregister(host);
+                               continue;
+                       }
+                       if (!request_region(host->io_port, 0xff, "qlogicfc")) {
+                               printk("qlogicfc%d : i/o region 0x%lx-0x%lx already "
+                                      "in use\n",
+                                      hostdata->host_id, host->io_port, host->io_port + 0xff);
+                               free_irq(host->irq, host);
+                               pci_free_consistent (pdev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+                               scsi_unregister(host);
+                               continue;
+                       }
+
+                       outw(0x0, host->io_port + PCI_SEMAPHORE);
+                       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+                       isp2x00_enable_irqs(host);
+                       /* wait for the loop to come up */
+                       for (wait_time = jiffies + 10 * HZ; time_before(jiffies, wait_time) && hostdata->adapter_state == AS_LOOP_DOWN;) {
+                               barrier();
+                               cpu_relax();
+                       }
+                       if (hostdata->adapter_state == AS_LOOP_DOWN) {
+                               printk("qlogicfc%d : link is not up\n", hostdata->host_id);
+                       }
+                       hosts++;
+                       hostdata->explore_timer.data = 0;
+               }
+       }
+
+
+       /* this busy loop should not be needed but the isp2x00 seems to need 
+          some time before recognizing it is attached to a fabric */
+
+#if ISP2x00_FABRIC
+       for (wait_time = jiffies + 5 * HZ; time_before(jiffies, wait_time);) {
+               barrier();
+               cpu_relax();
+       }
+#endif
+
+       LEAVE("isp2x00_detect");
+
+       return hosts;
+}
+
+
+static int isp2x00_make_portdb(struct Scsi_Host *host)
+{
+
+       short param[8];
+       int i, j;
+       struct isp2x00_hostdata *hostdata;
+
+       isp2x00_disable_irqs(host);
+
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+       memset(hostdata->tempmap, 0, sizeof(hostdata->tempmap));
+
+#if ISP2x00_FABRIC
+       for (i = 0x81; i < QLOGICFC_MAX_ID; i++) {
+               param[0] = MBOX_PORT_LOGOUT;
+               param[1] = i << 8;
+               param[2] = 0;
+               param[3] = 0;
+
+               isp2x00_mbox_command(host, param);
+
+               if (param[0] != MBOX_COMMAND_COMPLETE) {
+
+                       DEBUG_FABRIC(printk("qlogicfc%d : logout failed %x  %x\n", hostdata->host_id, i, param[0]));
+               }
+       }
+#endif
+
+
+       param[0] = MBOX_GET_INIT_SCSI_ID;
+
+       isp2x00_mbox_command(host, param);
+
+       if (param[0] == MBOX_COMMAND_COMPLETE) {
+               hostdata->port_id = ((u_int) param[3]) << 16;
+               hostdata->port_id |= param[2];
+               hostdata->tempmap[0].loop_id = param[1];
+               hostdata->tempmap[0].wwn = hostdata->wwn;
+       }
+       else {
+               printk("qlogicfc%d : error getting scsi id.\n", hostdata->host_id);
+       }
+
+        for (i = 0; i <=QLOGICFC_MAX_ID; i++)
+                hostdata->tempmap[i].loop_id = hostdata->tempmap[0].loop_id;
+   
+        for (i = 0, j = 1; i <= QLOGICFC_MAX_LOOP_ID; i++) {
+                param[0] = MBOX_GET_PORT_NAME;
+               param[1] = (i << 8) & 0xff00;
+
+               isp2x00_mbox_command(host, param);
+
+               if (param[0] == MBOX_COMMAND_COMPLETE) {
+                       hostdata->tempmap[j].loop_id = i;
+                       hostdata->tempmap[j].wwn = ((u64) (param[2] & 0xff)) << 56;
+                       hostdata->tempmap[j].wwn |= ((u64) ((param[2] >> 8) & 0xff)) << 48;
+                       hostdata->tempmap[j].wwn |= ((u64) (param[3] & 0xff)) << 40;
+                       hostdata->tempmap[j].wwn |= ((u64) ((param[3] >> 8) & 0xff)) << 32;
+                       hostdata->tempmap[j].wwn |= ((u64) (param[6] & 0xff)) << 24;
+                       hostdata->tempmap[j].wwn |= ((u64) ((param[6] >> 8) & 0xff)) << 16;
+                       hostdata->tempmap[j].wwn |= ((u64) (param[7] & 0xff)) << 8;
+                       hostdata->tempmap[j].wwn |= ((u64) ((param[7] >> 8) & 0xff));
+
+                       j++;
+
+               }
+       }
+
+
+#if ISP2x00_FABRIC
+       isp2x00_init_fabric(host, hostdata->tempmap, j);
+#endif
+
+       for (i = 0; i <= QLOGICFC_MAX_ID; i++) {
+               if (hostdata->tempmap[i].wwn != hostdata->port_db[i].wwn) {
+                       for (j = 0; j <= QLOGICFC_MAX_ID; j++) {
+                               if (hostdata->tempmap[j].wwn == hostdata->port_db[i].wwn) {
+                                       hostdata->port_db[i].loop_id = hostdata->tempmap[j].loop_id;
+                                       break;
+                               }
+                       }
+                       if (j == QLOGICFC_MAX_ID + 1)
+                               hostdata->port_db[i].loop_id = hostdata->tempmap[0].loop_id;
+
+                       for (j = 0; j <= QLOGICFC_MAX_ID; j++) {
+                               if (hostdata->port_db[j].wwn == hostdata->tempmap[i].wwn || !hostdata->port_db[j].wwn) {
+                                       break;
+                               }
+                       }
+                       if (j == QLOGICFC_MAX_ID + 1)
+                               printk("qlogicfc%d : Too many scsi devices, no more room in port map.\n", hostdata->host_id);
+                       if (!hostdata->port_db[j].wwn) {
+                               hostdata->port_db[j].loop_id = hostdata->tempmap[i].loop_id;
+                               hostdata->port_db[j].wwn = hostdata->tempmap[i].wwn;
+                       }
+               } else
+                       hostdata->port_db[i].loop_id = hostdata->tempmap[i].loop_id;
+
+       }
+
+       isp2x00_enable_irqs(host);
+
+       return 0;
+}
+
+
+#if ISP2x00_FABRIC
+
+#define FABRIC_PORT          0x7e
+#define FABRIC_CONTROLLER    0x7f
+#define FABRIC_SNS           0x80
+
+int isp2x00_init_fabric(struct Scsi_Host *host, struct id_name_map *port_db, int cur_scsi_id)
+{
+
+       u_short param[8];
+       u64 wwn;
+       int done = 0;
+       u_short loop_id = 0x81;
+       u_short scsi_id = cur_scsi_id;
+       u_int port_id;
+       struct sns_cb *req;
+       u_char *sns_response;
+       dma_addr_t busaddr;
+       struct isp2x00_hostdata *hostdata;
+
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+       
+       DEBUG_FABRIC(printk("qlogicfc%d : Checking for a fabric.\n", hostdata->host_id));
+       param[0] = MBOX_GET_PORT_NAME;
+       param[1] = (u16)FABRIC_PORT << 8;
+
+       isp2x00_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               DEBUG_FABRIC(printk("qlogicfc%d : fabric check result %x\n", hostdata->host_id, param[0]));
+               return 0;
+       }
+       printk("qlogicfc%d : Fabric found.\n", hostdata->host_id);
+
+       req = (struct sns_cb *)pci_alloc_consistent(hostdata->pci_dev, sizeof(*req) + 608, &busaddr);
+       
+       if (!req){
+               printk("qlogicfc%d : Could not allocate DMA resources for fabric initialization\n", hostdata->host_id);
+               return 0;
+       }
+       sns_response = (u_char *)(req + 1);
+
+       if (hostdata->adapter_state & AS_REDO_LOOP_PORTDB){
+               memset(req, 0, sizeof(*req));
+       
+               req->len = cpu_to_le16(8);
+               req->response_low = cpu_to_le32(pci64_dma_lo32(busaddr + sizeof(*req)));
+               req->response_high = cpu_to_le32(pci64_dma_hi32(busaddr + sizeof(*req)));
+               req->sub_len = cpu_to_le16(22);
+               req->data[0] = 0x17;
+               req->data[1] = 0x02;
+               req->data[8] = (u_char) (hostdata->port_id & 0xff);
+               req->data[9] = (u_char) (hostdata->port_id >> 8 & 0xff);
+               req->data[10] = (u_char) (hostdata->port_id >> 16 & 0xff);
+               req->data[13] = 0x01;
+               param[0] = MBOX_SEND_SNS;
+               param[1] = 30;
+               param[2] = pci64_dma_lo32(busaddr) >> 16;
+               param[3] = pci64_dma_lo32(busaddr);
+               param[6] = pci64_dma_hi32(busaddr) >> 16;
+               param[7] = pci64_dma_hi32(busaddr);
+
+               isp2x00_mbox_command(host, param);
+       
+               if (param[0] != MBOX_COMMAND_COMPLETE)
+                       printk("qlogicfc%d : error sending RFC-4\n", hostdata->host_id);
+       }
+
+       port_id = hostdata->port_id;
+       while (!done) {
+               memset(req, 0, sizeof(*req));
+
+               req->len = cpu_to_le16(304);
+               req->response_low = cpu_to_le32(pci64_dma_lo32(busaddr + sizeof(*req)));
+               req->response_high = cpu_to_le32(pci64_dma_hi32(busaddr + sizeof(*req)));
+               req->sub_len = cpu_to_le16(6);
+               req->data[0] = 0x00;
+               req->data[1] = 0x01;
+               req->data[8] = (u_char) (port_id & 0xff);
+               req->data[9] = (u_char) (port_id >> 8 & 0xff);
+               req->data[10] = (u_char) (port_id >> 16 & 0xff);
+
+               param[0] = MBOX_SEND_SNS;
+               param[1] = 14;
+               param[2] = pci64_dma_lo32(busaddr) >> 16;
+               param[3] = pci64_dma_lo32(busaddr);
+               param[6] = pci64_dma_hi32(busaddr) >> 16;
+               param[7] = pci64_dma_hi32(busaddr);
+
+               isp2x00_mbox_command(host, param);
+
+               if (param[0] == MBOX_COMMAND_COMPLETE) {
+                       DEBUG_FABRIC(printk("qlogicfc%d : found node %02x%02x%02x%02x%02x%02x%02x%02x ", hostdata->host_id, sns_response[20], sns_response[21], sns_response[22], sns_response[23], sns_response[24], sns_response[25], sns_response[26], sns_response[27]));
+                       DEBUG_FABRIC(printk("  port id: %02x%02x%02x\n", sns_response[17], sns_response[18], sns_response[19]));
+                       port_id = ((u_int) sns_response[17]) << 16;
+                       port_id |= ((u_int) sns_response[18]) << 8;
+                       port_id |= ((u_int) sns_response[19]);
+                       wwn = ((u64) sns_response[20]) << 56;
+                       wwn |= ((u64) sns_response[21]) << 48;
+                       wwn |= ((u64) sns_response[22]) << 40;
+                       wwn |= ((u64) sns_response[23]) << 32;
+                       wwn |= ((u64) sns_response[24]) << 24;
+                       wwn |= ((u64) sns_response[25]) << 16;
+                       wwn |= ((u64) sns_response[26]) << 8;
+                       wwn |= ((u64) sns_response[27]);
+                       if (hostdata->port_id >> 8 != port_id >> 8) {
+                               DEBUG_FABRIC(printk("qlogicfc%d : adding a fabric port: %x\n", hostdata->host_id, port_id));
+                               param[0] = MBOX_PORT_LOGIN;
+                               param[1] = loop_id << 8;
+                               param[2] = (u_short) (port_id >> 16);
+                               param[3] = (u_short) (port_id);
+
+                               isp2x00_mbox_command(host, param);
+
+                               if (param[0] == MBOX_COMMAND_COMPLETE) {
+                                       port_db[scsi_id].wwn = wwn;
+                                       port_db[scsi_id].loop_id = loop_id;
+                                       loop_id++;
+                                       scsi_id++;
+                               } else {
+                                       printk("qlogicfc%d : Error performing port login %x\n", hostdata->host_id, param[0]);
+                                       DEBUG_FABRIC(printk("qlogicfc%d : loop_id: %x\n", hostdata->host_id, loop_id));
+                                       param[0] = MBOX_PORT_LOGOUT;
+                                       param[1] = loop_id << 8;
+                                       param[2] = 0;
+                                       param[3] = 0;
+
+                                       isp2x00_mbox_command(host, param);
+                                       
+                               }
+
+                       }
+                       if (hostdata->port_id == port_id)
+                               done = 1;
+               } else {
+                       printk("qlogicfc%d : Get All Next failed %x.\n", hostdata->host_id, param[0]);
+                       pci_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);
+                       return 0;
+               }
+       }
+
+       pci_free_consistent(hostdata->pci_dev, sizeof(*req) + 608, req, busaddr);
+       return 1;
+}
+
+#endif                         /* ISP2x00_FABRIC */
+
+
+int isp2x00_release(struct Scsi_Host *host)
+{
+       struct isp2x00_hostdata *hostdata;
+       dma_addr_t busaddr;
+
+       ENTER("isp2x00_release");
+
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+
+       outw(0x0, host->io_port + PCI_INTER_CTL);
+       free_irq(host->irq, host);
+
+       release_region(host->io_port, 0xff);
+
+       busaddr = pci64_dma_build(le32_to_cpu(hostdata->control_block.res_queue_addr_high),
+                                 le32_to_cpu(hostdata->control_block.res_queue_addr_lo));
+       pci_free_consistent(hostdata->pci_dev, RES_SIZE + REQ_SIZE, hostdata->res, busaddr);
+
+       LEAVE("isp2x00_release");
+
+       return 0;
+}
+
+
+const char *isp2x00_info(struct Scsi_Host *host)
+{
+       static char buf[80];
+       struct isp2x00_hostdata *hostdata;
+       ENTER("isp2x00_info");
+
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+       sprintf(buf,
+               "QLogic ISP%04x SCSI on PCI bus %02x device %02x irq %d base 0x%lx",
+               hostdata->pci_dev->device, hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq,
+               host->io_port);
+
+
+       LEAVE("isp2x00_info");
+
+       return buf;
+}
+
+
+/*
+ * The middle SCSI layer ensures that queuecommand never gets invoked
+ * concurrently with itself or the interrupt handler (though the
+ * interrupt handler may call this routine as part of
+ * request-completion handling).
+ */
+int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
+{
+       int i, sg_count, n, num_free;
+       u_int in_ptr, out_ptr;
+       struct dataseg *ds;
+       struct scatterlist *sg;
+       struct Command_Entry *cmd;
+       struct Continuation_Entry *cont;
+       struct Scsi_Host *host;
+       struct isp2x00_hostdata *hostdata;
+
+       ENTER("isp2x00_queuecommand");
+
+       host = Cmnd->device->host;
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+       Cmnd->scsi_done = done;
+
+       DEBUG(isp2x00_print_scsi_cmd(Cmnd));
+
+       if (hostdata->adapter_state & AS_REDO_FABRIC_PORTDB || hostdata->adapter_state & AS_REDO_LOOP_PORTDB) {
+               isp2x00_make_portdb(host);
+               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: ", (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) {
+               printk("qlogicfc%d : The firmware is dead, just return.\n", hostdata->host_id);
+               host->max_id = 0;
+               return 0;
+       }
+
+       out_ptr = inw(host->io_port + MBOX4);
+       in_ptr = hostdata->req_in_ptr;
+
+       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*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));
+               return 1;
+       }
+       if (hostdata->send_marker) {
+               struct Marker_Entry *marker;
+
+               TRACE("queue marker", in_ptr, 0);
+
+               DEBUG(printk("qlogicfc%d : adding marker entry\n", hostdata->host_id));
+               marker = (struct Marker_Entry *) cmd;
+               memset(marker, 0, sizeof(struct Marker_Entry));
+
+               marker->hdr.entry_type = ENTRY_MARKER;
+               marker->hdr.entry_cnt = 1;
+               marker->modifier = SYNC_ALL;
+
+               hostdata->send_marker = 0;
+
+               if (((in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN) == out_ptr) {
+                       outw(in_ptr, host->io_port + MBOX4);
+                       hostdata->req_in_ptr = in_ptr;
+                       DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id));
+                       return 1;
+               }
+               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);
+
+       memset(cmd, 0, sizeof(struct Command_Entry));
+
+       /* find a free handle mapping slot */
+       for (i = in_ptr; i != (in_ptr - 1) && hostdata->handle_ptrs[i]; i = ((i + 1) % (QLOGICFC_REQ_QUEUE_LEN + 1)));
+
+       if (!hostdata->handle_ptrs[i]) {
+               cmd->handle = cpu_to_le32(i);
+               hostdata->handle_ptrs[i] = Cmnd;
+               hostdata->handle_serials[i] = Cmnd->serial_number;
+       } else {
+               printk("qlogicfc%d : no handle slots, this should not happen.\n", hostdata->host_id);
+               printk("hostdata->queued is %x, in_ptr: %x\n", hostdata->queued, in_ptr);
+               for (i = 0; i <= QLOGICFC_REQ_QUEUE_LEN; i++){
+                       if (!hostdata->handle_ptrs[i]){
+                               printk("slot %d has %p\n", i, hostdata->handle_ptrs[i]);
+                       }
+               }
+               return 1;
+       }
+
+       cmd->hdr.entry_type = ENTRY_COMMAND;
+       cmd->hdr.entry_cnt = 1;
+       cmd->target_lun = Cmnd->device->lun;
+       cmd->expanded_lun = cpu_to_le16(Cmnd->device->lun);
+#if ISP2x00_PORTDB
+       cmd->target_id = hostdata->port_db[Cmnd->device->id].loop_id;
+#else
+       cmd->target_id = Cmnd->target;
+#endif
+       cmd->total_byte_cnt = cpu_to_le32(Cmnd->request_bufflen);
+       cmd->time_out = 0;
+       memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
+
+       if (Cmnd->use_sg) {
+               sg = (struct scatterlist *) Cmnd->request_buffer;
+               sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+               cmd->segment_cnt = cpu_to_le16(sg_count);
+               ds = cmd->dataseg;
+               /* fill in first two sg entries: */
+               n = sg_count;
+               if (n > DATASEGS_PER_COMMAND)
+                       n = DATASEGS_PER_COMMAND;
+
+               for (i = 0; i < n; i++) {
+                       ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma_address(sg)));
+                       ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma_address(sg)));
+                       ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
+                       ++sg;
+               }
+               sg_count -= DATASEGS_PER_COMMAND;
+
+               while (sg_count > 0) {
+                       ++cmd->hdr.entry_cnt;
+                       cont = (struct Continuation_Entry *)
+                           &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) {
+                               DEBUG(printk("qlogicfc%d : unexpected request queue overflow\n", hostdata->host_id));
+                               return 1;
+                       }
+                       TRACE("queue continuation", in_ptr, 0);
+                       cont->hdr.entry_type = ENTRY_CONTINUATION;
+                       ds = cont->dataseg;
+                       n = sg_count;
+                       if (n > DATASEGS_PER_CONT)
+                               n = DATASEGS_PER_CONT;
+                       for (i = 0; i < n; ++i) {
+                               ds[i].d_base = cpu_to_le32(pci64_dma_lo32(sg_dma_address(sg)));
+                               ds[i].d_base_hi = cpu_to_le32(pci64_dma_hi32(sg_dma_address(sg)));
+                               ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
+                               ++sg;
+                       }
+                       sg_count -= n;
+               }
+       } else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE) {
+               struct page *page = virt_to_page(Cmnd->request_buffer);
+               unsigned long offset = offset_in_page(Cmnd->request_buffer);
+               dma_addr_t busaddr = pci_map_page(hostdata->pci_dev,
+                                                 page, offset,
+                                                 Cmnd->request_bufflen,
+                                                 scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+               Cmnd->SCp.dma_handle = busaddr;
+
+               cmd->dataseg[0].d_base = cpu_to_le32(pci64_dma_lo32(busaddr));
+               cmd->dataseg[0].d_base_hi = cpu_to_le32(pci64_dma_hi32(busaddr));
+               cmd->dataseg[0].d_count = cpu_to_le32(Cmnd->request_bufflen);
+               cmd->segment_cnt = cpu_to_le16(1);
+       } else {
+               cmd->dataseg[0].d_base = 0;
+               cmd->dataseg[0].d_base_hi = 0;
+               cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */
+       }
+
+       if (Cmnd->sc_data_direction == SCSI_DATA_WRITE)
+               cmd->control_flags = cpu_to_le16(CFLAG_WRITE);
+       else 
+               cmd->control_flags = cpu_to_le16(CFLAG_READ);
+
+       if (Cmnd->device->tagged_supported) {
+               if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * SCSI_TIMEOUT)) {
+                       cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG);
+                       hostdata->tag_ages[Cmnd->device->id] = jiffies;
+               } else
+                       switch (Cmnd->tag) {
+                       case HEAD_OF_QUEUE_TAG:
+                               cmd->control_flags |= cpu_to_le16(CFLAG_HEAD_TAG);
+                               break;
+                       case ORDERED_QUEUE_TAG:
+                               cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG);
+                               break;
+                       default:
+                               cmd->control_flags |= cpu_to_le16(CFLAG_SIMPLE_TAG);
+                               break;
+               }
+       }
+       /*
+        * TEST_UNIT_READY commands from scsi_scan will fail due to "overlapped
+        * commands attempted" unless we setup at least a simple queue (midlayer 
+        * will embelish this once it can do an INQUIRY command to the device)
+        */
+       else
+               cmd->control_flags |= cpu_to_le16(CFLAG_SIMPLE_TAG);
+       outw(in_ptr, host->io_port + MBOX4);
+       hostdata->req_in_ptr = in_ptr;
+
+       hostdata->queued++;
+
+       num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
+       num_free = (num_free > 2) ? num_free - 2 : 0;
+       host->can_queue = host->host_busy + num_free;
+       if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
+               host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
+       host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
+
+       LEAVE("isp2x00_queuecommand");
+
+       return 0;
+}
+
+
+/* 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(host->host_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]->device->id].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){
+                                if (hostdata->port_db[hostdata->handle_ptrs[i]->device->id].loop_id != hostdata->port_db[0].loop_id){
+                                       Scsi_Cmnd *Cmnd = hostdata->handle_ptrs[i];
+
+                                        if (Cmnd->use_sg)
+                                                pci_unmap_sg(hostdata->pci_dev,
+                                                             (struct scatterlist *)Cmnd->buffer,
+                                                             Cmnd->use_sg,
+                                                             scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                        else if (Cmnd->request_bufflen &&
+                                                 Cmnd->sc_data_direction != PCI_DMA_NONE) {
+                                                pci_unmap_page(hostdata->pci_dev,
+                                                               Cmnd->SCp.dma_handle,
+                                                               Cmnd->request_bufflen,
+                                                               scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                                        }
+
+                                        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(host->host_lock, flags);
+
+}
+
+#define ASYNC_EVENT_INTERRUPT  0x01
+
+irqreturn_t do_isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct Scsi_Host *host = dev_id;
+       unsigned long flags;
+
+       spin_lock_irqsave(host->host_lock, flags);
+       isp2x00_intr_handler(irq, dev_id, regs);
+       spin_unlock_irqrestore(host->host_lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       Scsi_Cmnd *Cmnd;
+       struct Status_Entry *sts;
+       struct Scsi_Host *host = dev_id;
+       struct isp2x00_hostdata *hostdata;
+       u_int in_ptr, out_ptr, handle, num_free;
+       u_short status;
+
+       ENTER_INTR("isp2x00_intr_handler");
+
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+
+       DEBUG_INTR(printk("qlogicfc%d : interrupt on line %d\n", hostdata->host_id, irq));
+
+       if (!(inw(host->io_port + PCI_INTER_STS) & 0x08)) {
+               /* spurious interrupts can happen legally */
+               DEBUG_INTR(printk("qlogicfc%d : got spurious interrupt\n", hostdata->host_id));
+               return;
+       }
+       in_ptr = inw(host->io_port + MBOX5);
+       out_ptr = hostdata->res_out_ptr;
+
+       if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
+               status = inw(host->io_port + MBOX0);
+
+               DEBUG_INTR(printk("qlogicfc%d : mbox completion status: %x\n",
+                                 hostdata->host_id, status));
+
+               switch (status) {
+               case LOOP_UP:
+               case POINT_TO_POINT_UP:
+                       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);
+                       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_OCCURRED:
+               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;
+               case SYSTEM_ERROR:
+                       printk("qlogicfc%d : The firmware just choked.\n", hostdata->host_id);
+                       hostdata->adapter_state = AS_FIRMWARE_DEAD;
+                       break;
+               case SCSI_COMMAND_COMPLETE:
+                       handle = inw(host->io_port + MBOX1) | (inw(host->io_port + MBOX2) << 16);
+                       Cmnd = hostdata->handle_ptrs[handle];
+                       hostdata->handle_ptrs[handle] = NULL;
+                       hostdata->handle_serials[handle] = 0;
+                       hostdata->queued--;
+                       if (Cmnd != NULL) {
+                               if (Cmnd->use_sg)
+                                       pci_unmap_sg(hostdata->pci_dev,
+                                                    (struct scatterlist *)Cmnd->buffer,
+                                                    Cmnd->use_sg,
+                                                    scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                               else if (Cmnd->request_bufflen &&
+                                        Cmnd->sc_data_direction != PCI_DMA_NONE)
+                                       pci_unmap_page(hostdata->pci_dev,
+                                                      Cmnd->SCp.dma_handle,
+                                                      Cmnd->request_bufflen,
+                                                      scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                               Cmnd->result = 0x0;
+                               (*Cmnd->scsi_done) (Cmnd);
+                       } else
+                               printk("qlogicfc%d.c : got a null value out of handle_ptrs, this sucks\n", hostdata->host_id);
+                       break;
+               case MBOX_COMMAND_COMPLETE:
+               case INVALID_COMMAND:
+               case HOST_INTERFACE_ERROR:
+               case TEST_FAILED:
+               case COMMAND_ERROR:
+               case COMMAND_PARAM_ERROR:
+               case PORT_ID_USED:
+               case LOOP_ID_USED:
+               case ALL_IDS_USED:
+                       hostdata->mbox_done = 1;
+                       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+                       return;
+               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) {
+                       unsigned le_hand;
+                       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));
+                       le_hand = le32_to_cpu(sts->handle);
+                       if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[le_hand])) {
+                               Cmnd->result = isp2x00_return_status(Cmnd, sts);
+                               hostdata->queued--;
+
+                               if (Cmnd->use_sg)
+                                       pci_unmap_sg(hostdata->pci_dev,
+                                                    (struct scatterlist *)Cmnd->buffer, Cmnd->use_sg,
+                                                    scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+                               else if (Cmnd->request_bufflen && Cmnd->sc_data_direction != PCI_DMA_NONE)
+                                       pci_unmap_page(hostdata->pci_dev,
+                                                      Cmnd->SCp.dma_handle,
+                                                      Cmnd->request_bufflen,
+                                                      scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+
+                               /* 
+                                * if any of the following are true we do not
+                                * call scsi_done.  if the status is CS_ABORTED
+                                * we don't have to call done because the upper
+                                * level should already know its aborted.
+                                */
+                               if (hostdata->handle_serials[le_hand] != Cmnd->serial_number 
+                                   || le16_to_cpu(sts->completion_status) == CS_ABORTED){
+                                       hostdata->handle_serials[le_hand] = 0;
+                                       hostdata->handle_ptrs[le_hand] = NULL;
+                                       outw(out_ptr, host->io_port + MBOX5);
+                                       continue;
+                               }
+                               /*
+                                * if we get back an error indicating the port
+                                * is not there or if the link is down and 
+                                * this is a device that used to be there 
+                                * allow the command to timeout.
+                                * the device may well be back in a couple of
+                                * seconds.
+                                */
+                               if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == cpu_to_le16(CS_PORT_UNAVAILABLE) || sts->completion_status == cpu_to_le16(CS_PORT_LOGGED_OUT) || sts->completion_status == cpu_to_le16(CS_PORT_CONFIG_CHANGED)) && hostdata->port_db[Cmnd->device->id].wwn){
+                                       outw(out_ptr, host->io_port + MBOX5);
+                                       continue;
+                               }
+                       } else {
+                               outw(out_ptr, host->io_port + MBOX5);
+                               continue;
+                       }
+
+                       hostdata->handle_ptrs[le_hand] = NULL;
+
+                       if (sts->completion_status == cpu_to_le16(CS_RESET_OCCURRED)
+                           || (sts->status_flags & cpu_to_le16(STF_BUS_RESET)))
+                               hostdata->send_marker = 1;
+
+                       if (le16_to_cpu(sts->scsi_status) & 0x0200)
+                               memcpy(Cmnd->sense_buffer, sts->req_sense_data,
+                                      sizeof(Cmnd->sense_buffer));
+
+                       outw(out_ptr, host->io_port + MBOX5);
+
+                       if (Cmnd->scsi_done != NULL) {
+                               (*Cmnd->scsi_done) (Cmnd);
+                       } else
+                               printk("qlogicfc%d : Ouch, scsi done is NULL\n", hostdata->host_id);
+               }
+               hostdata->res_out_ptr = out_ptr;
+       }
+
+
+       out_ptr = inw(host->io_port + MBOX4);
+       in_ptr = hostdata->req_in_ptr;
+
+       num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
+       num_free = (num_free > 2) ? num_free - 2 : 0;
+       host->can_queue = host->host_busy + num_free;
+       if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
+               host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
+       host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
+
+       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+       LEAVE_INTR("isp2x00_intr_handler");
+}
+
+
+static int isp2x00_return_status(Scsi_Cmnd *Cmnd, struct Status_Entry *sts)
+{
+       int host_status = DID_ERROR;
+#if DEBUG_ISP2x00_INTR
+       static char *reason[] =
+       {
+               "DID_OK",
+               "DID_NO_CONNECT",
+               "DID_BUS_BUSY",
+               "DID_TIME_OUT",
+               "DID_BAD_TARGET",
+               "DID_ABORT",
+               "DID_PARITY",
+               "DID_ERROR",
+               "DID_RESET",
+               "DID_BAD_INTR"
+       };
+#endif                         /* DEBUG_ISP2x00_INTR */
+
+       ENTER("isp2x00_return_status");
+
+       DEBUG(printk("qlogicfc : completion status = 0x%04x\n",
+                    le16_to_cpu(sts->completion_status)));
+
+       switch (le16_to_cpu(sts->completion_status)) {
+       case CS_COMPLETE:
+               host_status = DID_OK;
+               break;
+       case CS_DMA_ERROR:
+               host_status = DID_ERROR;
+               break;
+       case CS_RESET_OCCURRED:
+               host_status = DID_RESET;
+               break;
+       case CS_ABORTED:
+               host_status = DID_ABORT;
+               break;
+       case CS_TIMEOUT:
+               host_status = DID_TIME_OUT;
+               break;
+       case CS_DATA_OVERRUN:
+               host_status = DID_ERROR;
+               break;
+       case CS_DATA_UNDERRUN:
+               if (Cmnd->underflow <= (Cmnd->request_bufflen - le32_to_cpu(sts->residual)))
+                       host_status = DID_OK;
+               else
+                       host_status = DID_ERROR;
+               break;
+       case CS_PORT_UNAVAILABLE:
+       case CS_PORT_LOGGED_OUT:
+       case CS_PORT_CONFIG_CHANGED:
+               host_status = DID_BAD_TARGET;
+               break;
+       case CS_QUEUE_FULL:
+               host_status = DID_ERROR;
+               break;
+       default:
+               printk("qlogicfc : unknown completion status 0x%04x\n",
+                      le16_to_cpu(sts->completion_status));
+               host_status = DID_ERROR;
+               break;
+       }
+
+       DEBUG_INTR(printk("qlogicfc : host status (%s) scsi status %x\n",
+                         reason[host_status], le16_to_cpu(sts->scsi_status)));
+
+       LEAVE("isp2x00_return_status");
+
+       return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16);
+}
+
+
+int isp2x00_abort(Scsi_Cmnd * Cmnd)
+{
+       u_short param[8];
+       int i;
+       struct Scsi_Host *host;
+       struct isp2x00_hostdata *hostdata;
+       int return_status = SUCCESS;
+
+       ENTER("isp2x00_abort");
+
+       host = Cmnd->device->host;
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+
+       for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++)
+               if (hostdata->handle_ptrs[i] == Cmnd)
+                       break;
+
+       if (i == QLOGICFC_REQ_QUEUE_LEN){
+               return SUCCESS;
+       }
+
+       isp2x00_disable_irqs(host);
+
+       param[0] = MBOX_ABORT_IOCB;
+#if ISP2x00_PORTDB
+       param[1] = (((u_short) hostdata->port_db[Cmnd->device->id].loop_id) << 8) | Cmnd->device->lun;
+#else
+       param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
+#endif
+       param[2] = i & 0xffff;
+       param[3] = i >> 16;
+
+       isp2x00_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc%d : scsi abort failure: %x\n", hostdata->host_id, param[0]);
+               if (param[0] == 0x4005)
+                       Cmnd->result = DID_ERROR << 16;
+               if (param[0] == 0x4006)
+                       Cmnd->result = DID_BAD_TARGET << 16;
+               return_status = FAILED;
+       }
+
+       if (return_status != SUCCESS){
+               param[0] = MBOX_GET_FIRMWARE_STATE;
+               isp2x00_mbox_command(host, param);
+               printk("qlogicfc%d : abort failed\n", hostdata->host_id);
+               printk("qlogicfc%d : firmware status is %x %x\n", hostdata->host_id, param[0], param[1]);
+       }
+
+       isp2x00_enable_irqs(host);
+
+       LEAVE("isp2x00_abort");
+
+       return return_status;
+}
+
+
+int isp2x00_reset(Scsi_Cmnd * Cmnd, unsigned int reset_flags)
+{
+       u_short param[8];
+       struct Scsi_Host *host;
+       struct isp2x00_hostdata *hostdata;
+       int return_status = SCSI_RESET_SUCCESS;
+
+       ENTER("isp2x00_reset");
+
+       host = Cmnd->device->host;
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+       param[0] = MBOX_BUS_RESET;
+       param[1] = 3;
+
+       isp2x00_disable_irqs(host);
+
+       isp2x00_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc%d : scsi bus reset failure: %x\n", hostdata->host_id, param[0]);
+               return_status = SCSI_RESET_ERROR;
+       }
+       isp2x00_enable_irqs(host);
+
+       LEAVE("isp2x00_reset");
+
+       return return_status;;
+}
+
+
+int isp2x00_biosparam(struct scsi_device *sdev, struct block_device *n,
+               sector_t capacity, int ip[])
+{
+       int size = capacity;
+
+       ENTER("isp2x00_biosparam");
+
+       ip[0] = 64;
+       ip[1] = 32;
+       ip[2] = size >> 11;
+       if (ip[2] > 1024) {
+               ip[0] = 255;
+               ip[1] = 63;
+               ip[2] = size / (ip[0] * ip[1]);
+       }
+       LEAVE("isp2x00_biosparam");
+
+       return 0;
+}
+
+static int isp2x00_reset_hardware(struct Scsi_Host *host)
+{
+       u_short param[8];
+       struct isp2x00_hostdata *hostdata;
+       int loop_count;
+       dma_addr_t busaddr;
+
+       ENTER("isp2x00_reset_hardware");
+
+       hostdata = (struct isp2x00_hostdata *) host->hostdata;
+
+       /*
+        *      This cannot be right - PCI writes are posted
+        *      (apparently this is hardware design flaw not software ?)
+        */
+        
+       outw(0x01, host->io_port + ISP_CTRL_STATUS);
+       udelay(100);
+       outw(HCCR_RESET, host->io_port + HOST_HCCR);
+       udelay(100);
+       outw(HCCR_RELEASE, host->io_port + HOST_HCCR);
+       outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR);
+
+       loop_count = DEFAULT_LOOP_COUNT;
+       while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY) {
+               barrier();
+               cpu_relax();
+       }
+       if (!loop_count)
+               printk("qlogicfc%d : reset_hardware loop timeout\n", hostdata->host_id);
+
+
+
+#if DEBUG_ISP2x00
+       printk("qlogicfc%d : mbox 0 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX0));
+       printk("qlogicfc%d : mbox 1 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX1));
+       printk("qlogicfc%d : mbox 2 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX2));
+       printk("qlogicfc%d : mbox 3 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX3));
+       printk("qlogicfc%d : mbox 4 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX4));
+       printk("qlogicfc%d : mbox 5 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX5));
+       printk("qlogicfc%d : mbox 6 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX6));
+       printk("qlogicfc%d : mbox 7 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX7));
+#endif                         /* DEBUG_ISP2x00 */
+
+       DEBUG(printk("qlogicfc%d : verifying checksum\n", hostdata->host_id));
+
+#if defined(CONFIG_SCSI_QLOGIC_FC_FIRMWARE)
+       {
+               int i;
+               unsigned short * risc_code = NULL;
+               unsigned short risc_code_len = 0;
+               if (hostdata->pci_dev->device == PCI_DEVICE_ID_QLOGIC_ISP2100){
+                       risc_code = risc_code2100;
+                       risc_code_len = risc_code_length2100;
+               }
+               else if (hostdata->pci_dev->device == PCI_DEVICE_ID_QLOGIC_ISP2200){
+                       risc_code = risc_code2200;
+                       risc_code_len = risc_code_length2200;
+               }
+
+               for (i = 0; i < risc_code_len; i++) {
+                       param[0] = MBOX_WRITE_RAM_WORD;
+                       param[1] = risc_code_addr01 + i;
+                       param[2] = risc_code[i];
+
+                       isp2x00_mbox_command(host, param);
+
+                       if (param[0] != MBOX_COMMAND_COMPLETE) {
+                               printk("qlogicfc%d : firmware load failure\n", hostdata->host_id);
+                               return 1;
+                       }
+               }
+       }
+#endif                         /* RELOAD_FIRMWARE */
+
+       param[0] = MBOX_VERIFY_CHECKSUM;
+       param[1] = risc_code_addr01;
+
+       isp2x00_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc%d : ram checksum failure\n", hostdata->host_id);
+               return 1;
+       }
+       DEBUG(printk("qlogicfc%d : executing firmware\n", hostdata->host_id));
+
+       param[0] = MBOX_EXEC_FIRMWARE;
+       param[1] = risc_code_addr01;
+
+       isp2x00_mbox_command(host, param);
+
+       param[0] = MBOX_ABOUT_FIRMWARE;
+
+       isp2x00_mbox_command(host, param);
+
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc%d : about firmware failure\n", hostdata->host_id);
+               return 1;
+       }
+       DEBUG(printk("qlogicfc%d : firmware major revision %d\n", hostdata->host_id,  param[1]));
+       DEBUG(printk("qlogicfc%d : firmware minor revision %d\n", hostdata->host_id,  param[2]));
+
+#ifdef USE_NVRAM_DEFAULTS
+
+       if (isp2x00_get_nvram_defaults(host, &hostdata->control_block) != 0) {
+               printk("qlogicfc%d : Could not read from NVRAM\n", hostdata->host_id);
+       }
+#endif
+
+       hostdata->wwn = (u64) (cpu_to_le16(hostdata->control_block.node_name[0])) << 56;
+       hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[0]) & 0xff00) << 48;
+       hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[1]) & 0xff00) << 24;
+       hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[1]) & 0x00ff) << 48;
+       hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[2]) & 0x00ff) << 24;
+       hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[2]) & 0xff00) << 8;
+       hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0x00ff) << 8;
+       hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0xff00) >> 8;
+
+       /* FIXME: If the DMA transfer goes one way only, this should use
+        *        PCI_DMA_TODEVICE and below as well.
+        */
+       busaddr = pci_map_page(hostdata->pci_dev,
+                              virt_to_page(&hostdata->control_block),
+                              offset_in_page(&hostdata->control_block),
+                              sizeof(hostdata->control_block),
+                              PCI_DMA_BIDIRECTIONAL);
+
+       param[0] = MBOX_INIT_FIRMWARE;
+       param[2] = (u_short) (pci64_dma_lo32(busaddr) >> 16);
+       param[3] = (u_short) (pci64_dma_lo32(busaddr) & 0xffff);
+       param[4] = 0;
+       param[5] = 0;
+       param[6] = (u_short) (pci64_dma_hi32(busaddr) >> 16);
+       param[7] = (u_short) (pci64_dma_hi32(busaddr) & 0xffff);
+       isp2x00_mbox_command(host, param);
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc%d.c: Ouch 0x%04x\n", hostdata->host_id,  param[0]);
+               pci_unmap_page(hostdata->pci_dev, busaddr,
+                              sizeof(hostdata->control_block),
+                              PCI_DMA_BIDIRECTIONAL);
+               return 1;
+       }
+       param[0] = MBOX_GET_FIRMWARE_STATE;
+       isp2x00_mbox_command(host, param);
+       if (param[0] != MBOX_COMMAND_COMPLETE) {
+               printk("qlogicfc%d.c: 0x%04x\n", hostdata->host_id,  param[0]);
+               pci_unmap_page(hostdata->pci_dev, busaddr,
+                              sizeof(hostdata->control_block),
+                              PCI_DMA_BIDIRECTIONAL);
+               return 1;
+       }
+
+       pci_unmap_page(hostdata->pci_dev, busaddr,
+                      sizeof(hostdata->control_block),
+                      PCI_DMA_BIDIRECTIONAL);
+       LEAVE("isp2x00_reset_hardware");
+
+       return 0;
+}
+
+#ifdef USE_NVRAM_DEFAULTS
+
+static int isp2x00_get_nvram_defaults(struct Scsi_Host *host, struct init_cb *control_block)
+{
+
+       u_short value;
+       if (isp2x00_read_nvram_word(host, 0) != 0x5349)
+               return 1;
+
+       value = isp2x00_read_nvram_word(host, 8);
+       control_block->node_name[0] = cpu_to_le16(isp2x00_read_nvram_word(host, 9));
+       control_block->node_name[1] = cpu_to_le16(isp2x00_read_nvram_word(host, 10));
+       control_block->node_name[2] = cpu_to_le16(isp2x00_read_nvram_word(host, 11));
+       control_block->node_name[3] = cpu_to_le16(isp2x00_read_nvram_word(host, 12));
+       control_block->hard_addr = cpu_to_le16(isp2x00_read_nvram_word(host, 13));
+
+       return 0;
+
+}
+
+#endif
+
+static int isp2x00_init(struct Scsi_Host *sh)
+{
+       u_long io_base;
+       struct isp2x00_hostdata *hostdata;
+       u_char revision;
+       u_int irq;
+       u_short command;
+       struct pci_dev *pdev;
+
+
+       ENTER("isp2x00_init");
+
+       hostdata = (struct isp2x00_hostdata *) sh->hostdata;
+       pdev = hostdata->pci_dev;
+
+       if (pci_read_config_word(pdev, PCI_COMMAND, &command)
+         || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) {
+               printk("qlogicfc%d : error reading PCI configuration\n", hostdata->host_id);
+               return 1;
+       }
+       io_base = pci_resource_start(pdev, 0);
+       irq = pdev->irq;
+
+
+       if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {
+               printk("qlogicfc%d : 0x%04x is not QLogic vendor ID\n", hostdata->host_id, 
+                      pdev->vendor);
+               return 1;
+       }
+       if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2100 && pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2200) {
+               printk("qlogicfc%d : 0x%04x does not match ISP2100 or ISP2200 device id\n", hostdata->host_id, 
+                      pdev->device);
+               return 1;
+       }
+       if (!(command & PCI_COMMAND_IO) ||
+           !(pdev->resource[0].flags & IORESOURCE_IO)) {
+               printk("qlogicfc%d : i/o mapping is disabled\n", hostdata->host_id);
+               return 1;
+       }
+
+       pci_set_master(pdev);
+       if (revision != ISP2100_REV_ID1 && revision != ISP2100_REV_ID3 && revision != ISP2200_REV_ID5)
+               printk("qlogicfc%d : new isp2x00 revision ID (%d)\n", hostdata->host_id,  revision);
+
+
+       hostdata->revision = revision;
+
+       sh->irq = irq;
+       sh->io_port = io_base;
+
+       LEAVE("isp2x00_init");
+
+       return 0;
+}
+
+#if USE_NVRAM_DEFAULTS
+
+#define NVRAM_DELAY() udelay(10)       /* 10 microsecond delay */
+
+
+u_short isp2x00_read_nvram_word(struct Scsi_Host * host, u_short byte)
+{
+       int i;
+       u_short value, output, input;
+
+       outw(0x2, host->io_port + PCI_NVRAM);
+       NVRAM_DELAY();
+       outw(0x3, host->io_port + PCI_NVRAM);
+       NVRAM_DELAY();
+
+       byte &= 0xff;
+       byte |= 0x0600;
+       for (i = 10; i >= 0; i--) {
+               output = ((byte >> i) & 0x1) ? 0x4 : 0x0;
+               outw(output | 0x2, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               outw(output | 0x3, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               outw(output | 0x2, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+       }
+
+       for (i = 0xf, value = 0; i >= 0; i--) {
+               value <<= 1;
+               outw(0x3, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               input = inw(host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               outw(0x2, host->io_port + PCI_NVRAM);
+               NVRAM_DELAY();
+               if (input & 0x8)
+                       value |= 1;
+       }
+
+       outw(0x0, host->io_port + PCI_NVRAM);
+       NVRAM_DELAY();
+
+       return value;
+}
+
+
+#endif                         /* USE_NVRAM_DEFAULTS */
+
+
+
+/*
+ * currently, this is only called during initialization or abort/reset,
+ * at which times interrupts are disabled, so polling is OK, I guess...
+ */
+static int isp2x00_mbox_command(struct Scsi_Host *host, u_short param[])
+{
+       int loop_count;
+       struct isp2x00_hostdata *hostdata = (struct isp2x00_hostdata *) host->hostdata;
+
+       if (mbox_param[param[0]] == 0 || hostdata->adapter_state == AS_FIRMWARE_DEAD)
+               return 1;
+
+       loop_count = DEFAULT_LOOP_COUNT;
+       while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080) {
+               barrier();
+               cpu_relax();
+       }
+       if (!loop_count) {
+               printk("qlogicfc%d : mbox_command loop timeout #1\n", hostdata->host_id);
+               param[0] = 0x4006;
+               hostdata->adapter_state = AS_FIRMWARE_DEAD;
+               return 1;
+       }
+       hostdata->mbox_done = 0;
+
+       if (mbox_param[param[0]] == 0)
+               printk("qlogicfc%d : invalid mbox command\n", hostdata->host_id);
+
+       if (mbox_param[param[0]] & 0x80)
+               outw(param[7], host->io_port + MBOX7);
+       if (mbox_param[param[0]] & 0x40)
+               outw(param[6], host->io_port + MBOX6);
+       if (mbox_param[param[0]] & 0x20)
+               outw(param[5], host->io_port + MBOX5);
+       if (mbox_param[param[0]] & 0x10)
+               outw(param[4], host->io_port + MBOX4);
+       if (mbox_param[param[0]] & 0x08)
+               outw(param[3], host->io_port + MBOX3);
+       if (mbox_param[param[0]] & 0x04)
+               outw(param[2], host->io_port + MBOX2);
+       if (mbox_param[param[0]] & 0x02)
+               outw(param[1], host->io_port + MBOX1);
+       if (mbox_param[param[0]] & 0x01)
+               outw(param[0], host->io_port + MBOX0);
+
+
+       outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR);
+
+       while (1) {
+               loop_count = DEFAULT_LOOP_COUNT;
+               while (--loop_count && !(inw(host->io_port + PCI_INTER_STS) & 0x08)) { 
+                       barrier();
+                       cpu_relax();
+               }
+
+               if (!loop_count) {
+                       hostdata->adapter_state = AS_FIRMWARE_DEAD;
+                       printk("qlogicfc%d : mbox_command loop timeout #2\n", hostdata->host_id);
+                       break;
+               }
+               isp2x00_intr_handler(host->irq, host, NULL);
+
+               if (hostdata->mbox_done == 1)
+                       break;
+
+       }
+
+       loop_count = DEFAULT_LOOP_COUNT;
+       while (--loop_count && inw(host->io_port + MBOX0) == 0x04) {
+               barrier();
+               cpu_relax();
+       }
+       if (!loop_count)
+               printk("qlogicfc%d : mbox_command loop timeout #3\n", hostdata->host_id);
+
+       param[7] = inw(host->io_port + MBOX7);
+       param[6] = inw(host->io_port + MBOX6);
+       param[5] = inw(host->io_port + MBOX5);
+       param[4] = inw(host->io_port + MBOX4);
+       param[3] = inw(host->io_port + MBOX3);
+       param[2] = inw(host->io_port + MBOX2);
+       param[1] = inw(host->io_port + MBOX1);
+       param[0] = inw(host->io_port + MBOX0);
+
+
+       outw(0x0, host->io_port + PCI_SEMAPHORE);
+
+       if (inw(host->io_port + HOST_HCCR) & 0x0080) {
+               hostdata->adapter_state = AS_FIRMWARE_DEAD;
+               printk("qlogicfc%d : mbox op is still pending\n", hostdata->host_id);
+       }
+       return 0;
+}
+
+#if DEBUG_ISP2x00_INTR
+
+void isp2x00_print_status_entry(struct Status_Entry *status)
+{
+       printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", 
+       status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);
+       printk("qlogicfc : scsi status = 0x%04x, completion status = 0x%04x\n",
+              le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status));
+       printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n", 
+              le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags));
+       printk("qlogicfc : response info length = 0x%04x, request sense length = 0x%04x\n",
+              le16_to_cpu(status->res_info_len), le16_to_cpu(status->req_sense_len));
+       printk("qlogicfc : residual transfer length = 0x%08x, response = 0x%02x\n", le32_to_cpu(status->residual), status->res_info[3]);
+
+}
+
+#endif                         /* DEBUG_ISP2x00_INTR */
+
+
+#if DEBUG_ISP2x00
+
+void isp2x00_print_scsi_cmd(Scsi_Cmnd * cmd)
+{
+       int i;
+
+       printk("qlogicfc : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", 
+              cmd->target, cmd->lun, cmd->cmd_len);
+       printk("qlogicfc : command = ");
+       for (i = 0; i < cmd->cmd_len; i++)
+               printk("0x%02x ", cmd->cmnd[i]);
+       printk("\n");
+}
+
+#endif                         /* DEBUG_ISP2x00 */
+
+MODULE_LICENSE("GPL");
+
+static Scsi_Host_Template driver_template = {
+        .detect                 = isp2x00_detect,
+        .release                = isp2x00_release,
+        .info                   = isp2x00_info,
+        .queuecommand           = isp2x00_queuecommand,
+        .eh_abort_handler       = isp2x00_abort,
+        .bios_param             = isp2x00_biosparam,
+        .can_queue              = QLOGICFC_REQ_QUEUE_LEN,
+        .this_id                = -1,
+        .sg_tablesize           = QLOGICFC_MAX_SG(QLOGICFC_REQ_QUEUE_LEN),
+       .cmd_per_lun            = QLOGICFC_CMD_PER_LUN,
+        .use_clustering         = ENABLE_CLUSTERING,
+};
+#include "scsi_module.c"
diff --git a/drivers/scsi/qlogicfc.h b/drivers/scsi/qlogicfc.h
new file mode 100644 (file)
index 0000000..b7f4708
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * QLogic ISP2x00 SCSI-FCP
+ * 
+ * Written by Erik H. Moe, ehm@cris.com
+ * Copyright 1995, Erik H. Moe
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+/* Renamed and updated to 1.3.x by Michael Griffith <grif@cs.ucr.edu> */
+
+/* This is a version of the isp1020 driver which was modified by
+ * Chris Loveland <cwl@iol.unh.edu> to support the isp2x00
+ */
+
+
+/*
+ * $Date: 1995/09/22 02:32:56 $
+ * $Revision: 0.5 $
+ *
+ * $Log: isp1020.h,v $
+ * Revision 0.5  1995/09/22  02:32:56  root
+ * do auto request sense
+ *
+ * Revision 0.4  1995/08/07  04:48:28  root
+ * supply firmware with driver.
+ * numerous bug fixes/general cleanup of code.
+ *
+ * Revision 0.3  1995/07/16  16:17:16  root
+ * added reset/abort code.
+ *
+ * Revision 0.2  1995/06/29  03:19:43  root
+ * fixed biosparam.
+ * added queue protocol.
+ *
+ * Revision 0.1  1995/06/25  01:56:13  root
+ * Initial release.
+ *
+ */
+
+#ifndef _QLOGICFC_H
+#define _QLOGICFC_H
+
+/*
+ * With the qlogic interface, every queue slot can hold a SCSI
+ * command with up to 2 scatter/gather entries.  If we need more
+ * than 2 entries, continuation entries can be used that hold
+ * another 5 entries each.  Unlike for other drivers, this means
+ * that the maximum number of scatter/gather entries we can
+ * support at any given time is a function of the number of queue
+ * slots available.  That is, host->can_queue and host->sg_tablesize
+ * are dynamic and _not_ independent.  This all works fine because
+ * requests are queued serially and the scatter/gather limit is
+ * determined for each queue request anew.
+ */
+
+#define DATASEGS_PER_COMMAND 2
+#define DATASEGS_PER_CONT 5
+
+#define QLOGICFC_REQ_QUEUE_LEN 255     /* must be power of two - 1 */
+#define QLOGICFC_MAX_SG(ql)    (DATASEGS_PER_COMMAND + (((ql) > 0) ? DATASEGS_PER_CONT*((ql) - 1) : 0))
+#define QLOGICFC_CMD_PER_LUN    8
+
+int isp2x00_detect(Scsi_Host_Template *);
+int isp2x00_release(struct Scsi_Host *);
+const char * isp2x00_info(struct Scsi_Host *);
+int isp2x00_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
+int isp2x00_abort(Scsi_Cmnd *);
+int isp2x00_reset(Scsi_Cmnd *, unsigned int);
+int isp2x00_biosparam(struct scsi_device *, struct block_device *,
+               sector_t, int[]);
+#endif /* _QLOGICFC_H */
diff --git a/drivers/scsi/qlogicfc_asm.c b/drivers/scsi/qlogicfc_asm.c
new file mode 100644 (file)
index 0000000..55c6c4b
--- /dev/null
@@ -0,0 +1,9751 @@
+/************************************************************************
+ *                                                                     *
+ *      --- ISP2100 Fabric Initiator/Target Firmware ---               *
+ *                   with expanded LUN addressing                       *
+ *                   and FcTape (FCP-2) support                         *
+ *                                                                     *
+ *                                                                     *
+ ************************************************************************
+  Copyright (C) 2000 and 2001 Qlogic Corporation 
+  (www.qlogic.com)
+
+  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.
+************************************************************************/
+
+/*
+ *     Firmware Version 1.19.16 (10:36 Nov 02, 2000)
+ */
+
+unsigned short risc_code_addr01 = 0x1000 ;
+
+unsigned short risc_code_length2100 = 0x9260;
+unsigned short risc_code2100[] = {
+       0x0078, 0x102d, 0x0000, 0x9260, 0x0000, 0x0001, 0x0013, 0x0010,
+       0x0017, 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, 0x3139, 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, 0x1052, 0x20c1, 0x0021, 0x2c2c,
+       0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020,
+       0x2039, 0x8fff, 0x20a1, 0xaa00, 0x2708, 0x810d, 0x810d, 0x810d,
+       0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8,
+       0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102,
+       0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1,
+       0xa260, 0x2009, 0x0000, 0x20a9, 0x07a0, 0x41a4, 0x3400, 0x20c9,
+       0xa7ff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x255d,
+       0x2051, 0xa300, 0x2a70, 0x775e, 0xa786, 0x8fff, 0x0040, 0x1092,
+       0x705b, 0xca00, 0x7057, 0xc9f1, 0x7063, 0x0200, 0x7067, 0x0200,
+       0x0078, 0x109a, 0x7057, 0xba01, 0x7063, 0x0100, 0x7067, 0x0100,
+       0x705b, 0xba00, 0x1078, 0x12df, 0x1078, 0x13c0, 0x1078, 0x1569,
+       0x1078, 0x1ca4, 0x1078, 0x4229, 0x1078, 0x74cf, 0x1078, 0x134b,
+       0x1078, 0x2a3f, 0x1078, 0x4da2, 0x1078, 0x48b2, 0x1078, 0x57df,
+       0x1078, 0x21f7, 0x1078, 0x5abf, 0x1078, 0x5369, 0x1078, 0x210d,
+       0x1078, 0x21d4, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf,
+       0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068,
+       0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70,
+       0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000,
+       0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x35bc, 0x1078, 0x2a67,
+       0x1078, 0x4df2, 0x1078, 0x4a75, 0x2009, 0x0100, 0x2104, 0xa082,
+       0x0002, 0x0048, 0x10f3, 0x1078, 0x57fb, 0x0078, 0x10d6, 0x1079,
+       0x10f7, 0x0078, 0x10dc, 0x1078, 0x6fa9, 0x0078, 0x10eb, 0x1101,
+       0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078,
+       0x1328, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086,
+       0x0001, 0x00c0, 0x1198, 0x1078, 0x3a43, 0x2079, 0x0100, 0x7844,
+       0xa005, 0x00c0, 0x1198, 0x2011, 0x4129, 0x1078, 0x58d4, 0x1078,
+       0x1ab1, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011,
+       0x8010, 0x73c0, 0x1078, 0x3579, 0x2001, 0xffff, 0x1078, 0x5975,
+       0x7238, 0xc284, 0x723a, 0x2001, 0xa30c, 0x2014, 0xc2ac, 0x2202,
+       0x1078, 0x6db5, 0x2011, 0x0004, 0x1078, 0x8a59, 0x1078, 0x47ce,
+       0x1078, 0x4211, 0x0040, 0x1144, 0x7083, 0x0001, 0x70bb, 0x0000,
+       0x1078, 0x3bf5, 0x0078, 0x1198, 0x1078, 0x4897, 0x0040, 0x114d,
+       0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x8ddf, 0x70c8,
+       0xd09c, 0x00c0, 0x1159, 0x7094, 0xa005, 0x0040, 0x1159, 0x1078,
+       0x41f5, 0x70d3, 0x0000, 0x70cf, 0x0000, 0x72c8, 0x2079, 0xa351,
+       0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ca, 0xa296, 0x0004,
+       0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8a59, 0x708f, 0x0000,
+       0x7093, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x260d, 0x2011,
+       0x0005, 0x1078, 0x6ef2, 0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100,
+       0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x708f, 0x0000,
+       0x7093, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x6ef2,
+       0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f,
+       0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e,
+       0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078,
+       0x71e0, 0x027f, 0x1078, 0xa190, 0x037f, 0x027f, 0x017f, 0x1078,
+       0x2921, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706b, 0x0000, 0x706c,
+       0xa084, 0x00ff, 0x706e, 0x7097, 0x0000, 0x007c, 0x127e, 0x2091,
+       0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7090, 0xa086,
+       0xffff, 0x0040, 0x11d1, 0x1078, 0x260d, 0x1078, 0x6109, 0x0078,
+       0x1244, 0x70c8, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd,
+       0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c,
+       0x0040, 0x11fd, 0x70cc, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078,
+       0x278a, 0x1078, 0x6109, 0x70c8, 0xd094, 0x00c0, 0x1244, 0x2011,
+       0x0001, 0x2019, 0x0000, 0x1078, 0x27c2, 0x1078, 0x6109, 0x0078,
+       0x1244, 0x70d0, 0xa005, 0x00c0, 0x1244, 0x708c, 0xa005, 0x00c0,
+       0x1244, 0x1078, 0x4897, 0x00c0, 0x1244, 0x2001, 0xa352, 0x2004,
+       0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
+       0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x121a, 0x6000, 0xd0ec,
+       0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f,
+       0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003,
+       0x0003, 0x7093, 0xffff, 0x2001, 0x0000, 0x1078, 0x2480, 0x1078,
+       0x35f7, 0x2001, 0xa5ac, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c,
+       0x2011, 0x0000, 0x1078, 0x6ef2, 0x2011, 0x0000, 0x1078, 0x6efc,
+       0x1078, 0x6109, 0x1078, 0x61d3, 0x127f, 0x007c, 0x017e, 0x0f7e,
+       0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078,
+       0x41de, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040,
+       0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008,
+       0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5975, 0x7900, 0xa18a,
+       0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009,
+       0x00f8, 0x1078, 0x41de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+       0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0,
+       0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x2480, 0x0078,
+       0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0,
+       0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f,
+       0x0000, 0x2009, 0x00f8, 0x1078, 0x41de, 0x20a9, 0x000e, 0x0005,
+       0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010,
+       0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4,
+       0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009,
+       0xa331, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4,
+       0x200b, 0x0000, 0x1078, 0x251e, 0x2001, 0x0001, 0x1078, 0x2480,
+       0x0078, 0x12d3, 0x2001, 0xa331, 0x2003, 0x0000, 0x7828, 0xc09d,
+       0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f,
+       0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70,
+       0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x12eb, 0x704f,
+       0xffff, 0x0078, 0x12ed, 0x704f, 0x0000, 0x7053, 0xffff, 0x706b,
+       0x0000, 0x706f, 0x0000, 0x1078, 0x8ddf, 0x2061, 0xa58c, 0x6003,
+       0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
+       0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061,
+       0xa594, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f,
+       0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f,
+       0x0000, 0x2061, 0xa5a3, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b,
+       0x4943, 0x600f, 0x2020, 0x2001, 0xa325, 0x2003, 0x0000, 0x007c,
+       0x2091, 0x8000, 0x0068, 0x132a, 0x007e, 0x017e, 0x2079, 0x0000,
+       0x7818, 0xd084, 0x00c0, 0x1330, 0x017f, 0x792e, 0x007f, 0x782a,
+       0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001,
+       0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa300, 0x7803, 0x0005,
+       0x0078, 0x1348, 0x007c, 0x2071, 0xa300, 0x7158, 0x712e, 0x2021,
+       0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, 0x1361, 0x705c,
+       0xa302, 0x00c8, 0x1361, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078,
+       0x1353, 0x200b, 0x0000, 0x74a6, 0x74aa, 0x007c, 0x0e7e, 0x127e,
+       0x2091, 0x8000, 0x2071, 0xa300, 0x70a8, 0xa0ea, 0x0010, 0x00c8,
+       0x1374, 0xa06e, 0x0078, 0x137e, 0x8001, 0x70aa, 0x702c, 0x2068,
+       0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f,
+       0x007c, 0x0e7e, 0x2071, 0xa300, 0x127e, 0x2091, 0x8000, 0x70a8,
+       0x8001, 0x00c8, 0x138e, 0xa06e, 0x0078, 0x1397, 0x70aa, 0x702c,
+       0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f,
+       0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa300,
+       0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa, 0x127f,
+       0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13b6, 0x6804, 0x6807, 0x0000,
+       0x007e, 0x1078, 0x139a, 0x0d7f, 0x0078, 0x13aa, 0x007c, 0x0e7e,
+       0x2071, 0xa300, 0x70a8, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c,
+       0x0e7e, 0x2071, 0xa5d0, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f,
+       0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f,
+       0x007c, 0x0e7e, 0x2270, 0x700b, 0x0000, 0x2071, 0xa5d0, 0x7018,
+       0xa088, 0xa5d9, 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004,
+       0xa005, 0x00c0, 0x13e9, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa,
+       0x0f7f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa5d0, 0x7004, 0xa005,
+       0x00c0, 0x13f8, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa, 0x0f7f,
+       0x0e7f, 0x007c, 0x7000, 0x0079, 0x13fd, 0x1401, 0x146b, 0x1488,
+       0x1488, 0x7018, 0x711c, 0xa106, 0x00c0, 0x1409, 0x7007, 0x0000,
+       0x007c, 0x0d7e, 0xa180, 0xa5d9, 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, 0x142b, 0x7007, 0x0001,
+       0x1078, 0x1430, 0x007c, 0x7007, 0x0002, 0x1078, 0x1446, 0x007c,
+       0x017e, 0x027e, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8,
+       0x143b, 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, 0x145a,
+       0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+       0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f,
+       0x027f, 0x017f, 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa3f9,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+       0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+       0x7002, 0x700b, 0xa3f4, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+       0x137e, 0x147e, 0x157e, 0x2001, 0xa428, 0x209c, 0x20a1, 0x0014,
+       0x7803, 0x0026, 0x2001, 0xa429, 0x20ac, 0x53a6, 0x2099, 0xa42a,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+       0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+       0x7002, 0x700b, 0xa425, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+       0x017e, 0x0e7e, 0x2071, 0xa5d0, 0x0f7e, 0x2079, 0x0010, 0x7904,
+       0x7803, 0x0002, 0xd1fc, 0x0040, 0x14c2, 0xa18c, 0x0700, 0x7004,
+       0x1079, 0x14c6, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13fa, 0x14ce,
+       0x14fb, 0x1523, 0x1556, 0x14cc, 0x0078, 0x14cc, 0xa18c, 0x0700,
+       0x00c0, 0x14f4, 0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099,
+       0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016,
+       0x157f, 0x147f, 0x137f, 0x700c, 0xa005, 0x0040, 0x1510, 0x1078,
+       0x1430, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007,
+       0x0000, 0x1078, 0x13fa, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003,
+       0x0200, 0x0078, 0x14ef, 0xa18c, 0x0700, 0x00c0, 0x1506, 0x700c,
+       0xa005, 0x0040, 0x1510, 0x1078, 0x1446, 0x007c, 0x7008, 0xa080,
+       0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x1078, 0x13fa, 0x007c,
+       0x0d7e, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+       0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000,
+       0x1078, 0x13fa, 0x007c, 0xa18c, 0x0700, 0x00c0, 0x1550, 0x137e,
+       0x147e, 0x157e, 0x2001, 0xa3f7, 0x2004, 0xa080, 0x000d, 0x20a0,
+       0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001,
+       0xa3f9, 0x2004, 0xd0bc, 0x0040, 0x1546, 0x2001, 0xa402, 0x2004,
+       0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f,
+       0x137f, 0x7007, 0x0000, 0x1078, 0x4e9b, 0x1078, 0x13fa, 0x007c,
+       0x2011, 0x8003, 0x1078, 0x3579, 0x0078, 0x1554, 0xa18c, 0x0700,
+       0x00c0, 0x1563, 0x2001, 0xa427, 0x2003, 0x0100, 0x7007, 0x0000,
+       0x1078, 0x13fa, 0x007c, 0x2011, 0x8004, 0x1078, 0x3579, 0x0078,
+       0x1567, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa5e1,
+       0x7803, 0x0004, 0x7003, 0x0000, 0x700f, 0xa5e7, 0x7013, 0xa5e7,
+       0x780f, 0x0076, 0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184,
+       0x0007, 0x0079, 0x1583, 0x158b, 0x15d1, 0x158b, 0x158b, 0x158b,
+       0x15b6, 0x159a, 0x158f, 0xa085, 0x0001, 0x0078, 0x15eb, 0x684c,
+       0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858,
+       0x0078, 0x15d9, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x158b,
+       0x684c, 0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0x6858, 0x0078, 0x15e1, 0xa18c, 0x00ff,
+       0xa186, 0x0015, 0x00c0, 0x158b, 0x684c, 0xd0ac, 0x0040, 0x158b,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078,
+       0x15e1, 0x684c, 0xd0ac, 0x0040, 0x158b, 0xa006, 0x682e, 0x682a,
+       0x6858, 0xa18c, 0x000f, 0xa188, 0x2015, 0x210c, 0x6932, 0x2d08,
+       0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+       0x6912, 0x6980, 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000,
+       0x2001, 0x020a, 0x2004, 0x82ff, 0x0040, 0x160e, 0xa280, 0x0004,
+       0x0d7e, 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x160a, 0x1078, 0x157e,
+       0x0040, 0x160a, 0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016,
+       0x0078, 0x160e, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e,
+       0x037e, 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000,
+       0xa005, 0x00c0, 0x1622, 0x7206, 0x2001, 0x1643, 0x007e, 0x2260,
+       0x0078, 0x17be, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a,
+       0x8108, 0xa182, 0xa602, 0x0048, 0x162f, 0x2009, 0xa5e7, 0x710e,
+       0x7010, 0xa102, 0xa082, 0x0009, 0x0040, 0x163a, 0xa080, 0x001b,
+       0x00c0, 0x163d, 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0,
+       0x1643, 0x1078, 0x179f, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e,
+       0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f,
+       0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005,
+       0x0040, 0x16cf, 0x6808, 0xa005, 0x0040, 0x173c, 0x7000, 0xa005,
+       0x00c0, 0x1664, 0x0078, 0x16c4, 0x700c, 0x7110, 0xa106, 0x00c0,
+       0x1745, 0x7004, 0xa406, 0x00c0, 0x16c4, 0x2001, 0x0005, 0x2004,
+       0xd08c, 0x0040, 0x1681, 0x047e, 0x1078, 0x18e2, 0x047f, 0x2460,
+       0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x0040, 0x173c, 0x0078,
+       0x165e, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x166d, 0x7804,
+       0xa084, 0x6000, 0x0040, 0x1692, 0xa086, 0x6000, 0x0040, 0x1692,
+       0x0078, 0x166d, 0x7100, 0xa186, 0x0002, 0x00c0, 0x16b2, 0x0e7e,
+       0x2b68, 0x6818, 0x2060, 0x1078, 0x1fea, 0x2804, 0xac70, 0x6034,
+       0xd09c, 0x00c0, 0x16a7, 0x7108, 0x720c, 0x0078, 0x16a9, 0x7110,
+       0x7214, 0x6810, 0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f,
+       0x0078, 0x16b6, 0xa186, 0x0001, 0x00c0, 0x16be, 0x7820, 0x6910,
+       0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004,
+       0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0,
+       0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0078, 0x1745, 0x6808,
+       0xa005, 0x0040, 0x173c, 0x7000, 0xa005, 0x00c0, 0x16d9, 0x0078,
+       0x173c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x16e2, 0x7004, 0xa406,
+       0x00c0, 0x173c, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x16f6,
+       0x047e, 0x1078, 0x18e2, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002,
+       0x2004, 0xa005, 0x0040, 0x173c, 0x0078, 0x16d3, 0x2001, 0x0207,
+       0x2004, 0xd09c, 0x00c0, 0x16e2, 0x2001, 0x0005, 0x2004, 0xd08c,
+       0x00c0, 0x16e8, 0x7804, 0xa084, 0x6000, 0x0040, 0x170d, 0xa086,
+       0x6000, 0x0040, 0x170d, 0x0078, 0x16e2, 0x7007, 0x0000, 0xa016,
+       0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x172e, 0xa08e, 0x0002,
+       0x00c0, 0x173c, 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x1fea,
+       0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x172a, 0x7308, 0x720c,
+       0x0078, 0x172c, 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318,
+       0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816,
+       0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0,
+       0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0c7f, 0x0d7f, 0x127f,
+       0x007c, 0x0f7e, 0x0e7e, 0x027e, 0x037e, 0x047e, 0x1078, 0x1af7,
+       0x027e, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0000, 0x0040, 0x1790,
+       0x7004, 0xac06, 0x00c0, 0x1781, 0x2079, 0x0030, 0x7000, 0xa086,
+       0x0003, 0x0040, 0x1781, 0x7804, 0xd0fc, 0x00c0, 0x177d, 0x2001,
+       0x0207, 0x2004, 0xd09c, 0x00c0, 0x1763, 0x7803, 0x0004, 0x7804,
+       0xd0ac, 0x00c0, 0x176f, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003,
+       0x0003, 0x7007, 0x0000, 0x0078, 0x1781, 0x1078, 0x18e2, 0x0078,
+       0x1753, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa5e7, 0x2104, 0xac06,
+       0x00c0, 0x178b, 0x200a, 0xa188, 0x0003, 0x00f0, 0x1786, 0x157f,
+       0x027f, 0x2001, 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138,
+       0x2202, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f, 0x007c, 0x700c,
+       0x7110, 0xa106, 0x00c0, 0x17a7, 0x7003, 0x0000, 0x007c, 0x2104,
+       0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182,
+       0xa602, 0x0048, 0x17b5, 0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106,
+       0x00c0, 0x17be, 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x00c0,
+       0x17c5, 0x1078, 0x1b22, 0x0078, 0x1823, 0x6010, 0x2068, 0x2d58,
+       0x6828, 0xa406, 0x00c0, 0x17d0, 0x682c, 0xa306, 0x0040, 0x17fe,
+       0x601c, 0xa086, 0x0008, 0x0040, 0x17fe, 0x6024, 0xd0f4, 0x00c0,
+       0x17fa, 0xd0d4, 0x0040, 0x17f6, 0x6038, 0xa402, 0x6034, 0xa303,
+       0x0040, 0x17e4, 0x00c8, 0x17f6, 0x643a, 0x6336, 0x6c2a, 0x6b2e,
+       0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80,
+       0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x17fa, 0x1078, 0x8d8e,
+       0x0040, 0x17c1, 0x1078, 0x2035, 0x00c0, 0x17c1, 0x0c7e, 0x7004,
+       0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4, 0x0040,
+       0x180f, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17c1, 0x6824,
+       0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
+       0x2009, 0x0011, 0x1078, 0x1824, 0x0040, 0x1822, 0x2009, 0x0001,
+       0x1078, 0x1824, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18bb, 0xa03e,
+       0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1846, 0xd0f4, 0x00c0, 0x1856,
+       0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1836, 0x189d, 0x185d,
+       0x185d, 0x189d, 0x189d, 0x1895, 0x189d, 0x185d, 0x189d, 0x1863,
+       0x1863, 0x189d, 0x189d, 0x189d, 0x188c, 0x1863, 0xc0fc, 0x6852,
+       0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040, 0x18a0,
+       0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18a0, 0xc0f4, 0x6852,
+       0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18a7, 0x6b08, 0x6a0c, 0x6d00,
+       0x6c04, 0x0078, 0x18a0, 0x7b0c, 0xd3bc, 0x0040, 0x1884, 0x7004,
+       0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1884,
+       0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff,
+       0x00c0, 0x187f, 0x6810, 0xa302, 0x0048, 0x187f, 0x6b10, 0x2011,
+       0x0000, 0x2468, 0x0078, 0x1886, 0x6b10, 0x6a14, 0x6d00, 0x6c04,
+       0x6f08, 0x6e0c, 0x0078, 0x18a0, 0x0d7f, 0x0d7e, 0x6834, 0xa084,
+       0x00ff, 0xa086, 0x001e, 0x00c0, 0x189d, 0x0d7f, 0x1078, 0x1fd1,
+       0x00c0, 0x1824, 0xa00e, 0x0078, 0x18bb, 0x0d7f, 0x1078, 0x1328,
+       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, 0x1fd1, 0x007c, 0x1078, 0x1328, 0x1078, 0x1c52,
+       0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000, 0x1078,
+       0x1ac6, 0x1078, 0x8a44, 0x0040, 0x18db, 0x6808, 0x8001, 0x680a,
+       0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff,
+       0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758, 0x0078, 0x1aad,
+       0x1078, 0x1328, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e, 0x2b68,
+       0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
+       0x18be, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x18e0, 0x7000,
+       0x0079, 0x18fa, 0x1902, 0x1904, 0x1a06, 0x1a84, 0x1a9b, 0x1902,
+       0x1902, 0x1902, 0x1078, 0x1328, 0x8001, 0x7002, 0xa184, 0x0880,
+       0x00c0, 0x1919, 0x8aff, 0x0040, 0x199b, 0x2009, 0x0001, 0x1078,
+       0x1824, 0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078,
+       0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0, 0x1979,
+       0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1930, 0x7c20, 0x7d24,
+       0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1932,
+       0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500,
+       0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060, 0x6024,
+       0xd0f4, 0x00c0, 0x1945, 0x633a, 0x6236, 0x0c7f, 0x2400, 0x6910,
+       0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, 0x027f,
+       0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x1fea, 0x2a00, 0x6826,
+       0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808,
+       0x8001, 0x680a, 0x00c0, 0x196e, 0x684c, 0xd0e4, 0x0040, 0x196e,
+       0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x7000, 0xa086,
+       0x0004, 0x0040, 0x1aad, 0x7003, 0x0000, 0x1078, 0x179f, 0x0078,
+       0x1aad, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x1980, 0x1078, 0xa20c,
+       0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4893,
+       0x0040, 0x198d, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff,
+       0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980,
+       0x6916, 0x0078, 0x1aad, 0x7004, 0x0c7e, 0x2060, 0x6024, 0x0c7f,
+       0xd0f4, 0x0040, 0x19a8, 0x6808, 0x8001, 0x680a, 0x0078, 0x1aad,
+       0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19c0, 0x7003,
+       0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19bc, 0x7004, 0x2060,
+       0x2009, 0x0048, 0x1078, 0x756c, 0x1078, 0x179f, 0x0078, 0x1aad,
+       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, 0x1b4d, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+       0x0001, 0x7804, 0xd0fc, 0x0040, 0x19e1, 0x7803, 0x0002, 0x7803,
+       0x0004, 0x780f, 0x0076, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009,
+       0x0048, 0x1078, 0x756c, 0x1078, 0x1b81, 0x0040, 0x19bc, 0x7908,
+       0xd1ec, 0x00c0, 0x19ff, 0x2009, 0x0009, 0x0078, 0x1a01, 0x2009,
+       0x0019, 0x7902, 0x7003, 0x0003, 0x0078, 0x1aad, 0x8001, 0x7002,
+       0xd194, 0x0040, 0x1a18, 0x7804, 0xd0fc, 0x00c0, 0x18ea, 0x8aff,
+       0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078, 0x1aad,
+       0xa184, 0x0880, 0x00c0, 0x1a25, 0x8aff, 0x0040, 0x1aad, 0x2009,
+       0x0001, 0x1078, 0x1824, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003,
+       0x0000, 0xd1bc, 0x00c0, 0x1a65, 0x027e, 0x037e, 0x7808, 0xd0ec,
+       0x00c0, 0x1a38, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a3a,
+       0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x1078, 0x1fea, 0x0d7e, 0x0f7e,
+       0x2d78, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a55, 0x6808,
+       0x2008, 0xa31a, 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c,
+       0x7814, 0xa101, 0x7816, 0x0078, 0x1a61, 0x6810, 0x2008, 0xa31a,
+       0x6814, 0xa213, 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101,
+       0x7816, 0x0f7f, 0x0d7f, 0x0078, 0x1934, 0x057e, 0x7d0c, 0x1078,
+       0xa20c, 0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078,
+       0x4893, 0x0040, 0x1a76, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b,
+       0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912,
+       0x6980, 0x6916, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000,
+       0x7004, 0xa00d, 0x0040, 0x1a97, 0x6808, 0x8001, 0x680a, 0x00c0,
+       0x1a97, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x1078,
+       0x179f, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
+       0x2060, 0x6010, 0xa005, 0x0040, 0x1a97, 0x2068, 0x6808, 0x8000,
+       0x680a, 0x6c28, 0x6b2c, 0x1078, 0x17be, 0x017f, 0x007f, 0x127f,
+       0x007c, 0x127e, 0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0,
+       0x1ac4, 0x700c, 0x7110, 0xa106, 0x0040, 0x1ac4, 0x20e1, 0x9028,
+       0x700f, 0xa5e7, 0x7013, 0xa5e7, 0x127f, 0x007c, 0x0c7e, 0x1078,
+       0x1af7, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1aed,
+       0x2104, 0xa005, 0x0040, 0x1ada, 0x2060, 0x6010, 0x2060, 0x6008,
+       0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xa602, 0x0048, 0x1ae2,
+       0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106, 0x00c0, 0x1acb, 0x2001,
+       0x0138, 0x2003, 0x0008, 0x0078, 0x1acb, 0x2001, 0x015d, 0x200c,
+       0x810a, 0x2102, 0x2001, 0x0138, 0x2202, 0x0c7f, 0x007c, 0x2001,
+       0x0138, 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141,
+       0x201c, 0xd3dc, 0x00c0, 0x1b14, 0x2001, 0x0109, 0x201c, 0xa39c,
+       0x0048, 0x00c0, 0x1b14, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0,
+       0x1b14, 0x8421, 0x00c0, 0x1afe, 0x007c, 0x2011, 0x0201, 0x2009,
+       0x003c, 0x2204, 0xa005, 0x00c0, 0x1b21, 0x8109, 0x00c0, 0x1b19,
+       0x007c, 0x007c, 0x1078, 0x1b15, 0x0040, 0x1b4a, 0x7908, 0xd1ec,
+       0x00c0, 0x1b3a, 0x1078, 0x1b81, 0x0040, 0x1b3a, 0x7803, 0x0009,
+       0x7904, 0xd1fc, 0x0040, 0x1b30, 0x7803, 0x0006, 0x1078, 0x1b15,
+       0x0040, 0x1b4a, 0x780c, 0xd0a4, 0x00c0, 0x1b4a, 0x7007, 0x0000,
+       0x1078, 0x1b81, 0x0040, 0x1b4c, 0x7803, 0x0019, 0x7003, 0x0003,
+       0x0078, 0x1b4c, 0x1078, 0x1ac6, 0x007c, 0x0e7e, 0x2071, 0x0200,
+       0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1af7, 0x2019, 0x5000,
+       0x8319, 0x0040, 0x1b6b, 0x2001, 0xa602, 0x2004, 0xa086, 0x0000,
+       0x0040, 0x1b6b, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b58, 0x1078,
+       0x1e5d, 0x0078, 0x1b56, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028,
+       0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100,
+       0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x0e7f,
+       0x007c, 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x1b8c,
+       0xa085, 0x0001, 0x0078, 0x1b9e, 0x2001, 0x020a, 0x81ff, 0x0040,
+       0x1b97, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1,
+       0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007c, 0x7c20,
+       0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c24,
+       0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c24, 0x0d7e,
+       0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c22, 0x6824, 0xd0d4,
+       0x00c0, 0x1c22, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1bec,
+       0x8108, 0x2104, 0x6b2c, 0xa306, 0x00c0, 0x1c22, 0x8108, 0x2104,
+       0x6a28, 0xa206, 0x00c0, 0x1c22, 0x6850, 0xc0fc, 0xc0f5, 0x6852,
+       0x686c, 0x7822, 0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836,
+       0x6818, 0x2060, 0x6034, 0xd09c, 0x0040, 0x1be7, 0x6830, 0x2004,
+       0xac68, 0x6808, 0x783a, 0x680c, 0x783e, 0x0078, 0x1c20, 0xa006,
+       0x783a, 0x783e, 0x0078, 0x1c20, 0x8108, 0x2104, 0xa005, 0x00c0,
+       0x1c22, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c22, 0x6850, 0xc0f5,
+       0x6852, 0x6830, 0x2004, 0x6918, 0xa160, 0xa180, 0x000d, 0x2004,
+       0xd09c, 0x00c0, 0x1c12, 0x6008, 0x7822, 0x686e, 0x600c, 0x7826,
+       0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, 0x783a, 0x783e,
+       0x0078, 0x1c20, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, 0x6872,
+       0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, 0x783e,
+       0x7803, 0x0011, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e,
+       0x027e, 0x2071, 0xa5e1, 0x2079, 0x0030, 0x2011, 0x0050, 0x7000,
+       0xa086, 0x0000, 0x0040, 0x1c4d, 0x8211, 0x0040, 0x1c4b, 0x2001,
+       0x0005, 0x2004, 0xd08c, 0x0040, 0x1c34, 0x7904, 0xa18c, 0x0780,
+       0x017e, 0x1078, 0x18e2, 0x017f, 0x81ff, 0x00c0, 0x1c4b, 0x2011,
+       0x0050, 0x0078, 0x1c2f, 0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f,
+       0x0f7f, 0x007c, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+       0x0040, 0x1ca3, 0x8109, 0x00c0, 0x1c56, 0x2009, 0x0100, 0x210c,
+       0xa18a, 0x0003, 0x1048, 0x1328, 0x1078, 0x1f75, 0x0e7e, 0x0f7e,
+       0x2071, 0xa5d0, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0040,
+       0x1c9b, 0x7800, 0x007e, 0x7820, 0x007e, 0x7830, 0x007e, 0x7834,
+       0x007e, 0x7838, 0x007e, 0x783c, 0x007e, 0x7803, 0x0004, 0x7823,
+       0x0000, 0x0005, 0x0005, 0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0,
+       0x1328, 0x2079, 0x0010, 0x007f, 0x783e, 0x007f, 0x783a, 0x007f,
+       0x7836, 0x007f, 0x7832, 0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f,
+       0x0e7f, 0x0078, 0x1ca1, 0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0,
+       0x1328, 0x1078, 0x61d3, 0x007c, 0x0e7e, 0x2071, 0xa602, 0x7003,
+       0x0000, 0x0e7f, 0x007c, 0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c,
+       0xd1dc, 0x00c0, 0x1d26, 0x6934, 0xa184, 0x0007, 0x0079, 0x1cb8,
+       0x1cc0, 0x1d11, 0x1cc0, 0x1cc0, 0x1cc0, 0x1cf6, 0x1cd3, 0x1cc2,
+       0x1078, 0x1328, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+       0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+       0x6958, 0x0078, 0x1d19, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+       0x00c0, 0x1cc0, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+       0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0x6958, 0x0078, 0x1d22, 0xa18c, 0x00ff,
+       0xa186, 0x0015, 0x00c0, 0x1d26, 0x684c, 0xd0b4, 0x0040, 0x1e34,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0078,
+       0x1d22, 0x684c, 0xd0b4, 0x0040, 0x18bc, 0x6958, 0xa006, 0x682e,
+       0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2015,
+       0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c,
+       0x0f7e, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x10c0, 0x1e5d, 0x0e7e,
+       0x0d7e, 0x2071, 0xa602, 0x7000, 0xa005, 0x00c0, 0x1dab, 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, 0x2001, 0x04fd, 0x2004,
+       0xa086, 0x0007, 0x0040, 0x1d6d, 0xa184, 0x0007, 0x0040, 0x1d6d,
+       0x017e, 0x2009, 0x0008, 0xa102, 0x017f, 0xa108, 0x791a, 0x7116,
+       0x701e, 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e,
+       0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x00c0, 0x1d84, 0x6928,
+       0x6810, 0xa106, 0x0040, 0x1d91, 0x037e, 0x047e, 0x6b14, 0x6c10,
+       0x1078, 0x2035, 0x047f, 0x037f, 0x0040, 0x1d91, 0x0c7f, 0x0078,
+       0x1dab, 0x8aff, 0x00c0, 0x1d99, 0x0c7f, 0xa085, 0x0001, 0x0078,
+       0x1dab, 0x127e, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001,
+       0x1078, 0x1daf, 0x0040, 0x1da8, 0x2009, 0x0001, 0x1078, 0x1daf,
+       0x127f, 0x0c7f, 0xa006, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e,
+       0x067e, 0x057e, 0x047e, 0x037e, 0x027e, 0x8aff, 0x0040, 0x1e2d,
+       0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0048, 0x1e2c,
+       0xa705, 0x0040, 0x1e2c, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0,
+       0x1ddf, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1dcf, 0x1e0e,
+       0x1def, 0x1def, 0x1e0e, 0x1e0e, 0x1e06, 0x1e0e, 0x1def, 0x1e0e,
+       0x1df5, 0x1df5, 0x1e0e, 0x1e0e, 0x1e0e, 0x1dfd, 0x1df5, 0xc0fc,
+       0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e12,
+       0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x6b08,
+       0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1e11, 0x6b10, 0x6a14, 0x6d00,
+       0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x0d7f, 0x0d7e, 0x6834,
+       0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1e0e, 0x0d7f, 0x1078,
+       0x1fd1, 0x00c0, 0x1db5, 0xa00e, 0x0078, 0x1e2d, 0x0d7f, 0x1078,
+       0x1328, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e,
+       0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c,
+       0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012,
+       0x1078, 0x1fd1, 0x0078, 0x1e2d, 0xa006, 0x027f, 0x037f, 0x047f,
+       0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x1328, 0x027e, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44,
+       0x0040, 0x1e4d, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758,
+       0x20e1, 0x9040, 0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc,
+       0x1078, 0x61d3, 0x027f, 0x0078, 0x1f29, 0x127e, 0x2091, 0x2200,
+       0x007e, 0x017e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020,
+       0x2071, 0xa602, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
+       0xa184, 0x0700, 0x00c0, 0x1e36, 0x7000, 0x0079, 0x1e77, 0x1f29,
+       0x1e7b, 0x1ef6, 0x1f27, 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1e8f,
+       0x8aff, 0x0040, 0x1eae, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0040,
+       0x1f29, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0078, 0x1f29, 0x7803,
+       0x0004, 0xd194, 0x0040, 0x1e9f, 0x6850, 0xc0fc, 0x6852, 0x8aff,
+       0x00c0, 0x1ea4, 0x684c, 0xc0f5, 0x684e, 0x0078, 0x1ea4, 0x1078,
+       0x1fea, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a,
+       0x2800, 0x6832, 0x7003, 0x0000, 0x0078, 0x1f29, 0x711c, 0x81ff,
+       0x0040, 0x1ec4, 0x7918, 0x7922, 0x7827, 0x0000, 0x7803, 0x0001,
+       0x7000, 0x8000, 0x7002, 0x700c, 0xa100, 0x700e, 0x7010, 0xa081,
+       0x0000, 0x7012, 0x0078, 0x1f29, 0x0f7e, 0x027e, 0x781c, 0x007e,
+       0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085,
+       0x0012, 0x7816, 0x037e, 0x2019, 0x1000, 0x8319, 0x1040, 0x1328,
+       0x7820, 0xd0bc, 0x00c0, 0x1ed5, 0x037f, 0x79c8, 0x007f, 0xa102,
+       0x017f, 0x007e, 0x017e, 0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f,
+       0x78ca, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f,
+       0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1f29, 0x8001, 0x7002,
+       0xd194, 0x0040, 0x1f0b, 0x7804, 0xd0fc, 0x00c0, 0x1e6d, 0xd19c,
+       0x00c0, 0x1f25, 0x8aff, 0x0040, 0x1f29, 0x2009, 0x0001, 0x1078,
+       0x1daf, 0x0078, 0x1f29, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078,
+       0x1fea, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f1e,
+       0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1f22, 0x6810, 0xa31a,
+       0x6814, 0xa213, 0x0d7f, 0x0078, 0x1e9f, 0x0078, 0x1e9f, 0x1078,
+       0x1328, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f,
+       0x007c, 0x0f7e, 0x0e7e, 0x2071, 0xa602, 0x7000, 0xa086, 0x0000,
+       0x0040, 0x1f72, 0x2079, 0x0020, 0x017e, 0x2009, 0x0207, 0x210c,
+       0xd194, 0x0040, 0x1f4f, 0x2009, 0x020c, 0x210c, 0xa184, 0x0003,
+       0x0040, 0x1f4f, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102, 0x2009,
+       0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x00c0, 0x1f5a,
+       0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0040, 0x1f3d, 0x1078, 0x1e5d,
+       0x7000, 0xa086, 0x0000, 0x00c0, 0x1f3d, 0x017f, 0x7803, 0x0004,
+       0x7804, 0xd0ac, 0x00c0, 0x1f68, 0x20e1, 0x9040, 0x7803, 0x0002,
+       0x7003, 0x0000, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e,
+       0x0e7e, 0x0f7e, 0x2071, 0xa602, 0x2079, 0x0020, 0x7000, 0xa086,
+       0x0000, 0x0040, 0x1fae, 0x7004, 0x2060, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x1f98, 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c,
+       0xa206, 0x00c0, 0x1f98, 0x6808, 0x7a18, 0xa206, 0x0040, 0x1fb4,
+       0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004,
+       0x7003, 0x0000, 0x7004, 0x2060, 0x1078, 0x8758, 0x20e1, 0x9040,
+       0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc, 0x0f7f, 0x0e7f,
+       0x0d7f, 0x0c7f, 0x027f, 0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0,
+       0x1f98, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x1078, 0x1cab, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x2069, 0xa5ab, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078,
+       0x1fae, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1fe5, 0x6004, 0xa005,
+       0x0040, 0x1fe7, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2044, 0x88ff, 0x1040, 0x1328, 0x8a51, 0x007c, 0x2051,
+       0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, 0x2004,
+       0x2c00, 0xad06, 0x0040, 0x1ff9, 0x6000, 0xa005, 0x00c0, 0x1ff9,
+       0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x2025,
+       0x2044, 0x88ff, 0x1040, 0x1328, 0x007c, 0x0000, 0x0011, 0x0015,
+       0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015,
+       0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x200a, 0x2006,
+       0x0000, 0x0000, 0x2014, 0x0000, 0x200a, 0x0000, 0x2011, 0x200e,
+       0x0000, 0x0000, 0x0000, 0x2014, 0x2011, 0x0000, 0x200c, 0x200c,
+       0x0000, 0x0000, 0x2014, 0x0000, 0x200c, 0x0000, 0x2012, 0x2012,
+       0x0000, 0x0000, 0x0000, 0x2014, 0x2012, 0x0a7e, 0x097e, 0x087e,
+       0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0040, 0x20d8, 0x2d60, 0x6034,
+       0xa0cc, 0x000f, 0xa9c0, 0x2015, 0xa986, 0x0007, 0x0040, 0x2050,
+       0xa986, 0x000e, 0x0040, 0x2050, 0xa986, 0x000f, 0x00c0, 0x2054,
+       0x605c, 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x2062,
+       0x0050, 0x205c, 0x0078, 0x20d8, 0x6004, 0xa065, 0x0040, 0x20d8,
+       0x0078, 0x203f, 0x2804, 0xa005, 0x0040, 0x2080, 0xac68, 0xd99c,
+       0x00c0, 0x2070, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x2074,
+       0x6810, 0xa422, 0x6814, 0xa31b, 0x0048, 0x209f, 0x2300, 0xa405,
+       0x0040, 0x2086, 0x8a51, 0x0040, 0x20d8, 0x8840, 0x0078, 0x2062,
+       0x6004, 0xa065, 0x0040, 0x20d8, 0x0078, 0x203f, 0x8a51, 0x0040,
+       0x20d8, 0x8840, 0x2804, 0xa005, 0x00c0, 0x2099, 0x6004, 0xa065,
+       0x0040, 0x20d8, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2015, 0x2804,
+       0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x20cc, 0x8422,
+       0x8420, 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72,
+       0x0d7f, 0xd99c, 0x00c0, 0x20ba, 0x6908, 0x2400, 0xa122, 0x690c,
+       0x2300, 0xa11b, 0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319,
+       0x0078, 0x20c6, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+       0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+       0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+       0x2a00, 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x20dd,
+       0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005,
+       0x2004, 0xa084, 0x0007, 0x0079, 0x20e5, 0x20ed, 0x20ee, 0x20f1,
+       0x20f4, 0x20f9, 0x20fc, 0x2101, 0x2106, 0x007c, 0x1078, 0x1e5d,
+       0x007c, 0x1078, 0x18e2, 0x007c, 0x1078, 0x18e2, 0x1078, 0x1e5d,
+       0x007c, 0x1078, 0x14b0, 0x007c, 0x1078, 0x1e5d, 0x1078, 0x14b0,
+       0x007c, 0x1078, 0x18e2, 0x1078, 0x14b0, 0x007c, 0x1078, 0x18e2,
+       0x1078, 0x1e5d, 0x1078, 0x14b0, 0x007c, 0x127e, 0x2091, 0x2300,
+       0x2079, 0x0200, 0x2071, 0xa880, 0x2069, 0xa300, 0x2009, 0x0004,
+       0x7912, 0x7817, 0x0004, 0x1078, 0x24b5, 0x781b, 0x0002, 0x20e1,
+       0x8700, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084,
+       0x0007, 0x0079, 0x212b, 0x214f, 0x2133, 0x2137, 0x213b, 0x2141,
+       0x2145, 0x2149, 0x214d, 0x1078, 0x5372, 0x0078, 0x214f, 0x1078,
+       0x53b3, 0x0078, 0x214f, 0x1078, 0x5372, 0x1078, 0x53b3, 0x0078,
+       0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x0078,
+       0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x127f,
+       0x007c, 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040,
+       0x215d, 0x20e1, 0x9040, 0x0078, 0x2186, 0xa184, 0x0030, 0x0040,
+       0x216e, 0x6a00, 0xa286, 0x0003, 0x00c0, 0x2168, 0x0078, 0x216a,
+       0x1078, 0x4171, 0x20e1, 0x9010, 0x0078, 0x2186, 0xa184, 0x00c0,
+       0x0040, 0x2180, 0x0e7e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa5e1,
+       0x1078, 0x1ac6, 0x057f, 0x047f, 0x037f, 0x0e7f, 0x0078, 0x2186,
+       0xa184, 0x0300, 0x0040, 0x2186, 0x20e1, 0x9020, 0x7932, 0x027f,
+       0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071, 0xa300,
+       0x7128, 0x2001, 0xa58f, 0x2102, 0x2001, 0xa597, 0x2102, 0xa182,
+       0x0211, 0x00c8, 0x219f, 0x2009, 0x0008, 0x0078, 0x21c9, 0xa182,
+       0x0259, 0x00c8, 0x21a7, 0x2009, 0x0007, 0x0078, 0x21c9, 0xa182,
+       0x02c1, 0x00c8, 0x21af, 0x2009, 0x0006, 0x0078, 0x21c9, 0xa182,
+       0x0349, 0x00c8, 0x21b7, 0x2009, 0x0005, 0x0078, 0x21c9, 0xa182,
+       0x0421, 0x00c8, 0x21bf, 0x2009, 0x0004, 0x0078, 0x21c9, 0xa182,
+       0x0581, 0x00c8, 0x21c7, 0x2009, 0x0003, 0x0078, 0x21c9, 0x2009,
+       0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x1078, 0x24b5,
+       0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061,
+       0x0100, 0x2071, 0xa300, 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,
+       0xa32f, 0x2003, 0x0000, 0x2001, 0xa32e, 0x2003, 0x0001, 0x007c,
+       0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184,
+       0x002c, 0x00c0, 0x220f, 0xa184, 0x0007, 0x0079, 0x2215, 0xa195,
+       0x0004, 0xa284, 0x0007, 0x0079, 0x2215, 0x2241, 0x221d, 0x2221,
+       0x2225, 0x222b, 0x222f, 0x2235, 0x223b, 0x1078, 0x5ad2, 0x0078,
+       0x2241, 0x1078, 0x5bc1, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+       0x5ad2, 0x0078, 0x2241, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078,
+       0x5ad2, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+       0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078, 0x5ad2, 0x1078,
+       0x2246, 0x027f, 0x017f, 0x007f, 0x127f, 0x007c, 0x6124, 0xd1ac,
+       0x0040, 0x2342, 0x017e, 0x047e, 0x0c7e, 0x644c, 0xa486, 0xf0f0,
+       0x00c0, 0x2259, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043,
+       0x0010, 0x74c2, 0xa48c, 0xff00, 0x7034, 0xd084, 0x0040, 0x2271,
+       0xa186, 0xf800, 0x00c0, 0x2271, 0x7038, 0xd084, 0x00c0, 0x2271,
+       0xc085, 0x703a, 0x037e, 0x2418, 0x2011, 0x8016, 0x1078, 0x3579,
+       0x037f, 0xa196, 0xff00, 0x0040, 0x22b3, 0x6030, 0xa084, 0x00ff,
+       0x810f, 0xa116, 0x0040, 0x22b3, 0x7130, 0xd184, 0x00c0, 0x22b3,
+       0x2011, 0xa352, 0x2214, 0xd2ec, 0x0040, 0x228e, 0xc18d, 0x7132,
+       0x2011, 0xa352, 0x2214, 0xd2ac, 0x00c0, 0x22b3, 0x6240, 0xa294,
+       0x0010, 0x0040, 0x229a, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00,
+       0x0040, 0x22b3, 0x7030, 0xd08c, 0x0040, 0x2305, 0x7034, 0xd08c,
+       0x00c0, 0x22aa, 0x2001, 0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305,
+       0xc1ad, 0x2102, 0x037e, 0x73c0, 0x2011, 0x8013, 0x1078, 0x3579,
+       0x037f, 0x0078, 0x2305, 0x7034, 0xd08c, 0x00c0, 0x22bf, 0x2001,
+       0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305, 0xc1ad, 0x2102, 0x037e,
+       0x73c0, 0x2011, 0x8013, 0x1078, 0x3579, 0x037f, 0x7130, 0xc185,
+       0x7132, 0x2011, 0xa352, 0x220c, 0xd1a4, 0x0040, 0x22e9, 0x017e,
+       0x2009, 0x0001, 0x2011, 0x0100, 0x1078, 0x5a6d, 0x2019, 0x000e,
+       0x1078, 0x9e3b, 0xa484, 0x00ff, 0xa080, 0x293f, 0x200c, 0xa18c,
+       0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, 0x9ec0,
+       0x017f, 0xd1ac, 0x00c0, 0x22f6, 0x017e, 0x2009, 0x0000, 0x2019,
+       0x0004, 0x1078, 0x27e2, 0x017f, 0x0078, 0x2305, 0x157e, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x1078, 0x4501, 0x00c0, 0x2301, 0x1078,
+       0x4235, 0x8108, 0x00f0, 0x22fb, 0x157f, 0x0c7f, 0x047f, 0x0f7e,
+       0x2079, 0xa5be, 0x783c, 0xa086, 0x0000, 0x0040, 0x2317, 0x6027,
+       0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f,
+       0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011, 0x0002, 0x1078, 0x6efc,
+       0x1078, 0x6dda, 0x1078, 0x595a, 0x037e, 0x2019, 0x0000, 0x1078,
+       0x6e6c, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, 0xa300, 0x2014,
+       0xa296, 0x0004, 0x00c0, 0x233a, 0xd19c, 0x00c0, 0x233a, 0x6228,
+       0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa321, 0x2003, 0x0000,
+       0x6027, 0x0020, 0xd194, 0x0040, 0x2426, 0x0f7e, 0x2079, 0xa5be,
+       0x783c, 0xa086, 0x0001, 0x00c0, 0x2366, 0x017e, 0x6027, 0x0004,
+       0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000,
+       0x2079, 0xa5ab, 0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x6109,
+       0x1078, 0x61d3, 0x017f, 0x0f7f, 0x0078, 0x2426, 0x0f7f, 0x017e,
+       0x3900, 0xa082, 0xa6cd, 0x00c8, 0x2371, 0x017e, 0x1078, 0x728a,
+       0x017f, 0x6220, 0xd2b4, 0x0040, 0x23dc, 0x1078, 0x595a, 0x1078,
+       0x6c41, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa5b4, 0x2304, 0xa07d,
+       0x0040, 0x23b2, 0x7804, 0xa086, 0x0032, 0x00c0, 0x23b2, 0x0d7e,
+       0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
+       0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x00c0,
+       0x2396, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e,
+       0x628a, 0x1078, 0x6010, 0x1078, 0x6109, 0x7810, 0x2070, 0x7037,
+       0x0103, 0x2f60, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0d7f, 0x0f7f,
+       0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084,
+       0x4000, 0x0040, 0x23bf, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f,
+       0x0c7e, 0x2061, 0xa5ab, 0x6028, 0xa09a, 0x00c8, 0x00c8, 0x23cf,
+       0x8000, 0x602a, 0x0c7f, 0x1078, 0x6c33, 0x0078, 0x2425, 0x2019,
+       0xa5b4, 0x2304, 0xa065, 0x0040, 0x23d9, 0x2009, 0x0027, 0x1078,
+       0x756c, 0x0c7f, 0x0078, 0x2425, 0xd2bc, 0x0040, 0x2425, 0x1078,
+       0x5967, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140,
+       0x6804, 0xa084, 0x4000, 0x0040, 0x23f1, 0x6803, 0x1000, 0x6803,
+       0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa5ab, 0x6044, 0xa09a, 0x00c8,
+       0x00c8, 0x2414, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040,
+       0x2425, 0x2009, 0x07d0, 0x1078, 0x595f, 0xa080, 0x0007, 0x2004,
+       0xa086, 0x0006, 0x00c0, 0x2410, 0x6017, 0x0012, 0x0078, 0x2425,
+       0x6017, 0x0016, 0x0078, 0x2425, 0x037e, 0x2019, 0x0001, 0x1078,
+       0x6e6c, 0x037f, 0x2019, 0xa5ba, 0x2304, 0xa065, 0x0040, 0x2424,
+       0x2009, 0x004f, 0x1078, 0x756c, 0x0c7f, 0x017f, 0xd19c, 0x0040,
+       0x247c, 0x7034, 0xd0ac, 0x00c0, 0x2457, 0x017e, 0x157e, 0x6027,
+       0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0, 0x2435, 0x602f,
+       0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0320, 0x00e0,
+       0x243f, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0, 0x244e, 0x157f,
+       0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x247c, 0x1078, 0x250d,
+       0x00f0, 0x243f, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x017e,
+       0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011,
+       0x0002, 0x1078, 0x6efc, 0x1078, 0x6dda, 0x1078, 0x595a, 0x037e,
+       0x2019, 0x0000, 0x1078, 0x6e6c, 0x037f, 0x60e3, 0x0000, 0x1078,
+       0xa22a, 0x1078, 0xa248, 0x2001, 0xa300, 0x2003, 0x0004, 0x6027,
+       0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c,
+       0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000,
+       0x2071, 0xa300, 0x71b8, 0x70ba, 0xa116, 0x0040, 0x24ae, 0x81ff,
+       0x0040, 0x2498, 0x2011, 0x8011, 0x1078, 0x3579, 0x0078, 0x24ae,
+       0x2011, 0x8012, 0x1078, 0x3579, 0x2001, 0xa371, 0x2004, 0xd0fc,
+       0x00c0, 0x24ae, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028,
+       0x2009, 0x0000, 0x1078, 0x27e2, 0x0c7f, 0x037f, 0x127f, 0x0f7f,
+       0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e,
+       0x027e, 0x2061, 0x0100, 0xa190, 0x24d1, 0x2204, 0x60f2, 0x2011,
+       0x24de, 0x6000, 0xa082, 0x0003, 0x00c8, 0x24ca, 0x2001, 0x00ff,
+       0x0078, 0x24cb, 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, 0x24ee, 0x81ff, 0x0040, 0x24f2, 0x1078, 0x5623,
+       0x0078, 0x24f9, 0xa080, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+       0xa006, 0x007c, 0xa080, 0x293f, 0x200c, 0xa18c, 0x00ff, 0x007c,
+       0x0c7e, 0x2061, 0xa300, 0x6030, 0x0040, 0x2509, 0xc09d, 0x0078,
+       0x250a, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e, 0x157e, 0x0f7e,
+       0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x00c0, 0x251a,
+       0x00f0, 0x2514, 0x0f7f, 0x157f, 0x007f, 0x007c, 0x0c7e, 0x007e,
+       0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e, 0x60e4, 0x007e,
+       0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e, 0x60ec, 0x007e,
+       0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e, 0x60e0, 0x007e,
+       0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005, 0x0005, 0x0005,
+       0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2, 0x007f, 0x602a,
+       0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee, 0x007f, 0x60f2,
+       0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6, 0x007f, 0x604a,
+       0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x257d, 0x2581, 0x2585,
+       0x258b, 0x2591, 0x2597, 0x259d, 0x25a5, 0x25ad, 0x25b3, 0x25b9,
+       0x25c1, 0x25c9, 0x25d1, 0x25d9, 0x25e3, 0x25ed, 0x25ed, 0x25ed,
+       0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed,
+       0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x107e, 0x007e, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2200, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e,
+       0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x20de, 0x1078,
+       0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078,
+       0x20de, 0x1078, 0x2123, 0x0078, 0x2606, 0x0005, 0x0078, 0x25ed,
+       0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x25f6, 0x2606, 0x2583,
+       0x2587, 0x258d, 0x2593, 0x2599, 0x259f, 0x25a7, 0x25af, 0x25b5,
+       0x25bb, 0x25c3, 0x25cb, 0x25d3, 0x25db, 0x25e5, 0x0008, 0x25f0,
+       0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, 0x027e, 0x047e,
+       0x2021, 0x0000, 0x1078, 0x4897, 0x00c0, 0x2705, 0x70c8, 0xd09c,
+       0x0040, 0x2624, 0xd084, 0x00c0, 0x2624, 0xd0bc, 0x00c0, 0x2705,
+       0x1078, 0x2709, 0x0078, 0x2705, 0xd094, 0x0040, 0x262b, 0x7093,
+       0xffff, 0x0078, 0x2705, 0x2001, 0x010c, 0x203c, 0x7280, 0xd284,
+       0x0040, 0x2694, 0xd28c, 0x00c0, 0x2694, 0x037e, 0x7390, 0xa38e,
+       0xffff, 0x0040, 0x263e, 0x83ff, 0x00c0, 0x2640, 0x2019, 0x0001,
+       0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x264d,
+       0xa084, 0xff00, 0x8007, 0x0078, 0x264f, 0xa084, 0x00ff, 0xa70e,
+       0x0040, 0x2689, 0xa08e, 0x0000, 0x0040, 0x2689, 0xa08e, 0x00ff,
+       0x00c0, 0x2666, 0x7230, 0xd284, 0x00c0, 0x268f, 0x7280, 0xc28d,
+       0x7282, 0x7093, 0xffff, 0x037f, 0x0078, 0x2694, 0x2009, 0x0000,
+       0x1078, 0x24e3, 0x1078, 0x4499, 0x00c0, 0x268c, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x00c0, 0x2683, 0x7030, 0xd08c, 0x0040,
+       0x267d, 0x6000, 0xd0bc, 0x0040, 0x2683, 0x1078, 0x271f, 0x0040,
+       0x268c, 0x0078, 0x2689, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+       0x268c, 0x8318, 0x0078, 0x2640, 0x7392, 0x0078, 0x2691, 0x7093,
+       0xffff, 0x037f, 0x0078, 0x2705, 0xa780, 0x293f, 0x203c, 0xa7bc,
+       0xff00, 0x873f, 0x2041, 0x007e, 0x7090, 0xa096, 0xffff, 0x00c0,
+       0x26a6, 0x2009, 0x0000, 0x28a8, 0x0078, 0x26b2, 0xa812, 0x0048,
+       0x26ae, 0x2008, 0xa802, 0x20a8, 0x0078, 0x26b2, 0x7093, 0xffff,
+       0x0078, 0x2705, 0x2700, 0x157e, 0x017e, 0xa106, 0x0040, 0x26f9,
+       0xc484, 0x1078, 0x4501, 0x0040, 0x26c3, 0x1078, 0x4499, 0x00c0,
+       0x2702, 0x0078, 0x26c4, 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086,
+       0x0006, 0x00c0, 0x26d3, 0x7030, 0xd08c, 0x0040, 0x26f1, 0x6000,
+       0xd0bc, 0x00c0, 0x26f1, 0x7280, 0xd28c, 0x0040, 0x26e9, 0x6004,
+       0xa084, 0x00ff, 0xa082, 0x0006, 0x0048, 0x26f9, 0xd484, 0x00c0,
+       0x26e5, 0x1078, 0x44bc, 0x0078, 0x26e7, 0x1078, 0x2921, 0x0078,
+       0x26f9, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040, 0x2702, 0x0078,
+       0x26f9, 0x1078, 0x28ec, 0x0040, 0x26f9, 0x1078, 0x271f, 0x0040,
+       0x2702, 0x017f, 0x8108, 0x157f, 0x00f0, 0x26b2, 0x7093, 0xffff,
+       0x0078, 0x2705, 0x017f, 0x157f, 0x7192, 0x047f, 0x027f, 0x0c7f,
+       0x007c, 0x0c7e, 0x017e, 0x7093, 0x0000, 0x2009, 0x007e, 0x1078,
+       0x4499, 0x00c0, 0x271c, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+       0x271c, 0x70c8, 0xc0bd, 0x70ca, 0x017f, 0x0c7f, 0x007c, 0x017e,
+       0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa356, 0x2004, 0xa084,
+       0x00ff, 0x6842, 0x1078, 0x74d7, 0x0040, 0x2747, 0x2d00, 0x601a,
+       0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0000,
+       0x1078, 0x443f, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e,
+       0x127f, 0x2009, 0x0004, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f,
+       0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
+       0x2c68, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
+       0x74d7, 0x0040, 0x2785, 0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802,
+       0x68a0, 0xa086, 0x007e, 0x0040, 0x276e, 0x6804, 0xa084, 0x00ff,
+       0xa086, 0x0006, 0x00c0, 0x276e, 0x1078, 0x2813, 0x601f, 0x0001,
+       0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+       0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, 0x127f, 0x2009,
+       0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+       0x017f, 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, 0x4499,
+       0x00c0, 0x2798, 0x1078, 0x279b, 0x0040, 0x2798, 0x70cf, 0xffff,
+       0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68,
+       0x1078, 0x74d7, 0x0040, 0x27bd, 0x2d00, 0x601a, 0x601f, 0x0001,
+       0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+       0x127e, 0x2091, 0x8000, 0x70d0, 0x8000, 0x70d2, 0x127f, 0x2009,
+       0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+       0x017f, 0x007c, 0x0c7e, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2009,
+       0x007f, 0x1078, 0x4499, 0x00c0, 0x27de, 0x2c68, 0x1078, 0x74d7,
+       0x0040, 0x27de, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+       0x2009, 0x0022, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0d7f,
+       0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078,
+       0x5d60, 0x1078, 0x5d02, 0x1078, 0x7ddf, 0x2130, 0x81ff, 0x0040,
+       0x27f7, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0078, 0x27fb, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x2804,
+       0x1078, 0x471b, 0x1078, 0x4235, 0x017f, 0x8108, 0x00f0, 0x27fb,
+       0x86ff, 0x00c0, 0x280d, 0x1078, 0x119b, 0x027f, 0x037f, 0x067f,
+       0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e,
+       0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53,
+       0x077e, 0x2039, 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38,
+       0x077f, 0x017f, 0x2e60, 0x1078, 0x471b, 0x6210, 0x6314, 0x1078,
+       0x4235, 0x6212, 0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+       0x007c, 0x0e7e, 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc,
+       0x00c0, 0x284d, 0x2071, 0xa300, 0x708c, 0xa005, 0x0040, 0x284a,
+       0x8001, 0x708e, 0x007f, 0x0e7f, 0x007c, 0x2071, 0xa300, 0x70d0,
+       0xa005, 0x0040, 0x284a, 0x8001, 0x70d2, 0x0078, 0x284a, 0x6000,
+       0xc08c, 0x6002, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e,
+       0x017e, 0x157e, 0x2178, 0x81ff, 0x00c0, 0x286a, 0x20a9, 0x0001,
+       0x0078, 0x2885, 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x2881,
+       0xd0a4, 0x0040, 0x2881, 0x047e, 0x6018, 0xa080, 0x0028, 0x2024,
+       0xa4a4, 0x00ff, 0x8427, 0xa006, 0x2009, 0x002d, 0x1078, 0x9ec0,
+       0x047f, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x027e, 0xa28e, 0x007e,
+       0x0040, 0x28c9, 0xa28e, 0x007f, 0x0040, 0x28c9, 0xa28e, 0x0080,
+       0x0040, 0x28c9, 0xa288, 0xa434, 0x210c, 0x81ff, 0x0040, 0x28c9,
+       0x8fff, 0x1040, 0x28d5, 0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078,
+       0x48a2, 0x0c7f, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294,
+       0x00ff, 0xa286, 0x0006, 0x00c0, 0x28b9, 0x6007, 0x0404, 0x0078,
+       0x28be, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f,
+       0x017e, 0x2c08, 0x1078, 0x9c38, 0x017f, 0x077f, 0x2160, 0x1078,
+       0x471b, 0x027f, 0x8210, 0x00f0, 0x2885, 0x157f, 0x017f, 0x027f,
+       0x037f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e,
+       0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x28e8, 0xd0a4, 0x0040,
+       0x28e8, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x1078, 0x9ec0,
+       0x017f, 0x027f, 0x047f, 0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e,
+       0x7280, 0x82ff, 0x0040, 0x291a, 0xa290, 0xa352, 0x2214, 0xd2ac,
+       0x00c0, 0x291a, 0x2100, 0x1078, 0x24fa, 0x81ff, 0x0040, 0x291c,
+       0x2019, 0x0001, 0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xd384, 0x0040,
+       0x290e, 0xa084, 0xff00, 0x8007, 0x0078, 0x2910, 0xa084, 0x00ff,
+       0xa116, 0x0040, 0x291c, 0xa096, 0x00ff, 0x0040, 0x291a, 0x8318,
+       0x0078, 0x2902, 0xa085, 0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f,
+       0x007c, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0xa180, 0xa434,
+       0x2004, 0xa065, 0x0040, 0x293b, 0x017e, 0x0c7e, 0x1078, 0x8ec0,
+       0x017f, 0x1040, 0x1328, 0x611a, 0x1078, 0x2813, 0x1078, 0x753d,
+       0x017f, 0x1078, 0x44bc, 0x127f, 0x0c7f, 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, 0x8000, 0x2071,
+       0xa381, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e,
+       0x7033, 0xa391, 0x7037, 0xa391, 0x7007, 0x0001, 0x2061, 0xa3d1,
+       0x6003, 0x0002, 0x007c, 0x0090, 0x2a66, 0x0068, 0x2a66, 0x2071,
+       0xa381, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2a66, 0x2a60, 0x7820,
+       0xa08e, 0x0069, 0x00c0, 0x2b56, 0x0079, 0x2aea, 0x007c, 0x2071,
+       0xa381, 0x7004, 0x0079, 0x2a6c, 0x2a70, 0x2a71, 0x2a7b, 0x2a8d,
+       0x007c, 0x0090, 0x2a7a, 0x0068, 0x2a7a, 0x2b78, 0x7818, 0xd084,
+       0x0040, 0x2a99, 0x007c, 0x2b78, 0x2061, 0xa3d1, 0x6008, 0xa08e,
+       0x0100, 0x0040, 0x2a88, 0xa086, 0x0200, 0x0040, 0x2b4e, 0x007c,
+       0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068, 0x6834,
+       0xa086, 0x0103, 0x0040, 0x2a95, 0x007c, 0x2a60, 0x2b78, 0x7018,
+       0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, 0x2aa2, 0x61b8,
+       0x0079, 0x2aaa, 0x2100, 0xa08a, 0x003f, 0x00c8, 0x2b4a, 0x61b8,
+       0x0079, 0x2aea, 0x2b2c, 0x2b5e, 0x2b66, 0x2b6a, 0x2b72, 0x2b78,
+       0x2b7c, 0x2b88, 0x2b8c, 0x2b96, 0x2b9a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b9e, 0x2b4a, 0x2bae, 0x2bc5, 0x2bdc, 0x2c58, 0x2c5d, 0x2c8a,
+       0x2ce4, 0x2cf5, 0x2d13, 0x2d54, 0x2d5e, 0x2d6b, 0x2d7e, 0x2d9d,
+       0x2da6, 0x2de3, 0x2de9, 0x2b4a, 0x2e05, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2e0c, 0x2e16, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2e1e, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2e30, 0x2e47, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2e59, 0x2eb0, 0x2f0e, 0x2f1f, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x38f1, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2b96, 0x2b9a, 0x2f36, 0x2b4a, 0x2f43, 0x397d,
+       0x39da, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2f90, 0x30c5, 0x30e1, 0x30ed, 0x3150, 0x31a9,
+       0x31b4, 0x31f3, 0x3202, 0x3211, 0x3214, 0x2f47, 0x3238, 0x3284,
+       0x3291, 0x33a2, 0x34cd, 0x34f7, 0x3604, 0x3614, 0x3621, 0x365b,
+       0x372a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x3792, 0x37ae, 0x3828,
+       0x38e2, 0x713c, 0x0078, 0x2b2c, 0x2021, 0x4000, 0x1078, 0x3553,
+       0x127e, 0x2091, 0x8000, 0x0068, 0x2b39, 0x7818, 0xd084, 0x0040,
+       0x2b3c, 0x127f, 0x0078, 0x2b30, 0x7c22, 0x7926, 0x7a2a, 0x7b2e,
+       0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000,
+       0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x2b2e, 0x2021, 0x4002,
+       0x0078, 0x2b2e, 0x2021, 0x4003, 0x0078, 0x2b2e, 0x2021, 0x4005,
+       0x0078, 0x2b2e, 0x2021, 0x4006, 0x0078, 0x2b2e, 0xa02e, 0x2520,
+       0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3562, 0x7823, 0x0004,
+       0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930,
+       0x0078, 0x3566, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, 0x2b2c,
+       0x7924, 0x2114, 0x0078, 0x2b2c, 0x2099, 0x0009, 0x20a1, 0x0009,
+       0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078, 0x2b2c,
+       0x7824, 0x2060, 0x0078, 0x2ba0, 0x2009, 0x0001, 0x2011, 0x0013,
+       0x2019, 0x0010, 0x783b, 0x0017, 0x0078, 0x2b2c, 0x7d38, 0x7c3c,
+       0x0078, 0x2b60, 0x7d38, 0x7c3c, 0x0078, 0x2b6c, 0x2061, 0x1000,
+       0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, 0x2ba2,
+       0x2010, 0xa005, 0x0040, 0x2b2c, 0x0078, 0x2b52, 0x2069, 0xa351,
+       0x7824, 0x7930, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a,
+       0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a,
+       0x685e, 0x1078, 0x4dbd, 0x0078, 0x2b2c, 0x2069, 0xa351, 0x7824,
+       0x7934, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a, 0x684e,
+       0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e,
+       0x1078, 0x494d, 0x0078, 0x2b2c, 0xa02e, 0x2520, 0x81ff, 0x00c0,
+       0x2b56, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xa388,
+       0x41a1, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0020, 0x1078,
+       0x3562, 0x701b, 0x2bf4, 0x007c, 0x6834, 0x2008, 0xa084, 0x00ff,
+       0xa096, 0x0011, 0x0040, 0x2c00, 0xa096, 0x0019, 0x00c0, 0x2b56,
+       0x810f, 0xa18c, 0x00ff, 0x0040, 0x2b56, 0x710e, 0x700c, 0x8001,
+       0x0040, 0x2c31, 0x700e, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+       0x0020, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290,
+       0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078,
+       0x3562, 0x701b, 0x2c24, 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096,
+       0x0002, 0x0040, 0x2c2f, 0xa096, 0x000a, 0x00c0, 0x2b56, 0x0078,
+       0x2c06, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x436e,
+       0x00c0, 0x2c3f, 0x7007, 0x0003, 0x701b, 0x2c41, 0x007c, 0x1078,
+       0x4a60, 0x127e, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xa388,
+       0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+       0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, 0x3566,
+       0x61a0, 0x7824, 0x60a2, 0x0078, 0x2b2c, 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, 0x2b56, 0x7924, 0x810f, 0xa18c,
+       0x00ff, 0x1078, 0x4501, 0x00c0, 0x2b5a, 0x7e38, 0xa684, 0x3fff,
+       0xa082, 0x4000, 0x0048, 0x2c9e, 0x0078, 0x2b5a, 0x7c28, 0x7d2c,
+       0x1078, 0x46d6, 0xd28c, 0x00c0, 0x2ca9, 0x1078, 0x466a, 0x0078,
+       0x2cab, 0x1078, 0x46a4, 0x00c0, 0x2cd5, 0x2061, 0xaa00, 0x127e,
+       0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0040, 0x2cc3, 0x6010,
+       0xa06d, 0x0040, 0x2cc3, 0x683c, 0xa406, 0x00c0, 0x2cc3, 0x6840,
+       0xa506, 0x0040, 0x2cce, 0x127f, 0xace0, 0x0010, 0x2001, 0xa315,
+       0x2004, 0xac02, 0x00c8, 0x2b56, 0x0078, 0x2caf, 0x1078, 0x8758,
+       0x127f, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0xa00e, 0x2001, 0x0005,
+       0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cc0, 0x1078,
+       0x4982, 0x127f, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+       0x3530, 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078,
+       0x46e4, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+       0x1078, 0x3542, 0x0040, 0x2b5a, 0x1078, 0x475f, 0x0040, 0x2b56,
+       0x2019, 0x0005, 0x1078, 0x4705, 0x0040, 0x2b56, 0x7828, 0xa08a,
+       0x1000, 0x00c8, 0x2b5a, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078,
+       0x58e1, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040,
+       0x2d1d, 0x2009, 0x0001, 0x0078, 0x2d4e, 0x2029, 0x00ff, 0x644c,
+       0x2400, 0xa506, 0x0040, 0x2d48, 0x2508, 0x1078, 0x4501, 0x00c0,
+       0x2d48, 0x1078, 0x475f, 0x00c0, 0x2d33, 0x2009, 0x0002, 0x62a8,
+       0x2518, 0x0078, 0x2d4e, 0x2019, 0x0004, 0x1078, 0x4705, 0x00c0,
+       0x2d3d, 0x2009, 0x0006, 0x0078, 0x2d4e, 0x7824, 0xa08a, 0x1000,
+       0x00c8, 0x2d51, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x58e1,
+       0x8529, 0x00c8, 0x2d20, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078,
+       0x2b56, 0x127f, 0x0078, 0x2b5a, 0x1078, 0x3530, 0x0040, 0x2b5a,
+       0x1078, 0x461b, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0,
+       0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a, 0x1078, 0x460a, 0x1078,
+       0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+       0x0040, 0x2b5a, 0x1078, 0x46a7, 0x0040, 0x2b56, 0x1078, 0x43c1,
+       0x1078, 0x4663, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530,
+       0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x62a0, 0x2019,
+       0x0005, 0x0c7e, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e,
+       0x2039, 0x0000, 0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38,
+       0x077f, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530, 0x0040,
+       0x2b5a, 0x1078, 0x46d6, 0x2208, 0x0078, 0x2b2c, 0x157e, 0x0d7e,
+       0x0e7e, 0x2069, 0xa413, 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2db2,
+       0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9,
+       0x00ff, 0x2069, 0xa434, 0x2d04, 0xa075, 0x0040, 0x2dc7, 0x704c,
+       0x1078, 0x2dd1, 0xa210, 0x7080, 0x1078, 0x2dd1, 0xa318, 0x8d68,
+       0x00f0, 0x2dbb, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078,
+       0x2b2c, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x2de0, 0x2001, 0x0000,
+       0x8000, 0x2f0c, 0x81ff, 0x0040, 0x2de0, 0x2178, 0x0078, 0x2dd8,
+       0x017f, 0x0f7f, 0x007c, 0x2069, 0xa413, 0x6910, 0x62a4, 0x0078,
+       0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x614c, 0xa190, 0x293f, 0x2214,
+       0xa294, 0x00ff, 0x606c, 0xa084, 0xff00, 0xa215, 0x6368, 0x67c8,
+       0xd79c, 0x0040, 0x2dff, 0x2031, 0x0001, 0x0078, 0x2e01, 0x2031,
+       0x0000, 0x7e3a, 0x7f3e, 0x0078, 0x2b2c, 0x613c, 0x6240, 0x2019,
+       0xa5a0, 0x231c, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x6134,
+       0xa006, 0x2010, 0x2018, 0x127f, 0x0078, 0x2b2c, 0x1078, 0x3542,
+       0x0040, 0x2b5a, 0x6244, 0x6338, 0x0078, 0x2b2c, 0x613c, 0x6240,
+       0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xa351, 0x831f, 0xa305,
+       0x6816, 0x782c, 0x2069, 0xa5a0, 0x2d1c, 0x206a, 0x0078, 0x2b2c,
+       0x017e, 0x127e, 0x2091, 0x8000, 0x7824, 0x6036, 0xd094, 0x0040,
+       0x2e43, 0x7828, 0xa085, 0x0001, 0x2009, 0xa5a9, 0x200a, 0x2001,
+       0xffff, 0x1078, 0x5975, 0x127f, 0x017f, 0x0078, 0x2b2c, 0x1078,
+       0x3542, 0x0040, 0x2b5a, 0x7828, 0xa00d, 0x0040, 0x2b5a, 0x782c,
+       0xa005, 0x0040, 0x2b5a, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078,
+       0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56,
+       0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196,
+       0x00ff, 0x00c0, 0x2e70, 0x6030, 0xa085, 0xff00, 0x0078, 0x2e7f,
+       0xa182, 0x007f, 0x00c8, 0x2ea9, 0xa188, 0x293f, 0x210c, 0xa18c,
+       0x00ff, 0x6030, 0xa116, 0x0040, 0x2ea9, 0x810f, 0xa105, 0x127e,
+       0x2091, 0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2ea5,
+       0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040,
+       0x2eac, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+       0xc0fd, 0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032,
+       0x1078, 0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078,
+       0x2b56, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2ea5,
+       0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0c7e,
+       0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
+       0x00c0, 0x2ec7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2ed6, 0xa182,
+       0x007f, 0x00c8, 0x2f00, 0xa188, 0x293f, 0x210c, 0xa18c, 0x00ff,
+       0x6030, 0xa116, 0x0040, 0x2f00, 0x810f, 0xa105, 0x127e, 0x2091,
+       0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2efc, 0x601a,
+       0x600b, 0xbc05, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040, 0x2f03,
+       0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078,
+       0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2b56,
+       0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2efc, 0x6830,
+       0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x2061, 0xa62d,
+       0x127e, 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2f1c, 0x6104,
+       0x6208, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x81ff,
+       0x00c0, 0x2b56, 0x127e, 0x2091, 0x8000, 0x6244, 0x6060, 0xa202,
+       0x0048, 0x2f33, 0xa085, 0x0001, 0x1078, 0x2500, 0x1078, 0x3bf5,
+       0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x127e, 0x2091,
+       0x8000, 0x20a9, 0x0011, 0x2001, 0xa340, 0x20a0, 0xa006, 0x40a4,
+       0x127f, 0x0078, 0x2b2c, 0x7d38, 0x7c3c, 0x0078, 0x2bde, 0x7824,
+       0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2b56, 0x624c, 0xa084,
+       0xff00, 0x8007, 0xa206, 0x00c0, 0x2f5f, 0x2001, 0xa340, 0x2009,
+       0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566, 0x81ff,
+       0x00c0, 0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518,
+       0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+       0x1078, 0x8b85, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x2f81,
+       0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0xad80, 0x000e,
+       0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566,
+       0x1078, 0x3518, 0x0040, 0x2b56, 0x1078, 0x421a, 0x2009, 0x001c,
+       0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x2fa1,
+       0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040, 0x2b5a, 0x6804,
+       0xd0ac, 0x0040, 0x2fae, 0xd0a4, 0x0040, 0x2b5a, 0xd094, 0x0040,
+       0x2fb9, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c, 0xffdf, 0x6106,
+       0x0c7f, 0xd08c, 0x0040, 0x2fc4, 0x0c7e, 0x2061, 0x0100, 0x6104,
+       0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100, 0x210c, 0xa18a,
+       0x0002, 0x0048, 0x2fd9, 0xd084, 0x0040, 0x2fd9, 0x6a28, 0xa28a,
+       0x007f, 0x00c8, 0x2b5a, 0xa288, 0x293f, 0x210c, 0xa18c, 0x00ff,
+       0x6152, 0xd0dc, 0x0040, 0x2fe2, 0x6828, 0xa08a, 0x007f, 0x00c8,
+       0x2b5a, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0048, 0x2b5a, 0xa08a,
+       0x0841, 0x00c8, 0x2b5a, 0xa084, 0x0007, 0x00c0, 0x2b5a, 0x680c,
+       0xa005, 0x0040, 0x2b5a, 0x6810, 0xa005, 0x0040, 0x2b5a, 0x6848,
+       0x6940, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x684c,
+       0x6944, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x6804,
+       0xd0fc, 0x0040, 0x3038, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+       0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399,
+       0x0000, 0x1078, 0x3562, 0x701b, 0x301e, 0x007c, 0xade8, 0x000d,
+       0x20a9, 0x0014, 0x2d98, 0x2069, 0xa36d, 0x2da0, 0x53a3, 0x7010,
+       0xa0e8, 0x000d, 0x2001, 0xa371, 0x200c, 0xd1e4, 0x0040, 0x3038,
+       0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00, 0x6006, 0x0c7f,
+       0x20a9, 0x001c, 0x2d98, 0x2069, 0xa351, 0x2da0, 0x53a3, 0x6814,
+       0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, 0x00ff, 0x6042, 0x1078,
+       0x4dbd, 0x1078, 0x48dd, 0x1078, 0x494d, 0x6000, 0xa086, 0x0000,
+       0x00c0, 0x30c3, 0x6808, 0x602a, 0x1078, 0x218b, 0x6818, 0x691c,
+       0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+       0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x3070, 0x6830, 0x6934,
+       0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078, 0x3072,
+       0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078, 0x59a8,
+       0x6904, 0xd1fc, 0x0040, 0x30a5, 0x0c7e, 0x2009, 0x0000, 0x20a9,
+       0x0001, 0x6b70, 0xd384, 0x0040, 0x30a2, 0x0078, 0x308c, 0x839d,
+       0x00c8, 0x30a2, 0x3508, 0x8109, 0x1078, 0x5364, 0x6878, 0x6016,
+       0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff,
+       0x6006, 0x8108, 0x00c0, 0x30a0, 0x6003, 0x0003, 0x0078, 0x30a2,
+       0x6003, 0x0001, 0x00f0, 0x3087, 0x0c7f, 0x0c7e, 0x2061, 0x0100,
+       0x602f, 0x0040, 0x602f, 0x0000, 0x0c7f, 0x1078, 0x3784, 0x0040,
+       0x30b3, 0x1078, 0x2500, 0x60bc, 0xa005, 0x0040, 0x30bf, 0x6003,
+       0x0001, 0x2091, 0x301d, 0x1078, 0x4171, 0x0078, 0x30c3, 0x6003,
+       0x0004, 0x2091, 0x301d, 0x0078, 0x2b2c, 0x6000, 0xa086, 0x0000,
+       0x0040, 0x2b56, 0x2069, 0xa351, 0x7830, 0x6842, 0x7834, 0x6846,
+       0x6804, 0xd0fc, 0x0040, 0x30d8, 0x2009, 0x0030, 0x0078, 0x30da,
+       0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+       0x3566, 0xa006, 0x1078, 0x2500, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+       0x421a, 0x1078, 0x4171, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+       0x6180, 0x81ff, 0x0040, 0x3107, 0x703f, 0x0000, 0x2001, 0xa9c0,
+       0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e, 0x2091,
+       0x8000, 0x1078, 0x3566, 0x701b, 0x2b29, 0x127f, 0x007c, 0x703f,
+       0x0001, 0x0d7e, 0x2069, 0xa9c0, 0x20a9, 0x0040, 0x20a1, 0xa9c0,
+       0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x293f, 0x210c, 0xa18c,
+       0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, 0x0040,
+       0x3139, 0x1078, 0x4501, 0x00c0, 0x3139, 0x6014, 0x821c, 0x0048,
+       0x3131, 0xa398, 0xa9c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0078,
+       0x3138, 0xa398, 0xa9c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a,
+       0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x3140, 0x0078, 0x311d,
+       0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9, 0x0040,
+       0x20a1, 0xa9c0, 0x2099, 0xa9c0, 0x1078, 0x41be, 0x0078, 0x30f6,
+       0x1078, 0x3542, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f,
+       0x00c0, 0x315e, 0x2009, 0x0002, 0x0078, 0x2b56, 0x2001, 0xa352,
+       0x2004, 0xd0b4, 0x0040, 0x3185, 0x6000, 0xd08c, 0x00c0, 0x3185,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3185, 0x6837,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8bd9, 0x00c0, 0x317c,
+       0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3181,
+       0x007c, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x20a9, 0x002b, 0x2c98,
+       0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006,
+       0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x41be, 0x20a9, 0x0004,
+       0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078, 0x41be,
+       0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+       0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a,
+       0x1078, 0x46ef, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x7828,
+       0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x1078, 0x3542, 0x0040, 0x2b5a,
+       0x1078, 0x475f, 0x0040, 0x2b56, 0x2019, 0x0004, 0x1078, 0x4705,
+       0x7924, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x0078, 0x2b2c, 0xa186,
+       0x00ff, 0x0040, 0x31d7, 0x1078, 0x31e7, 0x0078, 0x31e6, 0x2029,
+       0x007e, 0x2061, 0xa300, 0x644c, 0x2400, 0xa506, 0x0040, 0x31e3,
+       0x2508, 0x1078, 0x31e7, 0x8529, 0x00c8, 0x31dc, 0x007c, 0x1078,
+       0x4501, 0x00c0, 0x31f2, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108,
+       0x1078, 0x58e1, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+       0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46fa,
+       0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+       0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46e4, 0x0078,
+       0x2b2c, 0x6100, 0x0078, 0x2b2c, 0x1078, 0x3542, 0x0040, 0x2b5a,
+       0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0d7e,
+       0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x3228, 0xace8, 0x0006,
+       0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f,
+       0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x2b2c,
+       0xa006, 0x1078, 0x2500, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+       0x0040, 0x3245, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x421a, 0x7828,
+       0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x7924, 0xa18c, 0xff00, 0x810f,
+       0xa186, 0x00ff, 0x0040, 0x325b, 0xa182, 0x007f, 0x00c8, 0x2b5a,
+       0x2100, 0x1078, 0x24fa, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000,
+       0x2061, 0xa5be, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x0100,
+       0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090,
+       0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078, 0x596c,
+       0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x127f,
+       0x0c7f, 0x027f, 0x0078, 0x2b2c, 0x7924, 0xa18c, 0xff00, 0x810f,
+       0x0c7e, 0x1078, 0x4499, 0x2c08, 0x0c7f, 0x00c0, 0x2b5a, 0x0078,
+       0x2b2c, 0x81ff, 0x0040, 0x3298, 0x2009, 0x0001, 0x0078, 0x2b56,
+       0x60c8, 0xd09c, 0x00c0, 0x32a0, 0x2009, 0x0005, 0x0078, 0x2b56,
+       0x1078, 0x3518, 0x00c0, 0x32a8, 0x2009, 0x0002, 0x0078, 0x2b56,
+       0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b,
+       0x32b2, 0x007c, 0x2009, 0x0080, 0x1078, 0x4501, 0x00c0, 0x32bf,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x32c3, 0x2021,
+       0x400a, 0x0078, 0x2b2e, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08,
+       0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040,
+       0x3336, 0xa0be, 0x0112, 0x0040, 0x3336, 0xa0be, 0x0113, 0x0040,
+       0x3336, 0xa0be, 0x0114, 0x0040, 0x3336, 0xa0be, 0x0117, 0x0040,
+       0x3336, 0xa0be, 0x011a, 0x0040, 0x3336, 0xa0be, 0x0121, 0x0040,
+       0x332c, 0xa0be, 0x0131, 0x0040, 0x332c, 0xa0be, 0x0171, 0x0040,
+       0x3336, 0xa0be, 0x0173, 0x0040, 0x3336, 0xa0be, 0x01a1, 0x00c0,
+       0x32fe, 0x6830, 0x8007, 0x6832, 0x0078, 0x333c, 0xa0be, 0x0212,
+       0x0040, 0x3332, 0xa0be, 0x0213, 0x0040, 0x3332, 0xa0be, 0x0214,
+       0x0040, 0x3324, 0xa0be, 0x0217, 0x0040, 0x331e, 0xa0be, 0x021a,
+       0x00c0, 0x3317, 0x6838, 0x8007, 0x683a, 0x0078, 0x3336, 0xa0be,
+       0x0300, 0x0040, 0x3336, 0x0d7f, 0x0078, 0x2b5a, 0xad80, 0x0010,
+       0x20a9, 0x0007, 0x1078, 0x337e, 0xad80, 0x000e, 0x20a9, 0x0001,
+       0x1078, 0x337e, 0x0078, 0x3336, 0xad80, 0x000c, 0x1078, 0x338c,
+       0x0078, 0x333c, 0xad80, 0x000e, 0x1078, 0x338c, 0xad80, 0x000c,
+       0x20a9, 0x0001, 0x1078, 0x337e, 0x0c7e, 0x1078, 0x3518, 0x0040,
+       0x336f, 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,
+       0x6804, 0x2068, 0x1078, 0x8ba1, 0x00c0, 0x336a, 0x2009, 0x0003,
+       0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3375, 0x007c, 0x0c7f,
+       0x0d7f, 0x2009, 0x0002, 0x0078, 0x2b56, 0x6820, 0xa086, 0x8001,
+       0x00c0, 0x2b2c, 0x2009, 0x0004, 0x0078, 0x2b56, 0x017e, 0x2008,
+       0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108,
+       0x00f0, 0x3380, 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, 0x33a9, 0x2009, 0x0001, 0x0078,
+       0x2b56, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080,
+       0x0048, 0x2b5a, 0xa182, 0x00ff, 0x00c8, 0x2b5a, 0x7a2c, 0x7b28,
+       0x6068, 0xa306, 0x00c0, 0x33c4, 0x606c, 0xa24e, 0x0040, 0x2b5a,
+       0xa9cc, 0xff00, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x346d, 0x2c68,
+       0x0c7f, 0x0040, 0x33fc, 0xa0c6, 0x4000, 0x00c0, 0x33e2, 0x0c7e,
+       0x007e, 0x2d60, 0x2009, 0x0000, 0x1078, 0x47cb, 0x00c0, 0x33d9,
+       0xc185, 0x6000, 0xd0bc, 0x0040, 0x33de, 0xc18d, 0x007f, 0x0c7f,
+       0x0078, 0x33f9, 0xa0c6, 0x4007, 0x00c0, 0x33e9, 0x2408, 0x0078,
+       0x33f9, 0xa0c6, 0x4008, 0x00c0, 0x33f1, 0x2708, 0x2610, 0x0078,
+       0x33f9, 0xa0c6, 0x4009, 0x00c0, 0x33f7, 0x0078, 0x33f9, 0x2001,
+       0x4006, 0x2020, 0x0078, 0x2b2e, 0x2d00, 0x7022, 0x017e, 0x0b7e,
+       0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x74d7, 0x0040, 0x3442, 0x2d00,
+       0x601a, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x2e58,
+       0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2b70, 0x00c0,
+       0x3423, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x2009,
+       0x0002, 0x0078, 0x2b56, 0x6837, 0x0000, 0x2d00, 0x6012, 0x6833,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x2813, 0x127f, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b,
+       0x2001, 0x0002, 0x1078, 0x443f, 0x2009, 0x0002, 0x1078, 0x756c,
+       0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x00c0, 0x344c,
+       0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3451,
+       0x007c, 0x6830, 0xa086, 0x0100, 0x7020, 0x2060, 0x00c0, 0x345f,
+       0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0078, 0x2b56, 0x2009,
+       0x0000, 0x1078, 0x47cb, 0x00c0, 0x3466, 0xc185, 0x6000, 0xd0bc,
+       0x0040, 0x346b, 0xc18d, 0x0078, 0x2b2c, 0x0e7e, 0x0d7e, 0x2029,
+       0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xa4b4, 0x2e04,
+       0xa005, 0x00c0, 0x3482, 0x2100, 0xa406, 0x00c0, 0x34b3, 0x2428,
+       0x0078, 0x34b3, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0, 0x34a4,
+       0x6e14, 0x2600, 0xa206, 0x00c0, 0x34a4, 0x2400, 0xa106, 0x00c0,
+       0x34a0, 0x2d60, 0xd884, 0x0040, 0x34c8, 0x6004, 0xa084, 0x00ff,
+       0xa086, 0x0006, 0x00c0, 0x34c8, 0x2001, 0x4000, 0x0078, 0x34c9,
+       0x2001, 0x4007, 0x0078, 0x34c9, 0x2400, 0xa106, 0x00c0, 0x34b3,
+       0x6e14, 0x87ff, 0x00c0, 0x34af, 0x86ff, 0x0040, 0x347f, 0x2001,
+       0x4008, 0x0078, 0x34c9, 0x8420, 0x8e70, 0x00f0, 0x3477, 0x85ff,
+       0x00c0, 0x34c2, 0x2001, 0x4009, 0x0078, 0x34c9, 0x2001, 0x0001,
+       0x0078, 0x34c9, 0x1078, 0x4499, 0x00c0, 0x34be, 0x6312, 0x6216,
+       0xa006, 0xa005, 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2b56,
+       0x1078, 0x3518, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x7824, 0xa005, 0x0040, 0x2b5a, 0xa096, 0x00ff, 0x0040,
+       0x34e5, 0xa092, 0x0004, 0x00c8, 0x2b5a, 0x2010, 0x2d18, 0x1078,
+       0x27c2, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x34f0, 0x007c,
+       0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x7924,
+       0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, 0x2b5a, 0xa182,
+       0x00ff, 0x00c8, 0x2b5a, 0x127e, 0x2091, 0x8000, 0x1078, 0x8a89,
+       0x00c0, 0x3515, 0xa190, 0xa434, 0x2204, 0xa065, 0x0040, 0x3515,
+       0x1078, 0x4235, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b56,
+       0x1078, 0x1381, 0x0040, 0x352f, 0xa006, 0x6802, 0x7010, 0xa005,
+       0x00c0, 0x3527, 0x2d00, 0x7012, 0x7016, 0x0078, 0x352d, 0x7014,
+       0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c,
+       0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501, 0x00c0, 0x353f,
+       0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x3540, 0xa066,
+       0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+       0x00c0, 0x3550, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x3551,
+       0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x355e,
+       0x2168, 0x6904, 0x1078, 0x139a, 0x0078, 0x3555, 0x7112, 0x7116,
+       0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x3568, 0x2031, 0x0000,
+       0x2061, 0xa3d1, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e,
+       0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x2b2c,
+       0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
+       0xa38f, 0x2004, 0xa005, 0x00c0, 0x3594, 0x0068, 0x3594, 0x7818,
+       0xd084, 0x00c0, 0x3594, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001,
+       0x2091, 0x4080, 0x0078, 0x35b9, 0x017e, 0x0c7e, 0x0e7e, 0x2071,
+       0xa381, 0x7138, 0xa182, 0x0008, 0x0048, 0x35a2, 0x7030, 0x2060,
+       0x0078, 0x35b3, 0x7030, 0xa0e0, 0x0008, 0xac82, 0xa3d1, 0x0048,
+       0x35ab, 0x2061, 0xa391, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x35b1,
+       0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f,
+       0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0xa381, 0x7038,
+       0xa005, 0x0040, 0x35f5, 0x127e, 0x2091, 0x8000, 0x0068, 0x35f4,
+       0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x35f3, 0x0c7e,
+       0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a,
+       0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005,
+       0x00c0, 0x35e9, 0x7033, 0xa391, 0x7037, 0xa391, 0x0c7f, 0x0078,
+       0x35f3, 0xac80, 0x0008, 0xa0fa, 0xa3d1, 0x0048, 0x35f1, 0x2001,
+       0xa391, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e,
+       0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x3602, 0x2011, 0x8014,
+       0x1078, 0x3579, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x127e,
+       0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x1078,
+       0x4171, 0x127f, 0x0078, 0x2b2c, 0x7824, 0x2008, 0xa18c, 0xfffd,
+       0x00c0, 0x361f, 0x61d4, 0xa10d, 0x61d6, 0x0078, 0x2b2c, 0x0078,
+       0x2b5a, 0x81ff, 0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x00c0,
+       0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x2b56, 0x1078,
+       0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+       0x00c0, 0x363e, 0x7828, 0xa005, 0x0040, 0x2b2c, 0x0c7e, 0x1078,
+       0x3518, 0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6833, 0x0000,
+       0x6838, 0xc0fd, 0x683a, 0x1078, 0x8c4d, 0x0040, 0x2b56, 0x7007,
+       0x0003, 0x701b, 0x3654, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040,
+       0x2b56, 0x0078, 0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003,
+       0x00c0, 0x2b56, 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078,
+       0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023,
+       0x0000, 0x702f, 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078,
+       0x4501, 0x00c0, 0x36d8, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006,
+       0x0040, 0x3688, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x36d8,
+       0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x3695, 0x1078, 0x47cb,
+       0x00c0, 0x3695, 0xd79c, 0x0040, 0x36d8, 0xd794, 0x00c0, 0x369b,
+       0xd784, 0x0040, 0x36a7, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+       0x0004, 0x53a3, 0x1078, 0x338c, 0xd794, 0x0040, 0x36b0, 0xac80,
+       0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x338c,
+       0x21a2, 0xd794, 0x0040, 0x36d0, 0xac80, 0x0000, 0x2098, 0x94a0,
+       0x20a9, 0x0002, 0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80,
+       0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x53a3, 0x1078, 0x337e,
+       0xac80, 0x0026, 0x2098, 0x20a9, 0x0002, 0x53a3, 0x0078, 0x36d1,
+       0x94a0, 0xd794, 0x0040, 0x36d6, 0xa6b0, 0x000b, 0xa6b0, 0x0005,
+       0x8108, 0xd78c, 0x0040, 0x36e2, 0xa186, 0x0100, 0x0040, 0x36f3,
+       0x0078, 0x36e6, 0xa186, 0x007e, 0x0040, 0x36f3, 0xd794, 0x0040,
+       0x36ed, 0xa686, 0x0020, 0x0078, 0x36ef, 0xa686, 0x0028, 0x0040,
+       0x36fc, 0x0078, 0x3677, 0x86ff, 0x00c0, 0x36fa, 0x7120, 0x810b,
+       0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022,
+       0x772a, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e,
+       0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007,
+       0x0002, 0x701b, 0x3714, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3726,
+       0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0xa3d1,
+       0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3677, 0x7120, 0x810b,
+       0x0078, 0x2b2c, 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38,
+       0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502,
+       0x0048, 0x2b5a, 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+       0xa502, 0x0048, 0x2b5a, 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020,
+       0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa284, 0x00ff, 0xa0e2,
+       0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa384, 0xff00,
+       0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a,
+       0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048,
+       0x2b5a, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+       0xa502, 0x0048, 0x2b5a, 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048,
+       0x2b5a, 0xa502, 0x0048, 0x2b5a, 0x2061, 0xa5a3, 0x6102, 0x6206,
+       0x630a, 0x640e, 0x0078, 0x2b2c, 0x007e, 0x2001, 0xa352, 0x2004,
+       0xd0cc, 0x007f, 0x007c, 0x007e, 0x2001, 0xa371, 0x2004, 0xd0bc,
+       0x007f, 0x007c, 0x6160, 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x379b,
+       0x7926, 0x0078, 0x2b2c, 0x83ff, 0x00c0, 0x2b5a, 0x2001, 0xfff0,
+       0xa200, 0x00c8, 0x2b5a, 0x2019, 0xffff, 0x6064, 0xa302, 0xa200,
+       0x0048, 0x2b5a, 0x7926, 0x6262, 0x0078, 0x2b2c, 0x2001, 0xa300,
+       0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x7c28, 0x7d24, 0x7e38,
+       0x7f2c, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2019,
+       0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026,
+       0x20a0, 0xa1e0, 0xa434, 0x2c64, 0x8cff, 0x0040, 0x37e8, 0x6004,
+       0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x37dd, 0x6004, 0xa084,
+       0xff00, 0xa086, 0x0600, 0x00c0, 0x37e8, 0x6014, 0x20a2, 0x94a0,
+       0x6010, 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002,
+       0x8108, 0xa182, 0x00ff, 0x0040, 0x37f3, 0xa386, 0x002a, 0x0040,
+       0x37fc, 0x0078, 0x37c9, 0x83ff, 0x00c0, 0x37fa, 0x7120, 0x810c,
+       0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022,
+       0x2061, 0xa3d1, 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426,
+       0x652a, 0x662e, 0x6732, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002,
+       0x701b, 0x3813, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3824, 0x711c,
+       0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xa3d1, 0x6424, 0x6528,
+       0x662c, 0x6730, 0x0078, 0x37c9, 0x7120, 0x810c, 0x0078, 0x2b2c,
+       0x81ff, 0x00c0, 0x2b56, 0x60c8, 0xd09c, 0x0040, 0x2b56, 0x1078,
+       0x3518, 0x0040, 0x2b56, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x1078, 0x3562, 0x701b, 0x383d, 0x007c, 0x0d7e, 0xade8, 0x000d,
+       0x6828, 0xa0be, 0x7000, 0x0040, 0x3850, 0xa0be, 0x7100, 0x0040,
+       0x3850, 0xa0be, 0x7200, 0x0040, 0x3850, 0x0d7f, 0x0078, 0x2b5a,
+       0x6820, 0x6924, 0x1078, 0x24e3, 0x00c0, 0x387b, 0x1078, 0x4499,
+       0x00c0, 0x387b, 0x7122, 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078,
+       0x3518, 0x0040, 0x387b, 0x1078, 0x3518, 0x0040, 0x387b, 0x0c7f,
+       0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000,
+       0x6804, 0x2068, 0x1078, 0x8bbd, 0x0040, 0x2b56, 0x7007, 0x0003,
+       0x701b, 0x387e, 0x007c, 0x0d7f, 0x0078, 0x2b56, 0x7120, 0x1078,
+       0x2921, 0x6820, 0xa086, 0x8001, 0x0040, 0x2b56, 0x2d00, 0x701e,
+       0x6804, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0,
+       0x1078, 0x41be, 0x007f, 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10,
+       0x6d14, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6,
+       0x7000, 0x00c0, 0x38a5, 0x0078, 0x38a9, 0xa7c6, 0x7100, 0x00c0,
+       0x38b1, 0xa6c2, 0x0004, 0x0048, 0x2b5a, 0x2009, 0x0004, 0x0078,
+       0x3566, 0xa7c6, 0x7200, 0x00c0, 0x2b5a, 0xa6c2, 0x0054, 0x0048,
+       0x2b5a, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532,
+       0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x38c8, 0x007c,
+       0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002,
+       0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x41be, 0x007f,
+       0x2009, 0x002a, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530,
+       0x0078, 0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+       0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x4710, 0x0078,
+       0x2b2c, 0x7824, 0xd084, 0x0040, 0x3150, 0x1078, 0x3542, 0x0040,
+       0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x00c0, 0x3903, 0x2009,
+       0x0002, 0x0078, 0x2b56, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+       0x0040, 0x3910, 0xa08e, 0x0004, 0x0040, 0x3910, 0xa08e, 0x0005,
+       0x00c0, 0x3934, 0x2001, 0xa352, 0x2004, 0xd0b4, 0x0040, 0x3185,
+       0x6000, 0xd08c, 0x00c0, 0x3185, 0x6837, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x1078, 0x8bd9, 0x00c0, 0x3929, 0x2009, 0x0003, 0x0078,
+       0x2b56, 0x7007, 0x0003, 0x701b, 0x392e, 0x007c, 0x1078, 0x3542,
+       0x0040, 0x2b5a, 0x0078, 0x3185, 0x2009, 0xa32e, 0x210c, 0x81ff,
+       0x0040, 0x393e, 0x2009, 0x0001, 0x0078, 0x2b56, 0x2001, 0xa300,
+       0x2004, 0xa086, 0x0003, 0x0040, 0x3949, 0x2009, 0x0007, 0x0078,
+       0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x0040, 0x3953, 0x2009,
+       0x0008, 0x0078, 0x2b56, 0x609c, 0xd0a4, 0x00c0, 0x395a, 0xd0ac,
+       0x00c0, 0x3185, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x1078, 0x8c4d, 0x00c0, 0x3969, 0x2009, 0x0003, 0x0078,
+       0x2b56, 0x7007, 0x0003, 0x701b, 0x396e, 0x007c, 0x6830, 0xa086,
+       0x0100, 0x00c0, 0x3977, 0x2009, 0x0004, 0x0078, 0x2b56, 0x1078,
+       0x3542, 0x0040, 0x2b5a, 0x0078, 0x3912, 0x81ff, 0x2009, 0x0001,
+       0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0,
+       0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x00c0,
+       0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff,
+       0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078,
+       0x3518, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2b56, 0x6837, 0x0000,
+       0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00,
+       0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x39bc, 0xc0ed, 0x6952,
+       0x792c, 0x6956, 0x0078, 0x39c5, 0xa28e, 0x0100, 0x00c0, 0x2b5a,
+       0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078, 0x8df6,
+       0x2009, 0x0003, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x39d1,
+       0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040, 0x2b56,
+       0x0078, 0x2b2c, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2b56, 0x6000,
+       0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2b56, 0x1078, 0x3542,
+       0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009,
+       0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2009,
+       0x0002, 0x0040, 0x2b56, 0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c,
+       0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x3a08, 0x007c,
+       0x0d7e, 0xade8, 0x000f, 0x6800, 0xa086, 0x0500, 0x00c0, 0x3a1b,
+       0x6804, 0xa005, 0x00c0, 0x3a1b, 0x6808, 0xa084, 0xff00, 0x00c0,
+       0x3a1b, 0x0078, 0x3a1e, 0x0d7f, 0x00c0, 0x2b5a, 0x0d7f, 0x6837,
+       0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e, 0x1078,
+       0x3542, 0x00c0, 0x3a2e, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x8e52,
+       0x2009, 0x0003, 0x0c7f, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b,
+       0x3a3a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040,
+       0x2b56, 0x0078, 0x2b2c, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100,
+       0x2071, 0xa300, 0x6044, 0xd0a4, 0x00c0, 0x3a6c, 0xd084, 0x0040,
+       0x3a55, 0x1078, 0x3bcc, 0x0078, 0x3a68, 0xd08c, 0x0040, 0x3a5c,
+       0x1078, 0x3ae3, 0x0078, 0x3a68, 0xd094, 0x0040, 0x3a63, 0x1078,
+       0x3ab7, 0x0078, 0x3a68, 0xd09c, 0x0040, 0x3a68, 0x1078, 0x3a76,
+       0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0,
+       0x3a73, 0xc19d, 0x612a, 0x017f, 0x0078, 0x3a68, 0x624c, 0xa286,
+       0xf0f0, 0x00c0, 0x3a87, 0x6048, 0xa086, 0xf0f0, 0x0040, 0x3a87,
+       0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x3ab6, 0xa294,
+       0xff00, 0xa296, 0xf700, 0x0040, 0x3a9c, 0x7134, 0xd1a4, 0x00c0,
+       0x3a9c, 0x6240, 0xa294, 0x0010, 0x0040, 0x3a9c, 0x2009, 0x00f7,
+       0x1078, 0x41de, 0x0078, 0x3ab6, 0x6043, 0x0040, 0x6043, 0x0000,
+       0x7073, 0x0000, 0x708b, 0x0001, 0x70af, 0x0000, 0x70cb, 0x0000,
+       0x2009, 0xa9c0, 0x200b, 0x0000, 0x7083, 0x0000, 0x7077, 0x000f,
+       0x2009, 0x000f, 0x2011, 0x4122, 0x1078, 0x596c, 0x007c, 0x157e,
+       0x7074, 0xa005, 0x00c0, 0x3ae1, 0x2011, 0x4122, 0x1078, 0x58d4,
+       0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8,
+       0x6044, 0xd08c, 0x00c0, 0x3ada, 0x00f0, 0x3ac8, 0x6242, 0x7087,
+       0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
+       0x0078, 0x3ae1, 0x6242, 0x7087, 0x0000, 0x707b, 0x0000, 0x0078,
+       0x3ae1, 0x157f, 0x007c, 0x7078, 0xa08a, 0x0003, 0x00c8, 0x3aec,
+       0x1079, 0x3aef, 0x0078, 0x3aee, 0x1078, 0x1328, 0x007c, 0x3af2,
+       0x3b41, 0x3bcb, 0x0f7e, 0x707b, 0x0001, 0x20e1, 0xa000, 0x20e1,
+       0x8700, 0x1078, 0x218b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079,
+       0xa800, 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, 0xa80c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099,
+       0xa305, 0x20a1, 0xa80e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0xa812,
+       0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xa800, 0x20a1, 0x020b,
+       0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x1078,
+       0x4158, 0x0f7f, 0x707f, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000,
+       0x007c, 0x0d7e, 0x707c, 0x707f, 0x0000, 0xa025, 0x0040, 0x3bb5,
+       0x6020, 0xd0b4, 0x00c0, 0x3bb3, 0x7188, 0x81ff, 0x0040, 0x3ba2,
+       0xa486, 0x000c, 0x00c0, 0x3bad, 0xa480, 0x0018, 0x8004, 0x20a8,
+       0x2011, 0xa880, 0x2019, 0xa800, 0x220c, 0x2304, 0xa106, 0x00c0,
+       0x3b79, 0x8210, 0x8318, 0x00f0, 0x3b5c, 0x6043, 0x0004, 0x608b,
+       0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707b, 0x0002, 0x7087,
+       0x0002, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c, 0x0078,
+       0x3bb3, 0x2069, 0xa880, 0x6930, 0xa18e, 0x1101, 0x00c0, 0x3bad,
+       0x6834, 0xa005, 0x00c0, 0x3bad, 0x6900, 0xa18c, 0x00ff, 0x00c0,
+       0x3b8d, 0x6804, 0xa005, 0x0040, 0x3ba2, 0x2011, 0xa88e, 0x2019,
+       0xa305, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048, 0x3ba0,
+       0x00c0, 0x3bad, 0x8210, 0x8318, 0x00f0, 0x3b93, 0x0078, 0x3bad,
+       0x708b, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+       0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, 0x6043,
+       0x0000, 0x0078, 0x3bb5, 0x0d7f, 0x007c, 0x6020, 0xd0b4, 0x00c0,
+       0x3bb3, 0x60c3, 0x000c, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+       0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078,
+       0x6c38, 0x0078, 0x3bb3, 0x007c, 0x7084, 0xa08a, 0x001d, 0x00c8,
+       0x3bd5, 0x1079, 0x3bd8, 0x0078, 0x3bd7, 0x1078, 0x1328, 0x007c,
+       0x3c02, 0x3c11, 0x3c40, 0x3c59, 0x3c85, 0x3cb1, 0x3cdd, 0x3d13,
+       0x3d3f, 0x3d67, 0x3daa, 0x3dd4, 0x3df6, 0x3e0c, 0x3e32, 0x3e45,
+       0x3e4e, 0x3e7e, 0x3eaa, 0x3ed6, 0x3f02, 0x3f38, 0x3f7d, 0x3fac,
+       0x3fce, 0x4010, 0x4036, 0x404f, 0x4050, 0x0c7e, 0x2061, 0xa300,
+       0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006,
+       0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002,
+       0x7087, 0x0001, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+       0x007c, 0x0f7e, 0x707c, 0xa086, 0x0014, 0x00c0, 0x3c3e, 0x6043,
+       0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3c3e, 0x2079, 0xa880, 0x7a30,
+       0xa296, 0x1102, 0x00c0, 0x3c3c, 0x7834, 0xa005, 0x00c0, 0x3c3c,
+       0x7a38, 0xd2fc, 0x0040, 0x3c32, 0x70ac, 0xa005, 0x00c0, 0x3c32,
+       0x70af, 0x0001, 0x2011, 0x4129, 0x1078, 0x58d4, 0x7087, 0x0010,
+       0x1078, 0x3e4e, 0x0078, 0x3c3e, 0x1078, 0x4171, 0x0f7f, 0x007c,
+       0x7087, 0x0003, 0x6043, 0x0004, 0x2011, 0x4129, 0x1078, 0x58d4,
+       0x1078, 0x41c6, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a,
+       0x20a3, 0x0000, 0x00f0, 0x3c50, 0x60c3, 0x0014, 0x1078, 0x4158,
+       0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3c83, 0x2011, 0x4129,
+       0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3c81, 0x2079, 0xa880,
+       0x7a30, 0xa296, 0x1102, 0x00c0, 0x3c81, 0x7834, 0xa005, 0x00c0,
+       0x3c81, 0x7a38, 0xd2fc, 0x0040, 0x3c7b, 0x70ac, 0xa005, 0x00c0,
+       0x3c7b, 0x70af, 0x0001, 0x7087, 0x0004, 0x1078, 0x3c85, 0x0078,
+       0x3c83, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0005, 0x1078,
+       0x41c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+       0x1078, 0x4211, 0x00c0, 0x3ca3, 0x7070, 0xa005, 0x00c0, 0x3ca3,
+       0x714c, 0xa186, 0xffff, 0x0040, 0x3ca3, 0x1078, 0x40ea, 0x0040,
+       0x3ca3, 0x1078, 0x41f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158,
+       0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3cdb, 0x2011, 0x4129,
+       0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3cd9, 0x2079, 0xa880,
+       0x7a30, 0xa296, 0x1103, 0x00c0, 0x3cd9, 0x7834, 0xa005, 0x00c0,
+       0x3cd9, 0x7a38, 0xd2fc, 0x0040, 0x3cd3, 0x70ac, 0xa005, 0x00c0,
+       0x3cd3, 0x70af, 0x0001, 0x7087, 0x0006, 0x1078, 0x3cdd, 0x0078,
+       0x3cdb, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0007, 0x1078,
+       0x41c6, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+       0x1078, 0x4211, 0x00c0, 0x3d05, 0x7070, 0xa005, 0x00c0, 0x3d05,
+       0x7150, 0xa186, 0xffff, 0x0040, 0x3d05, 0xa180, 0x293f, 0x200c,
+       0xa18c, 0xff00, 0x810f, 0x1078, 0x40ea, 0x0040, 0x3d05, 0x1078,
+       0x378b, 0x0040, 0x3d05, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2298,
+       0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3d3d,
+       0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3d3b,
+       0x2079, 0xa880, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3d3b, 0x7834,
+       0xa005, 0x00c0, 0x3d3b, 0x7a38, 0xd2fc, 0x0040, 0x3d35, 0x70ac,
+       0xa005, 0x00c0, 0x3d35, 0x70af, 0x0001, 0x7087, 0x0008, 0x1078,
+       0x3d3f, 0x0078, 0x3d3d, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087,
+       0x0009, 0x1078, 0x41c6, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430,
+       0x1078, 0x4211, 0x00c0, 0x3d58, 0x7070, 0xa005, 0x00c0, 0x3d58,
+       0x1078, 0x4051, 0x00c0, 0x3d62, 0xa085, 0x0001, 0x1078, 0x2500,
+       0x20a9, 0x0008, 0x2099, 0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e,
+       0x707c, 0xa005, 0x0040, 0x3da8, 0x2011, 0x4129, 0x1078, 0x58d4,
+       0xa086, 0x0014, 0x00c0, 0x3da6, 0x2079, 0xa880, 0x7a30, 0xa296,
+       0x1105, 0x00c0, 0x3da6, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0,
+       0x3d91, 0x7a38, 0xd2fc, 0x0040, 0x3d8b, 0x70ac, 0xa005, 0x00c0,
+       0x3d8b, 0x70af, 0x0001, 0x7087, 0x000a, 0x1078, 0x3daa, 0x0078,
+       0x3da8, 0xa005, 0x00c0, 0x3da6, 0x7a38, 0xd2fc, 0x0040, 0x3d9e,
+       0x70ac, 0xa005, 0x00c0, 0x3d9e, 0x70af, 0x0001, 0x7083, 0x0000,
+       0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3da8, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x000b, 0x2011, 0xa80e, 0x22a0, 0x20a9,
+       0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000,
+       0x41a4, 0x1078, 0x41c6, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x1078,
+       0x4211, 0x0040, 0x3dc7, 0x2013, 0x0000, 0x0078, 0x3dcb, 0x6030,
+       0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3,
+       0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+       0x3df4, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+       0x3df2, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3df2,
+       0x7834, 0xa005, 0x00c0, 0x3df2, 0x7087, 0x000c, 0x1078, 0x3df6,
+       0x0078, 0x3df4, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x000d,
+       0x1078, 0x41c6, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099, 0xa88e,
+       0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+       0x3e30, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+       0x3e2e, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3e2e,
+       0x7834, 0xa005, 0x00c0, 0x3e2e, 0x7083, 0x0001, 0x1078, 0x41b8,
+       0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3e30, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x000f, 0x707f, 0x0000, 0x608b, 0xbc85,
+       0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0,
+       0x2011, 0x4129, 0x1078, 0x58c7, 0x007c, 0x707c, 0xa005, 0x0040,
+       0x3e4d, 0x2011, 0x4129, 0x1078, 0x58d4, 0x007c, 0x7087, 0x0011,
+       0x1078, 0x4211, 0x00c0, 0x3e67, 0x7168, 0x81ff, 0x0040, 0x3e67,
+       0x2009, 0x0000, 0x706c, 0xa084, 0x00ff, 0x1078, 0x24e3, 0xa186,
+       0x0080, 0x0040, 0x3e67, 0x2011, 0xa88e, 0x1078, 0x40ea, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x747c,
+       0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8,
+       0x53a6, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+       0xa005, 0x0040, 0x3ea8, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+       0x0014, 0x00c0, 0x3ea6, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1103,
+       0x00c0, 0x3ea6, 0x7834, 0xa005, 0x00c0, 0x3ea6, 0x7a38, 0xd2fc,
+       0x0040, 0x3ea0, 0x70ac, 0xa005, 0x00c0, 0x3ea0, 0x70af, 0x0001,
+       0x7087, 0x0012, 0x1078, 0x3eaa, 0x0078, 0x3ea8, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x0013, 0x1078, 0x41d2, 0x20a3, 0x1103,
+       0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+       0x3ec8, 0x7070, 0xa005, 0x00c0, 0x3ec8, 0x714c, 0xa186, 0xffff,
+       0x0040, 0x3ec8, 0x1078, 0x40ea, 0x0040, 0x3ec8, 0x1078, 0x41f5,
+       0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+       0xa005, 0x0040, 0x3f00, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+       0x0014, 0x00c0, 0x3efe, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1104,
+       0x00c0, 0x3efe, 0x7834, 0xa005, 0x00c0, 0x3efe, 0x7a38, 0xd2fc,
+       0x0040, 0x3ef8, 0x70ac, 0xa005, 0x00c0, 0x3ef8, 0x70af, 0x0001,
+       0x7087, 0x0014, 0x1078, 0x3f02, 0x0078, 0x3f00, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x0015, 0x1078, 0x41d2, 0x20a3, 0x1104,
+       0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+       0x3f2a, 0x7070, 0xa005, 0x00c0, 0x3f2a, 0x7150, 0xa186, 0xffff,
+       0x0040, 0x3f2a, 0xa180, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+       0x1078, 0x40ea, 0x0040, 0x3f2a, 0x1078, 0x378b, 0x0040, 0x3f2a,
+       0x1078, 0x2500, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c,
+       0x0f7e, 0x707c, 0xa005, 0x0040, 0x3f7b, 0x2011, 0x4129, 0x1078,
+       0x58d4, 0xa086, 0x0014, 0x00c0, 0x3f79, 0x2079, 0xa880, 0x7a30,
+       0xa296, 0x1105, 0x00c0, 0x3f79, 0x7834, 0x2011, 0x0100, 0xa21e,
+       0x00c0, 0x3f5e, 0x7a38, 0xd2fc, 0x0040, 0x3f5c, 0x70ac, 0xa005,
+       0x00c0, 0x3f5c, 0x70af, 0x0001, 0x0078, 0x3f6d, 0xa005, 0x00c0,
+       0x3f79, 0x7a38, 0xd2fc, 0x0040, 0x3f6b, 0x70ac, 0xa005, 0x00c0,
+       0x3f6b, 0x70af, 0x0001, 0x7083, 0x0000, 0x7a38, 0xd2f4, 0x0040,
+       0x3f73, 0x70cb, 0x0008, 0x7087, 0x0016, 0x1078, 0x3f7d, 0x0078,
+       0x3f7b, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6,
+       0x3430, 0x2011, 0xa88e, 0x7087, 0x0017, 0x1078, 0x4211, 0x00c0,
+       0x3f9d, 0x7070, 0xa005, 0x00c0, 0x3f9d, 0x1078, 0x4051, 0x00c0,
+       0x3fa7, 0xa085, 0x0001, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2099,
+       0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+       0x3fcc, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+       0x3fca, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3fca,
+       0x7834, 0xa005, 0x00c0, 0x3fca, 0x7087, 0x0018, 0x1078, 0x3fce,
+       0x0078, 0x3fcc, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0019,
+       0x1078, 0x41d2, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099,
+       0xa88e, 0x2039, 0xa80e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x1078,
+       0x4211, 0x00c0, 0x4002, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff,
+       0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x6030,
+       0x2310, 0x8214, 0xa2a0, 0xa80e, 0x2414, 0xa38c, 0x0001, 0x0040,
+       0x3ffd, 0xa294, 0xff00, 0x0078, 0x4000, 0xa294, 0x00ff, 0x8007,
+       0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c,
+       0x0f7e, 0x707c, 0xa005, 0x0040, 0x4034, 0x2011, 0x4129, 0x1078,
+       0x58d4, 0xa086, 0x0084, 0x00c0, 0x4032, 0x2079, 0xa880, 0x7a30,
+       0xa296, 0x1107, 0x00c0, 0x4032, 0x7834, 0xa005, 0x00c0, 0x4032,
+       0x7083, 0x0001, 0x1078, 0x41b8, 0x7087, 0x001a, 0x1078, 0x4036,
+       0x0078, 0x4034, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x001b,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b,
+       0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004,
+       0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c, 0x007c,
+       0x007c, 0x087e, 0x097e, 0x2029, 0xa352, 0x252c, 0x20a9, 0x0008,
+       0x2041, 0xa80e, 0x28a0, 0x2099, 0xa88e, 0x53a3, 0x20a9, 0x0008,
+       0x2011, 0x0007, 0xd5d4, 0x0040, 0x4067, 0x2011, 0x0000, 0x2800,
+       0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, 0x4079, 0xd5d4, 0x0040,
+       0x4074, 0x8210, 0x0078, 0x4075, 0x8211, 0x00f0, 0x4067, 0x0078,
+       0x40e1, 0x82ff, 0x00c0, 0x408b, 0xd5d4, 0x0040, 0x4085, 0xa1a6,
+       0x3fff, 0x0040, 0x4071, 0x0078, 0x4089, 0xa1a6, 0x3fff, 0x0040,
+       0x40e1, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4,
+       0x0040, 0x4094, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0040, 0x409b,
+       0x8423, 0x0078, 0x409c, 0x8424, 0x00c8, 0x40a9, 0xd5d4, 0x0040,
+       0x40a4, 0x8319, 0x0078, 0x40a5, 0x8318, 0x00f0, 0x4095, 0x0078,
+       0x40e1, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x00f0, 0x40ad,
+       0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, 0x40c1, 0x007e, 0x2039,
+       0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0,
+       0x40bd, 0x754e, 0xa5c8, 0x293f, 0x292c, 0xa5ac, 0x00ff, 0x6532,
+       0x60e7, 0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x2018, 0x2304,
+       0xa405, 0x201a, 0x7073, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008,
+       0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078,
+       0x40e7, 0xa006, 0x0078, 0x40e7, 0xa006, 0x1078, 0x1328, 0x097f,
+       0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a,
+       0x0010, 0x0048, 0x40f7, 0x8420, 0x8001, 0x0078, 0x40ef, 0x2118,
+       0x84ff, 0x0040, 0x4100, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x40fb,
+       0x2021, 0x0001, 0x83ff, 0x0040, 0x4109, 0x8423, 0x8319, 0x00c0,
+       0x4105, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x4121, 0xa405, 0x203a,
+       0x714e, 0xa1a0, 0x293f, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7,
+       0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x7073, 0x0001, 0xa084,
+       0x0000, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x7077, 0x0000, 0x0e7f,
+       0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002, 0x1078, 0x5975, 0x2079,
+       0x0100, 0x2071, 0x0140, 0x1078, 0x6c41, 0x7004, 0xa084, 0x4000,
+       0x0040, 0x413e, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, 0x2091,
+       0x8000, 0x2071, 0xa321, 0x2073, 0x0000, 0x7840, 0x027e, 0x017e,
+       0x2009, 0x00f7, 0x1078, 0x41de, 0x017f, 0xa094, 0x0010, 0xa285,
+       0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, 0x0f7f, 0x0e7f, 0x007c,
+       0x127e, 0x2091, 0x8000, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+       0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
+       0x1078, 0x6c38, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+       0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009,
+       0x00f7, 0x1078, 0x41de, 0x2061, 0xa5be, 0x601b, 0x0000, 0x601f,
+       0x0000, 0x2061, 0xa300, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
+       0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078,
+       0x58c7, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e,
+       0x127e, 0x2091, 0x8000, 0x2001, 0x0001, 0x1078, 0x5975, 0x2071,
+       0x0100, 0x1078, 0x6c41, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000,
+       0x0040, 0x41ae, 0x7003, 0x1000, 0x7003, 0x0000, 0x2001, 0x0001,
+       0x1078, 0x2480, 0x1078, 0x4171, 0x127f, 0x007f, 0x0e7f, 0x007c,
+       0x20a9, 0x0040, 0x20a1, 0xa9c0, 0x2099, 0xa88e, 0x3304, 0x8007,
+       0x20a2, 0x9398, 0x94a0, 0x00f0, 0x41be, 0x007c, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x2099, 0xa800, 0x20a1, 0x020b, 0x20a9, 0x000c,
+       0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+       0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e,
+       0x2061, 0x0100, 0x810f, 0x2001, 0xa32e, 0x2004, 0xa005, 0x00c0,
+       0x41ef, 0x6030, 0xa084, 0x00ff, 0xa105, 0x0078, 0x41f1, 0xa185,
+       0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c, 0x017e, 0x047e, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x4208, 0xa006, 0x2020, 0x2009,
+       0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195, 0x2102,
+       0x2019, 0x002a, 0x2009, 0x0000, 0x1078, 0x27e2, 0x047f, 0x017f,
+       0x007c, 0x007e, 0x2001, 0xa30c, 0x2004, 0xd09c, 0x0040, 0x4218,
+       0x007f, 0x007c, 0x007e, 0x017e, 0x127e, 0x2091, 0x8000, 0x2001,
+       0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x127f, 0x017f, 0x007f,
+       0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0xa434, 0xa006, 0x200a,
+       0x8108, 0x00f0, 0x422f, 0x157f, 0x007c, 0x0d7e, 0x037e, 0x157e,
+       0x137e, 0x147e, 0x2069, 0xa351, 0xa006, 0x6002, 0x6007, 0x0707,
+       0x600a, 0x600e, 0x6012, 0xa198, 0x293f, 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, 0x60ae, 0x61a2, 0x0d7e, 0x60a4,
+       0xa06d, 0x0040, 0x4275, 0x1078, 0x139a, 0x60a7, 0x0000, 0x60a8,
+       0xa06d, 0x0040, 0x427d, 0x1078, 0x139a, 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, 0x4361, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x00c8, 0x4367, 0x2001, 0xa30c, 0x2004, 0xa084, 0x0003, 0x0040,
+       0x42c2, 0x2001, 0xa30c, 0x2004, 0xd084, 0x00c0, 0x4342, 0xa188,
+       0xa434, 0x2104, 0xa065, 0x0040, 0x4342, 0x6004, 0xa084, 0x00ff,
+       0xa08e, 0x0006, 0x00c0, 0x4342, 0x6000, 0xd0c4, 0x0040, 0x4342,
+       0x0078, 0x42cf, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4326,
+       0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x432c, 0x60a4,
+       0xa00d, 0x0040, 0x42d7, 0x1078, 0x4749, 0x0040, 0x4320, 0x60a8,
+       0xa00d, 0x0040, 0x42f1, 0x1078, 0x479a, 0x00c0, 0x42f1, 0x694c,
+       0xd1fc, 0x00c0, 0x42e7, 0x1078, 0x441c, 0x0078, 0x431b, 0x1078,
+       0x43d6, 0x694c, 0xd1ec, 0x00c0, 0x431b, 0x1078, 0x460a, 0x0078,
+       0x431b, 0x694c, 0xa184, 0xa000, 0x0040, 0x430b, 0xd1ec, 0x0040,
+       0x4304, 0xd1fc, 0x0040, 0x4300, 0x1078, 0x461b, 0x0078, 0x4307,
+       0x1078, 0x461b, 0x0078, 0x430b, 0xd1fc, 0x0040, 0x430b, 0x1078,
+       0x43d6, 0x0078, 0x431b, 0x6050, 0xa00d, 0x0040, 0x4316, 0x2d00,
+       0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x431b, 0x2d00, 0x6052,
+       0x604e, 0x6803, 0x0000, 0x1078, 0x5c17, 0xa006, 0x127f, 0x007c,
+       0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001, 0x0028,
+       0x2009, 0x0000, 0x0078, 0x436b, 0xa082, 0x0006, 0x00c8, 0x4342,
+       0x60a0, 0xd0bc, 0x00c0, 0x433e, 0x6100, 0xd1fc, 0x0040, 0x42cf,
+       0x2001, 0x0029, 0x2009, 0x1000, 0x0078, 0x436b, 0x2001, 0x0028,
+       0x0078, 0x435d, 0x2009, 0xa30c, 0x210c, 0xd18c, 0x0040, 0x434c,
+       0x2001, 0x0004, 0x0078, 0x435d, 0xd184, 0x0040, 0x4353, 0x2001,
+       0x0004, 0x0078, 0x435d, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0040,
+       0x435d, 0x2009, 0x1000, 0x0078, 0x436b, 0x2009, 0x0000, 0x0078,
+       0x436b, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001,
+       0x0029, 0x2009, 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48,
+       0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x43bb, 0xa18c, 0xff00,
+       0x810f, 0xa182, 0x00ff, 0x00c8, 0x43a1, 0xa188, 0xa434, 0x2104,
+       0xa065, 0x0040, 0x43a1, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
+       0x00c0, 0x43a7, 0x684c, 0xd0ec, 0x0040, 0x4394, 0x1078, 0x461b,
+       0x1078, 0x43d6, 0x0078, 0x439c, 0x1078, 0x43d6, 0x684c, 0xd0fc,
+       0x0040, 0x439c, 0x1078, 0x460a, 0x1078, 0x4663, 0xa006, 0x0078,
+       0x43bf, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x43bf, 0xa082,
+       0x0006, 0x00c8, 0x43b5, 0x6100, 0xd1fc, 0x0040, 0x438a, 0x2001,
+       0x0029, 0x2009, 0x1000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009,
+       0x0000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005,
+       0x007c, 0x127e, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0040, 0x43cf,
+       0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x127f, 0x007c, 0x2d00,
+       0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x43cd, 0x127e, 0x2091,
+       0x8000, 0x604c, 0xa005, 0x0040, 0x43ec, 0x0e7e, 0x2071, 0xa5ab,
+       0x7004, 0xa086, 0x0002, 0x0040, 0x43f3, 0x0e7f, 0x604c, 0x6802,
+       0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803,
+       0x0000, 0x0078, 0x43ea, 0x701c, 0xac06, 0x00c0, 0x43e5, 0x604c,
+       0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x0e7f, 0x127f, 0x007c,
+       0x127e, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0040, 0x440e, 0x6800,
+       0xa005, 0x00c0, 0x440c, 0x6052, 0x604e, 0xad05, 0x127f, 0x007c,
+       0x604c, 0xa06d, 0x0040, 0x441b, 0x6800, 0xa005, 0x00c0, 0x4419,
+       0x6052, 0x604e, 0xad05, 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d,
+       0x0040, 0x4426, 0x2d00, 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086,
+       0x6082, 0x0078, 0x4425, 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000,
+       0x6218, 0x2260, 0x6200, 0xa005, 0x0040, 0x4439, 0xc285, 0x0078,
+       0x443a, 0xc284, 0x6202, 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e,
+       0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086,
+       0x0006, 0x00c0, 0x445e, 0x609c, 0xd0ac, 0x0040, 0x445e, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x445e, 0xa284, 0xff00, 0x8007,
+       0xa086, 0x0007, 0x00c0, 0x445e, 0x2011, 0x0600, 0x007f, 0xa294,
+       0xff00, 0xa215, 0x6206, 0x007e, 0xa086, 0x0006, 0x00c0, 0x446e,
+       0x6290, 0x82ff, 0x00c0, 0x446e, 0x1078, 0x1328, 0x007f, 0x0c7f,
+       0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
+       0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4490, 0x609c, 0xd0a4,
+       0x0040, 0x4490, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x4490,
+       0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, 0x4490, 0x2011, 0x0006,
+       0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f,
+       0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x44a2, 0xa085, 0x0001,
+       0x0078, 0x44ba, 0xa190, 0xa434, 0x2204, 0xa065, 0x00c0, 0x44b9,
+       0x017e, 0x0d7e, 0x1078, 0x1366, 0x2d60, 0x0d7f, 0x017f, 0x0040,
+       0x449e, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078,
+       0x4235, 0xa006, 0x027f, 0x007c, 0x127e, 0x2091, 0x8000, 0x027e,
+       0xa182, 0x00ff, 0x0048, 0x44c8, 0xa085, 0x0001, 0x0078, 0x44fe,
+       0x0d7e, 0xa190, 0xa434, 0x2204, 0xa06d, 0x0040, 0x44fc, 0x2013,
+       0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4, 0xa06d, 0x0040, 0x44da,
+       0x1078, 0x139a, 0x60a8, 0xa06d, 0x0040, 0x44e0, 0x1078, 0x139a,
+       0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac, 0x2060, 0x8cff, 0x0040,
+       0x44f8, 0x600c, 0x007e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+       0x44f3, 0x1078, 0x13aa, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x44e6,
+       0x0c7f, 0x0d7f, 0x1078, 0x139a, 0x0d7f, 0xa006, 0x027f, 0x127f,
+       0x007c, 0x017e, 0xa182, 0x00ff, 0x0048, 0x450a, 0xa085, 0x0001,
+       0x0078, 0x4511, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4506,
+       0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b,
+       0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x2069, 0xa88e,
+       0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0048, 0x4529,
+       0x603a, 0x6814, 0x6066, 0x2099, 0xa896, 0xac88, 0x000a, 0x21a0,
+       0x20a9, 0x0004, 0x53a3, 0x2099, 0xa89a, 0xac88, 0x0006, 0x21a0,
+       0x20a9, 0x0004, 0x53a3, 0x2069, 0xa8ae, 0x6808, 0x606a, 0x690c,
+       0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8,
+       0x454d, 0x2009, 0x0008, 0x0078, 0x4577, 0xa182, 0x0259, 0x00c8,
+       0x4555, 0x2009, 0x0007, 0x0078, 0x4577, 0xa182, 0x02c1, 0x00c8,
+       0x455d, 0x2009, 0x0006, 0x0078, 0x4577, 0xa182, 0x0349, 0x00c8,
+       0x4565, 0x2009, 0x0005, 0x0078, 0x4577, 0xa182, 0x0421, 0x00c8,
+       0x456d, 0x2009, 0x0004, 0x0078, 0x4577, 0xa182, 0x0581, 0x00c8,
+       0x4575, 0x2009, 0x0003, 0x0078, 0x4577, 0x2009, 0x0002, 0x6192,
+       0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x017e, 0x027e, 0x0e7e,
+       0x2071, 0xa88d, 0x2e04, 0x6896, 0x2071, 0xa88e, 0x7004, 0x689a,
+       0x701c, 0x689e, 0x6a00, 0x2009, 0xa371, 0x210c, 0xd0bc, 0x0040,
+       0x4597, 0xd1ec, 0x0040, 0x4597, 0xc2ad, 0x0078, 0x4598, 0xc2ac,
+       0xd0c4, 0x0040, 0x45a1, 0xd1e4, 0x0040, 0x45a1, 0xc2bd, 0x0078,
+       0x45a2, 0xc2bc, 0x6a02, 0x0e7f, 0x027f, 0x017f, 0x007c, 0x0d7e,
+       0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0040, 0x45cb, 0x6900,
+       0x81ff, 0x00c0, 0x45df, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x45e4,
+       0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040,
+       0x45c6, 0x8108, 0x00f0, 0x45bc, 0x1078, 0x1328, 0x260a, 0x8210,
+       0x6a06, 0x0078, 0x45df, 0x1078, 0x1381, 0x0040, 0x45e4, 0x2d00,
+       0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
+       0xffff, 0x8108, 0x00f0, 0x45d7, 0x6807, 0x0001, 0x6e12, 0xa085,
+       0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x45e1, 0x127e,
+       0x2091, 0x8000, 0x0d7e, 0x60a4, 0xa00d, 0x0040, 0x4607, 0x2168,
+       0x6800, 0xa005, 0x00c0, 0x4603, 0x1078, 0x4749, 0x00c0, 0x4607,
+       0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0048, 0x4603, 0x8001,
+       0x6806, 0x0078, 0x4607, 0x1078, 0x139a, 0x60a7, 0x0000, 0x0d7f,
+       0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x47af, 0x0078,
+       0x4613, 0x1078, 0x43c1, 0x1078, 0x46a7, 0x00c0, 0x4611, 0x1078,
+       0x4663, 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8,
+       0xa06d, 0x0040, 0x463f, 0x6950, 0x81ff, 0x00c0, 0x4653, 0x6a54,
+       0xa282, 0x0010, 0x00c8, 0x4660, 0xad88, 0x0018, 0x20a9, 0x0010,
+       0x2104, 0xa086, 0xffff, 0x0040, 0x463a, 0x8108, 0x00f0, 0x4630,
+       0x1078, 0x1328, 0x260a, 0x8210, 0x6a56, 0x0078, 0x4653, 0x1078,
+       0x1381, 0x0040, 0x4660, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88,
+       0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x464b,
+       0x6857, 0x0001, 0x6e62, 0x0078, 0x4657, 0x1078, 0x441c, 0x1078,
+       0x466d, 0x00c0, 0x4655, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c,
+       0xa006, 0x0078, 0x465d, 0x127e, 0x2091, 0x8000, 0x1078, 0x5c17,
+       0x127f, 0x007c, 0xa01e, 0x0078, 0x466f, 0x2019, 0x0001, 0xa00e,
+       0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0,
+       0x468d, 0x8dff, 0x0040, 0x46a2, 0x83ff, 0x0040, 0x4685, 0x6848,
+       0xa606, 0x0040, 0x4692, 0x0078, 0x468d, 0x683c, 0xa406, 0x00c0,
+       0x468d, 0x6840, 0xa506, 0x0040, 0x4692, 0x2d08, 0x6800, 0x2068,
+       0x0078, 0x4679, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x469a, 0x624e,
+       0x0078, 0x469d, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x46a2,
+       0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x46a9, 0x2019,
+       0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x46d5, 0x83ff,
+       0x0040, 0x46b8, 0x6848, 0xa606, 0x0040, 0x46c5, 0x0078, 0x46c0,
+       0x683c, 0xa406, 0x00c0, 0x46c0, 0x6840, 0xa506, 0x0040, 0x46c5,
+       0x2d08, 0x6800, 0x2068, 0x0078, 0x46ac, 0x6a00, 0x6080, 0xad06,
+       0x00c0, 0x46cd, 0x6282, 0x0078, 0x46d0, 0xa180, 0x0000, 0x2202,
+       0x82ff, 0x00c0, 0x46d5, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078,
+       0x4742, 0x00c0, 0x46dd, 0x2011, 0x0001, 0x1078, 0x4793, 0x00c0,
+       0x46e3, 0xa295, 0x0002, 0x007c, 0x1078, 0x47cb, 0x0040, 0x46ec,
+       0x1078, 0x8b12, 0x0078, 0x46ee, 0xa085, 0x0001, 0x007c, 0x1078,
+       0x47cb, 0x0040, 0x46f7, 0x1078, 0x8aaa, 0x0078, 0x46f9, 0xa085,
+       0x0001, 0x007c, 0x1078, 0x47cb, 0x0040, 0x4702, 0x1078, 0x8af4,
+       0x0078, 0x4704, 0xa085, 0x0001, 0x007c, 0x1078, 0x47cb, 0x0040,
+       0x470d, 0x1078, 0x8ac6, 0x0078, 0x470f, 0xa085, 0x0001, 0x007c,
+       0x1078, 0x47cb, 0x0040, 0x4718, 0x1078, 0x8b30, 0x0078, 0x471a,
+       0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000,
+       0x6080, 0xa06d, 0x0040, 0x473a, 0x6800, 0x007e, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x007e, 0x6000, 0xd0fc,
+       0x0040, 0x4734, 0x1078, 0xa18c, 0x007f, 0x1078, 0x4982, 0x007f,
+       0x0078, 0x4721, 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f,
+       0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, 0x4749, 0xa085, 0x0001,
+       0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, 0x00c0, 0x475c, 0x20a9,
+       0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0040, 0x475c, 0x8108,
+       0x00f0, 0x4753, 0xa085, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0d7e,
+       0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x476d, 0x1078,
+       0x1381, 0x0040, 0x477f, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807,
+       0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
+       0x00f0, 0x4775, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
+       0x0078, 0x477c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d,
+       0x0040, 0x4790, 0x60a7, 0x0000, 0x1078, 0x139a, 0xa085, 0x0001,
+       0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x479a, 0xa085,
+       0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x47ad,
+       0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x47ad,
+       0x8108, 0x00f0, 0x47a4, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x4793, 0x00c0, 0x47c9, 0x200b, 0xffff,
+       0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x47c4,
+       0x8001, 0x6856, 0x0078, 0x47c8, 0x1078, 0x139a, 0x60ab, 0x0000,
+       0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71ac,
+       0x81ff, 0x00c0, 0x47e9, 0x71c8, 0xd19c, 0x0040, 0x47e9, 0x2001,
+       0x007e, 0xa080, 0xa434, 0x2004, 0xa07d, 0x0040, 0x47e9, 0x7804,
+       0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x47e9, 0x7800, 0xc0ed,
+       0x7802, 0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x480f, 0x157e,
+       0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501,
+       0x00c0, 0x4809, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+       0x0040, 0x4806, 0xa086, 0x0006, 0x00c0, 0x4809, 0x6000, 0xc0ed,
+       0x6002, 0x017f, 0x8108, 0x00f0, 0x47f5, 0x0c7f, 0x157f, 0x1078,
+       0x4897, 0x0040, 0x4818, 0x2001, 0xa59f, 0x200c, 0x0078, 0x4820,
+       0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x4824, 0x2009, 0x07d0,
+       0x2011, 0x4826, 0x1078, 0x596c, 0x0f7f, 0x007c, 0x2011, 0x4826,
+       0x1078, 0x58d4, 0x1078, 0x4897, 0x0040, 0x484e, 0x2001, 0xa4b2,
+       0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa352,
+       0x2004, 0xd0a4, 0x0040, 0x4842, 0x2009, 0x07d0, 0x2011, 0x4826,
+       0x1078, 0x596c, 0x0e7e, 0x2071, 0xa300, 0x706b, 0x0000, 0x706f,
+       0x0000, 0x1078, 0x260d, 0x0e7f, 0x0078, 0x4886, 0x157e, 0x0c7e,
+       0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0,
+       0x4880, 0x6000, 0xd0ec, 0x0040, 0x4880, 0x047e, 0x62a0, 0xa294,
+       0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6000,
+       0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700,
+       0x6006, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000,
+       0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38, 0x077f, 0x047f,
+       0x017f, 0x8108, 0x00f0, 0x4854, 0x0c7f, 0x157f, 0x007c, 0x0c7e,
+       0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818,
+       0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e,
+       0x2001, 0xa4b2, 0x2004, 0xa07d, 0x0040, 0x48a0, 0x7800, 0xd0ec,
+       0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x6200, 0xa005,
+       0x0040, 0x48ad, 0xc2fd, 0x0078, 0x48ae, 0xc2fc, 0x6202, 0x027f,
+       0x127f, 0x007c, 0x2071, 0xa413, 0x7003, 0x0001, 0x7007, 0x0000,
+       0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000,
+       0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020,
+       0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa57c, 0x7003, 0xa413,
+       0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa55c, 0x7013, 0x0020,
+       0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, 0x2071,
+       0xa534, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0xa352,
+       0x2004, 0xd0fc, 0x00c0, 0x48f7, 0x2001, 0xa352, 0x2004, 0xa00e,
+       0xd09c, 0x0040, 0x48f4, 0x8108, 0x7102, 0x0078, 0x494a, 0x2001,
+       0xa371, 0x200c, 0xa184, 0x000f, 0x2009, 0xa372, 0x210c, 0x0079,
+       0x4901, 0x48ec, 0x4922, 0x492a, 0x4935, 0x493b, 0x48ec, 0x48ec,
+       0x48ec, 0x4911, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec,
+       0x48ec, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, 0xa375,
+       0x20a1, 0xa585, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f,
+       0x0078, 0x494a, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002,
+       0x0078, 0x4930, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003,
+       0x7002, 0x7097, 0x0001, 0x0078, 0x4947, 0x7007, 0x0122, 0x2001,
+       0x0002, 0x0078, 0x493f, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002,
+       0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184,
+       0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, 0xa413,
+       0x684c, 0xa005, 0x00c0, 0x495b, 0x7028, 0xc085, 0x702a, 0xa085,
+       0x0001, 0x0078, 0x4980, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868,
+       0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844,
+       0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 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, 0x49d8,
+       0x6804, 0xa00d, 0x0040, 0x499e, 0x0d7e, 0x2071, 0xa300, 0xa016,
+       0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x00c0,
+       0x4991, 0x702e, 0x70a8, 0xa200, 0x70aa, 0x0d7f, 0x2071, 0xa413,
+       0x701c, 0xa005, 0x00c0, 0x49ea, 0x0068, 0x49e8, 0x2071, 0xa534,
+       0x7200, 0x82ff, 0x0040, 0x49e8, 0x6934, 0xa186, 0x0103, 0x00c0,
+       0x49fb, 0x6948, 0x6844, 0xa105, 0x00c0, 0x49db, 0x2009, 0x8020,
+       0x2200, 0x0079, 0x49bb, 0x49e8, 0x49c0, 0x4a18, 0x4a26, 0x49e8,
+       0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x49e8, 0x7122, 0x683c,
+       0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x2071,
+       0xa300, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa,
+       0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0, 0x49e8,
+       0x6868, 0xa005, 0x00c0, 0x49e8, 0x2009, 0x8020, 0x0078, 0x49b8,
+       0x2071, 0xa413, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012,
+       0x7018, 0xa06d, 0x711a, 0x0040, 0x49f8, 0x6902, 0x0078, 0x49f9,
+       0x711e, 0x0078, 0x49d8, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040,
+       0x4a09, 0xa186, 0x001e, 0x0040, 0x4a09, 0xa18e, 0x001f, 0x00c0,
+       0x49e8, 0x684c, 0xd0cc, 0x0040, 0x49e8, 0x6850, 0xa084, 0x00ff,
+       0xa086, 0x0001, 0x00c0, 0x49e8, 0x2009, 0x8021, 0x0078, 0x49b8,
+       0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x49e8, 0x7186, 0xae90,
+       0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x4a36, 0x7084, 0x8008,
+       0xa092, 0x000f, 0x00c8, 0x49e8, 0x7186, 0xae90, 0x0003, 0x8003,
+       0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a,
+       0x0048, 0x49cf, 0x718c, 0x7084, 0xa10a, 0x0048, 0x49cf, 0x2071,
+       0x0000, 0x7018, 0xd084, 0x00c0, 0x49cf, 0x2071, 0xa534, 0x7000,
+       0xa086, 0x0002, 0x00c0, 0x4a56, 0x1078, 0x4cd2, 0x2071, 0x0000,
+       0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf, 0x1078, 0x4cfd,
+       0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf,
+       0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80,
+       0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084, 0x00ff,
+       0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa413, 0x7004,
+       0x0079, 0x4a7a, 0x4a84, 0x4a95, 0x4ca3, 0x4ca4, 0x4ccb, 0x4cd1,
+       0x4a85, 0x4c91, 0x4c32, 0x4cb4, 0x007c, 0x127e, 0x2091, 0x8000,
+       0x0068, 0x4a94, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080,
+       0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa5be, 0x6844,
+       0xa005, 0x0050, 0x4abd, 0x00c0, 0x4abd, 0x127e, 0x2091, 0x8000,
+       0x2069, 0x0000, 0x6934, 0x2001, 0xa41f, 0x2004, 0xa10a, 0x0040,
+       0x4ab8, 0x0068, 0x4abc, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0,
+       0x4abc, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080,
+       0x2069, 0xa5be, 0x6847, 0xffff, 0x127f, 0x2069, 0xa300, 0x6844,
+       0x6960, 0xa102, 0x2069, 0xa534, 0x688a, 0x6984, 0x701c, 0xa06d,
+       0x0040, 0x4acf, 0x81ff, 0x0040, 0x4b17, 0x0078, 0x4ae5, 0x81ff,
+       0x0040, 0x4be9, 0x2071, 0xa534, 0x7184, 0x7088, 0xa10a, 0x00c8,
+       0x4ae5, 0x7190, 0x2071, 0xa5be, 0x7040, 0xa005, 0x0040, 0x4ae5,
+       0x00d0, 0x4be9, 0x7142, 0x0078, 0x4be9, 0x2071, 0xa534, 0x718c,
+       0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4c06, 0x0068,
+       0x4b9b, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4b9b, 0x2001,
+       0xffff, 0x2071, 0xa5be, 0x7042, 0x2071, 0xa534, 0x7000, 0xa086,
+       0x0002, 0x00c0, 0x4b0d, 0x1078, 0x4cd2, 0x2071, 0x0000, 0x701b,
+       0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x1078, 0x4cfd, 0x2071,
+       0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x2071,
+       0xa534, 0x7000, 0xa005, 0x0040, 0x4bc8, 0x6934, 0xa186, 0x0103,
+       0x00c0, 0x4b9e, 0x684c, 0xd0bc, 0x00c0, 0x4bc8, 0x6948, 0x6844,
+       0xa105, 0x00c0, 0x4bbb, 0x2009, 0x8020, 0x2071, 0xa534, 0x7000,
+       0x0079, 0x4b32, 0x4bc8, 0x4b80, 0x4b58, 0x4b6a, 0x4b37, 0x137e,
+       0x147e, 0x157e, 0x2099, 0xa375, 0x20a1, 0xa585, 0x20a9, 0x0004,
+       0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa57c, 0xad80, 0x000f,
+       0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10,
+       0x1078, 0x13d1, 0x2071, 0xa413, 0x7007, 0x0009, 0x0078, 0x4be9,
+       0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4be9, 0xae90, 0x0003,
+       0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b,
+       0x0078, 0x4be9, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x4be9,
+       0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840,
+       0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b, 0x0078, 0x4be9,
+       0x127e, 0x2091, 0x8000, 0x0068, 0x4b9b, 0x2071, 0x0000, 0x7018,
+       0xd084, 0x00c0, 0x4b9b, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+       0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa413, 0x1078,
+       0x4d5b, 0x0078, 0x4be9, 0x127f, 0x0078, 0x4be9, 0xa18c, 0x00ff,
+       0xa186, 0x0017, 0x0040, 0x4bac, 0xa186, 0x001e, 0x0040, 0x4bac,
+       0xa18e, 0x001f, 0x00c0, 0x4bc8, 0x684c, 0xd0cc, 0x0040, 0x4bc8,
+       0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4bc8, 0x2009,
+       0x8021, 0x0078, 0x4b2d, 0x6844, 0xa086, 0x0100, 0x00c0, 0x4bc8,
+       0x6868, 0xa005, 0x00c0, 0x4bc8, 0x2009, 0x8020, 0x0078, 0x4b2d,
+       0x2071, 0xa413, 0x1078, 0x4d6f, 0x0040, 0x4be9, 0x2071, 0xa413,
+       0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x00c0,
+       0x4be0, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4be0, 0x710e,
+       0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100, 0x0040,
+       0x4ca4, 0x127e, 0x2091, 0x8000, 0x2071, 0xa413, 0x7008, 0xa086,
+       0x0001, 0x00c0, 0x4c04, 0x0068, 0x4c04, 0x2009, 0x000d, 0x7030,
+       0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+       0x00c0, 0x4c04, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071, 0xa413,
+       0x1078, 0x4d6f, 0x0040, 0x4c2f, 0x2071, 0xa534, 0x7084, 0x700a,
+       0x20a9, 0x0020, 0x2099, 0xa535, 0x20a1, 0xa55c, 0x53a3, 0x7087,
+       0x0000, 0x2071, 0xa413, 0x2069, 0xa57c, 0x706c, 0x6826, 0x7070,
+       0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, 0x13d1,
+       0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa5be, 0x7042, 0x127f,
+       0x0078, 0x4be9, 0x2069, 0xa57c, 0x6808, 0xa08e, 0x0000, 0x0040,
+       0x4c90, 0xa08e, 0x0200, 0x0040, 0x4c8e, 0xa08e, 0x0100, 0x00c0,
+       0x4c90, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8b, 0x2069, 0x0000,
+       0x6818, 0xd084, 0x00c0, 0x4c8b, 0x702c, 0x7130, 0x8108, 0xa102,
+       0x0048, 0x4c59, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078,
+       0x4c63, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4c63, 0x7070,
+       0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001,
+       0xa559, 0x2004, 0xa005, 0x00c0, 0x4c82, 0x6934, 0x2069, 0xa534,
+       0x689c, 0x699e, 0x2069, 0xa5be, 0xa102, 0x00c0, 0x4c7b, 0x6844,
+       0xa005, 0x00d0, 0x4c89, 0x2001, 0xa55a, 0x200c, 0x810d, 0x6946,
+       0x0078, 0x4c89, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091,
+       0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4c90, 0x7007, 0x0005,
+       0x007c, 0x701c, 0xa06d, 0x0040, 0x4ca2, 0x1078, 0x4d6f, 0x0040,
+       0x4ca2, 0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100,
+       0x0040, 0x4ca4, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100, 0x00c0,
+       0x4cad, 0x7007, 0x0004, 0x0078, 0x4ccb, 0xa086, 0x0200, 0x00c0,
+       0x4cb3, 0x7007, 0x0005, 0x007c, 0x2001, 0xa57e, 0x2004, 0xa08e,
+       0x0100, 0x00c0, 0x4cc0, 0x7007, 0x0001, 0x1078, 0x4d5b, 0x007c,
+       0xa08e, 0x0000, 0x0040, 0x4cbf, 0xa08e, 0x0200, 0x00c0, 0x4cbf,
+       0x7007, 0x0005, 0x007c, 0x1078, 0x4d25, 0x7006, 0x1078, 0x4d5b,
+       0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa534, 0x7184, 0x81ff,
+       0x0040, 0x4cfa, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000,
+       0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x722a,
+       0x8000, 0x0070, 0x4cf7, 0x2014, 0x722e, 0x8000, 0x0070, 0x4cf7,
+       0x2014, 0x723a, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x723e, 0xa180,
+       0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e, 0x2071,
+       0xa534, 0x7184, 0x81ff, 0x0040, 0x4d22, 0xa006, 0x7086, 0xae80,
+       0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014,
+       0x722a, 0x8000, 0x0070, 0x4d1b, 0x2014, 0x723a, 0x8000, 0x2014,
+       0x723e, 0x0078, 0x4d1f, 0x2001, 0x8020, 0x0078, 0x4d21, 0x2001,
+       0x8042, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x702c, 0x7130, 0x8108,
+       0xa102, 0x0048, 0x4d32, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
+       0x0078, 0x4d3c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d3c,
+       0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e,
+       0x00c0, 0x4d52, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d55, 0x2001,
+       0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b, 0x0000,
+       0x127f, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x700b,
+       0x0001, 0x127f, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d6e, 0x127e,
+       0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005,
+       0x00c0, 0x4d6b, 0x701a, 0x127f, 0x1078, 0x139a, 0x007c, 0x2019,
+       0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, 0x4d7e, 0x2304, 0x230c,
+       0xa10e, 0x0040, 0x4d7e, 0xa006, 0x0078, 0x4d8e, 0x732c, 0x8319,
+       0x7130, 0xa102, 0x00c0, 0x4d88, 0x2300, 0xa005, 0x0078, 0x4d8e,
+       0x0048, 0x4d8d, 0xa302, 0x0078, 0x4d8e, 0x8002, 0x007c, 0x2d00,
+       0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, 0x2091,
+       0x8000, 0x2009, 0xa5d0, 0x2104, 0xc08d, 0x200a, 0x127f, 0x1078,
+       0x13eb, 0x007c, 0x2071, 0xa3e1, 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, 0xa3e1,
+       0x6848, 0xa005, 0x00c0, 0x4dcb, 0x7028, 0xc085, 0x702a, 0xa085,
+       0x0001, 0x0078, 0x4df0, 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, 0xa3e1, 0x7004, 0x1079, 0x4e50,
+       0x700c, 0x0079, 0x4dfb, 0x4e00, 0x4df5, 0x4df5, 0x4df5, 0x4df5,
+       0x007c, 0x700c, 0x0079, 0x4e04, 0x4e09, 0x4e4e, 0x4e4e, 0x4e4f,
+       0x4e4f, 0x7830, 0x7930, 0xa106, 0x0040, 0x4e13, 0x7830, 0x7930,
+       0xa106, 0x00c0, 0x4e39, 0x7030, 0xa10a, 0x0040, 0x4e39, 0x00c8,
+       0x4e1b, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4e3a, 0x1078,
+       0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001,
+       0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, 0x2009,
+       0xa5d0, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, 0x1078,
+       0x13eb, 0x007c, 0x1078, 0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a,
+       0x1078, 0x1366, 0x00c0, 0x4e46, 0x0078, 0x4e25, 0x2d00, 0x7086,
+       0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4e29, 0x007c, 0x007c,
+       0x4e61, 0x4e62, 0x4e99, 0x4e9a, 0x4e4e, 0x4ed0, 0x4ed5, 0x4f0c,
+       0x4f0d, 0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, 0x4f2d, 0x4fad,
+       0x4fd7, 0x007c, 0x700c, 0x0079, 0x4e65, 0x4e6a, 0x4e6d, 0x4e7d,
+       0x4e98, 0x4e98, 0x1078, 0x4e01, 0x007c, 0x127e, 0x8001, 0x700e,
+       0x7058, 0x007e, 0x1078, 0x5348, 0x0040, 0x4e7a, 0x2091, 0x8000,
+       0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4e86, 0x127e, 0x8001, 0x700e,
+       0x1078, 0x5348, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000,
+       0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x00c8,
+       0x4e95, 0x1079, 0x4eb0, 0x127f, 0x007c, 0x127f, 0x1078, 0x4f2e,
+       0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa3e1, 0x700c, 0x0079,
+       0x4ea1, 0x4ea6, 0x4ea6, 0x4ea6, 0x4ea8, 0x4eac, 0x0e7f, 0x007c,
+       0x700f, 0x0001, 0x0078, 0x4eae, 0x700f, 0x0002, 0x0e7f, 0x007c,
+       0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x5080, 0x4f2e, 0x4f2e, 0x4f2e,
+       0x4f2e, 0x4f2e, 0x4f4a, 0x50ca, 0x5117, 0x5170, 0x5186, 0x4f2e,
+       0x4f2e, 0x4f66, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f87, 0x5245, 0x5263,
+       0x4f2e, 0x4f66, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f7c, 0x5263,
+       0x7020, 0x2068, 0x1078, 0x139a, 0x007c, 0x700c, 0x0079, 0x4ed8,
+       0x4edd, 0x4ee0, 0x4ef0, 0x4f0b, 0x4f0b, 0x1078, 0x4e01, 0x007c,
+       0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x5348, 0x0040,
+       0x4eed, 0x2091, 0x8000, 0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4ef9,
+       0x127e, 0x8001, 0x700e, 0x1078, 0x5348, 0x7058, 0x2068, 0x7084,
+       0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+       0xa08a, 0x001a, 0x00c8, 0x4f08, 0x1079, 0x4f0e, 0x127f, 0x007c,
+       0x127f, 0x1078, 0x4f2e, 0x007c, 0x007c, 0x007c, 0x4f2e, 0x4f4a,
+       0x506a, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+       0x506a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+       0x506a, 0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f4a,
+       0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, 0x0001,
+       0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x4982, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084,
+       0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+       0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed,
+       0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c,
+       0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c, 0x6834, 0x8007,
+       0xa084, 0x00ff, 0x0040, 0x4f3c, 0x8001, 0x00c0, 0x4f73, 0x7007,
+       0x0001, 0x0078, 0x5049, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+       0x701a, 0x704b, 0x5049, 0x007c, 0x684c, 0xa084, 0x00c0, 0xa086,
+       0x00c0, 0x00c0, 0x4f87, 0x7007, 0x0001, 0x0078, 0x5280, 0x2d00,
+       0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1,
+       0xa40c, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, 0x4f58,
+       0x6884, 0xa08a, 0x0002, 0x00c8, 0x4f58, 0x82ff, 0x00c0, 0x4fa9,
+       0x6888, 0x698c, 0xa105, 0x0040, 0x4fa9, 0x2001, 0x5019, 0x0078,
+       0x4fac, 0xa280, 0x500f, 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040,
+       0x4ff7, 0x1078, 0x1366, 0x00c0, 0x4fb8, 0x7007, 0x000f, 0x007c,
+       0x2d00, 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, 0xad00,
+       0x7096, 0x6008, 0xa20a, 0x00c8, 0x4fc7, 0xa00e, 0x2200, 0x7112,
+       0x620c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x4fd0, 0xa108,
+       0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x13d1, 0x7090,
+       0xa08e, 0x0100, 0x0040, 0x4feb, 0xa086, 0x0200, 0x0040, 0x4fe3,
+       0x7007, 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x139a, 0x7014,
+       0x2068, 0x0078, 0x4f58, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807,
+       0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x4fad, 0x7014,
+       0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x00c0, 0x5006, 0x6888,
+       0x698c, 0xa105, 0x0040, 0x5006, 0x1078, 0x501d, 0x6834, 0xa084,
+       0x00ff, 0xa086, 0x001e, 0x0040, 0x5280, 0x0078, 0x5049, 0x5011,
+       0x5015, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, 0x0005,
+       0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x0f7e, 0x0e7e, 0x0c7e,
+       0x077e, 0x067e, 0x6f88, 0x6e8c, 0x6804, 0x2060, 0xacf0, 0x0021,
+       0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, 0x7008, 0x7812,
+       0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0040,
+       0x503f, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x502c, 0x6004,
+       0xa065, 0x00c0, 0x5026, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f,
+       0x007c, 0x2009, 0xa32e, 0x210c, 0x81ff, 0x00c0, 0x5064, 0x6838,
+       0xa084, 0x00ff, 0x683a, 0x1078, 0x4290, 0x00c0, 0x5058, 0x007c,
+       0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cb8, 0x1078,
+       0x4982, 0x127f, 0x0078, 0x5057, 0x2001, 0x0028, 0x2009, 0x0000,
+       0x0078, 0x5058, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a,
+       0x7010, 0x8001, 0x7012, 0x0040, 0x5079, 0x7007, 0x0006, 0x0078,
+       0x507f, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, 0x007c,
+       0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084,
+       0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x50a9, 0x2009,
+       0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x50a9, 0xa005,
+       0x00c0, 0x50bc, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+       0x00c0, 0x50bc, 0x067e, 0x6e50, 0x1078, 0x45e7, 0x067f, 0x0078,
+       0x50bc, 0x047e, 0x2011, 0xa30c, 0x2224, 0xc484, 0xc48c, 0x2412,
+       0x047f, 0x0c7e, 0x1078, 0x4501, 0x00c0, 0x50b8, 0x1078, 0x4782,
+       0x8108, 0x00f0, 0x50b2, 0x0c7f, 0x684c, 0xd084, 0x00c0, 0x50c3,
+       0x1078, 0x139a, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+       0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x510e, 0x2061, 0xa62d, 0x6100,
+       0xd184, 0x0040, 0x50ee, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x5111,
+       0x6000, 0xd084, 0x0040, 0x510e, 0x6004, 0xa005, 0x00c0, 0x5114,
+       0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x510b, 0x2011, 0x0001,
+       0x6860, 0xa005, 0x00c0, 0x50f6, 0x2001, 0x001e, 0x8000, 0x6016,
+       0x6858, 0xa084, 0x00ff, 0x0040, 0x510e, 0x6006, 0x6858, 0x8007,
+       0xa084, 0x00ff, 0x0040, 0x510e, 0x600a, 0x6858, 0x8000, 0x00c0,
+       0x510a, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5337, 0x127f, 0x0078,
+       0x532f, 0x127f, 0x0078, 0x5327, 0x127f, 0x0078, 0x532b, 0x127e,
+       0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa352, 0x2004, 0xd0a4,
+       0x0040, 0x516d, 0x2061, 0xa62d, 0x6000, 0xd084, 0x0040, 0x516d,
+       0x6204, 0x6308, 0xd08c, 0x00c0, 0x515f, 0x6c48, 0xa484, 0x0003,
+       0x0040, 0x5145, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x513e,
+       0x2100, 0xa210, 0x0048, 0x516a, 0x0078, 0x5145, 0x8001, 0x00c0,
+       0x516a, 0x2100, 0xa212, 0x0048, 0x516a, 0xa484, 0x000c, 0x0040,
+       0x515f, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
+       0x5157, 0x2100, 0xa318, 0x0048, 0x516a, 0x0078, 0x515f, 0xa082,
+       0x0004, 0x00c0, 0x516a, 0x2100, 0xa31a, 0x0048, 0x516a, 0x6860,
+       0xa005, 0x0040, 0x5165, 0x8000, 0x6016, 0x6206, 0x630a, 0x127f,
+       0x0078, 0x5337, 0x127f, 0x0078, 0x5333, 0x127f, 0x0078, 0x532f,
+       0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xa62d, 0x6300,
+       0xd38c, 0x00c0, 0x5180, 0x6308, 0x8318, 0x0048, 0x5183, 0x630a,
+       0x127f, 0x0078, 0x5345, 0x127f, 0x0078, 0x5333, 0x127e, 0x0c7e,
+       0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040, 0x519a,
+       0x0c7e, 0x2061, 0xa62d, 0x6000, 0xa084, 0xfcff, 0x6002, 0x0c7f,
+       0x0078, 0x51c9, 0x6858, 0xa005, 0x0040, 0x51e0, 0x685c, 0xa065,
+       0x0040, 0x51dc, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x51ac,
+       0x1078, 0x8c01, 0x0078, 0x51ba, 0x6013, 0x0400, 0x6037, 0x0000,
+       0x694c, 0xd1a4, 0x0040, 0x51b6, 0x6950, 0x6136, 0x2009, 0x0041,
+       0x1078, 0x756c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x00c0,
+       0x51c9, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, 0x5a6d,
+       0x027f, 0x684c, 0xd0c4, 0x0040, 0x51d8, 0x2061, 0xa62d, 0x6000,
+       0xd08c, 0x00c0, 0x51d8, 0x6008, 0x8000, 0x0048, 0x51dc, 0x600a,
+       0x0c7f, 0x127f, 0x0078, 0x5337, 0x0c7f, 0x127f, 0x0078, 0x532f,
+       0x6954, 0xa186, 0x0045, 0x0040, 0x5213, 0xa186, 0x002a, 0x00c0,
+       0x51f0, 0x2001, 0xa30c, 0x200c, 0xc194, 0x2102, 0x0078, 0x51c9,
+       0xa186, 0x0020, 0x0040, 0x5209, 0xa186, 0x0029, 0x0040, 0x51fc,
+       0xa186, 0x002d, 0x00c0, 0x51dc, 0x6944, 0xa18c, 0xff00, 0x810f,
+       0x1078, 0x4501, 0x00c0, 0x51c9, 0x6000, 0xc0e4, 0x6002, 0x0078,
+       0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x2001, 0xa5a1, 0x2004,
+       0x6016, 0x0078, 0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x0e7e,
+       0x6860, 0xa075, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x522b,
+       0x1078, 0x8c01, 0x8eff, 0x0040, 0x5228, 0x2e60, 0x1078, 0x8c01,
+       0x0e7f, 0x0078, 0x51c9, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60,
+       0x6007, 0x003a, 0x6870, 0xa005, 0x0040, 0x523c, 0x6007, 0x003b,
+       0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x1078, 0x5bf8,
+       0x1078, 0x6109, 0x0e7f, 0x0078, 0x51c9, 0x2061, 0xa62d, 0x6000,
+       0xd084, 0x0040, 0x525f, 0xd08c, 0x00c0, 0x5345, 0x2091, 0x8000,
+       0x6204, 0x8210, 0x0048, 0x5259, 0x6206, 0x2091, 0x8001, 0x0078,
+       0x5345, 0x2091, 0x8001, 0x6853, 0x0016, 0x0078, 0x533e, 0x6853,
+       0x0007, 0x0078, 0x533e, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0,
+       0x526d, 0x1078, 0x4f3c, 0x0078, 0x527f, 0x2030, 0x8001, 0x00c0,
+       0x5277, 0x7007, 0x0001, 0x1078, 0x5280, 0x0078, 0x527f, 0x7007,
+       0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5280, 0x007c,
+       0x0e7e, 0x127e, 0x2091, 0x8000, 0x2009, 0xa32e, 0x210c, 0x81ff,
+       0x00c0, 0x530b, 0x2009, 0xa30c, 0x210c, 0xd194, 0x00c0, 0x5315,
+       0x6848, 0x2070, 0xae82, 0xaa00, 0x0048, 0x52fb, 0x2001, 0xa315,
+       0x2004, 0xae02, 0x00c8, 0x52fb, 0x2061, 0xa62d, 0x6100, 0xa184,
+       0x0301, 0xa086, 0x0001, 0x00c0, 0x52de, 0x711c, 0xa186, 0x0006,
+       0x00c0, 0x52e6, 0x7018, 0xa005, 0x0040, 0x530b, 0x2004, 0xd0e4,
+       0x00c0, 0x530f, 0x7024, 0xd0dc, 0x00c0, 0x5319, 0x6853, 0x0000,
+       0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x00c0, 0x52ca, 0x7112,
+       0x684c, 0xd0f4, 0x00c0, 0x531d, 0x2e60, 0x1078, 0x59b6, 0x127f,
+       0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x52ca, 0x6902,
+       0x2168, 0x684c, 0xd0f4, 0x00c0, 0x531d, 0x127f, 0x0e7f, 0x007c,
+       0x127f, 0x0e7f, 0x6853, 0x0006, 0x0078, 0x533e, 0xd184, 0x0040,
+       0x52d8, 0xd1c4, 0x00c0, 0x52ff, 0x0078, 0x5303, 0x6944, 0xa18c,
+       0xff00, 0x810f, 0x1078, 0x4501, 0x00c0, 0x530f, 0x6000, 0xd0e4,
+       0x00c0, 0x530f, 0x711c, 0xa186, 0x0007, 0x00c0, 0x52fb, 0x6853,
+       0x0002, 0x0078, 0x5311, 0x6853, 0x0008, 0x0078, 0x5311, 0x6853,
+       0x000e, 0x0078, 0x5311, 0x6853, 0x0017, 0x0078, 0x5311, 0x6853,
+       0x0035, 0x0078, 0x5311, 0x6853, 0x0028, 0x0078, 0x5311, 0x6853,
+       0x0029, 0x127f, 0x0e7f, 0x0078, 0x533e, 0x6853, 0x002a, 0x0078,
+       0x5311, 0x6853, 0x0045, 0x0078, 0x5311, 0x2e60, 0x2019, 0x0002,
+       0x6017, 0x0014, 0x1078, 0x9a6a, 0x127f, 0x0e7f, 0x007c, 0x2009,
+       0x003e, 0x0078, 0x5339, 0x2009, 0x0004, 0x0078, 0x5339, 0x2009,
+       0x0006, 0x0078, 0x5339, 0x2009, 0x0016, 0x0078, 0x5339, 0x2009,
+       0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000,
+       0x1078, 0x4982, 0x2091, 0x8001, 0x007c, 0x1078, 0x139a, 0x007c,
+       0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x5355, 0xa00e, 0x7034,
+       0x7072, 0x7038, 0x7076, 0x0078, 0x5361, 0x7070, 0xa080, 0x0040,
+       0x7072, 0x00c8, 0x5361, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085,
+       0x0001, 0x7932, 0x7132, 0x007c, 0x0d7e, 0x1078, 0x59ad, 0x0d7f,
+       0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012,
+       0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00,
+       0xa084, 0x7000, 0x0040, 0x5380, 0xa086, 0x1000, 0x00c0, 0x53ac,
+       0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, 0xa084, 0xf000,
+       0xa086, 0x3000, 0x00c0, 0x5390, 0x1078, 0x5570, 0x0078, 0x53a7,
+       0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x5397, 0x3e60, 0xac84,
+       0x000f, 0x00c0, 0x53ac, 0xac82, 0xaa00, 0x0048, 0x53ac, 0x6854,
+       0xac02, 0x00c8, 0x53ac, 0x2009, 0x0047, 0x1078, 0x756c, 0x7a1c,
+       0xd284, 0x00c0, 0x5372, 0x007c, 0xa016, 0x1078, 0x15ec, 0x0078,
+       0x53a7, 0x0078, 0x53ac, 0x781c, 0xd08c, 0x0040, 0x53db, 0x157e,
+       0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076,
+       0x00c0, 0x53f1, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x53e0,
+       0x1078, 0x540c, 0x0040, 0x53f1, 0x20e1, 0x3000, 0x7828, 0x7828,
+       0x1078, 0x542a, 0x147f, 0x137f, 0x157f, 0x2009, 0xa5b3, 0x2104,
+       0xa005, 0x00c0, 0x53dc, 0x007c, 0x1078, 0x6109, 0x0078, 0x53db,
+       0xa484, 0x7000, 0x00c0, 0x53f1, 0x1078, 0x540c, 0x0040, 0x5403,
+       0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x53cc, 0x0078,
+       0x5403, 0x1078, 0xa1ee, 0xd5a4, 0x0040, 0x53ff, 0x1078, 0x1af7,
+       0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5407, 0x1078,
+       0x540c, 0x687f, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828, 0x147f,
+       0x137f, 0x157f, 0x0078, 0x53db, 0xa484, 0x01ff, 0x687e, 0xa005,
+       0x0040, 0x541e, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1,
+       0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, 0x000c,
+       0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001,
+       0x0078, 0x541d, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
+       0xa196, 0x0000, 0x00c0, 0x5437, 0x0078, 0x567c, 0x007c, 0xa196,
+       0x2000, 0x00c0, 0x5448, 0x6900, 0xa18e, 0x0001, 0x00c0, 0x5444,
+       0x1078, 0x3a43, 0x0078, 0x5436, 0x1078, 0x5450, 0x0078, 0x5436,
+       0xa196, 0x8000, 0x00c0, 0x5436, 0x1078, 0x570c, 0x0078, 0x5436,
+       0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0040,
+       0x545d, 0xa196, 0x0023, 0x00c0, 0x5568, 0xa08e, 0x0023, 0x00c0,
+       0x5492, 0x1078, 0x57b2, 0x0040, 0x5568, 0x7124, 0x610a, 0x7030,
+       0xa08e, 0x0200, 0x00c0, 0x5476, 0x7034, 0xa005, 0x00c0, 0x5568,
+       0x2009, 0x0015, 0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0214,
+       0x0040, 0x547e, 0xa08e, 0x0210, 0x00c0, 0x5484, 0x2009, 0x0015,
+       0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0100, 0x00c0, 0x5568,
+       0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, 0x0016, 0x1078, 0x756c,
+       0x0078, 0x5568, 0xa08e, 0x0022, 0x00c0, 0x5568, 0x7030, 0xa08e,
+       0x0300, 0x00c0, 0x54a3, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+       0x0017, 0x0078, 0x5534, 0xa08e, 0x0500, 0x00c0, 0x54af, 0x7034,
+       0xa005, 0x00c0, 0x5568, 0x2009, 0x0018, 0x0078, 0x5534, 0xa08e,
+       0x2010, 0x00c0, 0x54b7, 0x2009, 0x0019, 0x0078, 0x5534, 0xa08e,
+       0x2110, 0x00c0, 0x54bf, 0x2009, 0x001a, 0x0078, 0x5534, 0xa08e,
+       0x5200, 0x00c0, 0x54cb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+       0x001b, 0x0078, 0x5534, 0xa08e, 0x5000, 0x00c0, 0x54d7, 0x7034,
+       0xa005, 0x00c0, 0x5568, 0x2009, 0x001c, 0x0078, 0x5534, 0xa08e,
+       0x1300, 0x00c0, 0x54df, 0x2009, 0x0034, 0x0078, 0x5534, 0xa08e,
+       0x1200, 0x00c0, 0x54eb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+       0x0024, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0,
+       0x54f5, 0x2009, 0x002d, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e,
+       0x5300, 0x00c0, 0x54ff, 0x2009, 0x002a, 0x0078, 0x5534, 0xa08e,
+       0x0f00, 0x00c0, 0x5507, 0x2009, 0x0020, 0x0078, 0x5534, 0xa08e,
+       0x5300, 0x00c0, 0x550d, 0x0078, 0x552a, 0xa08e, 0x6104, 0x00c0,
+       0x552a, 0x2011, 0xa88d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8,
+       0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, 0x047e, 0x2124,
+       0x1078, 0x3579, 0x047f, 0x8108, 0x00f0, 0x551a, 0x2009, 0x0023,
+       0x0078, 0x5534, 0xa08e, 0x6000, 0x00c0, 0x5532, 0x2009, 0x003f,
+       0x0078, 0x5534, 0x2009, 0x001d, 0x017e, 0x2011, 0xa883, 0x2204,
+       0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x556a, 0x1078, 0x4499,
+       0x00c0, 0x556a, 0x6612, 0x6516, 0x86ff, 0x0040, 0x555a, 0x017f,
+       0x017e, 0xa186, 0x0017, 0x00c0, 0x555a, 0x6868, 0xa606, 0x00c0,
+       0x555a, 0x686c, 0xa506, 0xa084, 0xff00, 0x00c0, 0x555a, 0x6000,
+       0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x74d7, 0x0040, 0x556d, 0x017f,
+       0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x756c,
+       0x0c7f, 0x007c, 0x017f, 0x0078, 0x5568, 0x0c7f, 0x0078, 0x556a,
+       0x0c7e, 0x1078, 0x55d4, 0x00c0, 0x55d2, 0xa184, 0xff00, 0x8007,
+       0xa086, 0x0008, 0x00c0, 0x55d2, 0xa28e, 0x0033, 0x00c0, 0x55a3,
+       0x1078, 0x57b2, 0x0040, 0x55d2, 0x7124, 0x610a, 0x7030, 0xa08e,
+       0x0200, 0x00c0, 0x5595, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009,
+       0x0015, 0x1078, 0x756c, 0x0078, 0x55d2, 0xa08e, 0x0100, 0x00c0,
+       0x55d2, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009, 0x0016, 0x1078,
+       0x756c, 0x0078, 0x55d2, 0xa28e, 0x0032, 0x00c0, 0x55d2, 0x7030,
+       0xa08e, 0x1400, 0x00c0, 0x55d2, 0x2009, 0x0038, 0x017e, 0x2011,
+       0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x55d1,
+       0x1078, 0x4499, 0x00c0, 0x55d1, 0x6612, 0x6516, 0x0c7e, 0x1078,
+       0x74d7, 0x0040, 0x55d0, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120,
+       0x610a, 0x017f, 0x1078, 0x756c, 0x1078, 0x6109, 0x0078, 0x55d2,
+       0x0c7f, 0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0d7e, 0x027e, 0x017e,
+       0x137e, 0x147e, 0x157e, 0x3c00, 0x007e, 0x2079, 0x0030, 0x2069,
+       0x0200, 0x1078, 0x1c25, 0x00c0, 0x5615, 0x1078, 0x1b15, 0x0040,
+       0x561f, 0x7908, 0xa18c, 0x1fff, 0xa182, 0x0011, 0x00c8, 0x561f,
+       0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
+       0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x7a0c, 0x7808, 0xa080,
+       0x0007, 0xa084, 0x1ff8, 0xa08a, 0x0140, 0x10c8, 0x1328, 0x80ac,
+       0x20e1, 0x6000, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828,
+       0x6828, 0x7803, 0x0004, 0xa294, 0x0070, 0x007f, 0x20e0, 0x157f,
+       0x147f, 0x137f, 0x017f, 0x027f, 0x0d7f, 0x0f7f, 0x007c, 0xa085,
+       0x0001, 0x0078, 0x5615, 0x047e, 0x0e7e, 0x0d7e, 0x2028, 0x2130,
+       0xa696, 0x00ff, 0x00c0, 0x5644, 0xa596, 0xfffd, 0x00c0, 0x5634,
+       0x2009, 0x007f, 0x0078, 0x5677, 0xa596, 0xfffe, 0x00c0, 0x563c,
+       0x2009, 0x007e, 0x0078, 0x5677, 0xa596, 0xfffc, 0x00c0, 0x5644,
+       0x2009, 0x0080, 0x0078, 0x5677, 0x2011, 0x0000, 0x2021, 0x0081,
+       0x20a9, 0x007e, 0x2071, 0xa4b5, 0x2e1c, 0x83ff, 0x00c0, 0x5656,
+       0x82ff, 0x00c0, 0x566b, 0x2410, 0x0078, 0x566b, 0x2368, 0x6f10,
+       0x007e, 0x2100, 0xa706, 0x007f, 0x6b14, 0x00c0, 0x5665, 0xa346,
+       0x00c0, 0x5665, 0x2408, 0x0078, 0x5677, 0x87ff, 0x00c0, 0x566b,
+       0x83ff, 0x0040, 0x5650, 0x8420, 0x8e70, 0x00f0, 0x564c, 0x82ff,
+       0x00c0, 0x5676, 0xa085, 0x0001, 0x0078, 0x5678, 0x2208, 0xa006,
+       0x0d7f, 0x0e7f, 0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x5681,
+       0x007c, 0x5689, 0x5689, 0x5689, 0x57c8, 0x5689, 0x568a, 0x56a3,
+       0x56f3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x56a2, 0x7120, 0x2160,
+       0xac8c, 0x000f, 0x00c0, 0x56a2, 0xac8a, 0xaa00, 0x0048, 0x56a2,
+       0x6854, 0xac02, 0x00c8, 0x56a2, 0x7124, 0x610a, 0x2009, 0x0046,
+       0x1078, 0x756c, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x56f1,
+       0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0,
+       0x56f1, 0x1078, 0x4499, 0x00c0, 0x56f1, 0x6612, 0x6516, 0x6000,
+       0xd0ec, 0x00c0, 0x56f1, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286,
+       0x0006, 0x00c0, 0x56d6, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+       0x56f1, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6122,
+       0x2009, 0x0044, 0x1078, 0x756c, 0x0078, 0x56f1, 0x0c7e, 0x1078,
+       0x74d7, 0x017f, 0x0040, 0x56f1, 0x611a, 0x601f, 0x0004, 0x7120,
+       0x610a, 0xa286, 0x0004, 0x00c0, 0x56e9, 0x6007, 0x0005, 0x0078,
+       0x56eb, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078,
+       0x6109, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x570b, 0x7020,
+       0x2060, 0xac84, 0x000f, 0x00c0, 0x570b, 0xac82, 0xaa00, 0x0048,
+       0x570b, 0x6854, 0xac02, 0x00c8, 0x570b, 0x7124, 0x610a, 0x2009,
+       0x0045, 0x1078, 0x756c, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f,
+       0xa18e, 0x0000, 0x00c0, 0x571c, 0xa084, 0x000f, 0xa08a, 0x0006,
+       0x00c8, 0x571c, 0x1079, 0x571d, 0x007c, 0x5723, 0x5724, 0x5723,
+       0x5723, 0x5794, 0x57a3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x572c,
+       0x702c, 0xd084, 0x0040, 0x5793, 0x700c, 0x7108, 0x1078, 0x24e3,
+       0x00c0, 0x5793, 0x1078, 0x4499, 0x00c0, 0x5793, 0x6612, 0x6516,
+       0x6204, 0x7110, 0xd1bc, 0x0040, 0x575e, 0xa28c, 0x00ff, 0xa186,
+       0x0004, 0x0040, 0x5747, 0xa186, 0x0006, 0x00c0, 0x5784, 0x0c7e,
+       0x1078, 0x57b2, 0x0c7f, 0x0040, 0x5793, 0x0c7e, 0x1078, 0x74d7,
+       0x017f, 0x0040, 0x5793, 0x611a, 0x601f, 0x0002, 0x7120, 0x610a,
+       0x2009, 0x0088, 0x1078, 0x756c, 0x0078, 0x5793, 0xa28c, 0x00ff,
+       0xa186, 0x0006, 0x0040, 0x5773, 0xa186, 0x0004, 0x0040, 0x5773,
+       0xa294, 0xff00, 0x8217, 0xa286, 0x0004, 0x0040, 0x5773, 0xa286,
+       0x0006, 0x00c0, 0x5784, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+       0x5793, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088,
+       0x1078, 0x756c, 0x0078, 0x5793, 0x0c7e, 0x1078, 0x74d7, 0x017f,
+       0x0040, 0x5793, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009,
+       0x0001, 0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57a2,
+       0x1078, 0x57b2, 0x0040, 0x57a2, 0x7124, 0x610a, 0x2009, 0x0089,
+       0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57b1, 0x1078,
+       0x57b2, 0x0040, 0x57b1, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078,
+       0x756c, 0x007c, 0x7020, 0x2060, 0xac84, 0x000f, 0x00c0, 0x57c5,
+       0xac82, 0xaa00, 0x0048, 0x57c5, 0x2001, 0xa315, 0x2004, 0xac02,
+       0x00c8, 0x57c5, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x57c4,
+       0x7110, 0xd1bc, 0x00c0, 0x57de, 0x7024, 0x2060, 0xac84, 0x000f,
+       0x00c0, 0x57de, 0xac82, 0xaa00, 0x0048, 0x57de, 0x6854, 0xac02,
+       0x00c8, 0x57de, 0x2009, 0x0051, 0x1078, 0x756c, 0x007c, 0x2071,
+       0xa5be, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+       0x7017, 0xaa00, 0x7007, 0x0000, 0x7026, 0x702b, 0x6c4e, 0x7032,
+       0x7037, 0x6ca0, 0x703b, 0x0002, 0x703f, 0x0000, 0x7043, 0xffff,
+       0x7047, 0xffff, 0x007c, 0x2071, 0xa5be, 0x00e0, 0x58c1, 0x2091,
+       0x6000, 0x700c, 0x8001, 0x700e, 0x00c0, 0x5873, 0x700f, 0x0361,
+       0x7007, 0x0001, 0x127e, 0x2091, 0x8000, 0x7138, 0x8109, 0x713a,
+       0x00c0, 0x5871, 0x703b, 0x0002, 0x2009, 0x0100, 0x2104, 0xa082,
+       0x0003, 0x00c8, 0x5871, 0x703c, 0xa086, 0x0001, 0x00c0, 0x584e,
+       0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x582c,
+       0x6803, 0x1000, 0x0078, 0x5833, 0x6804, 0xa084, 0x1000, 0x0040,
+       0x5833, 0x6803, 0x0100, 0x6803, 0x0000, 0x703f, 0x0000, 0x2069,
+       0xa5ab, 0x6804, 0xa082, 0x0006, 0x00c0, 0x5840, 0x6807, 0x0000,
+       0x6830, 0xa082, 0x0003, 0x00c0, 0x5847, 0x6833, 0x0000, 0x1078,
+       0x6109, 0x1078, 0x61d3, 0x0d7f, 0x0078, 0x5871, 0x0d7e, 0x2069,
+       0xa300, 0x6944, 0x6860, 0xa102, 0x00c8, 0x5870, 0x2069, 0xa5ab,
+       0x6804, 0xa086, 0x0000, 0x00c0, 0x5870, 0x6830, 0xa086, 0x0000,
+       0x00c0, 0x5870, 0x703f, 0x0001, 0x6807, 0x0006, 0x6833, 0x0003,
+       0x2069, 0x0100, 0x6830, 0x689e, 0x2069, 0x0140, 0x6803, 0x0600,
+       0x0d7f, 0x0078, 0x5876, 0x127e, 0x2091, 0x8000, 0x7024, 0xa00d,
+       0x0040, 0x588e, 0x7020, 0x8001, 0x7022, 0x00c0, 0x588e, 0x7023,
+       0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, 0x00c0, 0x5889, 0x7028,
+       0x107a, 0x81ff, 0x00c0, 0x588e, 0x7028, 0x107a, 0x7030, 0xa00d,
+       0x0040, 0x589f, 0x702c, 0x8001, 0x702e, 0x00c0, 0x589f, 0x702f,
+       0x0009, 0x8109, 0x7132, 0x00c0, 0x589f, 0x7034, 0x107a, 0x7040,
+       0xa005, 0x0040, 0x58a7, 0x0050, 0x58a7, 0x8001, 0x7042, 0x7044,
+       0xa005, 0x0040, 0x58af, 0x0050, 0x58af, 0x8001, 0x7046, 0x7018,
+       0xa00d, 0x0040, 0x58c0, 0x7008, 0x8001, 0x700a, 0x00c0, 0x58c0,
+       0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x58c0, 0x701c, 0x107a,
+       0x127f, 0x7004, 0x0079, 0x58c4, 0x58eb, 0x58ec, 0x5908, 0x0e7e,
+       0x2071, 0xa5be, 0x7018, 0xa005, 0x00c0, 0x58d2, 0x711a, 0x721e,
+       0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, 0xa5be,
+       0x701c, 0xa206, 0x00c0, 0x58de, 0x701a, 0x701e, 0x007f, 0x0e7f,
+       0x007c, 0x0e7e, 0x2071, 0xa5be, 0x6088, 0xa102, 0x0048, 0x58e9,
+       0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x4501, 0x00c0,
+       0x58fe, 0x6088, 0x8001, 0x0048, 0x58fe, 0x608a, 0x00c0, 0x58fe,
+       0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x8108, 0xa182,
+       0x00ff, 0x0048, 0x5906, 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c,
+       0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005, 0x0040,
+       0x5917, 0x8001, 0x603e, 0x00c0, 0x5917, 0x1078, 0x8cd7, 0x6014,
+       0xa005, 0x0040, 0x5941, 0x8001, 0x6016, 0x00c0, 0x5941, 0x611c,
+       0xa186, 0x0003, 0x0040, 0x5928, 0xa186, 0x0006, 0x00c0, 0x593f,
+       0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x593f, 0xa082,
+       0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5938, 0x2001, 0x1999,
+       0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5941, 0x1078,
+       0x8810, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xca00, 0xa102,
+       0x0048, 0x594e, 0x7017, 0xaa00, 0x7007, 0x0000, 0x007c, 0x0e7e,
+       0x2071, 0xa5be, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b, 0x0002,
+       0x0e7f, 0x007c, 0x2001, 0xa5c7, 0x2003, 0x0000, 0x007c, 0x0e7e,
+       0x2071, 0xa5be, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011,
+       0xa5ca, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa5be, 0x711a,
+       0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e, 0x0f7e,
+       0x2079, 0xa300, 0x7a34, 0xd294, 0x0040, 0x59a4, 0x2071, 0xa5aa,
+       0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5991, 0xa0fe, 0x0001, 0x0040,
+       0x5995, 0xa0fe, 0x0002, 0x00c0, 0x59a0, 0xa292, 0x0085, 0x0078,
+       0x5997, 0xa292, 0x0005, 0x0078, 0x5997, 0xa292, 0x0002, 0x2272,
+       0x0040, 0x599c, 0x00c8, 0x59a4, 0x2011, 0x8037, 0x1078, 0x3579,
+       0x2011, 0xa5a9, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f, 0x007c,
+       0x0c7e, 0x2061, 0xa62d, 0x0c7f, 0x007c, 0xa184, 0x000f, 0x8003,
+       0x8003, 0x8003, 0xa080, 0xa62d, 0x2060, 0x007c, 0x6854, 0xa08a,
+       0x199a, 0x0048, 0x59bd, 0x2001, 0x1999, 0xa005, 0x00c0, 0x59cc,
+       0x0c7e, 0x2061, 0xa62d, 0x6014, 0x0c7f, 0xa005, 0x00c0, 0x59d1,
+       0x2001, 0x001e, 0x0078, 0x59d1, 0xa08e, 0xffff, 0x00c0, 0x59d1,
+       0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c,
+       0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5a24, 0xd0b4, 0x00c0, 0x59e8,
+       0xd0bc, 0x00c0, 0x5a14, 0x2009, 0x0006, 0x1078, 0x5a43, 0x007c,
+       0xd0fc, 0x0040, 0x59f3, 0xa084, 0x0003, 0x0040, 0x59f3, 0xa086,
+       0x0003, 0x00c0, 0x5a3c, 0x6024, 0xd0d4, 0x0040, 0x59fd, 0xc0d4,
+       0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa373, 0x2104,
+       0xd084, 0x0040, 0x5a0f, 0x6118, 0xa188, 0x0027, 0x2104, 0xd08c,
+       0x00c0, 0x5a0f, 0x2009, 0x0042, 0x1078, 0x756c, 0x007c, 0x2009,
+       0x0043, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a1f, 0xa084,
+       0x0003, 0x0040, 0x5a1f, 0xa086, 0x0003, 0x00c0, 0x5a3c, 0x2009,
+       0x0042, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a32, 0xa084,
+       0x0003, 0xa08e, 0x0002, 0x0040, 0x5a36, 0x2009, 0x0041, 0x1078,
+       0x756c, 0x007c, 0x1078, 0x5a41, 0x0078, 0x5a31, 0x2009, 0x0043,
+       0x1078, 0x756c, 0x0078, 0x5a31, 0x2009, 0x0004, 0x1078, 0x5a43,
+       0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040,
+       0x5a6b, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0,
+       0x5a65, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5a65,
+       0x0c7e, 0x2061, 0xa62d, 0x6200, 0xd28c, 0x00c0, 0x5a64, 0x6204,
+       0x8210, 0x0048, 0x5a64, 0x6206, 0x0c7f, 0x1078, 0x4982, 0x6010,
+       0xa06d, 0x10c0, 0x59b6, 0x0d7f, 0x007c, 0x157e, 0x0c7e, 0x2061,
+       0xa62d, 0x6000, 0x81ff, 0x0040, 0x5a78, 0xa205, 0x0078, 0x5a79,
+       0xa204, 0x6002, 0x0c7f, 0x157f, 0x007c, 0x6800, 0xd08c, 0x00c0,
+       0x5a89, 0x6808, 0xa005, 0x0040, 0x5a89, 0x8001, 0x680a, 0xa085,
+       0x0001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
+       0x00c8, 0x5a93, 0xa200, 0x00f0, 0x5a8e, 0x8086, 0x818e, 0x007c,
+       0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x5ab9, 0xa11a, 0x00c8,
+       0x5ab9, 0x8213, 0x818d, 0x0048, 0x5aac, 0xa11a, 0x00c8, 0x5aad,
+       0x00f0, 0x5aa1, 0x0078, 0x5ab1, 0xa11a, 0x2308, 0x8210, 0x00f0,
+       0x5aa1, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
+       0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x5ab5, 0x127e,
+       0x2091, 0x2200, 0x2079, 0xa5ab, 0x127f, 0x0d7e, 0x2069, 0xa5ab,
+       0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a,
+       0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007,
+       0x0079, 0x5ada, 0x5ae4, 0x5b09, 0x5b64, 0x5aea, 0x5b09, 0x5ae4,
+       0x5ae2, 0x5ae2, 0x1078, 0x1328, 0x1078, 0x595a, 0x1078, 0x6109,
+       0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x5af0, 0x0c7f, 0x007c,
+       0x2011, 0x4129, 0x1078, 0x58d4, 0x7828, 0xa092, 0x00c8, 0x00c8,
+       0x5aff, 0x8000, 0x782a, 0x1078, 0x4168, 0x0078, 0x5aee, 0x1078,
+       0x4129, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078,
+       0x5aee, 0x1078, 0x595a, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1,
+       0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x5b27, 0x62c0,
+       0x82ff, 0x00c0, 0x5b27, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040,
+       0x1328, 0x2009, 0x0013, 0x1078, 0x756c, 0x0c7f, 0x007c, 0x3900,
+       0xa082, 0xa6cd, 0x00c8, 0x5b2e, 0x1078, 0x728a, 0x0c7e, 0x7824,
+       0xa065, 0x1040, 0x1328, 0x7804, 0xa086, 0x0004, 0x0040, 0x5ba9,
+       0x7828, 0xa092, 0x2710, 0x00c8, 0x5b44, 0x8000, 0x782a, 0x0c7f,
+       0x1078, 0x6c33, 0x0078, 0x5b25, 0x6104, 0xa186, 0x0003, 0x00c0,
+       0x5b5b, 0x0e7e, 0x2071, 0xa300, 0x70d4, 0x0e7f, 0xd08c, 0x0040,
+       0x5b5b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0xa300, 0x1078,
+       0x4171, 0x0e7f, 0x0c7f, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+       0x756c, 0x0c7f, 0x0078, 0x5b25, 0x2001, 0xa5c7, 0x2003, 0x0000,
+       0x62c0, 0x82ff, 0x00c0, 0x5b78, 0x782b, 0x0000, 0x7824, 0xa065,
+       0x1040, 0x1328, 0x2009, 0x0013, 0x1078, 0x75c3, 0x0c7f, 0x007c,
+       0x0c7e, 0x0d7e, 0x3900, 0xa082, 0xa6cd, 0x00c8, 0x5b81, 0x1078,
+       0x728a, 0x7824, 0xa005, 0x1040, 0x1328, 0x781c, 0xa06d, 0x1040,
+       0x1328, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x753d,
+       0x693c, 0x81ff, 0x1040, 0x1328, 0x8109, 0x693e, 0x6854, 0xa015,
+       0x0040, 0x5b9d, 0x7a1e, 0x0078, 0x5b9f, 0x7918, 0x791e, 0x7807,
+       0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x6109, 0x0078,
+       0x5b76, 0x6104, 0xa186, 0x0002, 0x0040, 0x5bb4, 0xa186, 0x0004,
+       0x0040, 0x5bb4, 0x0078, 0x5b38, 0x7808, 0xac06, 0x0040, 0x5b38,
+       0x1078, 0x6010, 0x1078, 0x5c45, 0x0c7f, 0x1078, 0x6109, 0x0078,
+       0x5b25, 0x0c7e, 0x6027, 0x0002, 0x62c8, 0x82ff, 0x00c0, 0x5bdb,
+       0x62c4, 0x82ff, 0x00c0, 0x5bdb, 0x793c, 0xa1e5, 0x0000, 0x0040,
+       0x5bd5, 0x2009, 0x0049, 0x1078, 0x756c, 0x2011, 0xa5ca, 0x2013,
+       0x0000, 0x0c7f, 0x007c, 0x3908, 0xa192, 0xa6cd, 0x00c8, 0x5be2,
+       0x1078, 0x728a, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5bd5,
+       0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5bf4,
+       0x6017, 0x0012, 0x0078, 0x5bd9, 0x6017, 0x0016, 0x0078, 0x5bd9,
+       0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000,
+       0x2c08, 0x2061, 0xa5ab, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+       0x0040, 0x5c13, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, 0x0c7f,
+       0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x5c0e, 0x0d7e,
+       0x2069, 0xa5ab, 0x6000, 0xd0d4, 0x0040, 0x5c2c, 0x6820, 0x8000,
+       0x6822, 0xa086, 0x0001, 0x00c0, 0x5c27, 0x2c00, 0x681e, 0x6804,
+       0xa084, 0x0007, 0x0079, 0x6111, 0xc0d5, 0x6002, 0x6818, 0xa005,
+       0x0040, 0x5c3e, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, 0x681a,
+       0x0d7f, 0x685a, 0x2069, 0xa5ab, 0x0078, 0x5c1e, 0x6056, 0x605a,
+       0x2c00, 0x681a, 0x681e, 0x0078, 0x5c1e, 0x007e, 0x017e, 0x0c7e,
+       0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xa5ab,
+       0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x5c60, 0xa080,
+       0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c,
+       0x610e, 0x610a, 0x0078, 0x5c5b, 0x0c7e, 0x600f, 0x0000, 0x2c08,
+       0x2061, 0xa5ab, 0x6034, 0xa005, 0x0040, 0x5c74, 0xa080, 0x0003,
+       0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078, 0x5c72,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x017e, 0x007e,
+       0x127e, 0x2071, 0xa5ab, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
+       0x8cff, 0x0040, 0x5ced, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
+       0x00c0, 0x5ce8, 0x87ff, 0x0040, 0x5c99, 0x6020, 0xa106, 0x00c0,
+       0x5ce8, 0x703c, 0xac06, 0x00c0, 0x5cab, 0x037e, 0x2019, 0x0001,
+       0x1078, 0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+       0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5cb1, 0x660c,
+       0x763a, 0x7034, 0xac36, 0x00c0, 0x5cbf, 0x2c00, 0xaf36, 0x0040,
+       0x5cbd, 0x2f00, 0x7036, 0x0078, 0x5cbf, 0x7037, 0x0000, 0x660c,
+       0x067e, 0x2c00, 0xaf06, 0x0040, 0x5cc8, 0x7e0e, 0x0078, 0x5cc9,
+       0x2678, 0x600f, 0x0000, 0x1078, 0x8a44, 0x0040, 0x5ce3, 0x6010,
+       0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5cf7, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078,
+       0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5c88,
+       0x2c78, 0x600c, 0x2060, 0x0078, 0x5c88, 0x127f, 0x007f, 0x017f,
+       0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c,
+       0xa086, 0x0006, 0x00c0, 0x5cd6, 0x1078, 0xa181, 0x1078, 0x9e70,
+       0x0078, 0x5ce3, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031,
+       0x0000, 0x127e, 0x2091, 0x8000, 0x2079, 0xa5ab, 0x7838, 0xa065,
+       0x0040, 0x5d41, 0x600c, 0x007e, 0x600f, 0x0000, 0x783c, 0xac06,
+       0x00c0, 0x5d28, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x7833,
+       0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x037f,
+       0x1078, 0x8a44, 0x0040, 0x5d3c, 0x6010, 0x2068, 0x601c, 0xa086,
+       0x0003, 0x00c0, 0x5d4a, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+       0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x007f, 0x0078,
+       0x5d0f, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f,
+       0x007f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5d33, 0x1078,
+       0x9e70, 0x0078, 0x5d3c, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000,
+       0x1078, 0x5d6d, 0x1078, 0x5e21, 0x087f, 0x027f, 0x017f, 0x007c,
+       0x0f7e, 0x127e, 0x2079, 0xa5ab, 0x2091, 0x8000, 0x1078, 0x5ebc,
+       0x1078, 0x5f32, 0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e,
+       0x0c7e, 0x067e, 0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+       0xa5ab, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5e01, 0x6018,
+       0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5dfc, 0x88ff, 0x0040,
+       0x5d8d, 0x6020, 0xa106, 0x00c0, 0x5dfc, 0x7024, 0xac06, 0x00c0,
+       0x5dbd, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5db8, 0x1078,
+       0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027,
+       0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040,
+       0x5dad, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+       0xd084, 0x0040, 0x5db5, 0x6827, 0x0001, 0x037f, 0x0078, 0x5dbd,
+       0x6003, 0x0009, 0x630a, 0x0078, 0x5dfc, 0x7014, 0xac36, 0x00c0,
+       0x5dc3, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5dd1, 0x2c00,
+       0xaf36, 0x0040, 0x5dcf, 0x2f00, 0x7012, 0x0078, 0x5dd1, 0x7013,
+       0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5dda, 0x7e0e,
+       0x0078, 0x5ddb, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x5df5, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e0a,
+       0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078,
+       0xa181, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+       0x7045, 0x0c7f, 0x0078, 0x5d7c, 0x2c78, 0x600c, 0x2060, 0x0078,
+       0x5d7c, 0x127f, 0x007f, 0x017f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
+       0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5e15, 0x1078,
+       0xa181, 0x1078, 0x9e70, 0x0078, 0x5df5, 0x601c, 0xa086, 0x0002,
+       0x00c0, 0x5df5, 0x6004, 0xa086, 0x0085, 0x0040, 0x5de8, 0x0078,
+       0x5df5, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0xa280, 0xa434,
+       0x2004, 0xa065, 0x0040, 0x5eb8, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e,
+       0x2071, 0xa5ab, 0x6654, 0x7018, 0xac06, 0x00c0, 0x5e38, 0x761a,
+       0x701c, 0xac06, 0x00c0, 0x5e44, 0x86ff, 0x00c0, 0x5e43, 0x7018,
+       0x701e, 0x0078, 0x5e44, 0x761e, 0x6058, 0xa07d, 0x0040, 0x5e49,
+       0x7e56, 0xa6ed, 0x0000, 0x0040, 0x5e4f, 0x2f00, 0x685a, 0x6057,
+       0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078,
+       0x4410, 0x0040, 0x5eb4, 0x7624, 0x86ff, 0x0040, 0x5ea2, 0xa680,
+       0x0004, 0x2004, 0xad06, 0x00c0, 0x5ea2, 0x0d7e, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0040, 0x5e99, 0x1078, 0x595a, 0x1078, 0x6c41,
+       0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5e82, 0x6803, 0x0100,
+       0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5e8a,
+       0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040,
+       0x5e93, 0x8001, 0x603e, 0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078,
+       0x5ea2, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f,
+       0x0078, 0x5e57, 0x8dff, 0x0040, 0x5eb0, 0x6837, 0x0103, 0x6b4a,
+       0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078, 0x4982,
+       0x1078, 0x7045, 0x0078, 0x5e57, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e,
+       0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x5f16, 0x600c, 0x007e,
+       0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, 0x5efb, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0040, 0x5ef5, 0x1078, 0x595a, 0x1078, 0x6c41,
+       0x68c3, 0x0000, 0x1078, 0x7188, 0x7827, 0x0000, 0x037e, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5eea, 0x6803, 0x0100,
+       0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5ef2,
+       0x6827, 0x0001, 0x037f, 0x0078, 0x5efb, 0x6003, 0x0009, 0x630a,
+       0x2c30, 0x0078, 0x5f13, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+       0x5f0f, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5f1d, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078,
+       0x8c01, 0x1078, 0x7045, 0x007f, 0x0078, 0x5ec3, 0x7e16, 0x7e12,
+       0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006,
+       0x00c0, 0x5f26, 0x1078, 0x9e70, 0x0078, 0x5f0f, 0x601c, 0xa086,
+       0x0002, 0x00c0, 0x5f0f, 0x6004, 0xa086, 0x0085, 0x0040, 0x5f06,
+       0x0078, 0x5f0f, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065,
+       0x0040, 0x5fa0, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000,
+       0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x4410, 0x0040, 0x5f9d,
+       0x7e24, 0x86ff, 0x0040, 0x5f8f, 0xa680, 0x0004, 0x2004, 0xad06,
+       0x00c0, 0x5f8f, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
+       0x5f86, 0x1078, 0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078,
+       0x7188, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384,
+       0x1000, 0x0040, 0x5f6f, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
+       0x0100, 0x6824, 0xd084, 0x0040, 0x5f77, 0x6827, 0x0001, 0x037f,
+       0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5f80, 0x8001, 0x603e,
+       0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5f8f, 0x0d7f, 0x0c7e,
+       0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x5f44, 0x8dff,
+       0x0040, 0x5f99, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+       0x4982, 0x1078, 0x7045, 0x0078, 0x5f44, 0x007f, 0x0078, 0x5f37,
+       0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e,
+       0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x5fc4, 0x604c, 0xa06d,
+       0x0040, 0x5fc4, 0x6848, 0xa606, 0x00c0, 0x5fc4, 0x2071, 0xa5ab,
+       0x7024, 0xa035, 0x0040, 0x5fc4, 0xa080, 0x0004, 0x2004, 0xad06,
+       0x00c0, 0x5fc4, 0x1078, 0x5fc8, 0x067f, 0x0d7f, 0x0e7f, 0x007c,
+       0x0f7e, 0x2079, 0x0100, 0x78c0, 0xa005, 0x00c0, 0x5fd7, 0x0c7e,
+       0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x600e, 0x1078,
+       0x6c41, 0x78c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e,
+       0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0040, 0x5feb, 0x7803,
+       0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0040,
+       0x5ff3, 0x7827, 0x0001, 0x1078, 0x7188, 0x037f, 0x1078, 0x4410,
+       0x0c7e, 0x603c, 0xa005, 0x0040, 0x5fff, 0x8001, 0x603e, 0x2660,
+       0x1078, 0x753d, 0x0c7f, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+       0x1078, 0x8cb8, 0x1078, 0x4982, 0x1078, 0x7045, 0x0f7f, 0x007c,
+       0x0e7e, 0x0c7e, 0x2071, 0xa5ab, 0x7004, 0xa084, 0x0007, 0x0079,
+       0x6019, 0x6023, 0x6026, 0x603f, 0x605b, 0x60a0, 0x6023, 0x6023,
+       0x6021, 0x1078, 0x1328, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065,
+       0x0040, 0x6034, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0040,
+       0x603b, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
+       0x0c7f, 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x6034, 0x6018,
+       0x2060, 0x1078, 0x4410, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001,
+       0x7022, 0x0040, 0x6050, 0x6054, 0xa015, 0x0040, 0x6057, 0x721e,
+       0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218,
+       0x721e, 0x0078, 0x6050, 0x7024, 0xa065, 0x0040, 0x609d, 0x700c,
+       0xac06, 0x00c0, 0x6072, 0x1078, 0x7045, 0x600c, 0xa015, 0x0040,
+       0x606e, 0x720e, 0x600f, 0x0000, 0x0078, 0x609b, 0x720e, 0x720a,
+       0x0078, 0x609b, 0x7014, 0xac06, 0x00c0, 0x6085, 0x1078, 0x7045,
+       0x600c, 0xa015, 0x0040, 0x6081, 0x7216, 0x600f, 0x0000, 0x0078,
+       0x609b, 0x7216, 0x7212, 0x0078, 0x609b, 0x6018, 0x2060, 0x1078,
+       0x4410, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x7045, 0x701c, 0xa065,
+       0x0040, 0x609b, 0x6054, 0xa015, 0x0040, 0x6099, 0x721e, 0x0078,
+       0x609b, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
+       0x7024, 0xa065, 0x0040, 0x60ad, 0x1078, 0x7045, 0x600c, 0xa015,
+       0x0040, 0x60b4, 0x720e, 0x600f, 0x0000, 0x1078, 0x7188, 0x7027,
+       0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, 0x60ad,
+       0x0d7e, 0x2069, 0xa5ab, 0x6830, 0xa084, 0x0003, 0x0079, 0x60c0,
+       0x60c6, 0x60c8, 0x60ee, 0x60c6, 0x1078, 0x1328, 0x0d7f, 0x007c,
+       0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x60e4, 0x683c, 0xa065,
+       0x0040, 0x60d9, 0x600c, 0xa015, 0x0040, 0x60e0, 0x6a3a, 0x600f,
+       0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c,
+       0x683a, 0x6836, 0x0078, 0x60d9, 0x6843, 0x0000, 0x6838, 0xa065,
+       0x0040, 0x60d9, 0x6003, 0x0003, 0x0078, 0x60d9, 0x0c7e, 0x6843,
+       0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x6106, 0x600c,
+       0xa015, 0x0040, 0x6102, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+       0x0078, 0x6106, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f,
+       0x007c, 0x0d7e, 0x2069, 0xa5ab, 0x6804, 0xa084, 0x0007, 0x0079,
+       0x6111, 0x611b, 0x61c2, 0x61c2, 0x61c2, 0x61c2, 0x61c4, 0x61c2,
+       0x6119, 0x1078, 0x1328, 0x6820, 0xa005, 0x00c0, 0x6121, 0x0d7f,
+       0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x6130, 0x6807, 0x0004,
+       0x6826, 0x682b, 0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c,
+       0x6814, 0xa065, 0x0040, 0x613e, 0x6807, 0x0001, 0x6826, 0x682b,
+       0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e,
+       0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x61bd, 0x704c, 0xa00d, 0x0040,
+       0x614d, 0x7088, 0xa005, 0x0040, 0x6165, 0x7054, 0xa075, 0x0040,
+       0x6156, 0xa20e, 0x0040, 0x61bd, 0x0078, 0x615b, 0x6818, 0xa20e,
+       0x0040, 0x61bd, 0x2070, 0x704c, 0xa00d, 0x0040, 0x614d, 0x7088,
+       0xa005, 0x00c0, 0x614d, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302,
+       0x00c8, 0x614d, 0x1078, 0x750c, 0x0040, 0x61bd, 0x8318, 0x733e,
+       0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff,
+       0x6032, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004,
+       0xa08a, 0x199a, 0x0048, 0x6186, 0x2001, 0x1999, 0x8003, 0x801b,
+       0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc,
+       0x0040, 0x619f, 0x7100, 0xd1f4, 0x0040, 0x619b, 0x7114, 0xa18c,
+       0x00ff, 0x0078, 0x61a4, 0x2009, 0x0000, 0x0078, 0x61a4, 0xa1e0,
+       0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078,
+       0x679b, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26,
+       0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040,
+       0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f,
+       0x0078, 0x61bb, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040,
+       0x61d0, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x620a,
+       0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa5ab, 0x6830,
+       0xa086, 0x0000, 0x00c0, 0x61f1, 0x6838, 0xa07d, 0x0040, 0x61f1,
+       0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091,
+       0x2200, 0x027f, 0x1078, 0x1d28, 0x00c0, 0x61f4, 0x127f, 0x1078,
+       0x6ae5, 0x0d7f, 0x0f7f, 0x007c, 0x127f, 0x6843, 0x0000, 0x7803,
+       0x0002, 0x780c, 0xa015, 0x0040, 0x6206, 0x6a3a, 0x780f, 0x0000,
+       0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x61f1, 0x683a, 0x6836,
+       0x0078, 0x6200, 0x601c, 0xa084, 0x000f, 0x1079, 0x6210, 0x007c,
+       0x6219, 0x621e, 0x663f, 0x6758, 0x621e, 0x663f, 0x6758, 0x6219,
+       0x621e, 0x1078, 0x6010, 0x1078, 0x6109, 0x007c, 0x157e, 0x137e,
+       0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0044, 0x10c8, 0x1328,
+       0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x623b, 0x7900, 0xd1f4,
+       0x0040, 0x6237, 0x7914, 0xa18c, 0x00ff, 0x0078, 0x6240, 0x2009,
+       0x0000, 0x0078, 0x6240, 0xa1f8, 0x293f, 0x2f0c, 0xa18c, 0x00ff,
+       0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x00c8, 0x6292,
+       0x1079, 0x6250, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c,
+       0x62f8, 0x6340, 0x6368, 0x6403, 0x6433, 0x643b, 0x6462, 0x6473,
+       0x6484, 0x648c, 0x64a4, 0x648c, 0x650f, 0x6473, 0x6530, 0x6538,
+       0x6484, 0x6538, 0x6549, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290,
+       0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6d05, 0x6d2a,
+       0x6d3f, 0x6d62, 0x6d83, 0x6462, 0x6290, 0x6462, 0x648c, 0x6290,
+       0x6368, 0x6403, 0x6290, 0x72ac, 0x648c, 0x6290, 0x72cc, 0x648c,
+       0x6290, 0x6290, 0x62f3, 0x62a1, 0x6290, 0x72f1, 0x7368, 0x7450,
+       0x6290, 0x7461, 0x645c, 0x747d, 0x6290, 0x6d98, 0x6290, 0x6290,
+       0x1078, 0x1328, 0x2100, 0x1079, 0x629b, 0x0f7f, 0x0c7f, 0x147f,
+       0x137f, 0x157f, 0x007c, 0x629f, 0x629f, 0x629f, 0x62d5, 0x1078,
+       0x1328, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x6567, 0x7810, 0x2068,
+       0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0018, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x0d7e, 0x7818,
+       0x2068, 0x68a0, 0xa082, 0x007e, 0x0048, 0x62d2, 0xa085, 0x0001,
+       0x0d7f, 0x007c, 0xa006, 0x0078, 0x62d0, 0x0d7e, 0x20a1, 0x020b,
+       0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8,
+       0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814,
+       0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x1078,
+       0x6c2d, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x5200, 0x20a3, 0x0000,
+       0x0d7e, 0x2069, 0xa351, 0x6804, 0xd084, 0x0040, 0x6312, 0x6828,
+       0x20a3, 0x0000, 0x017e, 0x1078, 0x24fa, 0x21a2, 0x017f, 0x0d7f,
+       0x0078, 0x6317, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9,
+       0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+       0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048,
+       0x6331, 0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078,
+       0x6337, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048, 0x6358,
+       0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078, 0x635e,
+       0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004,
+       0x2099, 0xa305, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x6567, 0x0c7e, 0x7818, 0x2060, 0x2001,
+       0x0000, 0x1078, 0x48a2, 0x0c7f, 0x7818, 0xa080, 0x0028, 0x2004,
+       0xa086, 0x007e, 0x00c0, 0x6383, 0x20a3, 0x0400, 0x620c, 0xc2b4,
+       0x620e, 0x0078, 0x6385, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x63d2, 0x2099,
+       0xa58c, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, 0x3fff,
+       0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0xa305, 0x53a6,
+       0x20a9, 0x0004, 0x2099, 0xa301, 0x53a6, 0x20a9, 0x0010, 0x20a3,
+       0x0000, 0x00f0, 0x63af, 0x2099, 0xa594, 0x3304, 0xc0dd, 0x20a2,
+       0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040, 0x63ca, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, 0x0004,
+       0x0078, 0x63cc, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x00f0, 0x63cc,
+       0x0078, 0x63f2, 0x2099, 0xa58c, 0x20a9, 0x0008, 0x53a6, 0x20a9,
+       0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+       0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e3, 0x20a9,
+       0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e9, 0x2099, 0xa594, 0x20a9,
+       0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63f4,
+       0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x63fa, 0x60c3, 0x0074,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+       0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006,
+       0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351,
+       0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x641f, 0xa085, 0x0020, 0xd1a4,
+       0x0040, 0x6424, 0xa085, 0x0010, 0xa085, 0x0002, 0x0d7e, 0x0078,
+       0x64ed, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+       0x5000, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x6567, 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, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65ef,
+       0x0078, 0x6466, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3,
+       0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
+       0x0008, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+       0x20a3, 0x0200, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x65f8,
+       0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0040, 0x649b,
+       0x20a2, 0x0078, 0x649d, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3,
+       0x0008, 0x1078, 0x6c2d, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+       0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818,
+       0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x64ca, 0x6998, 0xa184,
+       0xc000, 0x00c0, 0x64c6, 0xd1ec, 0x0040, 0x64c2, 0x20a3, 0x2100,
+       0x0078, 0x64cc, 0x20a3, 0x0100, 0x0078, 0x64cc, 0x20a3, 0x0400,
+       0x0078, 0x64cc, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351, 0x7904, 0x0f7f, 0xd1ac,
+       0x00c0, 0x64dc, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x64e1, 0xa085,
+       0x0010, 0x2009, 0xa373, 0x210c, 0xd184, 0x0040, 0x64eb, 0x699c,
+       0xd18c, 0x0040, 0x64ed, 0xa085, 0x0002, 0x027e, 0x2009, 0xa371,
+       0x210c, 0xd1e4, 0x0040, 0x64fb, 0xc0c5, 0xa094, 0x0030, 0xa296,
+       0x0010, 0x0040, 0x6505, 0xd1ec, 0x0040, 0x6505, 0xa094, 0x0030,
+       0xa296, 0x0010, 0x0040, 0x6505, 0xc0bd, 0x027f, 0x20a2, 0x20a2,
+       0x20a2, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1,
+       0x020b, 0x1078, 0x65f8, 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, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x0078, 0x62fe,
+       0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+       0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x1078,
+       0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+       0x0000, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x027e, 0x037e,
+       0x047e, 0x2019, 0x3200, 0x2021, 0x0800, 0x0078, 0x656e, 0x027e,
+       0x037e, 0x047e, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e,
+       0x00c0, 0x6581, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x0078,
+       0x65b6, 0xa286, 0x007f, 0x00c0, 0x658d, 0x0d7e, 0xa385, 0x00ff,
+       0x20a2, 0x20a3, 0xfffd, 0x0078, 0x65a4, 0xd2bc, 0x0040, 0x65ac,
+       0xa286, 0x0080, 0x0d7e, 0x00c0, 0x659c, 0xa385, 0x00ff, 0x20a2,
+       0x20a3, 0xfffc, 0x0078, 0x65a4, 0xa2e8, 0xa434, 0x2d6c, 0x6810,
+       0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+       0x2da6, 0x0d7f, 0x0078, 0x65ba, 0x0d7e, 0xa2e8, 0xa434, 0x2d6c,
+       0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f, 0x037f, 0x20a3,
+       0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
+       0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc,
+       0x22a2, 0x0d7e, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+       0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x65c1, 0x20a3, 0x0100,
+       0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e,
+       0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800, 0x0078, 0x65ff,
+       0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092,
+       0x007e, 0x0048, 0x661c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+       0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+       0x2da6, 0x0d7f, 0x0078, 0x662a, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+       0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x047f,
+       0x037f, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+       0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0c7e,
+       0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a, 0x008c,
+       0x10c8, 0x1328, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x665d,
+       0x7900, 0xd1f4, 0x0040, 0x6659, 0x7914, 0xa18c, 0x00ff, 0x0078,
+       0x6662, 0x2009, 0x0000, 0x0078, 0x6662, 0xa1f8, 0x293f, 0x2f0c,
+       0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085,
+       0x1079, 0x666d, 0x0f7f, 0x0c7f, 0x007c, 0x6676, 0x6681, 0x669c,
+       0x6674, 0x6674, 0x6674, 0x6676, 0x1078, 0x1328, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x66af, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+       0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x66e3, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+       0x1078, 0x6c2d, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078,
+       0x6724, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0004, 0x1078, 0x6c2d, 0x147f, 0x007c, 0x027e,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+       0xa092, 0x007e, 0x0048, 0x66ce, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+       0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x66dd, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+       0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3,
+       0x0000, 0x0078, 0x65c1, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6702,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+       0x0078, 0x6711, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+       0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
+       0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2,
+       0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048,
+       0x6743, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8500,
+       0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+       0x0d7f, 0x0078, 0x6752, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+       0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x0078, 0x6715,
+       0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x1328,
+       0xa08a, 0x0053, 0x10c8, 0x1328, 0x7918, 0x2160, 0x61a0, 0xd1bc,
+       0x0040, 0x6777, 0x6100, 0xd1f4, 0x0040, 0x6773, 0x6114, 0xa18c,
+       0x00ff, 0x0078, 0x677c, 0x2009, 0x0000, 0x0078, 0x677c, 0xa1e0,
+       0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082,
+       0x0040, 0x1079, 0x6786, 0x0f7f, 0x0c7f, 0x007c, 0x679b, 0x68a9,
+       0x684a, 0x6a59, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799,
+       0x6799, 0x6f5e, 0x6f6f, 0x6f80, 0x6f91, 0x6799, 0x748e, 0x6799,
+       0x6f4d, 0x1078, 0x1328, 0x0d7e, 0x157e, 0x147e, 0x780b, 0xffff,
+       0x20a1, 0x020b, 0x1078, 0x6806, 0x7910, 0x2168, 0x6948, 0x7922,
+       0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x000f,
+       0x00c0, 0x67b6, 0x2001, 0x0005, 0x0078, 0x67c0, 0xd184, 0x0040,
+       0x67bd, 0x2001, 0x0004, 0x0078, 0x67c0, 0xa084, 0x0006, 0x8004,
+       0x017e, 0x2008, 0x7830, 0xa084, 0x00ff, 0x8007, 0xa105, 0x017f,
+       0x20a2, 0xd1ac, 0x0040, 0x67d0, 0x20a3, 0x0002, 0x0078, 0x67dc,
+       0xd1b4, 0x0040, 0x67d7, 0x20a3, 0x0001, 0x0078, 0x67dc, 0x20a3,
+       0x0000, 0x2230, 0x0078, 0x67de, 0x6a80, 0x6e7c, 0x20a9, 0x0008,
+       0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0, 0x67e2,
+       0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084,
+       0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa5c7, 0x2003, 0x07d0,
+       0x2001, 0xa5c6, 0x2003, 0x0009, 0x2001, 0xa5cc, 0x2003, 0x0002,
+       0x1078, 0x157e, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294,
+       0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc,
+       0x0040, 0x682c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+       0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+       0x2da6, 0x0d7f, 0x0078, 0x683b, 0x0d7e, 0xa0e8, 0xa434, 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, 0x686a, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2,
+       0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+       0x20a2, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x147f, 0x137f, 0x157f,
+       0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6888, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2,
+       0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6897,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+       0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
+       0x0889, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+       0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+       0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x7810, 0xa06d, 0x1078,
+       0x488f, 0x0040, 0x68bd, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020,
+       0x00c0, 0x68bd, 0x7824, 0xc0cd, 0x7826, 0x20a1, 0x020b, 0x1078,
+       0x6a12, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+       0xa084, 0xf000, 0x00c0, 0x68d4, 0x7810, 0xa084, 0x0700, 0x8007,
+       0x1079, 0x68dc, 0x0078, 0x68d7, 0xa006, 0x1079, 0x68dc, 0x147f,
+       0x137f, 0x157f, 0x0d7f, 0x007c, 0x68e6, 0x697e, 0x6989, 0x69b3,
+       0x69c7, 0x69e3, 0x69ee, 0x68e4, 0x1078, 0x1328, 0x017e, 0x037e,
+       0x694c, 0xa18c, 0x0003, 0x0040, 0x68f1, 0xa186, 0x0003, 0x00c0,
+       0x6900, 0x6b78, 0x7824, 0xd0cc, 0x0040, 0x68f7, 0xc3e5, 0x23a2,
+       0x6868, 0x20a2, 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x69be,
+       0xa186, 0x0001, 0x10c0, 0x1328, 0x6b78, 0x7824, 0xd0cc, 0x0040,
+       0x690a, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+       0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+       0x0300, 0x0040, 0x6978, 0xd3c4, 0x0040, 0x6920, 0x687c, 0xa108,
+       0xd3cc, 0x0040, 0x6925, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d,
+       0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x692a,
+       0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6978,
+       0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6958, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+       0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6967,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f,
+       0x7b24, 0xd3cc, 0x0040, 0x6970, 0x20a3, 0x0889, 0x0078, 0x6972,
+       0x20a3, 0x0898, 0x20a2, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+       0x61c2, 0x037f, 0x017f, 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008,
+       0x7824, 0xd0cc, 0x0040, 0x6985, 0xc2e5, 0x22a2, 0xa016, 0x0078,
+       0x69bc, 0x2011, 0x0302, 0x7824, 0xd0cc, 0x0040, 0x6990, 0xc2e5,
+       0x22a2, 0xa016, 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, 0x6c2d, 0x007c, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x0040,
+       0x69ba, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+       0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x6c2d, 0x007c, 0x2011,
+       0x0100, 0x7824, 0xd0cc, 0x0040, 0x69ce, 0xc2e5, 0x22a2, 0xa016,
+       0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2,
+       0x7834, 0xa084, 0x00ff, 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020,
+       0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0040,
+       0x69ea, 0xc2e5, 0x22a2, 0xa016, 0x0078, 0x69bc, 0x037e, 0x7b10,
+       0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x6a01,
+       0x7824, 0xd0cc, 0x0040, 0x69fd, 0xc2e5, 0x22a2, 0x037f, 0x0078,
+       0x69bc, 0x047e, 0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f,
+       0x0040, 0x6a0b, 0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f,
+       0x0078, 0x69be, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a30, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+       0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a3f,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824,
+       0xd0cc, 0x0040, 0x6a47, 0x20a3, 0x0889, 0x0078, 0x6a49, 0x20a3,
+       0x0898, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+       0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+       0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810,
+       0xa084, 0x0700, 0x8007, 0x1079, 0x6a6c, 0x037f, 0x017f, 0x147f,
+       0x137f, 0x157f, 0x0d7f, 0x007c, 0x6a74, 0x6a74, 0x6a76, 0x6a74,
+       0x6a74, 0x6a74, 0x6a9b, 0x6a74, 0x1078, 0x1328, 0x7910, 0xa18c,
+       0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+       0x1078, 0x6aa5, 0x0d7e, 0x2069, 0xa351, 0x6804, 0xd0bc, 0x0040,
+       0x6a90, 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6a92,
+       0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078,
+       0x6aa5, 0x20a3, 0x7f00, 0x0078, 0x6a93, 0x027e, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040,
+       0x6ac3, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0100,
+       0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+       0x0d7f, 0x0078, 0x6ad2, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+       0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078,
+       0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e,
+       0x057e, 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0xa300, 0x6130,
+       0x7818, 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6afc, 0x6910,
+       0x6a14, 0x6430, 0x0078, 0x6b00, 0x6910, 0x6a14, 0x7368, 0x746c,
+       0x781c, 0xa086, 0x0006, 0x0040, 0x6b5f, 0xd5bc, 0x0040, 0x6b10,
+       0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6b17,
+       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, 0x6b49, 0x6a00, 0xd2f4,
+       0x0040, 0x6b47, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6b49, 0x2011,
+       0x0000, 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084,
+       0xfff0, 0xa005, 0x0040, 0x6b56, 0x2009, 0x1b58, 0x1078, 0x595f,
+       0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810,
+       0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x6bb7,
+       0xd5bc, 0x0040, 0x6b73, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+       0x646e, 0x0078, 0x6b7a, 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, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080,
+       0x7928, 0xa109, 0x792a, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
+       0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6bb2, 0x6a00,
+       0xd2f4, 0x0040, 0x6bb0, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6bb2,
+       0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, 0x6b4c, 0xd5bc,
+       0x0040, 0x6bc2, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e,
+       0x0078, 0x6bc9, 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000,
+       0x646e, 0x1078, 0x488f, 0x0040, 0x6bdf, 0x0d7e, 0x7810, 0xa06d,
+       0x684c, 0x0d7f, 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6bdf,
+       0x7824, 0xc0cd, 0x7826, 0x6073, 0x0889, 0x0078, 0x6be1, 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, 0x6c0f, 0x6a00, 0xd2f4, 0x0040, 0x6c0d,
+       0x6a14, 0xa294, 0x00ff, 0x0078, 0x6c0f, 0x2011, 0x0000, 0x629e,
+       0x7824, 0xd0cc, 0x0040, 0x6c18, 0x6017, 0x0016, 0x0078, 0x6b4c,
+       0x6017, 0x0012, 0x0078, 0x6b4c, 0x7a18, 0xa280, 0x0023, 0x2014,
+       0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069,
+       0xa5ab, 0x6843, 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3,
+       0x0056, 0x60a7, 0x9575, 0x1078, 0x6c38, 0x1078, 0x594f, 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, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194,
+       0x4000, 0x0040, 0x6c89, 0x1078, 0x6c41, 0x6803, 0x1000, 0x6803,
+       0x0000, 0x0c7e, 0x2061, 0xa5ab, 0x6128, 0xa192, 0x00c8, 0x00c8,
+       0x6c76, 0x8108, 0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6c84,
+       0x1078, 0x594f, 0x1078, 0x6c38, 0x0078, 0x6c84, 0x6124, 0xa1e5,
+       0x0000, 0x0040, 0x6c81, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+       0x756c, 0x0c7f, 0x0078, 0x6c84, 0x027f, 0x017f, 0x0d7f, 0x0c7f,
+       0x007c, 0x2001, 0xa5c7, 0x2004, 0xa005, 0x00c0, 0x6c84, 0x0c7e,
+       0x2061, 0xa5ab, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6c76, 0x8108,
+       0x612a, 0x0c7f, 0x1078, 0x594f, 0x1078, 0x4171, 0x0078, 0x6c84,
+       0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5967, 0x2071,
+       0xa5ab, 0x713c, 0x81ff, 0x0040, 0x6cca, 0x2061, 0x0100, 0x2069,
+       0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6cd0, 0x6803, 0x1000,
+       0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x037f,
+       0x713c, 0x2160, 0x1078, 0xa241, 0x2009, 0x004a, 0x1078, 0x756c,
+       0x0078, 0x6cca, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c,
+       0x0078, 0x6cba, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, 0x047e,
+       0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071,
+       0xa5ab, 0x7018, 0x2068, 0x8dff, 0x0040, 0x6cfc, 0x68a0, 0xa406,
+       0x0040, 0x6cee, 0x6854, 0x2068, 0x0078, 0x6ce3, 0x6010, 0x2060,
+       0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, 0x466a, 0x0040, 0x6cfc,
+       0x1078, 0x7045, 0xa085, 0x0001, 0x127f, 0x007f, 0x047f, 0x057f,
+       0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x20a1, 0x020b, 0x1078,
+       0x6567, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+       0xa086, 0x0004, 0x00c0, 0x6d17, 0x6098, 0x0078, 0x6d18, 0x6030,
+       0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+       0x20a2, 0x00f0, 0x6d20, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x1078,
+       0x6c2d, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6567,
+       0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+       0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c, 0x157e,
+       0x147e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x20a3,
+       0x0000, 0x20a9, 0x0006, 0x2011, 0xa340, 0x2019, 0xa341, 0x23a6,
+       0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0, 0x6d4f, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x147f,
+       0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b,
+       0x1078, 0x65cf, 0x1078, 0x65e6, 0x7810, 0xa080, 0x0000, 0x2004,
+       0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+       0xa080, 0x0004, 0x8003, 0x60c2, 0x1078, 0x6c2d, 0x027f, 0x017f,
+       0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
+       0x6567, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+       0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c,
+       0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x6567,
+       0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+       0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x1078, 0x6c2d,
+       0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, 0x0c7e, 0x007e,
+       0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x700c, 0x2060, 0x8cff,
+       0x0040, 0x6dd1, 0x1078, 0x8c3b, 0x00c0, 0x6dc8, 0x1078, 0x7a05,
+       0x600c, 0x007e, 0x1078, 0x753d, 0x1078, 0x7045, 0x0c7f, 0x0078,
+       0x6dbf, 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, 0xa5ab, 0x7024, 0x2060, 0x8cff, 0x0040, 0x6e2a,
+       0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x595a, 0x2009, 0x0013,
+       0x1078, 0x756c, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x6e0d,
+       0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6e1f, 0x7803,
+       0x1000, 0x7803, 0x0000, 0x0078, 0x6e1f, 0xd084, 0x0040, 0x6e14,
+       0x6827, 0x0001, 0x0078, 0x6e16, 0x00f0, 0x6dfc, 0x7804, 0xa084,
+       0x1000, 0x0040, 0x6e1f, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+       0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+       0x127f, 0x007c, 0x2001, 0xa300, 0x2004, 0xa096, 0x0001, 0x0040,
+       0x6e62, 0xa096, 0x0004, 0x0040, 0x6e62, 0x6817, 0x0008, 0x68c3,
+       0x0000, 0x2011, 0x4129, 0x1078, 0x58d4, 0x20a9, 0x01f4, 0x6824,
+       0xd094, 0x0040, 0x6e50, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000,
+       0x0040, 0x6e62, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x6e62,
+       0xd084, 0x0040, 0x6e57, 0x6827, 0x0001, 0x0078, 0x6e59, 0x00f0,
+       0x6e3f, 0x7804, 0xa084, 0x1000, 0x0040, 0x6e62, 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, 0xa5ab, 0x703c, 0x2060, 0x8cff,
+       0x0040, 0x6ee8, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0,
+       0x6e86, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x1078, 0x5967, 0x1078,
+       0x1f31, 0x047e, 0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5,
+       0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+       0x6eb7, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079,
+       0x0020, 0x2071, 0xa602, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012,
+       0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a,
+       0x057f, 0x047f, 0xa39d, 0x0000, 0x00c0, 0x6ec2, 0x2009, 0x0049,
+       0x1078, 0x756c, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x6ed5,
+       0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6ee7, 0x7803,
+       0x1000, 0x7803, 0x0000, 0x0078, 0x6ee7, 0xd08c, 0x0040, 0x6edc,
+       0x6827, 0x0002, 0x0078, 0x6ede, 0x00f0, 0x6ec4, 0x7804, 0xa084,
+       0x1000, 0x0040, 0x6ee7, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+       0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+       0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa5ab,
+       0x6a06, 0x127f, 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000,
+       0x2069, 0xa5ab, 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e,
+       0x0c7e, 0x067e, 0x007e, 0x127e, 0x2071, 0xa5ab, 0x7614, 0x2660,
+       0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x6f46, 0x601c, 0xa206,
+       0x00c0, 0x6f41, 0x7014, 0xac36, 0x00c0, 0x6f20, 0x660c, 0x7616,
+       0x7010, 0xac36, 0x00c0, 0x6f2e, 0x2c00, 0xaf36, 0x0040, 0x6f2c,
+       0x2f00, 0x7012, 0x0078, 0x6f2e, 0x7013, 0x0000, 0x660c, 0x067e,
+       0x2c00, 0xaf06, 0x0040, 0x6f37, 0x7e0e, 0x0078, 0x6f38, 0x2678,
+       0x600f, 0x0000, 0x1078, 0x8c01, 0x1078, 0x7045, 0x0c7f, 0x0078,
+       0x6f13, 0x2c78, 0x600c, 0x2060, 0x0078, 0x6f13, 0x127f, 0x007f,
+       0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0078, 0x6fa0, 0x157e, 0x147e,
+       0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2,
+       0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0078, 0x6fa0, 0x157e,
+       0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006,
+       0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x6fa0,
+       0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2,
+       0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078,
+       0x6fa0, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+       0x1078, 0x7050, 0x60c3, 0x0020, 0x1078, 0x6c2d, 0x147f, 0x157f,
+       0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120,
+       0xd1b4, 0x00c0, 0x6fb8, 0xd1bc, 0x00c0, 0x7002, 0x0078, 0x7042,
+       0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069,
+       0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000,
+       0x0040, 0x6ff9, 0x6020, 0xd0b4, 0x0040, 0x6ff9, 0x6024, 0xd094,
+       0x00c0, 0x6ff9, 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+       0x6ff9, 0x00f0, 0x6fc5, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107,
+       0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b,
+       0xbc91, 0x6043, 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024,
+       0xd094, 0x00c0, 0x6ff8, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x6fef,
+       0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000,
+       0x0078, 0x7042, 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e,
+       0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804,
+       0xa084, 0x4000, 0x0040, 0x703b, 0x6020, 0xd0bc, 0x0040, 0x703b,
+       0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x703b, 0x00f0,
+       0x700f, 0x027e, 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c,
+       0x00ff, 0xa10d, 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043,
+       0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000,
+       0x00c0, 0x7035, 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f,
+       0x200b, 0x0000, 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa5ab,
+       0x7020, 0xa005, 0x0040, 0x704e, 0x8001, 0x7022, 0x0e7f, 0x007c,
+       0x20a9, 0x0008, 0x20a2, 0x00f0, 0x7052, 0x20a2, 0x20a2, 0x007c,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e,
+       0x2091, 0x8000, 0x2071, 0xa5ab, 0x7614, 0x2660, 0x2678, 0x2039,
+       0x0001, 0x87ff, 0x0040, 0x70f4, 0x8cff, 0x0040, 0x70f4, 0x601c,
+       0xa086, 0x0006, 0x00c0, 0x70ef, 0x88ff, 0x0040, 0x707f, 0x2800,
+       0xac06, 0x00c0, 0x70ef, 0x2039, 0x0000, 0x0078, 0x708a, 0x6018,
+       0xa206, 0x00c0, 0x70ef, 0x85ff, 0x0040, 0x708a, 0x6020, 0xa106,
+       0x00c0, 0x70ef, 0x7024, 0xac06, 0x00c0, 0x70ba, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0040, 0x70b5, 0x1078, 0x595a, 0x6817, 0x0008,
+       0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x70aa, 0x6803, 0x0100,
+       0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x70b2,
+       0x6827, 0x0001, 0x037f, 0x0078, 0x70ba, 0x6003, 0x0009, 0x630a,
+       0x0078, 0x70ef, 0x7014, 0xac36, 0x00c0, 0x70c0, 0x660c, 0x7616,
+       0x7010, 0xac36, 0x00c0, 0x70ce, 0x2c00, 0xaf36, 0x0040, 0x70cc,
+       0x2f00, 0x7012, 0x0078, 0x70ce, 0x7013, 0x0000, 0x660c, 0x067e,
+       0x2c00, 0xaf06, 0x0040, 0x70d7, 0x7e0e, 0x0078, 0x70d8, 0x2678,
+       0x89ff, 0x00c0, 0x70e7, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x70e5, 0x1078, 0x9e70, 0x1078, 0x8c01, 0x1078,
+       0x7045, 0x88ff, 0x00c0, 0x70fe, 0x0c7f, 0x0078, 0x7069, 0x2c78,
+       0x600c, 0x2060, 0x0078, 0x7069, 0xa006, 0x127f, 0x007f, 0x067f,
+       0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000,
+       0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x70f5, 0x0f7e, 0x0e7e, 0x0d7e,
+       0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+       0xa5ab, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x7177, 0x601c,
+       0xa086, 0x0006, 0x00c0, 0x7172, 0x87ff, 0x0040, 0x7125, 0x2700,
+       0xac06, 0x00c0, 0x7172, 0x0078, 0x7130, 0x6018, 0xa206, 0x00c0,
+       0x7172, 0x85ff, 0x0040, 0x7130, 0x6020, 0xa106, 0x00c0, 0x7172,
+       0x703c, 0xac06, 0x00c0, 0x7142, 0x037e, 0x2019, 0x0001, 0x1078,
+       0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047,
+       0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x7148, 0x660c, 0x763a,
+       0x7034, 0xac36, 0x00c0, 0x7156, 0x2c00, 0xaf36, 0x0040, 0x7154,
+       0x2f00, 0x7036, 0x0078, 0x7156, 0x7037, 0x0000, 0x660c, 0x067e,
+       0x2c00, 0xaf06, 0x0040, 0x715f, 0x7e0e, 0x0078, 0x7160, 0x2678,
+       0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x716a,
+       0x1078, 0x9e70, 0x1078, 0x8c01, 0x87ff, 0x00c0, 0x7181, 0x0c7f,
+       0x0078, 0x7114, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7114, 0xa006,
+       0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7178,
+       0x0e7e, 0x2071, 0xa5ab, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002,
+       0x00c0, 0x7196, 0x7007, 0x0005, 0x0078, 0x7198, 0x7007, 0x0000,
+       0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
+       0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x2c10, 0x7638, 0x2660,
+       0x2678, 0x8cff, 0x0040, 0x71d8, 0x2200, 0xac06, 0x00c0, 0x71d3,
+       0x7038, 0xac36, 0x00c0, 0x71b6, 0x660c, 0x763a, 0x7034, 0xac36,
+       0x00c0, 0x71c4, 0x2c00, 0xaf36, 0x0040, 0x71c2, 0x2f00, 0x7036,
+       0x0078, 0x71c4, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0040,
+       0x71cc, 0x7e0e, 0x0078, 0x71cd, 0x2678, 0x600f, 0x0000, 0xa085,
+       0x0001, 0x0078, 0x71d8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x71a9,
+       0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091,
+       0x8000, 0x2071, 0xa5ab, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040,
+       0x7279, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7274,
+       0x7024, 0xac06, 0x00c0, 0x721f, 0x2069, 0x0100, 0x68c0, 0xa005,
+       0x0040, 0x724d, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188,
+       0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+       0x0040, 0x7216, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+       0x6824, 0xd084, 0x0040, 0x721e, 0x6827, 0x0001, 0x037f, 0x700c,
+       0xac36, 0x00c0, 0x7225, 0x660c, 0x760e, 0x7008, 0xac36, 0x00c0,
+       0x7233, 0x2c00, 0xaf36, 0x0040, 0x7231, 0x2f00, 0x700a, 0x0078,
+       0x7233, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040,
+       0x723c, 0x7e0e, 0x0078, 0x723d, 0x2678, 0x600f, 0x0000, 0x1078,
+       0x8c27, 0x00c0, 0x7251, 0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0,
+       0x726d, 0x1078, 0x7a05, 0x0078, 0x726d, 0x1078, 0x7188, 0x0078,
+       0x721f, 0x1078, 0x8c3b, 0x00c0, 0x7259, 0x1078, 0x7a05, 0x0078,
+       0x726d, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x726d, 0x601c,
+       0xa086, 0x0003, 0x00c0, 0x7281, 0x6837, 0x0103, 0x6b4a, 0x6847,
+       0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+       0x7045, 0x0c7f, 0x0078, 0x71ee, 0x2c78, 0x600c, 0x2060, 0x0078,
+       0x71ee, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x726d, 0x1078, 0x9e70,
+       0x0078, 0x726d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006,
+       0xa190, 0x0020, 0x221c, 0xa39e, 0x260c, 0x00c0, 0x729b, 0x8210,
+       0x8000, 0x0078, 0x7292, 0xa005, 0x0040, 0x72a7, 0x20a9, 0x0020,
+       0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f,
+       0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+       0x65f8, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x2099, 0xa5a3, 0x20a9, 0x0004, 0x53a6,
+       0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+       0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084,
+       0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6c2d,
+       0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x8ef5,
+       0x00c0, 0x7361, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x1300,
+       0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040,
+       0x733d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0,
+       0x7317, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7352, 0xa286,
+       0x007f, 0x00c0, 0x7321, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078,
+       0x7352, 0xd2bc, 0x0040, 0x7337, 0xa286, 0x0080, 0x00c0, 0x732e,
+       0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7352, 0xa2e8, 0xa434,
+       0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7352, 0x20a3,
+       0x0000, 0x6098, 0x20a2, 0x0078, 0x7352, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xa082, 0x007e, 0x0048, 0x734e, 0x0d7e, 0x2069, 0xa31a,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7352, 0x20a3, 0x0000,
+       0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x017f, 0x0d7f,
+       0x007c, 0x7817, 0x0001, 0x7803, 0x0006, 0x017f, 0x0d7f, 0x007c,
+       0x0d7e, 0x027e, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x0040,
+       0x738a, 0xa186, 0x0003, 0x0040, 0x73e5, 0xa186, 0x0005, 0x0040,
+       0x73c8, 0xa186, 0x0004, 0x0040, 0x73b8, 0xa186, 0x0008, 0x0040,
+       0x73d2, 0x7807, 0x0037, 0x7813, 0x1700, 0x1078, 0x7450, 0x027f,
+       0x0d7f, 0x007c, 0x1078, 0x740d, 0x2009, 0x4000, 0x6800, 0x0079,
+       0x7391, 0x73a4, 0x73b2, 0x73a6, 0x73b2, 0x73ad, 0x73a4, 0x73a4,
+       0x73b2, 0x73b2, 0x73b2, 0x73b2, 0x73a4, 0x73a4, 0x73a4, 0x73a4,
+       0x73a4, 0x73b2, 0x73a4, 0x73b2, 0x1078, 0x1328, 0x6824, 0xd0e4,
+       0x0040, 0x73ad, 0xd0cc, 0x0040, 0x73b0, 0xa00e, 0x0078, 0x73b2,
+       0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0078, 0x7403,
+       0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+       0x6a00, 0xa286, 0x0002, 0x00c0, 0x73c6, 0xa00e, 0x0078, 0x7403,
+       0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+       0x0078, 0x7403, 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x2009, 0x4000, 0xa286, 0x0005, 0x0040, 0x73e2, 0xa286, 0x0002,
+       0x00c0, 0x73e3, 0xa00e, 0x0078, 0x7403, 0x1078, 0x740d, 0x6810,
+       0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2,
+       0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, 0x0040,
+       0x7401, 0xa08e, 0x0004, 0x0040, 0x7401, 0x2009, 0x4000, 0x0078,
+       0x7403, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018,
+       0x1078, 0x6c2d, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e,
+       0x067e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0xa006, 0x20a3, 0x0200,
+       0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xa092, 0x007e, 0x0048, 0x7433, 0x0d7e, 0x2069, 0xa31a,
+       0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa434, 0x2d6c, 0x6b10, 0x6c14,
+       0x0d7f, 0x0078, 0x7439, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000,
+       0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0,
+       0x7447, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x744b, 0x23a2,
+       0x24a2, 0x25a2, 0x26a2, 0x067f, 0x057f, 0x047f, 0x037f, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+       0x007c, 0x20a1, 0x020b, 0x1078, 0x655e, 0x20a3, 0x1400, 0x20a3,
+       0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c,
+       0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000,
+       0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078,
+       0x65ef, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810,
+       0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x7499, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+       0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xd0bc, 0x0040, 0x74b6, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+       0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x74be, 0x20a3, 0x0300,
+       0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819,
+       0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
+       0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061,
+       0xaa00, 0x2a70, 0x7060, 0x7046, 0x704b, 0xaa00, 0x007c, 0x0e7e,
+       0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582, 0x0010,
+       0x0048, 0x7509, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
+       0x74f5, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x74f1, 0x0078,
+       0x74e4, 0x2061, 0xaa00, 0x0078, 0x74e4, 0x6003, 0x0008, 0x8529,
+       0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x7505, 0x754a,
+       0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00, 0x0078,
+       0x7500, 0xa006, 0x0078, 0x7502, 0x0e7e, 0x2071, 0xa300, 0x7544,
+       0xa582, 0x0010, 0x0048, 0x753a, 0x7048, 0x2060, 0x6000, 0xa086,
+       0x0000, 0x0040, 0x7527, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+       0x7523, 0x0078, 0x7516, 0x2061, 0xaa00, 0x0078, 0x7516, 0x6003,
+       0x0008, 0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8,
+       0x7536, 0x754a, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+       0x0078, 0x7532, 0xa006, 0x0078, 0x7534, 0xac82, 0xaa00, 0x1048,
+       0x1328, 0x2001, 0xa315, 0x2004, 0xac02, 0x10c8, 0x1328, 0xa006,
+       0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000,
+       0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
+       0x603a, 0x603e, 0x2061, 0xa300, 0x6044, 0x8000, 0x6046, 0xa086,
+       0x0001, 0x0040, 0x7564, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x6109, 0x127f, 0x0078, 0x7563, 0x601c, 0xa084, 0x000f, 0x0079,
+       0x7571, 0x757a, 0x758b, 0x75a7, 0x75c3, 0x8f2d, 0x8f49, 0x8f65,
+       0x757a, 0x758b, 0xa186, 0x0013, 0x00c0, 0x7583, 0x1078, 0x6010,
+       0x1078, 0x6109, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x758a, 0xa016,
+       0x1078, 0x15ec, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+       0x1328, 0x1079, 0x7595, 0x067f, 0x007c, 0x75a5, 0x7891, 0x7a34,
+       0x75a5, 0x7ab8, 0x75df, 0x75a5, 0x75a5, 0x7823, 0x7e6d, 0x75a5,
+       0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x1078, 0x1328, 0x067e,
+       0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079, 0x75b1, 0x067f,
+       0x007c, 0x75c1, 0x8522, 0x75c1, 0x75c1, 0x75c1, 0x75c1, 0x75c1,
+       0x75c1, 0x84c5, 0x86a8, 0x75c1, 0x8552, 0x85d8, 0x8552, 0x85d8,
+       0x75c1, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+       0x1328, 0x1079, 0x75cd, 0x067f, 0x007c, 0x75dd, 0x7eb4, 0x7f81,
+       0x80c6, 0x8242, 0x75dd, 0x75dd, 0x75dd, 0x7e8d, 0x846d, 0x8471,
+       0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x84a1, 0x1078, 0x1328, 0xa1b6,
+       0x0015, 0x00c0, 0x75e7, 0x1078, 0x753d, 0x0078, 0x75ed, 0xa1b6,
+       0x0016, 0x10c0, 0x1328, 0x1078, 0x753d, 0x007c, 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, 0x75fc,
+       0x0e7e, 0x1078, 0x8a44, 0x0040, 0x7613, 0x6010, 0x2070, 0x7007,
+       0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c, 0x0d7e,
+       0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7624, 0x6018, 0x2068,
+       0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x762e,
+       0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x753d,
+       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,
+       0x753d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68,
+       0x017e, 0x2009, 0x0035, 0x1078, 0x8ef5, 0x017f, 0x00c0, 0x766f,
+       0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xa88c, 0x6b1c, 0xa386,
+       0x0003, 0x0040, 0x7673, 0xa386, 0x0006, 0x0040, 0x7677, 0x1078,
+       0x753d, 0x0078, 0x7679, 0x1078, 0x767c, 0x0078, 0x7679, 0x1078,
+       0x771e, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186,
+       0x0015, 0x0040, 0x7705, 0xa18e, 0x0016, 0x00c0, 0x771c, 0x700c,
+       0xa084, 0xff00, 0xa086, 0x1700, 0x00c0, 0x76e0, 0x8fff, 0x0040,
+       0x771a, 0x6808, 0xa086, 0xffff, 0x00c0, 0x7709, 0x784c, 0xa084,
+       0x0060, 0xa086, 0x0020, 0x00c0, 0x76a7, 0x797c, 0x7810, 0xa106,
+       0x00c0, 0x7709, 0x7980, 0x7814, 0xa106, 0x00c0, 0x7709, 0x1078,
+       0x8bf4, 0x6830, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e,
+       0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x1078, 0x5a98, 0x7854,
+       0xa20a, 0x0048, 0x76bc, 0x8011, 0x7a56, 0x82ff, 0x027f, 0x00c0,
+       0x76c8, 0x0c7e, 0x2d60, 0x1078, 0x8832, 0x0c7f, 0x0078, 0x771a,
+       0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc, 0x00c0, 0x76d3, 0x1078,
+       0x4290, 0x0078, 0x76d5, 0x1078, 0x436e, 0x0d7f, 0x0c7f, 0x00c0,
+       0x7709, 0x0c7e, 0x2d60, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x771a,
+       0x7008, 0xa086, 0x000b, 0x00c0, 0x76fa, 0x6018, 0x200c, 0xc1bc,
+       0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003,
+       0x000b, 0x601f, 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f,
+       0x0078, 0x771a, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7709, 0x2001,
+       0xa5a2, 0x2004, 0x683e, 0x0078, 0x771a, 0x1078, 0x7739, 0x0078,
+       0x771c, 0x8fff, 0x1040, 0x1328, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68,
+       0x684b, 0x0003, 0x1078, 0x8726, 0x1078, 0x8bf4, 0x1078, 0x8c01,
+       0x0d7f, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0xa186, 0x0015,
+       0x00c0, 0x7728, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x7736,
+       0xa18e, 0x0016, 0x00c0, 0x7738, 0x0c7e, 0x2d00, 0x2060, 0x1078,
+       0xa134, 0x1078, 0x5a41, 0x1078, 0x753d, 0x0c7f, 0x1078, 0x753d,
+       0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80, 0x7b7c, 0xd2f4,
+       0x0040, 0x7748, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x77ac,
+       0x0c7e, 0x2d60, 0x1078, 0x874a, 0x0c7f, 0x6804, 0xa086, 0x0050,
+       0x00c0, 0x7760, 0x0c7e, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+       0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x77ac,
+       0x6800, 0xa086, 0x000f, 0x0040, 0x7782, 0x8fff, 0x1040, 0x1328,
+       0x6824, 0xd0dc, 0x00c0, 0x7782, 0x6800, 0xa086, 0x0004, 0x00c0,
+       0x7787, 0x784c, 0xd0ac, 0x0040, 0x7787, 0x784c, 0xc0dc, 0xc0f4,
+       0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, 0x0001, 0x682e,
+       0x0078, 0x77a6, 0x2001, 0x0007, 0x682e, 0x0078, 0x77a6, 0x784c,
+       0xd0b4, 0x00c0, 0x7794, 0xd0ac, 0x0040, 0x7782, 0x784c, 0xd0f4,
+       0x00c0, 0x7782, 0x0078, 0x7775, 0xd2ec, 0x00c0, 0x7782, 0x7024,
+       0xa306, 0x00c0, 0x779f, 0x7020, 0xa406, 0x0040, 0x7782, 0x7020,
+       0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x1078, 0x8d2b,
+       0x1078, 0x6109, 0x0078, 0x77ae, 0x1078, 0x753d, 0x047f, 0x037f,
+       0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034, 0x2068, 0x6a1c,
+       0xa286, 0x0007, 0x0040, 0x7806, 0xa286, 0x0002, 0x0040, 0x7806,
+       0xa286, 0x0000, 0x0040, 0x7806, 0x6808, 0x6338, 0xa306, 0x00c0,
+       0x7806, 0x2071, 0xa88c, 0xa186, 0x0015, 0x0040, 0x7800, 0xa18e,
+       0x0016, 0x00c0, 0x77e8, 0x6030, 0xa084, 0x00ff, 0xa086, 0x0001,
+       0x00c0, 0x77e8, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x77e8, 0x6034,
+       0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102, 0x0078, 0x7800,
+       0x0c7e, 0x6034, 0x2060, 0x6010, 0x2068, 0x1078, 0x8a44, 0x1040,
+       0x1328, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+       0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x7806,
+       0x6034, 0x2068, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x1078, 0x753d,
+       0x027f, 0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98,
+       0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7820, 0x6018,
+       0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802,
+       0x0d7f, 0x0078, 0x7608, 0x2100, 0xa1b2, 0x0044, 0x10c8, 0x1328,
+       0xa1b2, 0x0040, 0x00c8, 0x7888, 0x0079, 0x782e, 0x787c, 0x7870,
+       0x787c, 0x787c, 0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x787c,
+       0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x786e, 0x1078, 0x1328,
+       0x6003, 0x0001, 0x6106, 0x1078, 0x5c45, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
+       0x5c45, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c,
+       0x2600, 0x0079, 0x788b, 0x788f, 0x788f, 0x788f, 0x787c, 0x1078,
+       0x1328, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328, 0xa1b6, 0x0013,
+       0x00c0, 0x78a1, 0xa0b2, 0x0040, 0x00c8, 0x79fb, 0x2008, 0x0079,
+       0x7941, 0xa1b6, 0x0027, 0x00c0, 0x78fe, 0x1078, 0x6010, 0x6004,
+       0x1078, 0x8c27, 0x0040, 0x78be, 0x1078, 0x8c3b, 0x0040, 0x78f6,
+       0xa08e, 0x0021, 0x0040, 0x78fa, 0xa08e, 0x0022, 0x0040, 0x78f6,
+       0xa08e, 0x003d, 0x0040, 0x78fa, 0x0078, 0x78f1, 0x1078, 0x2839,
+       0x2001, 0x0007, 0x1078, 0x443f, 0x6018, 0xa080, 0x0028, 0x200c,
+       0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x78d3, 0x2001, 0xa332,
+       0x2014, 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019,
+       0x0028, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078, 0x5c78,
+       0x0c7e, 0x6018, 0xa065, 0x0040, 0x78e7, 0x1078, 0x471b, 0x0c7f,
+       0x2c08, 0x1078, 0x9c38, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078,
+       0x44bc, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x7a05,
+       0x0078, 0x78f1, 0x1078, 0x7a28, 0x0078, 0x78f1, 0xa186, 0x0014,
+       0x00c0, 0x78f5, 0x1078, 0x6010, 0x1078, 0x2813, 0x1078, 0x8c27,
+       0x00c0, 0x791d, 0x1078, 0x2839, 0x6018, 0xa080, 0x0028, 0x200c,
+       0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x791b, 0x2001, 0xa332,
+       0x200c, 0xc185, 0x2102, 0x0078, 0x78f1, 0x1078, 0x8c3b, 0x00c0,
+       0x7925, 0x1078, 0x7a05, 0x0078, 0x78f1, 0x6004, 0xa08e, 0x0032,
+       0x00c0, 0x7936, 0x0e7e, 0x0f7e, 0x2071, 0xa381, 0x2079, 0x0000,
+       0x1078, 0x2b56, 0x0f7f, 0x0e7f, 0x0078, 0x78f1, 0x6004, 0xa08e,
+       0x0021, 0x0040, 0x7921, 0xa08e, 0x0022, 0x1040, 0x7a05, 0x0078,
+       0x78f1, 0x7983, 0x7985, 0x7989, 0x798d, 0x7991, 0x7995, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7999,
+       0x79ab, 0x7981, 0x79ad, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x79ab, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x79de, 0x79ab, 0x7981, 0x79a5, 0x7981,
+       0x7981, 0x7981, 0x79a7, 0x7981, 0x7981, 0x7981, 0x79ab, 0x7981,
+       0x7981, 0x1078, 0x1328, 0x0078, 0x79ab, 0x2001, 0x000b, 0x0078,
+       0x79b8, 0x2001, 0x0003, 0x0078, 0x79b8, 0x2001, 0x0005, 0x0078,
+       0x79b8, 0x2001, 0x0001, 0x0078, 0x79b8, 0x2001, 0x0009, 0x0078,
+       0x79b8, 0x1078, 0x6010, 0x6003, 0x0005, 0x2001, 0xa5a2, 0x2004,
+       0x603e, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0078, 0x79ab, 0x0078,
+       0x79ab, 0x1078, 0x443f, 0x0078, 0x79f0, 0x1078, 0x6010, 0x6003,
+       0x0004, 0x2001, 0xa5a0, 0x2004, 0x6016, 0x1078, 0x6109, 0x007c,
+       0x1078, 0x443f, 0x1078, 0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e,
+       0x6003, 0x0002, 0x037e, 0x2019, 0xa35c, 0x2304, 0xa084, 0xff00,
+       0x00c0, 0x79cf, 0x2019, 0xa5a0, 0x231c, 0x0078, 0x79d8, 0x8007,
+       0xa09a, 0x0004, 0x0048, 0x79ca, 0x8003, 0x801b, 0x831b, 0xa318,
+       0x6316, 0x037f, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0e7e, 0x0f7e,
+       0x2071, 0xa381, 0x2079, 0x0000, 0x1078, 0x2b56, 0x0f7f, 0x0e7f,
+       0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x0078, 0x79b7,
+       0x1078, 0x6010, 0x6003, 0x0002, 0x2001, 0xa5a0, 0x2004, 0x6016,
+       0x1078, 0x6109, 0x007c, 0x2600, 0x2008, 0x0079, 0x79ff, 0x7a03,
+       0x7a03, 0x7a03, 0x79f0, 0x1078, 0x1328, 0x0e7e, 0x1078, 0x8a44,
+       0x0040, 0x7a21, 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7a21,
+       0x7007, 0x0000, 0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7a23,
+       0xa08e, 0x003d, 0x0040, 0x7a23, 0x017f, 0x7037, 0x0103, 0x7033,
+       0x0100, 0x0e7f, 0x007c, 0x017f, 0x1078, 0x7a28, 0x0078, 0x7a21,
+       0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103,
+       0x7023, 0x8001, 0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804,
+       0xa084, 0x00ff, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0x6604,
+       0xa6b6, 0x0043, 0x00c0, 0x7a48, 0x1078, 0x8e6d, 0x0078, 0x7aa7,
+       0x6604, 0xa6b6, 0x0033, 0x00c0, 0x7a51, 0x1078, 0x8e11, 0x0078,
+       0x7aa7, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x7a5a, 0x1078, 0x8c6a,
+       0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7a63, 0x1078,
+       0x8c84, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7a6c,
+       0x1078, 0x75ee, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0000, 0x00c0,
+       0x7a75, 0x1078, 0x780c, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0022,
+       0x00c0, 0x7a7e, 0x1078, 0x7617, 0x0078, 0x7aa7, 0x6604, 0xa6b6,
+       0x0035, 0x00c0, 0x7a87, 0x1078, 0x7653, 0x0078, 0x7aa7, 0x6604,
+       0xa6b6, 0x0039, 0x00c0, 0x7a90, 0x1078, 0x77b2, 0x0078, 0x7aa7,
+       0x6604, 0xa6b6, 0x003d, 0x00c0, 0x7a99, 0x1078, 0x7633, 0x0078,
+       0x7aa7, 0xa1b6, 0x0015, 0x00c0, 0x7aa1, 0x1079, 0x7aac, 0x0078,
+       0x7aa7, 0xa1b6, 0x0016, 0x00c0, 0x7aa8, 0x1079, 0x7bfd, 0x007c,
+       0x1078, 0x7583, 0x0078, 0x7aa7, 0x7ad0, 0x7ad3, 0x7ad0, 0x7b1e,
+       0x7ad0, 0x7b91, 0x7c09, 0x7ad0, 0x7ad0, 0x7bd5, 0x7ad0, 0x7beb,
+       0xa1b6, 0x0048, 0x0040, 0x7ac4, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+       0x2c10, 0x1078, 0x15ec, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74,
+       0x7000, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c,
+       0x0005, 0x0005, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086,
+       0x0074, 0x00c0, 0x7b07, 0x1078, 0x9c0c, 0x00c0, 0x7af9, 0x0d7e,
+       0x6018, 0x2068, 0x7030, 0xd08c, 0x0040, 0x7aec, 0x6800, 0xd0bc,
+       0x0040, 0x7aec, 0xc0c5, 0x6802, 0x1078, 0x7b0b, 0x0d7f, 0x2001,
+       0x0006, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078,
+       0x7b09, 0x2001, 0x000a, 0x1078, 0x443f, 0x1078, 0x2839, 0x6003,
+       0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7b09, 0x1078,
+       0x7b81, 0x0e7f, 0x007c, 0x6800, 0xd084, 0x0040, 0x7b1d, 0x2001,
+       0x0000, 0x1078, 0x442b, 0x2069, 0xa351, 0x6804, 0xd0a4, 0x0040,
+       0x7b1d, 0x2001, 0x0006, 0x1078, 0x4472, 0x007c, 0x0d7e, 0x2011,
+       0xa31f, 0x2204, 0xa086, 0x0074, 0x00c0, 0x7b7d, 0x6018, 0x2068,
+       0x6aa0, 0xa286, 0x007e, 0x00c0, 0x7b31, 0x1078, 0x7d17, 0x0078,
+       0x7b7f, 0x1078, 0x7d0d, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014,
+       0xa286, 0x0080, 0x00c0, 0x7b55, 0x6813, 0x00ff, 0x6817, 0xfffc,
+       0x6010, 0xa005, 0x0040, 0x7b4b, 0x2068, 0x6807, 0x0000, 0x6837,
+       0x0103, 0x6833, 0x0200, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+       0x2839, 0x1078, 0x753d, 0x0078, 0x7b7f, 0x0e7e, 0x2071, 0xa332,
+       0x2e04, 0xd09c, 0x0040, 0x7b70, 0x2071, 0xa880, 0x7108, 0x720c,
+       0xa18c, 0x00ff, 0x00c0, 0x7b68, 0xa284, 0xff00, 0x0040, 0x7b70,
+       0x6018, 0x2070, 0x70a0, 0xd0bc, 0x00c0, 0x7b70, 0x7112, 0x7216,
+       0x0e7f, 0x2001, 0x0004, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+       0x0003, 0x1078, 0x5c45, 0x0078, 0x7b7f, 0x1078, 0x7b81, 0x0d7f,
+       0x007c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x0040, 0x7b8c,
+       0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d,
+       0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086, 0x0014, 0x00c0,
+       0x7bcf, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7ba4, 0x6010, 0xa005,
+       0x00c0, 0x7ba4, 0x1078, 0x35f7, 0x0d7e, 0x6018, 0x2068, 0x1078,
+       0x457d, 0x1078, 0x7b0b, 0x0d7f, 0x1078, 0x7dba, 0x00c0, 0x7bcf,
+       0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x7bcf,
+       0x2001, 0x0006, 0x1078, 0x443f, 0x0e7e, 0x6010, 0xa005, 0x0040,
+       0x7bc8, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200,
+       0x0e7f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078, 0x7bd3, 0x1078,
+       0x7a05, 0x1078, 0x7b81, 0x0e7f, 0x007c, 0x2011, 0xa31f, 0x2204,
+       0xa086, 0x0014, 0x00c0, 0x7be8, 0x2001, 0x0002, 0x1078, 0x443f,
+       0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7bea,
+       0x1078, 0x7b81, 0x007c, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0004,
+       0x00c0, 0x7bfa, 0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x753d,
+       0x0078, 0x7bfc, 0x1078, 0x7b81, 0x007c, 0x7ad0, 0x7c11, 0x7ad0,
+       0x7c4e, 0x7ad0, 0x7cc0, 0x7c09, 0x7ad0, 0x7ad0, 0x7cd5, 0x7ad0,
+       0x7ce8, 0x6604, 0xa6b6, 0x001e, 0x00c0, 0x7c10, 0x1078, 0x753d,
+       0x007c, 0x0d7e, 0x0c7e, 0x1078, 0x7cfb, 0x00c0, 0x7c27, 0x2001,
+       0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003,
+       0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x0078, 0x7c4b, 0x2009,
+       0xa88e, 0x2104, 0xa086, 0x0009, 0x00c0, 0x7c3c, 0x6018, 0x2068,
+       0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x7c49, 0x8001, 0x6842,
+       0x6017, 0x000a, 0x0078, 0x7c4b, 0x2009, 0xa88f, 0x2104, 0xa084,
+       0xff00, 0xa086, 0x1900, 0x00c0, 0x7c49, 0x1078, 0x753d, 0x0078,
+       0x7c4b, 0x1078, 0x7b81, 0x0c7f, 0x0d7f, 0x007c, 0x1078, 0x7d0a,
+       0x00c0, 0x7c62, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002,
+       0x1078, 0x443f, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45,
+       0x0078, 0x7c8e, 0x1078, 0x7a05, 0x2009, 0xa88e, 0x2134, 0xa6b4,
+       0x00ff, 0xa686, 0x0005, 0x0040, 0x7c8f, 0xa686, 0x000b, 0x0040,
+       0x7c8c, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0x00c0, 0x7c7c,
+       0xa686, 0x0009, 0x0040, 0x7c8f, 0xa086, 0x1900, 0x00c0, 0x7c8c,
+       0xa686, 0x0009, 0x0040, 0x7c8f, 0x2001, 0x0004, 0x1078, 0x443f,
+       0x1078, 0x753d, 0x0078, 0x7c8e, 0x1078, 0x7b81, 0x007c, 0x0d7e,
+       0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x7c9d, 0x6838, 0xd0fc,
+       0x0040, 0x7c9d, 0x0d7f, 0x0078, 0x7c8c, 0x6018, 0x2068, 0x6840,
+       0xa084, 0x00ff, 0xa005, 0x0040, 0x7cae, 0x8001, 0x6842, 0x6017,
+       0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x7c8e, 0x68a0, 0xa086,
+       0x007e, 0x00c0, 0x7cbb, 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5,
+       0x0e7f, 0x0078, 0x7cbd, 0x1078, 0x2813, 0x0d7f, 0x0078, 0x7c8c,
+       0x1078, 0x7d0a, 0x00c0, 0x7cd0, 0x2001, 0x0004, 0x1078, 0x443f,
+       0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x5c45, 0x0078, 0x7cd4,
+       0x1078, 0x7a05, 0x1078, 0x7b81, 0x007c, 0x1078, 0x7d0a, 0x00c0,
+       0x7ce5, 0x2001, 0x0008, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+       0x0005, 0x1078, 0x5c45, 0x0078, 0x7ce7, 0x1078, 0x7b81, 0x007c,
+       0x1078, 0x7d0a, 0x00c0, 0x7cf8, 0x2001, 0x000a, 0x1078, 0x443f,
+       0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7cfa,
+       0x1078, 0x7b81, 0x007c, 0x2009, 0xa88e, 0x2104, 0xa086, 0x0003,
+       0x00c0, 0x7d09, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0xa086,
+       0x2a00, 0x007c, 0xa085, 0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88,
+       0x0006, 0x2164, 0x1078, 0x4513, 0x017f, 0x0c7f, 0x007c, 0x0f7e,
+       0x0e7e, 0x0d7e, 0x037e, 0x017e, 0x6018, 0x2068, 0x2071, 0xa332,
+       0x2e04, 0xa085, 0x0003, 0x2072, 0x1078, 0x7d8b, 0x0040, 0x7d50,
+       0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x7d39, 0xa006, 0x2020,
+       0x2009, 0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195,
+       0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x27e2, 0x2071,
+       0xa300, 0x1078, 0x260d, 0x0c7e, 0x157e, 0x20a9, 0x0081, 0x2009,
+       0x007f, 0x1078, 0x2921, 0x8108, 0x00f0, 0x7d49, 0x157f, 0x0c7f,
+       0x1078, 0x7d0d, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0xa880,
+       0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa31a, 0x206a,
+       0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa31b, 0x206a, 0x78ea,
+       0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa325, 0x200a, 0x2069,
+       0xa88e, 0x2071, 0xa59c, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+       0x700a, 0x681c, 0x700e, 0x1078, 0x8da9, 0x2001, 0x0006, 0x1078,
+       0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x017f, 0x037f, 0x0d7f,
+       0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e, 0x2019,
+       0xa325, 0x231c, 0x83ff, 0x0040, 0x7db5, 0x2071, 0xa880, 0x2e14,
+       0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x00c0,
+       0x7db5, 0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078,
+       0x7e55, 0x00c0, 0x7db5, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9,
+       0x0004, 0x1078, 0x7e55, 0x00c0, 0x7db5, 0x157f, 0x0e7f, 0x037f,
+       0x027f, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7004, 0xa086, 0x0014,
+       0x00c0, 0x7ddd, 0x7008, 0xa086, 0x0800, 0x00c0, 0x7ddd, 0x700c,
+       0xd0ec, 0x0040, 0x7ddb, 0xa084, 0x0f00, 0xa086, 0x0100, 0x00c0,
+       0x7ddb, 0x7024, 0xd0a4, 0x00c0, 0x7dd8, 0xd0ac, 0x0040, 0x7ddb,
+       0xa006, 0x0078, 0x7ddd, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e,
+       0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e,
+       0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba, 0x2424,
+       0x2061, 0xaa00, 0x2071, 0xa300, 0x7244, 0x7060, 0xa202, 0x00c8,
+       0x7e43, 0x1078, 0x9ee5, 0x0040, 0x7e3b, 0x671c, 0xa786, 0x0001,
+       0x0040, 0x7e3b, 0xa786, 0x0007, 0x0040, 0x7e3b, 0x2500, 0xac06,
+       0x0040, 0x7e3b, 0x2400, 0xac06, 0x0040, 0x7e3b, 0x0c7e, 0x6000,
+       0xa086, 0x0004, 0x00c0, 0x7e16, 0x1078, 0x1749, 0xa786, 0x0008,
+       0x00c0, 0x7e25, 0x1078, 0x8c3b, 0x00c0, 0x7e25, 0x0c7f, 0x1078,
+       0x7a05, 0x1078, 0x8c01, 0x0078, 0x7e3b, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x7e38, 0xa786, 0x0003, 0x00c0, 0x7e4d, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4,
+       0x1078, 0x8c01, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+       0x7e43, 0x0078, 0x7df4, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f,
+       0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+       0x7e2f, 0x1078, 0x9e70, 0x0078, 0x7e38, 0x220c, 0x2304, 0xa106,
+       0x00c0, 0x7e60, 0x8210, 0x8318, 0x00f0, 0x7e55, 0xa006, 0x007c,
+       0x2304, 0xa102, 0x0048, 0x7e68, 0x2001, 0x0001, 0x0078, 0x7e6a,
+       0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0044,
+       0x10c8, 0x1328, 0x1078, 0x8c27, 0x0040, 0x7e7c, 0x1078, 0x8c3b,
+       0x0040, 0x7e89, 0x0078, 0x7e82, 0x1078, 0x2839, 0x1078, 0x8c3b,
+       0x0040, 0x7e89, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+       0x007c, 0x1078, 0x7a05, 0x0078, 0x7e82, 0xa182, 0x0040, 0x0079,
+       0x7e91, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4,
+       0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x7ea6, 0x7ea6, 0x7ea6,
+       0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x1078, 0x1328, 0x600b, 0xffff,
+       0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x6109, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x7ebd,
+       0x6004, 0xa082, 0x0040, 0x0079, 0x7f48, 0xa186, 0x0027, 0x00c0,
+       0x7edf, 0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168,
+       0x1078, 0x8a44, 0x0040, 0x7ed9, 0x6837, 0x0103, 0x684b, 0x0029,
+       0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4982, 0x1078,
+       0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0xa186,
+       0x0014, 0x00c0, 0x7ee8, 0x6004, 0xa082, 0x0040, 0x0079, 0x7f10,
+       0xa186, 0x0046, 0x0040, 0x7ef4, 0xa186, 0x0045, 0x0040, 0x7ef4,
+       0xa186, 0x0047, 0x10c0, 0x1328, 0x2001, 0x0109, 0x2004, 0xd084,
+       0x0040, 0x7f0d, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e,
+       0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086,
+       0x0002, 0x00c0, 0x7f0d, 0x0078, 0x7f81, 0x1078, 0x7583, 0x007c,
+       0x7f25, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23,
+       0x7f23, 0x7f23, 0x7f23, 0x7f41, 0x7f41, 0x7f41, 0x7f41, 0x7f23,
+       0x7f41, 0x7f23, 0x7f41, 0x1078, 0x1328, 0x1078, 0x6010, 0x0d7e,
+       0x6110, 0x2168, 0x1078, 0x8a44, 0x0040, 0x7f3b, 0x6837, 0x0103,
+       0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x1078,
+       0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109,
+       0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c,
+       0x7f5d, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b,
+       0x7f5b, 0x7f5b, 0x7f5b, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f5b,
+       0x7f7a, 0x7f5b, 0x7f6f, 0x1078, 0x1328, 0x1078, 0x6010, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x6109, 0x6010,
+       0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078,
+       0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x000f, 0x1078,
+       0x6109, 0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+       0x007c, 0xa182, 0x0040, 0x0079, 0x7f85, 0x7f98, 0x7f98, 0x7f98,
+       0x7f98, 0x7f98, 0x7f9a, 0x8095, 0x80b7, 0x7f98, 0x7f98, 0x7f98,
+       0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98,
+       0x1078, 0x1328, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2071, 0xa880,
+       0x7124, 0x610a, 0x2071, 0xa88c, 0x6110, 0x2168, 0x7614, 0xa6b4,
+       0x0fff, 0x86ff, 0x0040, 0x8058, 0xa68c, 0x0c00, 0x0040, 0x7fd1,
+       0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x7fcd, 0x684c,
+       0xd0ac, 0x0040, 0x7fcd, 0x6024, 0xd0dc, 0x00c0, 0x7fcd, 0x6850,
+       0xd0bc, 0x00c0, 0x7fcd, 0x7318, 0x6814, 0xa306, 0x00c0, 0x806f,
+       0x731c, 0x6810, 0xa306, 0x00c0, 0x806f, 0x7318, 0x6b62, 0x731c,
+       0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x8004, 0xa186,
+       0x0028, 0x00c0, 0x7fe1, 0x1078, 0x8c15, 0x684b, 0x001c, 0x0078,
+       0x8006, 0xd6dc, 0x0040, 0x7ffd, 0x684b, 0x0015, 0x684c, 0xd0ac,
+       0x0040, 0x7ffb, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x7ffb,
+       0x7018, 0xa106, 0x00c0, 0x7ff8, 0x701c, 0xa206, 0x0040, 0x7ffb,
+       0x6962, 0x6a5e, 0xc6dc, 0x0078, 0x8006, 0xd6d4, 0x0040, 0x8004,
+       0x684b, 0x0007, 0x0078, 0x8006, 0x684b, 0x0000, 0x6837, 0x0103,
+       0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x802f, 0xa686, 0x0100, 0x00c0,
+       0x801a, 0x2001, 0xa899, 0x2004, 0xa005, 0x00c0, 0x801a, 0xc6c4,
+       0x0078, 0x7fa9, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x802f,
+       0xa38a, 0x0009, 0x0048, 0x8026, 0x2019, 0x0008, 0x037e, 0x2308,
+       0x2019, 0xa898, 0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc,
+       0x0040, 0x8085, 0x7124, 0x695a, 0x81ff, 0x0040, 0x8085, 0xa192,
+       0x0021, 0x00c8, 0x8046, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18,
+       0xad90, 0x001d, 0x1078, 0x8739, 0x0078, 0x8085, 0x6838, 0xd0fc,
+       0x0040, 0x804f, 0x2009, 0x0020, 0x695a, 0x0078, 0x803b, 0x0f7e,
+       0x2d78, 0x1078, 0x86d1, 0x0f7f, 0x1078, 0x8726, 0x0078, 0x8087,
+       0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8075, 0x684c,
+       0xd0ac, 0x0040, 0x8075, 0x6024, 0xd0dc, 0x00c0, 0x8075, 0x6850,
+       0xd0bc, 0x00c0, 0x8075, 0x684c, 0xd0f4, 0x00c0, 0x8075, 0x1078,
+       0x8cfa, 0x0d7f, 0x0e7f, 0x0078, 0x8094, 0x684b, 0x0000, 0x6837,
+       0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x8085, 0x6810, 0x6914,
+       0xa115, 0x0040, 0x8085, 0x1078, 0x8233, 0x1078, 0x4982, 0x6218,
+       0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x1078, 0x8cc4, 0x0d7f, 0x0e7f,
+       0x00c0, 0x8094, 0x1078, 0x753d, 0x007c, 0x0f7e, 0x6003, 0x0003,
+       0x2079, 0xa88c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078,
+       0x784c, 0xd0ac, 0x0040, 0x80a8, 0x6003, 0x0002, 0x0f7f, 0x007c,
+       0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x603f, 0x0000, 0x2c10,
+       0x1078, 0x1cab, 0x1078, 0x5c64, 0x1078, 0x61d3, 0x007c, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
+       0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0xa182, 0x0040,
+       0x0079, 0x80ca, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80df,
+       0x8182, 0x80dd, 0x80dd, 0x8198, 0x8209, 0x80dd, 0x80dd, 0x80dd,
+       0x80dd, 0x8218, 0x80dd, 0x80dd, 0x80dd, 0x1078, 0x1328, 0x077e,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xa88c, 0x6110, 0x2178, 0x7614,
+       0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268,
+       0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x817d, 0xa694, 0xff00,
+       0xa284, 0x0c00, 0x0040, 0x8100, 0x7018, 0x7862, 0x701c, 0x785e,
+       0xa284, 0x0300, 0x0040, 0x817d, 0x1078, 0x1381, 0x1040, 0x1328,
+       0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
+       0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+       0x0040, 0x811e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+       0xa186, 0x0002, 0x0040, 0x813a, 0xa186, 0x0028, 0x00c0, 0x812c,
+       0x684b, 0x001c, 0x0078, 0x813c, 0xd6dc, 0x0040, 0x8133, 0x684b,
+       0x0015, 0x0078, 0x813c, 0xd6d4, 0x0040, 0x813a, 0x684b, 0x0007,
+       0x0078, 0x813c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+       0x6856, 0xa01e, 0xd6c4, 0x0040, 0x815a, 0x7328, 0x732c, 0x6b56,
+       0x83ff, 0x0040, 0x815a, 0xa38a, 0x0009, 0x0048, 0x8151, 0x2019,
+       0x0008, 0x037e, 0x2308, 0x2019, 0xa898, 0xad90, 0x0019, 0x1078,
+       0x8739, 0x037f, 0xd6cc, 0x0040, 0x817d, 0x7124, 0x695a, 0x81ff,
+       0x0040, 0x817d, 0xa192, 0x0021, 0x00c8, 0x8171, 0x2071, 0xa898,
+       0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x8739, 0x0078,
+       0x817d, 0x7838, 0xd0fc, 0x0040, 0x817a, 0x2009, 0x0020, 0x695a,
+       0x0078, 0x8166, 0x2d78, 0x1078, 0x86d1, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xa88c, 0x7c04,
+       0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a,
+       0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x6c26, 0x007c,
+       0x0d7e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x81a4,
+       0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x60b8,
+       0x1078, 0x61d3, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x8207,
+       0xd1cc, 0x0040, 0x81de, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x81d6,
+       0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198,
+       0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318,
+       0x8210, 0x00f0, 0x81c5, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e,
+       0x017f, 0x2168, 0x1078, 0x13aa, 0x0078, 0x8201, 0x017e, 0x1078,
+       0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8201, 0x6837, 0x0103,
+       0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x81fd, 0xa086,
+       0x0028, 0x00c0, 0x81ef, 0x684b, 0x001c, 0x0078, 0x81ff, 0xd1dc,
+       0x0040, 0x81f6, 0x684b, 0x0015, 0x0078, 0x81ff, 0xd1d4, 0x0040,
+       0x81fd, 0x684b, 0x0007, 0x0078, 0x81ff, 0x684b, 0x0000, 0x1078,
+       0x4982, 0x1078, 0x8cc4, 0x00c0, 0x8207, 0x1078, 0x753d, 0x0d7f,
+       0x007c, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x6003, 0x0002, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x1078, 0x60b8, 0x1078, 0x61d3, 0x007c,
+       0x1078, 0x60b8, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168, 0x1078,
+       0x8a44, 0x0040, 0x822d, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847,
+       0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+       0x1078, 0x61d3, 0x007c, 0x684b, 0x0015, 0xd1fc, 0x0040, 0x823f,
+       0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+       0x685e, 0x007c, 0xa182, 0x0040, 0x0079, 0x8246, 0x8259, 0x8259,
+       0x8259, 0x8259, 0x8259, 0x825b, 0x8259, 0x8333, 0x833f, 0x8259,
+       0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259,
+       0x8259, 0x1078, 0x1328, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071,
+       0xa88c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x0f7f, 0x0040, 0x827e, 0xa684, 0x00ff, 0x00c0,
+       0x827e, 0x6024, 0xd0f4, 0x00c0, 0x827a, 0x7808, 0xa086, 0x0000,
+       0x00c0, 0x827e, 0x1078, 0x8cfa, 0x0078, 0x832e, 0x7e46, 0x7f4c,
+       0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff,
+       0x0040, 0x8323, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x8294,
+       0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x8320,
+       0xa686, 0x0100, 0x00c0, 0x82a6, 0x2001, 0xa899, 0x2004, 0xa005,
+       0x00c0, 0x82a6, 0xc6c4, 0x7e46, 0x0078, 0x8287, 0x1078, 0x1381,
+       0x1040, 0x1328, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e,
+       0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842,
+       0x6e46, 0xa68c, 0x0c00, 0x0040, 0x82c1, 0x7318, 0x6b62, 0x731c,
+       0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x82dd, 0xa186,
+       0x0028, 0x00c0, 0x82cf, 0x684b, 0x001c, 0x0078, 0x82df, 0xd6dc,
+       0x0040, 0x82d6, 0x684b, 0x0015, 0x0078, 0x82df, 0xd6d4, 0x0040,
+       0x82dd, 0x684b, 0x0007, 0x0078, 0x82df, 0x684b, 0x0000, 0x6f4e,
+       0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x82fd,
+       0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x82fd, 0xa38a, 0x0009,
+       0x0048, 0x82f4, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xa898,
+       0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc, 0x0040, 0x8320,
+       0x7124, 0x695a, 0x81ff, 0x0040, 0x8320, 0xa192, 0x0021, 0x00c8,
+       0x8314, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d,
+       0x1078, 0x8739, 0x0078, 0x8320, 0x7838, 0xd0fc, 0x0040, 0x831d,
+       0x2009, 0x0020, 0x695a, 0x0078, 0x8309, 0x2d78, 0x1078, 0x86d1,
+       0xd6dc, 0x00c0, 0x8326, 0xa006, 0x0078, 0x832c, 0x2001, 0x0001,
+       0x2071, 0xa88c, 0x7218, 0x731c, 0x1078, 0x1645, 0x0d7f, 0x0e7f,
+       0x0f7f, 0x077f, 0x007c, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x20e1,
+       0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168,
+       0x694c, 0xd1e4, 0x0040, 0x846b, 0x603f, 0x0000, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x0f7f, 0x0040, 0x8385, 0x6814, 0x6910, 0xa115,
+       0x0040, 0x8385, 0x6a60, 0xa206, 0x00c0, 0x8362, 0x685c, 0xa106,
+       0x0040, 0x8385, 0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863,
+       0x0000, 0x685f, 0x0000, 0x6024, 0xd0f4, 0x00c0, 0x837a, 0x697c,
+       0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6024,
+       0xc0f5, 0x6026, 0x0d7e, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+       0x0d7f, 0x1078, 0x8cfa, 0x0078, 0x846b, 0x694c, 0xd1cc, 0x0040,
+       0x8430, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x83ea, 0x017e, 0x684c,
+       0x007e, 0x6850, 0x007e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x0040, 0x83bf, 0xa086, 0x0028, 0x00c0, 0x83a6,
+       0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x83ca, 0xd1dc, 0x0040,
+       0x83b6, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+       0x83b4, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x83ca, 0xd1d4, 0x0040,
+       0x83bf, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x83ca, 0x684c,
+       0xd0ac, 0x0040, 0x83ca, 0x6810, 0x6914, 0xa115, 0x0040, 0x83ca,
+       0x1078, 0x8233, 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e,
+       0xad90, 0x000d, 0xaf98, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8,
+       0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x83d8, 0x157f, 0x0f7f,
+       0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x13aa,
+       0x0078, 0x8465, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x0040, 0x8417, 0xa086, 0x0028, 0x00c0, 0x83fe,
+       0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x8422, 0xd1dc, 0x0040,
+       0x840e, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+       0x840c, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x8422, 0xd1d4, 0x0040,
+       0x8417, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x8422, 0x684c,
+       0xd0ac, 0x0040, 0x8422, 0x6810, 0x6914, 0xa115, 0x0040, 0x8422,
+       0x1078, 0x8233, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e,
+       0x0f7f, 0x1078, 0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8465,
+       0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
+       0x8456, 0xa086, 0x0028, 0x00c0, 0x8441, 0x684b, 0x001c, 0x0078,
+       0x8463, 0xd1dc, 0x0040, 0x844f, 0x684b, 0x0015, 0x1078, 0x8ea5,
+       0x0040, 0x844d, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8463, 0xd1d4,
+       0x0040, 0x8456, 0x684b, 0x0007, 0x0078, 0x8463, 0x684b, 0x0000,
+       0x684c, 0xd0ac, 0x0040, 0x8463, 0x6810, 0x6914, 0xa115, 0x0040,
+       0x8463, 0x1078, 0x8233, 0x1078, 0x4982, 0x1078, 0x8cc4, 0x00c0,
+       0x846b, 0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x6010, 0x0078,
+       0x8473, 0x1078, 0x60b8, 0x1078, 0x8a44, 0x0040, 0x8492, 0x0d7e,
+       0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa30c, 0x210c, 0xd18c,
+       0x00c0, 0x849d, 0xd184, 0x00c0, 0x8499, 0x6108, 0x694a, 0xa18e,
+       0x0029, 0x00c0, 0x848d, 0x1078, 0xa181, 0x6847, 0x0000, 0x1078,
+       0x4982, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x1078, 0x61d3,
+       0x007c, 0x684b, 0x0004, 0x0078, 0x848d, 0x684b, 0x0004, 0x0078,
+       0x848d, 0xa182, 0x0040, 0x0079, 0x84a5, 0x84b8, 0x84b8, 0x84b8,
+       0x84b8, 0x84b8, 0x84ba, 0x84b8, 0x84bd, 0x84b8, 0x84b8, 0x84b8,
+       0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8,
+       0x1078, 0x1328, 0x1078, 0x753d, 0x007c, 0x007e, 0x027e, 0xa016,
+       0x1078, 0x15ec, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079,
+       0x84c9, 0x84d2, 0x84d0, 0x84d0, 0x84de, 0x84d0, 0x84d0, 0x84d0,
+       0x1078, 0x1328, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x057e,
+       0x0d7e, 0x0e7e, 0x2071, 0xa880, 0x7224, 0x6212, 0x7220, 0x1078,
+       0x8a30, 0x0040, 0x8503, 0x2268, 0x6800, 0xa086, 0x0000, 0x0040,
+       0x8503, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x8503, 0x0c7e, 0x2d60,
+       0x1078, 0x874a, 0x0c7f, 0x0040, 0x8503, 0x6803, 0x0002, 0x6007,
+       0x0086, 0x0078, 0x8505, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x0f7e, 0x2278, 0x1078, 0x4893, 0x0f7f,
+       0x0040, 0x851d, 0x6824, 0xd0ec, 0x0040, 0x851d, 0x0c7e, 0x2260,
+       0x603f, 0x0000, 0x1078, 0x8cfa, 0x0c7f, 0x0e7f, 0x0d7f, 0x057f,
+       0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x8533, 0x6004, 0xa08a,
+       0x0085, 0x1048, 0x1328, 0xa08a, 0x008c, 0x10c8, 0x1328, 0xa082,
+       0x0085, 0x0079, 0x8542, 0xa186, 0x0027, 0x0040, 0x853b, 0xa186,
+       0x0014, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0x8549, 0x854b, 0x854b, 0x8549, 0x8549, 0x8549,
+       0x8549, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0xa186, 0x0013, 0x00c0, 0x855c, 0x6004, 0xa082,
+       0x0085, 0x2008, 0x0078, 0x8597, 0xa186, 0x0027, 0x00c0, 0x857f,
+       0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b,
+       0x0029, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+       0x1078, 0x6109, 0x007c, 0x1078, 0x7583, 0x0078, 0x857a, 0xa186,
+       0x0014, 0x00c0, 0x857b, 0x1078, 0x6010, 0x0d7e, 0x6010, 0x2068,
+       0x1078, 0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000,
+       0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8571, 0x0079,
+       0x8599, 0x85a2, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85bd,
+       0x1078, 0x1328, 0x1078, 0x6010, 0x6030, 0xa08c, 0xff00, 0x810f,
+       0xa186, 0x0039, 0x0040, 0x85b0, 0xa186, 0x0035, 0x00c0, 0x85b4,
+       0x2001, 0xa5a0, 0x0078, 0x85b6, 0x2001, 0xa5a1, 0x2004, 0x6016,
+       0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x6030,
+       0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x85cb, 0xa186,
+       0x0035, 0x00c0, 0x85cf, 0x2001, 0xa5a0, 0x0078, 0x85d1, 0x2001,
+       0xa5a1, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x6109, 0x007c,
+       0xa182, 0x008c, 0x00c8, 0x85e2, 0xa182, 0x0085, 0x0048, 0x85e2,
+       0x0079, 0x85e5, 0x1078, 0x7583, 0x007c, 0x85ec, 0x85ec, 0x85ec,
+       0x85ec, 0x85ee, 0x8643, 0x85ec, 0x1078, 0x1328, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x0f7f, 0x0040, 0x8601, 0x6030, 0xa08c, 0xff00,
+       0x810f, 0xa186, 0x0039, 0x0040, 0x865a, 0xa186, 0x0035, 0x0040,
+       0x865a, 0x0d7e, 0x1078, 0x8bf4, 0x1078, 0x8a44, 0x0040, 0x8625,
+       0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x8616,
+       0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x8621, 0xd0bc, 0x0040,
+       0x861d, 0x684b, 0x0002, 0x0078, 0x8621, 0x684b, 0x0005, 0x1078,
+       0x8cc0, 0x6847, 0x0000, 0x1078, 0x4982, 0x2c68, 0x1078, 0x74d7,
+       0x0040, 0x863e, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xa88e,
+       0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x6918, 0x611a,
+       0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5bf8, 0x2d60, 0x1078,
+       0x753d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f,
+       0x0040, 0x8680, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+       0x0040, 0x865a, 0xa186, 0x001e, 0x0040, 0x865a, 0xa186, 0x0039,
+       0x00c0, 0x8680, 0x0d7e, 0x2c68, 0x1078, 0x8ef5, 0x00c0, 0x86a4,
+       0x1078, 0x74d7, 0x0040, 0x867d, 0x6106, 0x6003, 0x0001, 0x601f,
+       0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e, 0x6930,
+       0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a, 0x6920,
+       0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x2d60, 0x0078, 0x86a4,
+       0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86a4, 0x6837,
+       0x0103, 0x6850, 0xd0b4, 0x0040, 0x8693, 0xc0ec, 0x6852, 0x684b,
+       0x0006, 0x0078, 0x869e, 0xd0bc, 0x0040, 0x869a, 0x684b, 0x0002,
+       0x0078, 0x869e, 0x684b, 0x0005, 0x1078, 0x8cc0, 0x6847, 0x0000,
+       0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x007c,
+       0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86b8,
+       0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, 0x4982,
+       0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x86ca, 0xa186, 0x0014,
+       0x0040, 0x86ca, 0xa186, 0x0027, 0x0040, 0x86ca, 0x1078, 0x7583,
+       0x0078, 0x86d0, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+       0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182,
+       0x0101, 0x00c8, 0x86dd, 0x0078, 0x86df, 0x2009, 0x0100, 0x2130,
+       0x2069, 0xa898, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
+       0x001d, 0x1078, 0x8739, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040,
+       0x86f3, 0x1078, 0x13aa, 0x1078, 0x1381, 0x0040, 0x871d, 0x8528,
+       0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d,
+       0x00c8, 0x8709, 0x2608, 0xad90, 0x000f, 0x1078, 0x8739, 0x0078,
+       0x871d, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f,
+       0x1078, 0x8739, 0x0078, 0x86f3, 0x0f7f, 0x852f, 0xa5ad, 0x0003,
+       0x7d36, 0xa5ac, 0x0000, 0x0078, 0x8722, 0x0f7f, 0x852f, 0xa5ad,
+       0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff,
+       0x0040, 0x8737, 0x6804, 0xa07d, 0x0040, 0x8735, 0x6807, 0x0000,
+       0x1078, 0x4982, 0x2f68, 0x0078, 0x872a, 0x1078, 0x4982, 0x0f7f,
+       0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x873f, 0x8108, 0x810c,
+       0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x8741,
+       0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031, 0x0001,
+       0x601c, 0xa084, 0x000f, 0x1079, 0x8766, 0x127f, 0x067f, 0x007c,
+       0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c, 0xa084,
+       0x000f, 0x1079, 0x8766, 0x067f, 0x127f, 0x007c, 0x8780, 0x876e,
+       0x877b, 0x879c, 0x876e, 0x877b, 0x879c, 0x877b, 0x1078, 0x1328,
+       0x037e, 0x2019, 0x0010, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003,
+       0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
+       0x0d7e, 0x86ff, 0x00c0, 0x8797, 0x6010, 0x2068, 0x1078, 0x8a44,
+       0x0040, 0x8799, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4a60, 0x1078,
+       0x8cc0, 0x1078, 0x4982, 0x1078, 0x753d, 0xa085, 0x0001, 0x0d7f,
+       0x007c, 0xa006, 0x0078, 0x8797, 0x6000, 0xa08a, 0x0010, 0x10c8,
+       0x1328, 0x1079, 0x87a4, 0x007c, 0x87b4, 0x87d4, 0x87b6, 0x87f7,
+       0x87d0, 0x87b4, 0x877b, 0x8780, 0x8780, 0x877b, 0x877b, 0x877b,
+       0x877b, 0x877b, 0x877b, 0x877b, 0x1078, 0x1328, 0x86ff, 0x00c0,
+       0x87cd, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x87c2,
+       0x1078, 0x8cc0, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+       0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0xa085, 0x0001, 0x007c,
+       0x1078, 0x1749, 0x0078, 0x87b6, 0x0e7e, 0x2071, 0xa5ab, 0x7024,
+       0xac06, 0x00c0, 0x87dd, 0x1078, 0x6dda, 0x601c, 0xa084, 0x000f,
+       0xa086, 0x0006, 0x00c0, 0x87ef, 0x087e, 0x097e, 0x2049, 0x0001,
+       0x2c40, 0x1078, 0x7058, 0x097f, 0x087f, 0x0078, 0x87f1, 0x1078,
+       0x6cd2, 0x0e7f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c, 0x037e,
+       0x0e7e, 0x2071, 0xa5ab, 0x703c, 0xac06, 0x00c0, 0x8807, 0x2019,
+       0x0000, 0x1078, 0x6e6c, 0x0e7f, 0x037f, 0x0078, 0x87b6, 0x1078,
+       0x719a, 0x0e7f, 0x037f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c,
+       0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x8818, 0x0c7f, 0x007c,
+       0x8827, 0x8895, 0x89cd, 0x8832, 0x8c01, 0x8827, 0x9a5b, 0x753d,
+       0x8895, 0x1078, 0x8c3b, 0x00c0, 0x8827, 0x1078, 0x7a05, 0x007c,
+       0x1078, 0x6010, 0x1078, 0x6109, 0x1078, 0x753d, 0x007c, 0x6017,
+       0x0001, 0x007c, 0x6010, 0xa080, 0x0019, 0x2c02, 0x6000, 0xa08a,
+       0x0010, 0x10c8, 0x1328, 0x1079, 0x883e, 0x007c, 0x884e, 0x8850,
+       0x8872, 0x8884, 0x8891, 0x884e, 0x8827, 0x8827, 0x8827, 0x8884,
+       0x8884, 0x884e, 0x884e, 0x884e, 0x884e, 0x888e, 0x1078, 0x1328,
+       0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0xa5ab,
+       0x7024, 0xac06, 0x0040, 0x886e, 0x1078, 0x6cd2, 0x6007, 0x0085,
+       0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa5a1, 0x2004, 0x6016,
+       0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x6017, 0x0001,
+       0x0078, 0x886c, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852,
+       0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010,
+       0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x753d,
+       0x007c, 0x1078, 0x1749, 0x0078, 0x8872, 0x6000, 0xa08a, 0x0010,
+       0x10c8, 0x1328, 0x1079, 0x889d, 0x007c, 0x88ad, 0x882f, 0x88af,
+       0x88ad, 0x88af, 0x88af, 0x8828, 0x88ad, 0x8821, 0x8821, 0x88ad,
+       0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x1078, 0x1328, 0x0d7e,
+       0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, 0x000c,
+       0x10c8, 0x1328, 0x1079, 0x88bd, 0x007c, 0x88c9, 0x8971, 0x88cb,
+       0x890b, 0x88cb, 0x890b, 0x88cb, 0x88d8, 0x88c9, 0x890b, 0x88c9,
+       0x88f5, 0x1078, 0x1328, 0x6004, 0xa08e, 0x0016, 0x0040, 0x8906,
+       0xa08e, 0x0004, 0x0040, 0x8906, 0xa08e, 0x0002, 0x0040, 0x8906,
+       0x6004, 0x1078, 0x8c3b, 0x0040, 0x898c, 0xa08e, 0x0021, 0x0040,
+       0x8990, 0xa08e, 0x0022, 0x0040, 0x898c, 0xa08e, 0x003d, 0x0040,
+       0x8990, 0xa08e, 0x0039, 0x0040, 0x8994, 0xa08e, 0x0035, 0x0040,
+       0x8994, 0xa08e, 0x001e, 0x0040, 0x8908, 0xa08e, 0x0001, 0x00c0,
+       0x8904, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
+       0xa086, 0x0006, 0x0040, 0x8906, 0x1078, 0x2813, 0x1078, 0x7a05,
+       0x1078, 0x8c01, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016,
+       0x0040, 0x8961, 0xa186, 0x0002, 0x00c0, 0x8934, 0x6018, 0x2068,
+       0x68a0, 0xd0bc, 0x00c0, 0x89b8, 0x6840, 0xa084, 0x00ff, 0xa005,
+       0x0040, 0x8934, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007,
+       0x6017, 0x0398, 0x1078, 0x74d7, 0x0040, 0x8934, 0x2d00, 0x601a,
+       0x601f, 0x0001, 0x0078, 0x8961, 0x0d7f, 0x0c7f, 0x6004, 0xa08e,
+       0x0002, 0x00c0, 0x8952, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086,
+       0x007e, 0x00c0, 0x8952, 0x2009, 0xa332, 0x2104, 0xc085, 0x200a,
+       0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x0e7f, 0x1078, 0x7a05,
+       0x0078, 0x8956, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x2839, 0x127f, 0x0e7f, 0x1078, 0x8c01,
+       0x007c, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+       0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0d7f, 0x0c7f, 0x0078,
+       0x8960, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040, 0x8961,
+       0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x8934,
+       0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078, 0x6109,
+       0x0d7f, 0x0c7f, 0x0078, 0x8960, 0x1078, 0x7a05, 0x0078, 0x8908,
+       0x1078, 0x7a28, 0x0078, 0x8908, 0x0d7e, 0x2c68, 0x6104, 0x1078,
+       0x8ef5, 0x0d7f, 0x0040, 0x89a0, 0x1078, 0x753d, 0x0078, 0x89b7,
+       0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007,
+       0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038, 0x600a, 0x2001,
+       0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c,
+       0x0d7f, 0x0c7f, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x2839, 0x6013, 0x0000, 0x601f, 0x0007,
+       0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000, 0xa08a, 0x0010,
+       0x10c8, 0x1328, 0x1079, 0x89d5, 0x007c, 0x89e5, 0x89e5, 0x89e5,
+       0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x8827, 0x89e5,
+       0x882f, 0x89e7, 0x882f, 0x89f5, 0x89e5, 0x1078, 0x1328, 0x6004,
+       0xa086, 0x008b, 0x0040, 0x89f5, 0x6007, 0x008b, 0x6003, 0x000d,
+       0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c, 0x1078, 0x8bf4, 0x1078,
+       0x8a44, 0x0040, 0x8a2d, 0x1078, 0x2813, 0x0d7e, 0x1078, 0x8a44,
+       0x0040, 0x8a0f, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+       0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, 0x4982, 0x2c68,
+       0x1078, 0x74d7, 0x0040, 0x8a1d, 0x6818, 0x601a, 0x0c7e, 0x2d60,
+       0x1078, 0x8c01, 0x0c7f, 0x0078, 0x8a1e, 0x2d60, 0x0d7f, 0x6013,
+       0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078,
+       0x5c45, 0x1078, 0x6109, 0x0078, 0x8a2f, 0x1078, 0x8c01, 0x007c,
+       0xa284, 0x000f, 0x00c0, 0x8a41, 0xa282, 0xaa00, 0x0048, 0x8a41,
+       0x2001, 0xa315, 0x2004, 0xa202, 0x00c8, 0x8a41, 0xa085, 0x0001,
+       0x007c, 0xa006, 0x0078, 0x8a40, 0x027e, 0x0e7e, 0x2071, 0xa300,
+       0x6210, 0x7058, 0xa202, 0x0048, 0x8a56, 0x705c, 0xa202, 0x00c8,
+       0x8a56, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, 0xa006, 0x0078,
+       0x8a53, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, 0x2091, 0x8000,
+       0x2061, 0xaa00, 0x2071, 0xa300, 0x7344, 0x7060, 0xa302, 0x00c8,
+       0x8a83, 0x601c, 0xa206, 0x00c0, 0x8a7b, 0x1078, 0x8d66, 0x0040,
+       0x8a7b, 0x1078, 0x8c3b, 0x00c0, 0x8a77, 0x1078, 0x7a05, 0x0c7e,
+       0x1078, 0x753d, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+       0x8a83, 0x0078, 0x8a64, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f,
+       0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa434, 0x210c, 0x81ff,
+       0x0040, 0x8aa1, 0x2061, 0xaa00, 0x2071, 0xa300, 0x017e, 0x1078,
+       0x74d7, 0x017f, 0x0040, 0x8aa4, 0x611a, 0x1078, 0x2813, 0x1078,
+       0x753d, 0xa006, 0x0078, 0x8aa6, 0xa085, 0x0001, 0x017f, 0x0c7f,
+       0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
+       0x1078, 0x74d7, 0x057f, 0x0040, 0x8ac3, 0x6612, 0x651a, 0x601f,
+       0x0003, 0x2009, 0x004b, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+       0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8abf, 0x0c7e, 0x057e,
+       0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x74d7, 0x057f,
+       0x0040, 0x8af1, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
+       0x2560, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2009,
+       0x004c, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f,
+       0x007c, 0xa006, 0x0078, 0x8aed, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e,
+       0x1078, 0x74d7, 0x2c78, 0x0c7f, 0x0040, 0x8b0e, 0x7e12, 0x2c00,
+       0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60,
+       0x2009, 0x004d, 0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f,
+       0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7,
+       0x2c78, 0x0c7f, 0x0040, 0x8b2c, 0x7e12, 0x2c00, 0x781a, 0x781f,
+       0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x004e,
+       0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c,
+       0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7, 0x2c78, 0x0c7f,
+       0x0040, 0x8b4a, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021,
+       0x0004, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x0052, 0x1078, 0x756c,
+       0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c, 0x097e, 0x077e,
+       0x127e, 0x2091, 0x8000, 0x1078, 0x46a7, 0x0040, 0x8b5b, 0x2001,
+       0x8b53, 0x0078, 0x8b61, 0x1078, 0x466d, 0x0040, 0x8b6a, 0x2001,
+       0x8b5b, 0x007e, 0xa00e, 0x2400, 0x1078, 0x4a60, 0x1078, 0x4982,
+       0x007f, 0x007a, 0x2418, 0x1078, 0x5fa7, 0x62a0, 0x087e, 0x2041,
+       0x0001, 0x2039, 0x0001, 0x2608, 0x1078, 0x5d6d, 0x087f, 0x1078,
+       0x5c78, 0x2f08, 0x2648, 0x1078, 0x9c38, 0x613c, 0x81ff, 0x1040,
+       0x5e21, 0x127f, 0x077f, 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+       0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8b9e, 0x660a,
+       0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078,
+       0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+       0x8b9b, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+       0x017f, 0x0040, 0x8bba, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00,
+       0x6012, 0x2009, 0x0021, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+       0x0c7f, 0x007c, 0xa006, 0x0078, 0x8bb7, 0x0c7e, 0x127e, 0x2091,
+       0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8bd6, 0x660a,
+       0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078,
+       0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+       0x8bd3, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+       0x017f, 0x0040, 0x8bf1, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
+       0x2009, 0x0000, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f,
+       0x007c, 0xa006, 0x0078, 0x8bee, 0x027e, 0x0d7e, 0x6218, 0x2268,
+       0x6a3c, 0x82ff, 0x0040, 0x8bfe, 0x8211, 0x6a3e, 0x0d7f, 0x027f,
+       0x007c, 0x007e, 0x6000, 0xa086, 0x0000, 0x0040, 0x8c13, 0x6013,
+       0x0000, 0x601f, 0x0007, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078,
+       0xa134, 0x603f, 0x0000, 0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e,
+       0x2031, 0xa352, 0x2634, 0xd6e4, 0x0040, 0x8c23, 0x6618, 0x2660,
+       0x6e48, 0x1078, 0x461b, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e,
+       0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x8c38, 0xa08e, 0x0003,
+       0x0040, 0x8c38, 0xa08e, 0x0004, 0x0040, 0x8c38, 0xa085, 0x0001,
+       0x017f, 0x007f, 0x007c, 0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040,
+       0x8c48, 0x6838, 0xd0fc, 0x0040, 0x8c48, 0xa006, 0x0078, 0x8c4a,
+       0xa085, 0x0001, 0x0d7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+       0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8c67, 0x611a,
+       0x601f, 0x0001, 0x2d00, 0x6012, 0x1078, 0x2813, 0x2009, 0x0028,
+       0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
+       0x0078, 0x8c64, 0xa186, 0x0015, 0x00c0, 0x8c7f, 0x2011, 0xa31f,
+       0x2204, 0xa086, 0x0074, 0x00c0, 0x8c7f, 0x1078, 0x7d0d, 0x6003,
+       0x0001, 0x6007, 0x0029, 0x1078, 0x5c45, 0x0078, 0x8c83, 0x1078,
+       0x7a05, 0x1078, 0x753d, 0x007c, 0xa186, 0x0016, 0x00c0, 0x8c8e,
+       0x2001, 0x0004, 0x1078, 0x443f, 0x0078, 0x8caf, 0xa186, 0x0015,
+       0x00c0, 0x8cb3, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0014, 0x00c0,
+       0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x1078, 0x457d, 0x0d7f, 0x1078,
+       0x7dba, 0x00c0, 0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f,
+       0xa005, 0x0040, 0x8cb3, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+       0x7608, 0x0078, 0x8cb7, 0x1078, 0x7a05, 0x1078, 0x753d, 0x007c,
+       0x6848, 0xa086, 0x0005, 0x00c0, 0x8cbf, 0x1078, 0x8cc0, 0x007c,
+       0x6850, 0xc0ad, 0x6852, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7014,
+       0xd0e4, 0x0040, 0x8cd5, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007,
+       0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x0c7e,
+       0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8ce4, 0x601c,
+       0xa084, 0x000f, 0x1079, 0x8ce6, 0x0c7f, 0x007c, 0x8827, 0x8cf1,
+       0x8cf4, 0x8cf7, 0x9f00, 0x9f1c, 0x9f1f, 0x8827, 0x8827, 0x1078,
+       0x1328, 0x0005, 0x0005, 0x007c, 0x0005, 0x0005, 0x007c, 0x1078,
+       0x8cfa, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0040, 0x8d29,
+       0x1078, 0x74d7, 0x00c0, 0x8d0a, 0x2001, 0xa5a2, 0x2004, 0x783e,
+       0x0078, 0x8d29, 0x7818, 0x601a, 0x781c, 0xa086, 0x0003, 0x0040,
+       0x8d17, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0078, 0x8d1b, 0x7808,
+       0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007, 0x0035,
+       0x6003, 0x0001, 0x7920, 0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109,
+       0x2f60, 0x0f7f, 0x007c, 0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e,
+       0x0001, 0x0040, 0x8d3c, 0xa086, 0x0005, 0x0040, 0x8d40, 0xa006,
+       0x602a, 0x602e, 0x0078, 0x8d51, 0x6824, 0xc0f4, 0xc0d5, 0x6826,
+       0x6810, 0x2078, 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103,
+       0x00c8, 0x8d37, 0x6834, 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a,
+       0x602e, 0x2d00, 0x6036, 0x6808, 0x603a, 0x6918, 0x611a, 0x6920,
+       0x6122, 0x601f, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x6803, 0x0002, 0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e,
+       0x6004, 0xa08e, 0x0034, 0x0040, 0x8d8b, 0xa08e, 0x0035, 0x0040,
+       0x8d8b, 0xa08e, 0x0036, 0x0040, 0x8d8b, 0xa08e, 0x0037, 0x0040,
+       0x8d8b, 0xa08e, 0x0038, 0x0040, 0x8d8b, 0xa08e, 0x0039, 0x0040,
+       0x8d8b, 0xa08e, 0x003a, 0x0040, 0x8d8b, 0xa08e, 0x003b, 0x0040,
+       0x8d8b, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x00c0, 0x8d98, 0xa085, 0x0001, 0x0078, 0x8da7,
+       0x6024, 0xd0f4, 0x00c0, 0x8da6, 0xc0f5, 0x6026, 0x6010, 0x2078,
+       0x7828, 0x603a, 0x782c, 0x6036, 0x1078, 0x1749, 0xa006, 0x0f7f,
+       0x007c, 0x007e, 0x017e, 0x027e, 0x037e, 0x0e7e, 0x2001, 0xa59c,
+       0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x1078, 0x5a98, 0x2001,
+       0xa5a0, 0x82ff, 0x00c0, 0x8dbe, 0x2011, 0x0002, 0x2202, 0x2001,
+       0xa59e, 0x200c, 0x8000, 0x2014, 0x2071, 0xa58c, 0x711a, 0x721e,
+       0x2001, 0x0064, 0x1078, 0x5a98, 0x2001, 0xa5a1, 0x82ff, 0x00c0,
+       0x8dd3, 0x2011, 0x0002, 0x2202, 0x2009, 0xa5a2, 0xa280, 0x000a,
+       0x200a, 0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e,
+       0x0e7e, 0x2001, 0xa5a0, 0x2003, 0x0028, 0x2001, 0xa5a1, 0x2003,
+       0x0014, 0x2071, 0xa58c, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+       0xa5a2, 0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e,
+       0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8e0e,
+       0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078,
+       0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+       0x8e0b, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa300, 0xa186, 0x0015,
+       0x00c0, 0x8e40, 0x707c, 0xa086, 0x0018, 0x00c0, 0x8e40, 0x6010,
+       0x2068, 0x6a3c, 0xd2e4, 0x00c0, 0x8e34, 0x2c78, 0x1078, 0x62c6,
+       0x0040, 0x8e48, 0x7068, 0x6a50, 0xa206, 0x00c0, 0x8e3c, 0x706c,
+       0x6a54, 0xa206, 0x00c0, 0x8e3c, 0x6218, 0xa290, 0x0028, 0x2214,
+       0x2009, 0x0000, 0x1078, 0x285b, 0x1078, 0x7608, 0x0078, 0x8e44,
+       0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c,
+       0x704c, 0xa080, 0x293f, 0x2004, 0x6a54, 0xa206, 0x0040, 0x8e34,
+       0x0078, 0x8e3c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
+       0x74d7, 0x017f, 0x0040, 0x8e6a, 0x611a, 0x601f, 0x0001, 0x2d00,
+       0x6012, 0x2009, 0x0043, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+       0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e67, 0x0d7e, 0x0e7e, 0x0f7e,
+       0x2071, 0xa300, 0xa186, 0x0015, 0x00c0, 0x8e93, 0x707c, 0xa086,
+       0x0004, 0x00c0, 0x8e93, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078,
+       0x62c6, 0x0040, 0x8e9b, 0x7068, 0x6a08, 0xa206, 0x00c0, 0x8e8f,
+       0x706c, 0x6a0c, 0xa206, 0x00c0, 0x8e8f, 0x1078, 0x2813, 0x1078,
+       0x7608, 0x0078, 0x8e97, 0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f,
+       0x0e7f, 0x0d7f, 0x007c, 0x704c, 0xa080, 0x293f, 0x2004, 0x6a0c,
+       0xa206, 0x0040, 0x8e8d, 0x0078, 0x8e8f, 0x017e, 0x027e, 0x684c,
+       0xd0ac, 0x0040, 0x8ebd, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040,
+       0x8ebd, 0x6860, 0xa106, 0x00c0, 0x8eb9, 0x685c, 0xa206, 0x0040,
+       0x8ebd, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c,
+       0x0e7e, 0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582,
+       0x0001, 0x0048, 0x8ef2, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000,
+       0x0040, 0x8ede, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x8eda,
+       0x0078, 0x8ecd, 0x2061, 0xaa00, 0x0078, 0x8ecd, 0x6003, 0x0008,
+       0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x8eee,
+       0x754a, 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+       0x0078, 0x8ee9, 0xa006, 0x0078, 0x8eeb, 0x0c7e, 0x027e, 0x017e,
+       0xa186, 0x0035, 0x0040, 0x8eff, 0x6a34, 0x0078, 0x8f00, 0x6a28,
+       0x1078, 0x8a30, 0x0040, 0x8f29, 0x2260, 0x611c, 0xa186, 0x0003,
+       0x0040, 0x8f0e, 0xa186, 0x0006, 0x00c0, 0x8f25, 0x6834, 0xa206,
+       0x0040, 0x8f1d, 0x6838, 0xa206, 0x00c0, 0x8f25, 0x6108, 0x6834,
+       0xa106, 0x00c0, 0x8f25, 0x0078, 0x8f22, 0x6008, 0x6938, 0xa106,
+       0x00c0, 0x8f25, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f,
+       0x007c, 0xa085, 0x0001, 0x0078, 0x8f25, 0x067e, 0x6000, 0xa0b2,
+       0x0010, 0x10c8, 0x1328, 0x1079, 0x8f37, 0x067f, 0x007c, 0x8f47,
+       0x93bb, 0x94d3, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f81,
+       0x955e, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x1078,
+       0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079,
+       0x8f53, 0x067f, 0x007c, 0x8f63, 0x99f6, 0x8f63, 0x8f63, 0x8f63,
+       0x8f63, 0x8f63, 0x8f63, 0x99b4, 0x9a44, 0x8f63, 0xa053, 0xa087,
+       0xa053, 0xa087, 0x8f63, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2,
+       0x0010, 0x10c8, 0x1328, 0x1079, 0x8f6f, 0x067f, 0x007c, 0x8f7f,
+       0x969f, 0x976a, 0x9798, 0x9813, 0x8f7f, 0x9919, 0x98c1, 0x956a,
+       0x9988, 0x999e, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x1078,
+       0x1328, 0xa1b2, 0x0044, 0x10c8, 0x1328, 0x2100, 0x0079, 0x8f88,
+       0x8fc8, 0x919a, 0x8fc8, 0x8fc8, 0x8fc8, 0x91a2, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fca,
+       0x902d, 0x9038, 0x9081, 0x909c, 0x911b, 0x918b, 0x8fc8, 0x8fc8,
+       0x91a6, 0x8fc8, 0x8fc8, 0x91b5, 0x91bc, 0x8fc8, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x91ea, 0x8fc8, 0x8fc8, 0x91f5, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x920a, 0x8fc8, 0x8fc8, 0x8fc8,
+       0x9291, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x9305,
+       0x1078, 0x1328, 0x1078, 0x4897, 0x00c0, 0x8fd7, 0x2001, 0xa332,
+       0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x8fdf, 0x6007,
+       0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195, 0x1078,
+       0x4887, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270,
+       0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x017f,
+       0x2e60, 0x1078, 0x471b, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+       0x6618, 0x0c7e, 0x2660, 0x1078, 0x4513, 0x0c7f, 0xa6b0, 0x0001,
+       0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x901f, 0x1078,
+       0x9b6c, 0x00c0, 0x907b, 0x1078, 0x9afd, 0x00c0, 0x901b, 0x6007,
+       0x0008, 0x0078, 0x9195, 0x6007, 0x0009, 0x0078, 0x9195, 0x1078,
+       0x9d45, 0x0040, 0x9029, 0x1078, 0x9b6c, 0x0040, 0x9013, 0x0078,
+       0x907b, 0x6013, 0x1900, 0x0078, 0x901b, 0x6106, 0x1078, 0x9aa8,
+       0x6007, 0x0006, 0x0078, 0x9195, 0x6007, 0x0007, 0x0078, 0x9195,
+       0x1078, 0xa0bf, 0x00c0, 0x9340, 0x0d7e, 0x6618, 0x2668, 0x6e04,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x905d, 0xa686,
+       0x0004, 0x0040, 0x905d, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+       0x0040, 0x905d, 0xa686, 0x0004, 0x0040, 0x905d, 0xa686, 0x0005,
+       0x0040, 0x905d, 0x0d7f, 0x0078, 0x907b, 0x1078, 0x9bd2, 0x00c0,
+       0x9076, 0xa686, 0x0006, 0x00c0, 0x906f, 0x027e, 0x6218, 0xa290,
+       0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f, 0x1078,
+       0x457d, 0x6007, 0x000a, 0x0d7f, 0x0078, 0x9195, 0x6007, 0x000b,
+       0x0d7f, 0x0078, 0x9195, 0x1078, 0x2813, 0x6007, 0x0001, 0x0078,
+       0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x6618, 0x0d7e, 0x2668,
+       0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x907b, 0x027e, 0x6218,
+       0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f,
+       0x6007, 0x000c, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x90a9,
+       0x2001, 0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0,
+       0x90b1, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078,
+       0x9195, 0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684,
+       0x00ff, 0xa082, 0x0006, 0x0048, 0x90f5, 0xa6b4, 0xff00, 0x8637,
+       0xa686, 0x0004, 0x0040, 0x90c8, 0xa686, 0x0006, 0x00c0, 0x907b,
+       0x1078, 0x9be1, 0x00c0, 0x90d0, 0x6007, 0x000e, 0x0078, 0x9195,
+       0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427,
+       0x047e, 0x1078, 0x2813, 0x047f, 0x017e, 0xa006, 0x2009, 0xa352,
+       0x210c, 0xd1a4, 0x0040, 0x90ef, 0x2009, 0x0029, 0x1078, 0x9ec0,
+       0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f,
+       0x047f, 0x6007, 0x0001, 0x0078, 0x9195, 0x2001, 0x0001, 0x1078,
+       0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+       0xa305, 0x2011, 0xa890, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+       0x157f, 0xa005, 0x0040, 0x9115, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0006, 0x0040, 0x90c8, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+       0x0009, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x9128, 0x2001,
+       0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x9130,
+       0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195,
+       0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff,
+       0xa082, 0x0006, 0x0048, 0x9178, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0004, 0x0040, 0x9147, 0xa686, 0x0006, 0x00c0, 0x907b, 0x1078,
+       0x9c0c, 0x00c0, 0x9153, 0x1078, 0x9afd, 0x00c0, 0x9153, 0x6007,
+       0x0010, 0x0078, 0x9195, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424,
+       0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2813, 0x047f, 0x017e,
+       0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040, 0x9172, 0x2009,
+       0x0029, 0x1078, 0x9ec0, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5,
+       0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x9195,
+       0x1078, 0x9d45, 0x0040, 0x9185, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0006, 0x0040, 0x9147, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+       0x0009, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x1078,
+       0x9343, 0x00c0, 0x907b, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078,
+       0x5c45, 0x007c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45,
+       0x0078, 0x9199, 0x6007, 0x0005, 0x0078, 0x919c, 0x1078, 0xa0bf,
+       0x00c0, 0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6007, 0x0020,
+       0x6003, 0x0001, 0x1078, 0x5c45, 0x007c, 0x6007, 0x0023, 0x6003,
+       0x0001, 0x1078, 0x5c45, 0x007c, 0x1078, 0xa0bf, 0x00c0, 0x9340,
+       0x1078, 0x9343, 0x00c0, 0x907b, 0x017e, 0x027e, 0x2011, 0xa890,
+       0x2214, 0x2c08, 0x1078, 0x9e8c, 0x00c0, 0x91de, 0x2160, 0x6007,
+       0x0026, 0x6013, 0x1700, 0x2011, 0xa889, 0x2214, 0xa296, 0xffff,
+       0x00c0, 0x91e3, 0x6007, 0x0025, 0x0078, 0x91e3, 0x1078, 0x753d,
+       0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5c45, 0x027f,
+       0x017f, 0x007c, 0x6106, 0x1078, 0x9363, 0x6007, 0x002b, 0x0078,
+       0x9195, 0x6007, 0x002c, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0,
+       0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6106, 0x1078, 0x9368,
+       0x00c0, 0x9206, 0x6007, 0x002e, 0x0078, 0x9195, 0x6007, 0x002f,
+       0x0078, 0x9195, 0x0e7e, 0x0d7e, 0x0c7e, 0x6018, 0xa080, 0x0001,
+       0x200c, 0xa184, 0x00ff, 0xa086, 0x0006, 0x0040, 0x9223, 0xa184,
+       0xff00, 0x8007, 0xa086, 0x0006, 0x0040, 0x9223, 0x0c7f, 0x0d7f,
+       0x0e7f, 0x0078, 0x919a, 0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040,
+       0x928d, 0x2071, 0xa88c, 0x7010, 0x6036, 0x7014, 0x603a, 0x7108,
+       0x720c, 0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x9241, 0x6018,
+       0x2068, 0x6810, 0xa106, 0x00c0, 0x9241, 0x6814, 0xa206, 0x0040,
+       0x9265, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x9281, 0x2069,
+       0xa300, 0x686c, 0xa206, 0x00c0, 0x9281, 0x6868, 0xa106, 0x00c0,
+       0x9281, 0x7210, 0x1078, 0x8a30, 0x0040, 0x9287, 0x1078, 0x9f31,
+       0x0040, 0x9287, 0x622a, 0x6007, 0x0036, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7214, 0xa286, 0xffff,
+       0x0040, 0x9277, 0x1078, 0x8a30, 0x0040, 0x9287, 0xa280, 0x0002,
+       0x2004, 0x7110, 0xa106, 0x00c0, 0x9287, 0x0078, 0x9252, 0x7210,
+       0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x2160, 0x0040, 0x9287, 0x0078,
+       0x9252, 0x6007, 0x0037, 0x6013, 0x1500, 0x0078, 0x925d, 0x6007,
+       0x0037, 0x6013, 0x1700, 0x0078, 0x925d, 0x6007, 0x0012, 0x0078,
+       0x925d, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084, 0xff00, 0x8007,
+       0xa086, 0x0006, 0x00c0, 0x919a, 0x0e7e, 0x0d7e, 0x0c7e, 0x2001,
+       0xa371, 0x2004, 0xd0e4, 0x0040, 0x92fd, 0x2069, 0xa300, 0x2071,
+       0xa88c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286, 0xffff, 0x00c0,
+       0x92ba, 0x7208, 0x0c7e, 0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x0c7f,
+       0x0040, 0x92f1, 0x1078, 0x8a30, 0x0040, 0x92f1, 0x0c7e, 0x027e,
+       0x2260, 0x1078, 0x874a, 0x027f, 0x0c7f, 0x7118, 0xa18c, 0xff00,
+       0x810f, 0xa186, 0x0001, 0x0040, 0x92db, 0xa186, 0x0005, 0x0040,
+       0x92d5, 0xa186, 0x0007, 0x00c0, 0x92e5, 0xa280, 0x0004, 0x2004,
+       0xa005, 0x0040, 0x92e5, 0x057e, 0x7510, 0x7614, 0x1078, 0x9f46,
+       0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x6007, 0x003b, 0x602b,
+       0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x0078,
+       0x92e1, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x1700, 0x6003,
+       0x0001, 0x1078, 0x5bf8, 0x0078, 0x92e1, 0x6007, 0x003b, 0x602b,
+       0x000b, 0x6013, 0x0000, 0x0078, 0x925d, 0x0e7e, 0x027e, 0x1078,
+       0x4897, 0x0040, 0x933a, 0x1078, 0x4887, 0x1078, 0xa148, 0x00c0,
+       0x9338, 0x2071, 0xa300, 0x70c8, 0xc085, 0x70ca, 0x0f7e, 0x2079,
+       0x0100, 0x7294, 0xa284, 0x00ff, 0x706a, 0x78e6, 0xa284, 0xff00,
+       0x726c, 0xa205, 0x706e, 0x78ea, 0x0f7f, 0x70d3, 0x0000, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x9331, 0x2011, 0xa5c4, 0x2013,
+       0x07d0, 0xd0ac, 0x00c0, 0x933a, 0x1078, 0x260d, 0x0078, 0x933a,
+       0x1078, 0xa178, 0x027f, 0x0e7f, 0x1078, 0x753d, 0x0078, 0x9199,
+       0x1078, 0x753d, 0x007c, 0x0d7e, 0x067e, 0x6618, 0x2668, 0x6e04,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x9360, 0xa686,
+       0x0004, 0x0040, 0x9360, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+       0x0040, 0x9360, 0xa686, 0x0004, 0x0040, 0x9360, 0xa085, 0x0001,
+       0x067f, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x9397, 0x0d7f, 0x007c,
+       0x0d7e, 0x1078, 0x93a6, 0x00c0, 0x9390, 0x680c, 0xa08c, 0xff00,
+       0x6820, 0xa084, 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4,
+       0x0040, 0x937e, 0x2009, 0x0001, 0x0078, 0x938c, 0xd1ec, 0x0040,
+       0x9390, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x1078, 0x24e3, 0x00c0,
+       0x9390, 0x2110, 0x2009, 0x0000, 0x1078, 0x285b, 0x0078, 0x9394,
+       0xa085, 0x0001, 0x0078, 0x9395, 0xa006, 0x0d7f, 0x007c, 0x2069,
+       0xa88d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x93a4, 0x6013, 0x0000,
+       0xa085, 0x0001, 0x0078, 0x93a5, 0xa006, 0x007c, 0x6013, 0x0000,
+       0x2069, 0xa88c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x00c0,
+       0x93ba, 0x6800, 0xa084, 0x00ff, 0xa08e, 0x0014, 0x0040, 0x93ba,
+       0xa08e, 0x0010, 0x007c, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328,
+       0xa1b6, 0x0013, 0x00c0, 0x93c7, 0x2008, 0x0079, 0x93da, 0xa1b6,
+       0x0027, 0x0040, 0x93cf, 0xa1b6, 0x0014, 0x10c0, 0x1328, 0x2001,
+       0x0007, 0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0x941a, 0x941c, 0x941a, 0x941a, 0x941a, 0x941c,
+       0x9424, 0x94ae, 0x9471, 0x94ae, 0x9485, 0x94ae, 0x9424, 0x94ae,
+       0x94a6, 0x94ae, 0x94a6, 0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a,
+       0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a,
+       0x941c, 0x941a, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x941a, 0x94ae,
+       0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a,
+       0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941c,
+       0x94ae, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a, 0x941a,
+       0x941a, 0x941a, 0x1078, 0x1328, 0x1078, 0x6010, 0x6003, 0x0002,
+       0x1078, 0x6109, 0x0078, 0x94b4, 0x0f7e, 0x2079, 0xa351, 0x7804,
+       0x0f7f, 0xd0ac, 0x00c0, 0x94ae, 0x2001, 0x0000, 0x1078, 0x442b,
+       0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x94ae,
+       0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9448, 0x6010,
+       0xa005, 0x0040, 0x9448, 0x0c7f, 0x1078, 0x35f7, 0x0078, 0x94ae,
+       0x0c7f, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002, 0x00c0, 0x9457,
+       0x0f7e, 0x2079, 0xa300, 0x788c, 0x8000, 0x788e, 0x0f7f, 0x2001,
+       0x0002, 0x1078, 0x443f, 0x1078, 0x6010, 0x601f, 0x0001, 0x6003,
+       0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0c7e,
+       0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x58e1, 0x0c7f, 0x0078,
+       0x94b4, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
+       0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0xa686, 0x0004, 0x0040,
+       0x94ae, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0xa300, 0x2004,
+       0xa086, 0x0003, 0x00c0, 0x948e, 0x1078, 0x35f7, 0x2001, 0x0006,
+       0x1078, 0x94b5, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
+       0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0x2001, 0x0006,
+       0x0078, 0x94ac, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0x0006,
+       0x1078, 0x94b5, 0x0078, 0x94ae, 0x1078, 0x4472, 0x1078, 0x6010,
+       0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x017e, 0x0d7e, 0x6118,
+       0x2168, 0x6900, 0xd184, 0x0040, 0x94d0, 0x6104, 0xa18e, 0x000a,
+       0x00c0, 0x94c8, 0x699c, 0xd1a4, 0x00c0, 0x94c8, 0x2001, 0x0007,
+       0x1078, 0x443f, 0x2001, 0x0000, 0x1078, 0x442b, 0x1078, 0x2839,
+       0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084,
+       0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0xa1b6,
+       0x0015, 0x00c0, 0x94e7, 0x1079, 0x94ee, 0x0078, 0x94ed, 0xa1b6,
+       0x0016, 0x10c0, 0x1328, 0x1079, 0x94fa, 0x007c, 0x7ad0, 0x7ad0,
+       0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x9547, 0x9506, 0x7ad0, 0x7ad0,
+       0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0,
+       0x9547, 0x954f, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x0f7e, 0x2079,
+       0xa351, 0x7804, 0xd0ac, 0x00c0, 0x952d, 0x6018, 0xa07d, 0x0040,
+       0x952d, 0x7800, 0xd0f4, 0x00c0, 0x9519, 0x7810, 0xa005, 0x00c0,
+       0x952d, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078,
+       0x443f, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
+       0x5c45, 0x1078, 0x6109, 0x0078, 0x9545, 0x2011, 0xa883, 0x2204,
+       0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x9545, 0x0c7e, 0x1078,
+       0x4501, 0x0040, 0x9540, 0x0c7f, 0x1078, 0x753d, 0x0078, 0x9545,
+       0x1078, 0x4235, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0x6604,
+       0xa6b6, 0x001e, 0x00c0, 0x954e, 0x1078, 0x753d, 0x007c, 0x1078,
+       0x7d0a, 0x00c0, 0x955b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
+       0x5c45, 0x0078, 0x955d, 0x1078, 0x753d, 0x007c, 0x6004, 0xa08a,
+       0x0044, 0x10c8, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0xa182, 0x0040, 0x0079, 0x956e, 0x9581, 0x9581,
+       0x9581, 0x9581, 0x9583, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+       0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+       0x9581, 0x1078, 0x1328, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
+       0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x9594,
+       0x2021, 0x0000, 0x1078, 0xa111, 0x6106, 0x2071, 0xa880, 0x7444,
+       0xa4a4, 0xff00, 0x0040, 0x95eb, 0xa486, 0x2000, 0x00c0, 0x95a6,
+       0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5a6d, 0x1078, 0x1381,
+       0x1040, 0x1328, 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, 0x4982,
+       0x017f, 0xa486, 0x2000, 0x00c0, 0x95d3, 0x2019, 0x0017, 0x1078,
+       0x9e3b, 0x0078, 0x9645, 0xa486, 0x0400, 0x00c0, 0x95dd, 0x2019,
+       0x0002, 0x1078, 0x9dec, 0x0078, 0x9645, 0xa486, 0x0200, 0x00c0,
+       0x95e3, 0x1078, 0x9dd1, 0xa486, 0x1000, 0x00c0, 0x95e9, 0x1078,
+       0x9e20, 0x0078, 0x9645, 0x2069, 0xa62d, 0x6a00, 0xd284, 0x0040,
+       0x969b, 0xa284, 0x0300, 0x00c0, 0x9693, 0x6804, 0xa005, 0x0040,
+       0x9683, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1366, 0x0040, 0x964c,
+       0x7800, 0xd08c, 0x00c0, 0x9607, 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, 0x9627, 0x684f, 0x0040, 0x0078, 0x9631, 0xa286,
+       0x0001, 0x00c0, 0x962f, 0x684f, 0x0080, 0x0078, 0x9631, 0x684f,
+       0x0000, 0x20a9, 0x000a, 0x2001, 0xa890, 0xad90, 0x0015, 0x200c,
+       0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x9637, 0x200c, 0x6982,
+       0x8000, 0x200c, 0x697e, 0x1078, 0x4982, 0x027f, 0x047f, 0x157f,
+       0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003, 0x0001,
+       0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645,
+       0x2069, 0xa892, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x00c0,
+       0x9677, 0x2069, 0xa880, 0x686c, 0xa084, 0x00ff, 0x017e, 0x6110,
+       0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001, 0x6007,
+       0x0043, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645, 0x6013,
+       0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+       0x6109, 0x0078, 0x9645, 0x6013, 0x0300, 0x0078, 0x9689, 0x6013,
+       0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+       0x6109, 0x0078, 0x9645, 0x6013, 0x0500, 0x0078, 0x9689, 0x6013,
+       0x0600, 0x0078, 0x9658, 0x6013, 0x0200, 0x0078, 0x9658, 0xa186,
+       0x0013, 0x00c0, 0x96b1, 0x6004, 0xa08a, 0x0040, 0x1048, 0x1328,
+       0xa08a, 0x0053, 0x10c8, 0x1328, 0xa082, 0x0040, 0x2008, 0x0079,
+       0x9725, 0xa186, 0x0051, 0x0040, 0x96be, 0xa186, 0x0047, 0x00c0,
+       0x96d7, 0x6004, 0xa086, 0x0041, 0x0040, 0x96e5, 0x2001, 0x0109,
+       0x2004, 0xd084, 0x0040, 0x96e5, 0x127e, 0x2091, 0x2200, 0x007e,
+       0x017e, 0x027e, 0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f,
+       0x6000, 0xa086, 0x0002, 0x00c0, 0x96e5, 0x0078, 0x976a, 0xa186,
+       0x0027, 0x0040, 0x96df, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6004,
+       0xa082, 0x0040, 0x2008, 0x0079, 0x96e8, 0x1078, 0x7583, 0x007c,
+       0x96fb, 0x96fd, 0x96fd, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+       0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+       0x96fb, 0x96fb, 0x96fb, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078,
+       0x6109, 0x037e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x9722, 0xad84,
+       0xf000, 0x0040, 0x9722, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc,
+       0x00c0, 0x9722, 0x2019, 0x0004, 0x1078, 0x9e70, 0x6013, 0x0000,
+       0x6014, 0xa005, 0x00c0, 0x9720, 0x2001, 0xa5a1, 0x2004, 0x6016,
+       0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c, 0x9738, 0x9757, 0x9741,
+       0x9764, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+       0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+       0x1078, 0x1328, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400,
+       0x200a, 0x1078, 0x6010, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4,
+       0x0040, 0x9752, 0x6003, 0x0007, 0x2009, 0x0043, 0x1078, 0x756c,
+       0x0078, 0x9754, 0x6003, 0x0002, 0x1078, 0x6109, 0x007c, 0x1078,
+       0x6010, 0x1078, 0xa0c6, 0x00c0, 0x9761, 0x1078, 0x5a41, 0x1078,
+       0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x2009, 0x0041,
+       0x0078, 0x98c1, 0xa182, 0x0040, 0x0079, 0x976e, 0x9781, 0x9783,
+       0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9784, 0x9781, 0x9781,
+       0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x978f,
+       0x9781, 0x1078, 0x1328, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1,
+       0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x0d7e,
+       0x1078, 0x5a41, 0x0d7f, 0x1078, 0xa134, 0x1078, 0x753d, 0x007c,
+       0xa182, 0x0040, 0x0079, 0x979c, 0x97af, 0x97af, 0x97af, 0x97af,
+       0x97af, 0x97af, 0x97af, 0x97b1, 0x97af, 0x97b4, 0x97df, 0x97af,
+       0x97af, 0x97af, 0x97af, 0x97df, 0x97af, 0x97af, 0x97af, 0x1078,
+       0x1328, 0x1078, 0x7583, 0x007c, 0x1078, 0x60b8, 0x1078, 0x61d3,
+       0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x97ca, 0xa08c,
+       0x0003, 0xa18e, 0x0002, 0x0040, 0x97d2, 0x2009, 0x0041, 0x0d7f,
+       0x0078, 0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41,
+       0x0d7f, 0x007c, 0x1078, 0xa0c6, 0x0040, 0x97d8, 0x0d7f, 0x007c,
+       0x1078, 0x5a41, 0x1078, 0x753d, 0x0d7f, 0x0078, 0x97d1, 0x037e,
+       0x1078, 0x60b8, 0x1078, 0x61d3, 0x6010, 0x0d7e, 0x2068, 0x6018,
+       0x2004, 0xd0bc, 0x0040, 0x97ff, 0x684c, 0xa084, 0x0003, 0xa086,
+       0x0002, 0x0040, 0x97fb, 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880,
+       0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0078, 0x9810, 0x2019,
+       0x0004, 0x1078, 0x9e70, 0x6014, 0xa005, 0x00c0, 0x980c, 0x2001,
+       0xa5a1, 0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007,
+       0x0d7f, 0x037f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9821, 0x6004,
+       0xa086, 0x0042, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x6109,
+       0x007c, 0xa186, 0x0027, 0x0040, 0x9829, 0xa186, 0x0014, 0x00c0,
+       0x9839, 0x6004, 0xa086, 0x0042, 0x10c0, 0x1328, 0x2001, 0x0007,
+       0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+       0x007c, 0xa182, 0x0040, 0x0079, 0x983d, 0x9850, 0x9850, 0x9850,
+       0x9850, 0x9850, 0x9850, 0x9850, 0x9852, 0x985e, 0x9850, 0x9850,
+       0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850,
+       0x1078, 0x1328, 0x037e, 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+       0x2c10, 0x1078, 0x15ec, 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e,
+       0x2068, 0x6810, 0x6a14, 0x6118, 0x210c, 0xd1bc, 0x0040, 0x987d,
+       0x6124, 0xd1f4, 0x00c0, 0x987d, 0x007e, 0x047e, 0x057e, 0x6c7c,
+       0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028,
+       0xa529, 0x652a, 0x057f, 0x047f, 0x007f, 0xa20d, 0x00c0, 0x9891,
+       0x684c, 0xd0fc, 0x0040, 0x9889, 0x2009, 0x0041, 0x0d7f, 0x0078,
+       0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41, 0x0d7f,
+       0x007c, 0x007e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x007f,
+       0x0040, 0x989e, 0x6003, 0x0002, 0x0d7f, 0x007c, 0x2009, 0xa30d,
+       0x210c, 0xd19c, 0x0040, 0x98a8, 0x6003, 0x0007, 0x0078, 0x98aa,
+       0x6003, 0x0006, 0x1078, 0x98b0, 0x1078, 0x5a43, 0x0d7f, 0x007c,
+       0xd2fc, 0x0040, 0x98bc, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000,
+       0x2009, 0x0009, 0x0078, 0x98be, 0x2009, 0x0015, 0x6a6a, 0x6866,
+       0x007c, 0xa182, 0x0040, 0x0048, 0x98c7, 0x0079, 0x98d4, 0xa186,
+       0x0013, 0x0040, 0x98cf, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6024,
+       0xd0dc, 0x1040, 0x1328, 0x007c, 0x98e7, 0x98ee, 0x98fa, 0x9906,
+       0x98e7, 0x98e7, 0x98e7, 0x9915, 0x98e7, 0x98e9, 0x98e9, 0x98e7,
+       0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x1078,
+       0x1328, 0x6024, 0xd0dc, 0x1040, 0x1328, 0x007c, 0x6003, 0x0001,
+       0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109,
+       0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0003,
+       0x6106, 0x2c10, 0x1078, 0x1cab, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x5c64, 0x1078, 0x61d3, 0x127f, 0x007c, 0xa016, 0x1078, 0x15ec,
+       0x007c, 0x127e, 0x2091, 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040,
+       0x1079, 0x9926, 0x0d7f, 0x037f, 0x127f, 0x007c, 0x9936, 0x9938,
+       0x994d, 0x996c, 0x9936, 0x9936, 0x9936, 0x9984, 0x9936, 0x9936,
+       0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x1078, 0x1328,
+       0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003,
+       0xa39e, 0x0003, 0x0040, 0x9962, 0x6003, 0x0001, 0x6106, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c,
+       0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040,
+       0x9962, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x1078, 0x6109,
+       0x0078, 0x9987, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004,
+       0x1078, 0x9e70, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c, 0xd0fc,
+       0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9962,
+       0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x5c64,
+       0x1078, 0x61d3, 0x0078, 0x9987, 0xa016, 0x1078, 0x15ec, 0x007c,
+       0x1078, 0x6010, 0x6110, 0x81ff, 0x0040, 0x9999, 0x0d7e, 0x2168,
+       0x1078, 0xa181, 0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f,
+       0x0d7f, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x1078, 0x60b8,
+       0x6110, 0x81ff, 0x0040, 0x99af, 0x0d7e, 0x2168, 0x1078, 0xa181,
+       0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f, 0x0d7f, 0x1078,
+       0x8c01, 0x1078, 0x61d3, 0x007c, 0xa182, 0x0085, 0x0079, 0x99b8,
+       0x99c1, 0x99bf, 0x99bf, 0x99cd, 0x99bf, 0x99bf, 0x99bf, 0x1078,
+       0x1328, 0x6003, 0x000b, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091,
+       0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078,
+       0xa0bf, 0x0040, 0x99d7, 0x1078, 0x753d, 0x0078, 0x99f3, 0x2071,
+       0xa880, 0x7224, 0x6212, 0x7220, 0x1078, 0x9d10, 0x0040, 0x99e4,
+       0x6007, 0x0086, 0x0078, 0x99ed, 0x6007, 0x0087, 0x7224, 0xa296,
+       0xffff, 0x00c0, 0x99ed, 0x6007, 0x0086, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013,
+       0x00c0, 0x9a07, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a,
+       0x008c, 0x10c8, 0x1328, 0xa082, 0x0085, 0x0079, 0x9a1e, 0xa186,
+       0x0027, 0x0040, 0x9a13, 0xa186, 0x0014, 0x0040, 0x9a13, 0x1078,
+       0x7583, 0x0078, 0x9a1d, 0x2001, 0x0007, 0x1078, 0x4472, 0x1078,
+       0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x9a25, 0x9a27,
+       0x9a27, 0x9a25, 0x9a25, 0x9a25, 0x9a25, 0x1078, 0x1328, 0x1078,
+       0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0xa182, 0x0085,
+       0x1048, 0x1328, 0xa182, 0x008c, 0x10c8, 0x1328, 0xa182, 0x0085,
+       0x0079, 0x9a3a, 0x9a41, 0x9a41, 0x9a41, 0x9a43, 0x9a41, 0x9a41,
+       0x9a41, 0x1078, 0x1328, 0x007c, 0xa186, 0x0013, 0x0040, 0x9a54,
+       0xa186, 0x0014, 0x0040, 0x9a54, 0xa186, 0x0027, 0x0040, 0x9a54,
+       0x1078, 0x7583, 0x0078, 0x9a5a, 0x1078, 0x6010, 0x1078, 0x8c01,
+       0x1078, 0x6109, 0x007c, 0x037e, 0x1078, 0xa134, 0x603f, 0x0000,
+       0x2019, 0x000b, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003, 0x0007,
+       0x037f, 0x007c, 0x127e, 0x037e, 0x2091, 0x8000, 0x087e, 0x2c40,
+       0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x00c0,
+       0x9aa5, 0x077e, 0x2c38, 0x1078, 0x7105, 0x077f, 0x00c0, 0x9aa5,
+       0x6000, 0xa086, 0x0000, 0x0040, 0x9aa5, 0x601c, 0xa086, 0x0007,
+       0x0040, 0x9aa5, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x9a96,
+       0x1078, 0xa134, 0x601f, 0x0007, 0x1078, 0x1749, 0x6010, 0x2068,
+       0x1078, 0x8a44, 0x0040, 0x9a9e, 0x1078, 0x9e70, 0x0d7f, 0x6013,
+       0x0000, 0x1078, 0xa134, 0x601f, 0x0007, 0x037f, 0x127f, 0x007c,
+       0x0f7e, 0x0c7e, 0x037e, 0x157e, 0x2079, 0xa880, 0x7938, 0x783c,
+       0x1078, 0x24e3, 0x00c0, 0x9af6, 0x017e, 0x0c7e, 0x1078, 0x4501,
+       0x00c0, 0x9af6, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9, 0x0004,
+       0x1078, 0x7e55, 0x00c0, 0x9af6, 0x017f, 0x027f, 0x027e, 0x017e,
+       0x2019, 0x0029, 0x1078, 0x71e0, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x077f, 0x017f, 0x077e, 0x2039, 0x0000,
+       0x1078, 0x9c38, 0x077f, 0x1078, 0x471b, 0x027e, 0x6204, 0xa294,
+       0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9aea, 0xa286, 0x0004,
+       0x00c0, 0x9aed, 0x62a0, 0x1078, 0x28d5, 0x027f, 0x017f, 0x1078,
+       0x4235, 0x6612, 0x6516, 0xa006, 0x0078, 0x9af8, 0x0c7f, 0x017f,
+       0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x0e7e,
+       0x017e, 0x2009, 0xa31f, 0x2104, 0xa086, 0x0074, 0x00c0, 0x9b60,
+       0x2069, 0xa88e, 0x690c, 0xa182, 0x0100, 0x0048, 0x9b50, 0x6908,
+       0xa184, 0x8000, 0x0040, 0x9b5c, 0x6018, 0x2070, 0x7010, 0xa084,
+       0x00ff, 0x0040, 0x9b1f, 0x7000, 0xd0f4, 0x0040, 0x9b23, 0xa184,
+       0x0800, 0x0040, 0x9b5c, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54,
+       0x6914, 0x2069, 0xa8ae, 0x6904, 0x81ff, 0x00c0, 0x9b48, 0x690c,
+       0xa182, 0x0100, 0x0048, 0x9b50, 0x6908, 0x81ff, 0x00c0, 0x9b4c,
+       0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54, 0x6918, 0xa18a, 0x0001,
+       0x0048, 0x9b5c, 0x0078, 0x9b66, 0x6013, 0x0100, 0x0078, 0x9b62,
+       0x6013, 0x0300, 0x0078, 0x9b62, 0x6013, 0x0500, 0x0078, 0x9b62,
+       0x6013, 0x0700, 0x0078, 0x9b62, 0x6013, 0x0900, 0x0078, 0x9b62,
+       0x6013, 0x0b00, 0x0078, 0x9b62, 0x6013, 0x0f00, 0x0078, 0x9b62,
+       0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, 0x9b67, 0xa006, 0x017f,
+       0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x027e, 0x037e,
+       0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006,
+       0x0040, 0x9b90, 0xa286, 0x0004, 0x0040, 0x9b90, 0xa394, 0xff00,
+       0x8217, 0xa286, 0x0006, 0x0040, 0x9b90, 0xa286, 0x0004, 0x0040,
+       0x9b90, 0x0c7e, 0x2d60, 0x1078, 0x4513, 0x0c7f, 0x0078, 0x9bcb,
+       0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55,
+       0x00c0, 0x9bcc, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9, 0x0004,
+       0x1078, 0x7e55, 0x00c0, 0x9bcc, 0x047e, 0x017e, 0x6aa0, 0xa294,
+       0x00ff, 0x8227, 0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040,
+       0x9bb8, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6800, 0xc0e5, 0x6802,
+       0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078,
+       0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2001, 0x0007, 0x1078,
+       0x4472, 0x017f, 0x047f, 0xa006, 0x157f, 0x037f, 0x027f, 0x0d7f,
+       0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xa88e, 0x6800, 0xa086, 0x0800,
+       0x0040, 0x9bde, 0x6013, 0x0000, 0x0078, 0x9bdf, 0xa006, 0x0d7f,
+       0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2079,
+       0xa88c, 0x7930, 0x7834, 0x1078, 0x24e3, 0x00c0, 0x9c05, 0x1078,
+       0x4501, 0x00c0, 0x9c05, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9,
+       0x0004, 0x1078, 0x7e55, 0x00c0, 0x9c05, 0x2011, 0xa894, 0xac98,
+       0x0006, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x157f, 0x037f, 0x027f,
+       0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, 0x017e, 0x027e,
+       0x037e, 0x157e, 0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078,
+       0x24e3, 0x00c0, 0x9c31, 0x1078, 0x4501, 0x00c0, 0x9c31, 0x2011,
+       0xa896, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+       0x9c31, 0x2011, 0xa89a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078,
+       0x7e55, 0x157f, 0x037f, 0x027f, 0x017f, 0x007f, 0x0c7f, 0x007c,
+       0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e,
+       0x127e, 0x2091, 0x8000, 0x2740, 0x2029, 0xa5b4, 0x252c, 0x2021,
+       0xa5ba, 0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060,
+       0x81ff, 0x0040, 0x9c59, 0x8001, 0xa602, 0x00c8, 0x9cc3, 0x0078,
+       0x9c5c, 0xa606, 0x0040, 0x9cc3, 0x2100, 0xac06, 0x0040, 0x9cb9,
+       0x1078, 0x9ee5, 0x0040, 0x9cb9, 0x671c, 0xa786, 0x0001, 0x0040,
+       0x9cde, 0xa786, 0x0004, 0x0040, 0x9cde, 0xa786, 0x0007, 0x0040,
+       0x9cb9, 0x2500, 0xac06, 0x0040, 0x9cb9, 0x2400, 0xac06, 0x0040,
+       0x9cb9, 0x1078, 0x9ef9, 0x00c0, 0x9cb9, 0x88ff, 0x0040, 0x9c84,
+       0x6020, 0xa906, 0x00c0, 0x9cb9, 0x0d7e, 0x6000, 0xa086, 0x0004,
+       0x00c0, 0x9c8e, 0x017e, 0x1078, 0x1749, 0x017f, 0xa786, 0x0008,
+       0x00c0, 0x9c9d, 0x1078, 0x8c3b, 0x00c0, 0x9c9d, 0x1078, 0x7a05,
+       0x0d7f, 0x1078, 0x8c01, 0x0078, 0x9cb9, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x9cb6, 0xa786, 0x0003, 0x00c0, 0x9ccd, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa181, 0x017e, 0x1078,
+       0x8cb8, 0x1078, 0x4982, 0x017f, 0x1078, 0x8bf4, 0x0d7f, 0x1078,
+       0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+       0x9cc3, 0x0078, 0x9c4c, 0x127f, 0x027f, 0x047f, 0x057f, 0x067f,
+       0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+       0x9ca7, 0xa386, 0x0005, 0x0040, 0x9cdb, 0x1078, 0xa181, 0x1078,
+       0x9e70, 0x0078, 0x9cb6, 0x0d7f, 0x0078, 0x9cb9, 0x1078, 0x9ef9,
+       0x00c0, 0x9cb9, 0x81ff, 0x0040, 0x9cb9, 0xa180, 0x0001, 0x2004,
+       0xa086, 0x0018, 0x0040, 0x9cf3, 0xa180, 0x0001, 0x2004, 0xa086,
+       0x002d, 0x00c0, 0x9cb9, 0x6000, 0xa086, 0x0002, 0x00c0, 0x9cb9,
+       0x1078, 0x8c27, 0x0040, 0x9d04, 0x1078, 0x8c3b, 0x00c0, 0x9cb9,
+       0x1078, 0x7a05, 0x0078, 0x9d0c, 0x1078, 0x2839, 0x1078, 0x8c3b,
+       0x00c0, 0x9d0c, 0x1078, 0x7a05, 0x1078, 0x8c01, 0x0078, 0x9cb9,
+       0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x9e8c, 0x017f,
+       0x0040, 0x9d1f, 0x601c, 0xa084, 0x000f, 0x1079, 0x9d22, 0x0e7f,
+       0x0c7f, 0x007c, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a,
+       0x9d2c, 0x9d2a, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080,
+       0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020,
+       0x1078, 0x9ec0, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078,
+       0x9a6a, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078,
+       0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+       0xa305, 0x2011, 0xa896, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+       0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x087e, 0x077e,
+       0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2061, 0xaa00,
+       0x2079, 0x0001, 0x8fff, 0x0040, 0x9dc3, 0x2071, 0xa300, 0x7644,
+       0x7060, 0x8001, 0xa602, 0x00c8, 0x9dc3, 0x88ff, 0x0040, 0x9d7e,
+       0x2800, 0xac06, 0x00c0, 0x9db9, 0x2079, 0x0000, 0x1078, 0x9ee5,
+       0x0040, 0x9db9, 0x2400, 0xac06, 0x0040, 0x9db9, 0x671c, 0xa786,
+       0x0006, 0x00c0, 0x9db9, 0xa786, 0x0007, 0x0040, 0x9db9, 0x88ff,
+       0x00c0, 0x9d9d, 0x6018, 0xa206, 0x00c0, 0x9db9, 0x85ff, 0x0040,
+       0x9d9d, 0x6020, 0xa106, 0x00c0, 0x9db9, 0x0d7e, 0x6000, 0xa086,
+       0x0004, 0x00c0, 0x9da9, 0x1078, 0xa134, 0x601f, 0x0007, 0x1078,
+       0x1749, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x9db3, 0x047e,
+       0x1078, 0x9e70, 0x047f, 0x0d7f, 0x1078, 0x8c01, 0x88ff, 0x00c0,
+       0x9dcd, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+       0x9dc3, 0x0078, 0x9d6a, 0xa006, 0x127f, 0x027f, 0x067f, 0x077f,
+       0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078,
+       0x9dc4, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+       0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049, 0x0000, 0x1078,
+       0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x1078,
+       0x9d5b, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e,
+       0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000,
+       0x017e, 0x037e, 0x1078, 0x4501, 0x00c0, 0x9e14, 0x2c10, 0x057e,
+       0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x097e, 0x2049,
+       0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078,
+       0x7105, 0x1078, 0x9d5b, 0x057f, 0x037f, 0x017f, 0x8108, 0x00f0,
+       0x9df8, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+       0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+       0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f,
+       0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x2c20, 0x1078, 0x9d5b,
+       0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e, 0x0c7e,
+       0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x037e,
+       0x1078, 0x4501, 0x00c0, 0x9e64, 0x2c10, 0x087e, 0x2041, 0x0000,
+       0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa111, 0x047f, 0x097e,
+       0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000,
+       0x1078, 0x7105, 0x1078, 0x9d5b, 0x037f, 0x017f, 0x8108, 0x00f0,
+       0x9e46, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+       0x017e, 0x0f7e, 0xad82, 0xca00, 0x0048, 0x9e89, 0xad82, 0xffff,
+       0x00c8, 0x9e89, 0x6800, 0xa07d, 0x0040, 0x9e86, 0x6803, 0x0000,
+       0x6b52, 0x1078, 0x4982, 0x2f68, 0x0078, 0x9e7a, 0x6b52, 0x1078,
+       0x4982, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061,
+       0xaa00, 0x2071, 0xa300, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8,
+       0x9ebb, 0x2100, 0xac06, 0x0040, 0x9ead, 0x6000, 0xa086, 0x0000,
+       0x0040, 0x9ead, 0x6008, 0xa206, 0x00c0, 0x9ead, 0x6018, 0xa1a0,
+       0x0006, 0x2424, 0xa406, 0x0040, 0x9eb7, 0xace0, 0x0010, 0x2001,
+       0xa315, 0x2004, 0xac02, 0x00c8, 0x9ebb, 0x0078, 0x9e91, 0xa085,
+       0x0001, 0x0078, 0x9ebc, 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c,
+       0x0d7e, 0x007e, 0x1078, 0x1381, 0x007f, 0x1040, 0x1328, 0x6837,
+       0x010d, 0x685e, 0x027e, 0x2010, 0x1078, 0x8a30, 0x2001, 0x0000,
+       0x0040, 0x9ed6, 0x2200, 0xa080, 0x0008, 0x2004, 0x027f, 0x684a,
+       0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a,
+       0x685a, 0x1078, 0x4982, 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000,
+       0x0040, 0x9ef8, 0xa786, 0x0001, 0x0040, 0x9ef8, 0xa786, 0x000a,
+       0x0040, 0x9ef8, 0xa786, 0x0009, 0x0040, 0x9ef8, 0xa085, 0x0001,
+       0x007c, 0x0e7e, 0x6018, 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c,
+       0x017e, 0x6004, 0xa08e, 0x001e, 0x00c0, 0x9f1a, 0x8007, 0x6130,
+       0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b,
+       0x601f, 0x0005, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8,
+       0x1078, 0x6109, 0x017f, 0x007c, 0x0005, 0x0005, 0x007c, 0x6024,
+       0xd0e4, 0x0040, 0x9f30, 0xd0cc, 0x0040, 0x9f2a, 0x1078, 0x8cfa,
+       0x0078, 0x9f30, 0x1078, 0xa134, 0x1078, 0x5a41, 0x1078, 0x753d,
+       0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, 0x0079, 0x9f38,
+       0x9f41, 0x9f41, 0x9f41, 0x9f43, 0x9f41, 0x9f43, 0x9f43, 0x9f41,
+       0x9f43, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa280, 0x0007,
+       0x2004, 0xa084, 0x000f, 0x0079, 0x9f4d, 0x9f56, 0x9f56, 0x9f56,
+       0x9f56, 0x9f56, 0x9f56, 0x9f61, 0x9f56, 0x9f56, 0x6007, 0x003b,
+       0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8,
+       0x007c, 0x0c7e, 0x2260, 0x1078, 0xa134, 0x603f, 0x0000, 0x6024,
+       0xc0f4, 0xc0cc, 0x6026, 0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007,
+       0x00c0, 0x9fc2, 0x6810, 0xa005, 0x0040, 0x9f7f, 0xa080, 0x0013,
+       0x2004, 0xd0fc, 0x00c0, 0x9f7f, 0x0d7f, 0x0078, 0x9f56, 0x6007,
+       0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7e,
+       0x2d60, 0x6100, 0xa186, 0x0002, 0x00c0, 0xa050, 0x6010, 0xa005,
+       0x00c0, 0x9f99, 0x6000, 0xa086, 0x0007, 0x10c0, 0x1328, 0x0078,
+       0xa050, 0xa08c, 0xf000, 0x00c0, 0x9fa5, 0x0078, 0x9fa5, 0x2068,
+       0x6800, 0xa005, 0x00c0, 0x9f9f, 0x2d00, 0xa080, 0x0013, 0x2004,
+       0xa084, 0x0003, 0xa086, 0x0002, 0x00c0, 0x9fbe, 0x6010, 0x2068,
+       0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852,
+       0x2009, 0x0043, 0x1078, 0x98c1, 0x0078, 0xa050, 0x2009, 0x0041,
+       0x0078, 0xa04a, 0xa186, 0x0005, 0x00c0, 0xa009, 0x6810, 0xa080,
+       0x0013, 0x2004, 0xd0bc, 0x00c0, 0x9fd0, 0x0d7f, 0x0078, 0x9f56,
+       0xd0b4, 0x0040, 0x9fd8, 0xd0fc, 0x1040, 0x1328, 0x0078, 0x9f72,
+       0x6007, 0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109,
+       0x0c7e, 0x2d60, 0x6100, 0xa186, 0x0002, 0x0040, 0x9feb, 0xa186,
+       0x0004, 0x00c0, 0xa050, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0003,
+       0x00c0, 0x9ff8, 0x7004, 0xac06, 0x00c0, 0x9ff8, 0x7003, 0x0000,
+       0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+       0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078,
+       0xa04a, 0x037e, 0x0d7e, 0x0d7e, 0x1078, 0x1381, 0x037f, 0x1040,
+       0x1328, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+       0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+       0x2360, 0x6024, 0xc0dd, 0x6026, 0x6018, 0xa080, 0x0028, 0x2004,
+       0xa084, 0x00ff, 0x8007, 0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000,
+       0x6d6a, 0x6e66, 0x686f, 0x0001, 0x1078, 0x4982, 0x2019, 0x0045,
+       0x6008, 0x2068, 0x1078, 0x9a6a, 0x2d00, 0x600a, 0x601f, 0x0006,
+       0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f,
+       0x0078, 0xa051, 0x603f, 0x0000, 0x6003, 0x0007, 0x1078, 0x98c1,
+       0x0c7f, 0x0d7f, 0x007c, 0xa186, 0x0013, 0x00c0, 0xa05d, 0x6004,
+       0xa082, 0x0085, 0x2008, 0x0079, 0xa077, 0xa186, 0x0027, 0x00c0,
+       0xa070, 0x1078, 0x6010, 0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019,
+       0x0004, 0x1078, 0x9e70, 0x0d7f, 0x037f, 0x1078, 0x6109, 0x007c,
+       0xa186, 0x0014, 0x0040, 0xa061, 0x1078, 0x7583, 0x007c, 0xa080,
+       0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa080, 0x1078, 0x1328,
+       0x1078, 0x6010, 0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0xa182,
+       0x008c, 0x00c8, 0xa091, 0xa182, 0x0085, 0x0048, 0xa091, 0x0079,
+       0xa094, 0x1078, 0x7583, 0x007c, 0xa09b, 0xa09b, 0xa09b, 0xa09b,
+       0xa09d, 0xa0bc, 0xa09b, 0x1078, 0x1328, 0x0d7e, 0x2c68, 0x1078,
+       0x74d7, 0x0040, 0xa0b7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
+       0xa88e, 0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x600b,
+       0xffff, 0x6918, 0x611a, 0x601f, 0x0004, 0x1078, 0x5bf8, 0x2d60,
+       0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x753d, 0x007c, 0x0e7e,
+       0x6018, 0x2070, 0x7000, 0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa080,
+       0x0013, 0x200c, 0xd1ec, 0x0040, 0xa110, 0x2001, 0xa371, 0x2004,
+       0xd0ec, 0x0040, 0xa110, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026,
+       0xd1ac, 0x0040, 0xa0ee, 0x0f7e, 0x2c78, 0x1078, 0x488f, 0x0f7f,
+       0x0040, 0xa0ee, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x2009, 0xa371,
+       0x210c, 0xd1f4, 0x00c0, 0xa10e, 0x0078, 0xa100, 0x2009, 0xa371,
+       0x210c, 0xd1f4, 0x0040, 0xa0fa, 0x6024, 0xc0e4, 0x6026, 0xa006,
+       0x0078, 0xa110, 0x2001, 0xa5a2, 0x200c, 0x8103, 0xa100, 0x603e,
+       0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa10b, 0xa088,
+       0x0003, 0x0078, 0xa103, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001,
+       0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b, 0x2e04,
+       0x2060, 0x8cff, 0x0040, 0xa130, 0x84ff, 0x00c0, 0xa123, 0x6020,
+       0xa106, 0x00c0, 0xa12b, 0x600c, 0x2072, 0x1078, 0x5a41, 0x1078,
+       0x753d, 0x0078, 0xa12d, 0xacf0, 0x0003, 0x2e64, 0x0078, 0xa119,
+       0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8, 0x002b,
+       0x2d04, 0xa005, 0x0040, 0xa146, 0xac06, 0x0040, 0xa144, 0x2d04,
+       0xa0e8, 0x0003, 0x0078, 0xa138, 0x600c, 0x206a, 0x0d7f, 0x007c,
+       0x027e, 0x037e, 0x157e, 0x2011, 0xa325, 0x2204, 0xa084, 0x00ff,
+       0x2019, 0xa88e, 0x2334, 0xa636, 0x00c0, 0xa174, 0x8318, 0x2334,
+       0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa174, 0x2011, 0xa890,
+       0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+       0xa174, 0x2011, 0xa894, 0x6018, 0xa098, 0x0006, 0x20a9, 0x0004,
+       0x1078, 0x7e55, 0x00c0, 0xa174, 0x157f, 0x037f, 0x027f, 0x007c,
+       0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x1078, 0x260d, 0x0e7f,
+       0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040, 0xa18a,
+       0x1078, 0xa18c, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852, 0x007c,
+       0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, 0x017e,
+       0x127e, 0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba,
+       0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060, 0xa606,
+       0x0040, 0xa1e4, 0x671c, 0xa786, 0x0001, 0x0040, 0xa1b3, 0xa786,
+       0x0008, 0x00c0, 0xa1da, 0x2500, 0xac06, 0x0040, 0xa1da, 0x2400,
+       0xac06, 0x0040, 0xa1da, 0x1078, 0x9ee5, 0x0040, 0xa1da, 0x1078,
+       0x9ef9, 0x00c0, 0xa1da, 0x6000, 0xa086, 0x0004, 0x00c0, 0xa1cc,
+       0x017e, 0x1078, 0x1749, 0x017f, 0x1078, 0x8c27, 0x00c0, 0xa1d2,
+       0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0, 0xa1d8, 0x1078, 0x7a05,
+       0x1078, 0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02,
+       0x00c8, 0xa1e4, 0x0078, 0xa1a3, 0x127f, 0x017f, 0x027f, 0x047f,
+       0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x007e,
+       0x0e7e, 0x2091, 0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa1fb,
+       0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa201, 0x7030, 0x8000,
+       0x7032, 0xd5ac, 0x0040, 0xa208, 0x2071, 0xa34a, 0x1078, 0xa237,
+       0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091,
+       0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa219, 0x7034, 0x8000,
+       0x7036, 0xd5b4, 0x0040, 0xa21f, 0x7030, 0x8000, 0x7032, 0xd5ac,
+       0x0040, 0xa226, 0x2071, 0xa34a, 0x1078, 0xa237, 0x0e7f, 0x007f,
+       0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
+       0xa342, 0x1078, 0xa237, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04,
+       0x8000, 0x2072, 0x00c8, 0xa240, 0x8e70, 0x2e04, 0x8000, 0x2072,
+       0x007c, 0x0e7e, 0x2071, 0xa340, 0x1078, 0xa237, 0x0e7f, 0x007c,
+       0x0e7e, 0x2071, 0xa344, 0x1078, 0xa237, 0x0e7f, 0x007c, 0x0001,
+       0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+       0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x6286
+};
+
+/************************************************************************
+ *                                                                     *
+ *               --- ISP2200 Initiator/Target Firmware ---              *
+ *             with Fabric (Public Loop), Point-point, and              *
+ *             expanded LUN addressing for FCTAPE                       *
+ *                                                                     *
+ ************************************************************************
+  Copyright (C) 2000 and 2100 Qlogic Corporation 
+  (www.qlogic.com)
+
+  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.
+************************************************************************/
+
+/*
+ *     Firmware Version 2.01.27 (11:07 Dec 18, 2000)
+ */
+
+unsigned short risc_code_length2200 = 0x9cbf;
+unsigned short risc_code2200[] = { 
+       0x0470, 0x0000, 0x0000, 0x9cbf, 0x0000, 0x0002, 0x0001, 0x001b,
+       0x0017, 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, 0x3031, 0x2e32, 0x3720, 0x2020, 0x2020, 0x2400, 0x20c1,
+       0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xb1ff, 0x2091,
+       0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x27b5,
+       0x2051, 0xad00, 0x2a70, 0x2029, 0xe400, 0x2031, 0xffff, 0x2039,
+       0xe3e9, 0x2021, 0x0200, 0x0804, 0x1449, 0x20a1, 0xacbf, 0xa00e,
+       0x20a9, 0x0741, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466,
+       0x746a, 0x20a1, 0xb400, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d,
+       0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4,
+       0x3400, 0x8211, 0x1dd8, 0x7160, 0x3400, 0xa102, 0x0120, 0x0218,
+       0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xad00,
+       0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001,
+       0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0,
+       0x2009, 0xad00, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
+       0x41a4, 0x080c, 0x13fc, 0x080c, 0x1613, 0x080c, 0x17ac, 0x080c,
+       0x1e67, 0x080c, 0x492e, 0x080c, 0x801a, 0x080c, 0x159c, 0x080c,
+       0x2ce6, 0x080c, 0x5a01, 0x080c, 0x5045, 0x080c, 0x6487, 0x080c,
+       0x236a, 0x080c, 0x6686, 0x080c, 0x5fae, 0x080c, 0x226b, 0x080c,
+       0x2338, 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, 0x3c98, 0x080c,
+       0x2d0d, 0x080c, 0x5a4f, 0x080c, 0x51f4, 0x080c, 0x64a2, 0x0c80,
+       0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1203, 0x10e2, 0x12cc, 0x13f9,
+       0x13fa, 0x13fb, 0x080c, 0x14f6, 0x0005, 0x0126, 0x00f6, 0x2091,
+       0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11d1, 0x080c, 0x1569,
+       0x080c, 0x574f, 0x0150, 0x080c, 0x5775, 0x1580, 0x2079, 0x0100,
+       0x7828, 0xa085, 0x1800, 0x782a, 0x0448, 0x080c, 0x569a, 0x7000,
+       0xa086, 0x0001, 0x1904, 0x11d1, 0x7088, 0xa086, 0x0028, 0x1904,
+       0x11d1, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0xa295, 0x1e2f,
+       0x7a2a, 0x2011, 0x566e, 0x080c, 0x650d, 0x2011, 0x567b, 0x080c,
+       0x650d, 0x2011, 0x481b, 0x080c, 0x650d, 0x2011, 0x8030, 0x2019,
+       0x0000, 0x7087, 0x0000, 0x080c, 0x1d0f, 0x00e8, 0x080c, 0x41d1,
+       0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11d1, 0x2011, 0x481b,
+       0x080c, 0x650d, 0x2011, 0x567b, 0x080c, 0x650d, 0x080c, 0x1d0f,
+       0x2001, 0xaf8c, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842,
+       0x2011, 0x8010, 0x73c8, 0x080c, 0x3c5c, 0x7238, 0xc284, 0x723a,
+       0x2001, 0xad0c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x79bd, 0x2011,
+       0x0004, 0x080c, 0x959c, 0x080c, 0x4f71, 0x080c, 0x574f, 0x0158,
+       0x080c, 0x4917, 0x0140, 0x7087, 0x0001, 0x70c3, 0x0000, 0x080c,
+       0x436e, 0x0804, 0x11d1, 0x080c, 0x502d, 0x0120, 0x7a0c, 0xc2b4,
+       0x7a0e, 0x0050, 0x080c, 0x9937, 0x70d0, 0xd09c, 0x1128, 0x709c,
+       0xa005, 0x0110, 0x080c, 0x48f5, 0x70db, 0x0000, 0x70d7, 0x0000,
+       0x72d0, 0x080c, 0x574f, 0x1178, 0x2011, 0x0000, 0x0016, 0x080c,
+       0x2744, 0x2019, 0xaf8e, 0x211a, 0x001e, 0x704f, 0xffff, 0x7053,
+       0x00ef, 0x7073, 0x0000, 0x2079, 0xad51, 0x7804, 0xd0ac, 0x0108,
+       0xc295, 0x72d2, 0x080c, 0x574f, 0x0118, 0xa296, 0x0004, 0x0508,
+       0x2011, 0x0001, 0x080c, 0x959c, 0x7097, 0x0000, 0x709b, 0xffff,
+       0x7003, 0x0002, 0x00fe, 0x080c, 0x28fa, 0x2011, 0x0005, 0x080c,
+       0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148, 0x00c6, 0x2061,
+       0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e, 0x00ce, 0x012e,
+       0x00d0, 0x7097, 0x0000, 0x709b, 0xffff, 0x7003, 0x0002, 0x2011,
+       0x0005, 0x080c, 0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148,
+       0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e,
+       0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1118,
+       0x20a9, 0x0100, 0x0010, 0x20a9, 0x0082, 0x080c, 0x574f, 0x1118,
+       0x2009, 0x0000, 0x0010, 0x2009, 0x007e, 0x0016, 0x0026, 0x0036,
+       0x2110, 0x0026, 0x2019, 0x0029, 0x080c, 0x7cf4, 0x002e, 0x080c,
+       0xac07, 0x003e, 0x002e, 0x001e, 0x080c, 0x2bc9, 0x8108, 0x1f04,
+       0x11e5, 0x00ce, 0x706f, 0x0000, 0x7070, 0xa084, 0x00ff, 0x7072,
+       0x709f, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x7000, 0xa086,
+       0x0002, 0x1904, 0x12ca, 0x7098, 0xa086, 0xffff, 0x0130, 0x080c,
+       0x28fa, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d0, 0xd0ac, 0x1110,
+       0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x0016, 0x2001, 0x0103,
+       0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e, 0xd08c, 0x01d0,
+       0x70d4, 0xa086, 0xffff, 0x0190, 0x080c, 0x2a56, 0x080c, 0x6c50,
+       0x70d0, 0xd094, 0x1904, 0x12ca, 0x2011, 0x0001, 0x2019, 0x0000,
+       0x080c, 0x2a8c, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d8, 0xa005,
+       0x1904, 0x12ca, 0x7094, 0xa005, 0x1904, 0x12ca, 0x70d0, 0xd0a4,
+       0x0118, 0xd0b4, 0x0904, 0x12ca, 0x080c, 0x502d, 0x1904, 0x12ca,
+       0x2001, 0xad52, 0x2004, 0xd0ac, 0x01c8, 0x0156, 0x00c6, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1118, 0x6000,
+       0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x125b, 0x00ce, 0x015e,
+       0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x12ca, 0x0006, 0x0016,
+       0x2001, 0x0103, 0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e,
+       0xa006, 0x2009, 0x0700, 0x20a9, 0x0002, 0x20a1, 0xafb5, 0x40a1,
+       0x706c, 0x8007, 0x7170, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x2009,
+       0x0000, 0x080c, 0x14dc, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002,
+       0x40a1, 0xa006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x20a1, 0xafc5,
+       0x40a1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x709b, 0xffff,
+       0x080c, 0x1562, 0xa006, 0x080c, 0x261e, 0x080c, 0x3cce, 0x00f6,
+       0x2079, 0x0100, 0x080c, 0x5775, 0x0150, 0x080c, 0x574f, 0x7828,
+       0x0118, 0xa084, 0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe,
+       0x2001, 0xafc8, 0x2004, 0xa086, 0x0005, 0x1120, 0x2011, 0x0000,
+       0x080c, 0x7adf, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c, 0x6c50,
+       0x080c, 0x6d0d, 0x012e, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126,
+       0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0xad33, 0x2104, 0xa005,
+       0x1110, 0x080c, 0x2770, 0x2009, 0x00f7, 0x080c, 0x48de, 0x7940,
+       0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040,
+       0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954,
+       0xd1ac, 0x1904, 0x133a, 0x080c, 0x5761, 0x0158, 0x080c, 0x5775,
+       0x1128, 0x2001, 0xaf9d, 0x2003, 0x0000, 0x0070, 0x080c, 0x5757,
+       0x0dc0, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+       0x0001, 0x080c, 0x569a, 0x0058, 0x080c, 0x574f, 0x0140, 0x2009,
+       0x00f8, 0x080c, 0x48de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+       0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x574f, 0x0138, 0x7824,
+       0xd0ac, 0x1904, 0x13e0, 0x1f04, 0x1319, 0x0070, 0x7824, 0x080c,
+       0x576b, 0x0118, 0xd0ac, 0x1904, 0x13e0, 0xa084, 0x1800, 0x0d98,
+       0x7003, 0x0001, 0x0804, 0x13e0, 0x2001, 0x0001, 0x080c, 0x261e,
+       0x0804, 0x13ef, 0x7850, 0xa084, 0x0180, 0x7852, 0x782f, 0x0020,
+       0x20a9, 0x0046, 0x1d04, 0x1342, 0x2091, 0x6000, 0x1f04, 0x1342,
+       0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x782f, 0x0000,
+       0x080c, 0x5761, 0x0158, 0x080c, 0x5775, 0x1128, 0x2001, 0xaf9d,
+       0x2003, 0x0000, 0x0070, 0x080c, 0x5757, 0x0dc0, 0x2001, 0xaf9d,
+       0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x080c, 0x569a,
+       0x0020, 0x2009, 0x00f8, 0x080c, 0x48de, 0x20a9, 0x000e, 0xe000,
+       0x1f04, 0x136f, 0x7850, 0xa084, 0x0180, 0xa085, 0x1400, 0x7852,
+       0x080c, 0x574f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021,
+       0xe678, 0x2019, 0xea60, 0x7820, 0xd09c, 0x1558, 0x080c, 0x574f,
+       0x05b8, 0x7824, 0xd0ac, 0x1904, 0x13e0, 0x080c, 0x5775, 0x1508,
+       0x0046, 0x2021, 0x0190, 0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8,
+       0x7827, 0x0048, 0x20a9, 0x01f4, 0x1d04, 0x139c, 0x2091, 0x6000,
+       0x1f04, 0x139c, 0x7824, 0xa084, 0x0068, 0x15a8, 0x2001, 0xaf9d,
+       0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x7003, 0x0001,
+       0x0478, 0x8319, 0x1980, 0x2009, 0xad33, 0x2104, 0x8000, 0x200a,
+       0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c, 0x2770, 0x00d8,
+       0x080c, 0x5761, 0x1140, 0xa4a2, 0x0064, 0x1128, 0x080c, 0x5726,
+       0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000, 0xe000, 0x7824,
+       0x080c, 0x576b, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800, 0x09c8,
+       0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x261e, 0x0048,
+       0x2001, 0xad33, 0x2003, 0x0000, 0x7827, 0x0048, 0x7828, 0xc09d,
+       0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x015e,
+       0x003e, 0x000e, 0x080c, 0x1539, 0x012e, 0x00fe, 0x004e, 0x001e,
+       0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2001, 0xaf9d, 0x2003,
+       0x0000, 0x7087, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002,
+       0x0218, 0x704f, 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff,
+       0x706f, 0x0000, 0x7073, 0x0000, 0x080c, 0x9937, 0x2061, 0xaf8d,
+       0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200,
+       0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0,
+       0x2061, 0xaf95, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000,
+       0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001,
+       0x601f, 0x0000, 0x2061, 0xafa6, 0x6003, 0x514c, 0x6007, 0x4f47,
+       0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xad27, 0x2003, 0x0000,
+       0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570, 0xa186, 0x0001,
+       0x1148, 0x2031, 0x8fff, 0x2039, 0xcc01, 0x2021, 0x0100, 0x2029,
+       0xcc00, 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, 0x1485, 0x0804, 0x14d6, 0x2019, 0xaaaa, 0x2061,
+       0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0xa306, 0x2262,
+       0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019, 0x1498, 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, 0x14b3, 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, 0x14d4, 0x0010, 0x0804, 0x144a, 0x3800, 0xa084,
+       0xfffc, 0xa205, 0x20c0, 0x0837, 0x2011, 0x0000, 0x080c, 0x4cdc,
+       0x1178, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0128, 0xa0c4,
+       0xff00, 0xa8c6, 0x0600, 0x1120, 0xa186, 0x0080, 0x0108, 0x8210,
+       0x8108, 0xa186, 0x0100, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
+       0x0e04, 0x14f8, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084,
+       0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900,
+       0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0126,
+       0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1, 0xb0c8, 0x2091, 0x2000,
+       0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010,
+       0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1,
+       0x20a9, 0x0010, 0x2091, 0x2800, 0x40a1, 0x014e, 0x015e, 0x012e,
+       0x2079, 0xad00, 0x7803, 0x0005, 0x2091, 0x4080, 0x04c9, 0x0cf8,
+       0x0005, 0x0006, 0x080c, 0x1584, 0x1518, 0x00f6, 0x2079, 0xad23,
+       0x2f04, 0x8000, 0x207a, 0xa082, 0x000f, 0x0258, 0xa006, 0x207a,
+       0x2079, 0xad25, 0x2f04, 0xa084, 0x0001, 0xa086, 0x0001, 0x207a,
+       0x0070, 0x2079, 0xad25, 0x2f7c, 0x8fff, 0x1128, 0x2001, 0x0c03,
+       0x2003, 0x0040, 0x0020, 0x2001, 0x0c03, 0x2003, 0x00c0, 0x00fe,
+       0x000e, 0x0005, 0x0409, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0080,
+       0x0005, 0x00d1, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0005,
+       0x0006, 0x0091, 0x1178, 0x2001, 0x0c03, 0x2003, 0x0040, 0x2009,
+       0x0fff, 0x00a1, 0x2001, 0x0c03, 0x2003, 0x0080, 0x2009, 0x0fff,
+       0x0069, 0x0c88, 0x000e, 0x0005, 0x00c6, 0x2061, 0x0c00, 0x2c04,
+       0xa084, 0x00ff, 0xa086, 0x00aa, 0x00ce, 0x0005, 0x0156, 0x0126,
+       0xa18c, 0x0fff, 0x21a8, 0x1d04, 0x1593, 0x2091, 0x6000, 0x1f04,
+       0x1593, 0x012e, 0x015e, 0x0005, 0x2071, 0xad00, 0x715c, 0x712e,
+       0x2021, 0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7060,
+       0xa302, 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800,
+       0xd08c, 0x0148, 0x7060, 0xa086, 0xad00, 0x0128, 0x7063, 0xad00,
+       0x2011, 0x1000, 0x0c48, 0x200b, 0x0000, 0x74ae, 0x74b2, 0x0005,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x70b0, 0xa0ea,
+       0x0010, 0x0268, 0x8001, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e,
+       0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e,
+       0x0cd8, 0x00e6, 0x2071, 0xad00, 0x0126, 0x2091, 0x8000, 0x70b0,
+       0x8001, 0x0260, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b,
+       0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x702c, 0x206a,
+       0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x012e, 0x00ee, 0x0005,
+       0x8dff, 0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de,
+       0x0cb8, 0x0005, 0x00e6, 0x2071, 0xad00, 0x70b0, 0xa08a, 0x0010,
+       0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7007, 0x0000,
+       0x701b, 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085,
+       0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6, 0x2270, 0x700b, 0x0000,
+       0x2071, 0xafec, 0x7018, 0xa088, 0xaff5, 0x220a, 0x8000, 0xa084,
+       0x0007, 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010,
+       0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7004,
+       0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee,
+       0x0005, 0x7000, 0x0002, 0x164f, 0x16b3, 0x16d0, 0x16d0, 0x7018,
+       0x711c, 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180,
+       0xaff5, 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, 0xadf9,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+       0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+       0x7002, 0x700b, 0xadf4, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+       0x0136, 0x0146, 0x0156, 0x2001, 0xae28, 0x209c, 0x20a1, 0x0014,
+       0x7803, 0x0026, 0x2001, 0xae29, 0x20ac, 0x53a6, 0x2099, 0xae2a,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+       0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+       0x7002, 0x700b, 0xae25, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+       0x0016, 0x00e6, 0x2071, 0xafec, 0x00f6, 0x2079, 0x0010, 0x7904,
+       0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023,
+       0x00fe, 0x00ee, 0x001e, 0x0005, 0x1649, 0x1713, 0x1741, 0x176b,
+       0x179b, 0x1712, 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, 0x167a,
+       0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000,
+       0x080c, 0x1649, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200,
+       0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830,
+       0x7832, 0x7834, 0x7836, 0x080c, 0x168f, 0x0005, 0x7008, 0xa080,
+       0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005,
+       0x00d6, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+       0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000,
+       0x080c, 0x1649, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146,
+       0x0156, 0x2001, 0xadf7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099,
+       0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xadf9,
+       0x2004, 0xd0bc, 0x0148, 0x2001, 0xae02, 0x2004, 0xa080, 0x000d,
+       0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007,
+       0x0000, 0x080c, 0x5ae6, 0x080c, 0x1649, 0x0005, 0x2011, 0x8003,
+       0x080c, 0x3c5c, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0xae27,
+       0x2003, 0x0100, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005, 0x2011,
+       0x8004, 0x080c, 0x3c5c, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079,
+       0x0030, 0x2071, 0xaffd, 0x7003, 0x0000, 0x700f, 0xb003, 0x7013,
+       0xb003, 0x780f, 0x00f6, 0x7803, 0x0004, 0x012e, 0x0005, 0x6934,
+       0xa184, 0x0007, 0x0002, 0x17cb, 0x1809, 0x17cb, 0x17cb, 0x17cb,
+       0x17f1, 0x17d8, 0x17cf, 0xa085, 0x0001, 0x0804, 0x1823, 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, 0x2186, 0x2005, 0x6832, 0x6858,
+       0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac,
+       0x0990, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+       0xa080, 0x2186, 0x2005, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858,
+       0x0080, 0x684c, 0xd0ac, 0x0904, 0x17cb, 0xa006, 0x682e, 0x682a,
+       0x6858, 0xa18c, 0x000f, 0xa188, 0x2186, 0x210d, 0x6932, 0x2d08,
+       0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+       0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000,
+       0x2001, 0x020a, 0x2004, 0x82ff, 0x01a8, 0xa280, 0x0004, 0x00d6,
+       0x206c, 0x684c, 0xd0dc, 0x1150, 0x080c, 0x17bf, 0x0138, 0x00de,
+       0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0020, 0x6808, 0x8000,
+       0x680a, 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200,
+       0x002e, 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a,
+       0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0xb01e, 0x0210,
+       0x2009, 0xb003, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118,
+       0xa080, 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005,
+       0x7206, 0x2001, 0x1866, 0x0006, 0x2260, 0x0804, 0x197a, 0x0126,
+       0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e,
+       0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62,
+       0x6b5e, 0xa005, 0x0904, 0x18c8, 0x6808, 0xa005, 0x0904, 0x18ff,
+       0x7000, 0xa005, 0x1108, 0x0488, 0x700c, 0x7110, 0xa106, 0x1904,
+       0x1907, 0x7004, 0xa406, 0x1548, 0x2001, 0x0005, 0x2004, 0xd08c,
+       0x0168, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010, 0xa080,
+       0x0002, 0x2004, 0xa005, 0x0904, 0x18ff, 0x0c10, 0x2001, 0x0207,
+       0x2004, 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086,
+       0x6000, 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803,
+       0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004,
+       0x1904, 0x1907, 0x2009, 0x0048, 0x080c, 0x80a7, 0x0804, 0x1907,
+       0x6808, 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c, 0x7110,
+       0xa106, 0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005, 0x2004,
+       0xd08c, 0x0160, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010,
+       0xa080, 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001, 0x0207,
+       0x2004, 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d50,
+       0x7804, 0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0, 0x7818,
+       0x6812, 0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x6100,
+       0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x80a7, 0x00ce,
+       0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046,
+       0x0056, 0x080c, 0x1d86, 0x0026, 0x0056, 0x2071, 0xaffd, 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, 0x1a6c, 0x08d0, 0x0156, 0x20a9, 0x0009,
+       0x2009, 0xb003, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003,
+       0x1f04, 0x1942, 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, 0x19dd, 0x2104, 0x7006, 0x2060, 0x8108,
+       0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb01e, 0x0210, 0x2009,
+       0xb003, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c, 0x2744, 0x2001,
+       0x0138, 0x2102, 0x8cff, 0x0588, 0x6010, 0x2068, 0x2d58, 0x6828,
+       0xa406, 0x1580, 0x682c, 0xa306, 0x1568, 0x7004, 0x2060, 0x6020,
+       0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817, 0xffff, 0x6813,
+       0xffff, 0x00d8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810,
+       0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+       0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x04c9, 0x0118,
+       0x2009, 0x0001, 0x04a9, 0x2d58, 0x0005, 0x080c, 0x1ced, 0x0904,
+       0x195f, 0x0cd0, 0x6020, 0xd0d4, 0x01b8, 0x6038, 0xa402, 0x6034,
+       0xa303, 0x0108, 0x1288, 0x643a, 0x6336, 0x6c2a, 0x6b2e, 0x0046,
+       0x0036, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, 0xa303,
+       0x6816, 0x003e, 0x004e, 0x0018, 0x080c, 0x98cb, 0x09f0, 0x601c,
+       0xa08e, 0x0008, 0x0904, 0x1985, 0xa08e, 0x000a, 0x0904, 0x1985,
+       0x080c, 0x21a6, 0x1990, 0x0804, 0x1985, 0x7003, 0x0000, 0x0005,
+       0x8aff, 0x0904, 0x1a46, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11b8,
+       0xd0f4, 0x1528, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1a30,
+       0x1a15, 0x1a15, 0x1a30, 0x1a30, 0x1a29, 0x1a30, 0x1a15, 0x1a30,
+       0x1a1a, 0x1a1a, 0x1a30, 0x1a30, 0x1a30, 0x1a21, 0x1a1a, 0x7803,
+       0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6,
+       0xd99c, 0x0548, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x0420, 0xc0f4,
+       0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0428, 0x6b08, 0x6a0c, 0x6d00,
+       0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c,
+       0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+       0x1138, 0x00de, 0x080c, 0x2148, 0x1904, 0x19e0, 0xa00e, 0x00b0,
+       0x00de, 0x080c, 0x14f6, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+       0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de, 0x6828, 0xa300,
+       0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x2148, 0x0005, 0x080c,
+       0x14f6, 0x080c, 0x1e1a, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068,
+       0x7003, 0x0000, 0x080c, 0x1d22, 0x080c, 0x9596, 0x0170, 0x6808,
+       0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff,
+       0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c,
+       0x0804, 0x1c5e, 0x080c, 0x14f6, 0x0126, 0x2091, 0x2200, 0x0006,
+       0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+       0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000,
+       0x0002, 0x1a89, 0x1a8f, 0x1b92, 0x1c39, 0x1c4d, 0x1a89, 0x1a89,
+       0x1a89, 0x7804, 0xd09c, 0x1904, 0x1c5e, 0x080c, 0x14f6, 0x8001,
+       0x7002, 0xa184, 0x0880, 0x1190, 0xd19c, 0x1904, 0x1b20, 0x8aff,
+       0x0904, 0x1b20, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0904, 0x1c5e,
+       0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7803, 0x0004,
+       0x7003, 0x0000, 0xd1bc, 0x1904, 0x1b00, 0x0026, 0x0036, 0x7c20,
+       0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001,
+       0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803,
+       0x0009, 0x7003, 0x0004, 0x0010, 0x080c, 0x1c62, 0x6b28, 0x6a2c,
+       0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e,
+       0x00c6, 0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110, 0x633a, 0x6236,
+       0x00ce, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x080c, 0x215e, 0x2a00,
+       0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852,
+       0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004,
+       0x2060, 0x2009, 0x0048, 0x080c, 0x80a7, 0x7000, 0xa086, 0x0004,
+       0x0904, 0x1c5e, 0x7003, 0x0000, 0x080c, 0x195f, 0x0804, 0x1c5e,
+       0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0xac73, 0x005e, 0x080c,
+       0x1d22, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5029, 0x0118, 0x7820,
+       0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808,
+       0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0804, 0x1c5e,
+       0x7004, 0x00c6, 0x2060, 0x6020, 0x00ce, 0xd0f4, 0x0128, 0x6808,
+       0x8001, 0x680a, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x7a1c, 0x6a16,
+       0xd19c, 0x0160, 0xa205, 0x0150, 0x7004, 0xa080, 0x0007, 0x2004,
+       0xa084, 0xfffd, 0xa086, 0x0008, 0x1904, 0x1aa6, 0x684c, 0xc0f5,
+       0x684e, 0x7814, 0xa005, 0x1180, 0x7003, 0x0000, 0x6808, 0x8001,
+       0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x80a7,
+       0x080c, 0x195f, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x781c, 0x6816,
+       0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214,
+       0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b,
+       0x810b, 0x080c, 0x1da5, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+       0x0001, 0x7804, 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, 0x0004,
+       0x780f, 0x00f6, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048,
+       0x080c, 0x80a7, 0x080c, 0x1dd7, 0x0958, 0x7908, 0xd1ec, 0x1118,
+       0x2009, 0x0009, 0x0010, 0x2009, 0x0019, 0x7902, 0x7003, 0x0003,
+       0x0804, 0x1c5e, 0x8001, 0x7002, 0xd194, 0x01a8, 0x7804, 0xd0fc,
+       0x1904, 0x1c2c, 0xd09c, 0x0130, 0x7804, 0xd0fc, 0x1904, 0x1a74,
+       0xd09c, 0x11a8, 0x8aff, 0x0904, 0x1c5e, 0x2009, 0x0001, 0x080c,
+       0x19e0, 0x0804, 0x1c5e, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904,
+       0x1c5e, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7818,
+       0x6812, 0x7a1c, 0x6a16, 0xa205, 0x0904, 0x1b3e, 0x7803, 0x0004,
+       0x7003, 0x0000, 0xd1bc, 0x1904, 0x1c0f, 0x6834, 0xa084, 0x00ff,
+       0xa086, 0x0029, 0x1118, 0xd19c, 0x1904, 0x1b3e, 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, 0x1c62,
+       0x001e, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6, 0x2805, 0xac68,
+       0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020,
+       0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1ac8,
+       0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001,
+       0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1b50, 0x0056,
+       0x7d0c, 0x080c, 0xac73, 0x005e, 0x080c, 0x1d22, 0x00f6, 0x7004,
+       0x2078, 0x080c, 0x5029, 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe,
+       0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c,
+       0x791a, 0x6980, 0x791e, 0x0490, 0x7804, 0xd09c, 0x0904, 0x1a74,
+       0x7c20, 0x7824, 0xa405, 0x1904, 0x1a74, 0x7803, 0x0002, 0x0804,
+       0x1bb7, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0150,
+       0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048,
+       0x080c, 0x80a7, 0x080c, 0x195f, 0x0088, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068, 0x6808,
+       0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x197a, 0x001e, 0x000e,
+       0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1ce1, 0x7004,
+       0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1ce1, 0x00d6, 0x00c6,
+       0x216c, 0x2d00, 0xa005, 0x0904, 0x1cdf, 0x6820, 0xd0d4, 0x1904,
+       0x1cdf, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104,
+       0x6b2c, 0xa306, 0x1904, 0x1cdf, 0x8108, 0x2104, 0x6a28, 0xa206,
+       0x1904, 0x1cdf, 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, 0x04a0, 0xa006, 0x783a, 0x783e,
+       0x0480, 0x8108, 0x2104, 0xa005, 0x1590, 0x8108, 0x2104, 0xa005,
+       0x1570, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160,
+       0xa180, 0x000d, 0x2004, 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, 0x1dd7, 0x0148, 0x7803, 0x0009, 0x7904,
+       0xd1fc, 0x0de8, 0x7803, 0x0006, 0x0c29, 0x0168, 0x780c, 0xd0a4,
+       0x1150, 0x7007, 0x0000, 0x080c, 0x1dd7, 0x0140, 0x7803, 0x0019,
+       0x7003, 0x0003, 0x0018, 0x00b1, 0xa085, 0x0001, 0x0005, 0x0126,
+       0x2091, 0x2200, 0x7000, 0xa086, 0x0003, 0x1150, 0x700c, 0x7110,
+       0xa106, 0x0130, 0x20e1, 0x9028, 0x700f, 0xb003, 0x7013, 0xb003,
+       0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1550, 0x2001, 0x0160,
+       0x2003, 0x0000, 0x2001, 0x0138, 0x2003, 0x0000, 0x2011, 0x00c8,
+       0xe000, 0xe000, 0x8211, 0x1de0, 0x080c, 0x1d7e, 0x700c, 0x7110,
+       0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060,
+       0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb01e, 0x0210,
+       0x2009, 0xb003, 0x7112, 0x0c50, 0x080c, 0x57d1, 0x00ce, 0x0005,
+       0x04a9, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01d0, 0x2104,
+       0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
+       0xa188, 0x0003, 0xa182, 0xb01e, 0x0210, 0x2009, 0xb003, 0x7112,
+       0x700c, 0xa106, 0x1d40, 0x080c, 0x2744, 0x2001, 0x0138, 0x2102,
+       0x0c10, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x2001, 0x0160,
+       0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x20e1, 0x9028,
+       0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 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, 0x00e6, 0x2071, 0x0200,
+       0x7808, 0xa084, 0xf000, 0xa10d, 0x08c9, 0x2019, 0x5000, 0x8319,
+       0x0168, 0x2001, 0xb01e, 0x2004, 0xa086, 0x0000, 0x0138, 0x2001,
+       0x0021, 0xd0fc, 0x0da0, 0x080c, 0x1ff4, 0x0c78, 0x20e1, 0x7000,
+       0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f,
+       0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001,
+       0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x0005, 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, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x0026, 0x2071, 0xaffd,
+       0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x01a8,
+       0x8211, 0x0188, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0dc8, 0x7904,
+       0xa18c, 0x0780, 0x0016, 0x080c, 0x1a6c, 0x001e, 0x81ff, 0x1118,
+       0x2011, 0x0050, 0x0c48, 0xa085, 0x0001, 0x002e, 0x001e, 0x00ee,
+       0x00fe, 0x0005, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+       0x0904, 0x1e66, 0x8109, 0x1dd0, 0x2009, 0x0100, 0x210c, 0xa18a,
+       0x0003, 0x0a0c, 0x14f6, 0x080c, 0x20f2, 0x00e6, 0x00f6, 0x2071,
+       0xafec, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0538, 0x7800,
+       0x0006, 0x7820, 0x0006, 0x7830, 0x0006, 0x7834, 0x0006, 0x7838,
+       0x0006, 0x783c, 0x0006, 0x7803, 0x0004, 0xe000, 0xe000, 0x2079,
+       0x0030, 0x7804, 0xd0ac, 0x190c, 0x14f6, 0x2079, 0x0010, 0x000e,
+       0x783e, 0x000e, 0x783a, 0x000e, 0x7836, 0x000e, 0x7832, 0x000e,
+       0x7822, 0x000e, 0x7802, 0x00fe, 0x00ee, 0x0030, 0x00fe, 0x00ee,
+       0x7804, 0xd0ac, 0x190c, 0x14f6, 0x080c, 0x6d0d, 0x0005, 0x00e6,
+       0x2071, 0xb01e, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0xa280,
+       0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1ee4, 0x6934, 0xa184,
+       0x0007, 0x0002, 0x1e82, 0x1ecf, 0x1e82, 0x1e82, 0x1e82, 0x1eb6,
+       0x1e95, 0x1e84, 0x080c, 0x14f6, 0x684c, 0xd0b4, 0x0904, 0x1fcc,
+       0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a,
+       0x6880, 0x680e, 0x6958, 0x0804, 0x1ed7, 0x6834, 0xa084, 0x00ff,
+       0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6860,
+       0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880,
+       0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+       0xa080, 0x2186, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, 0x00ff,
+       0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6804,
+       0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x2186,
+       0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, 0x684c,
+       0xd0b4, 0x0904, 0x1a47, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00,
+       0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832,
+       0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, 0x2079,
+       0x0020, 0x7804, 0xd0fc, 0x190c, 0x1ff4, 0x00e6, 0x00d6, 0x2071,
+       0xb01e, 0x7000, 0xa005, 0x1904, 0x1f4c, 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, 0x791a, 0x7116, 0x680c, 0x781e, 0x701a,
+       0xa006, 0x700e, 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120,
+       0x6928, 0x6810, 0xa106, 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10,
+       0x080c, 0x21a6, 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,
+       0x1fc5, 0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04,
+       0x1fc4, 0xa705, 0x0904, 0x1fc4, 0xa03e, 0x2730, 0x6850, 0xd0fc,
+       0x11a8, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1fa7, 0x1f8c,
+       0x1f8c, 0x1fa7, 0x1fa7, 0x1fa0, 0x1fa7, 0x1f8c, 0x1fa7, 0x1f91,
+       0x1f91, 0x1fa7, 0x1fa7, 0x1fa7, 0x1f98, 0x1f91, 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, 0x2148, 0x1904, 0x1f56, 0xa00e, 0x00f0, 0x00de,
+       0x080c, 0x14f6, 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+       0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a,
+       0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201,
+       0x7012, 0x080c, 0x2148, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e,
+       0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x14f6, 0x0026, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596,
+       0x0118, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c, 0x20e1,
+       0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c,
+       0x6d0d, 0x002e, 0x0804, 0x20ad, 0x0126, 0x2091, 0x2400, 0x0006,
+       0x0016, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071,
+       0xb01e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+       0x0700, 0x1920, 0x7000, 0x0002, 0x20ad, 0x2010, 0x2080, 0x20ab,
+       0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001,
+       0x080c, 0x1f50, 0x0904, 0x20ad, 0x2009, 0x0001, 0x080c, 0x1f50,
+       0x0804, 0x20ad, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc,
+       0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, 0x00b8, 0x0026,
+       0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872,
+       0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, 0x6a2e, 0x003e,
+       0x002e, 0x080c, 0x215e, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826,
+       0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0804, 0x20ad,
+       0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100,
+       0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x0036, 0x2019,
+       0x1000, 0x8319, 0x090c, 0x14f6, 0x7820, 0xd0bc, 0x1dd0, 0x003e,
+       0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e,
+       0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012,
+       0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468,
+       0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x2004,
+       0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x1f50,
+       0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6,
+       0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c,
+       0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804,
+       0x2033, 0x0804, 0x202f, 0x080c, 0x14f6, 0x00ce, 0x00de, 0x00ee,
+       0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071,
+       0xb01e, 0x7000, 0xa086, 0x0000, 0x0590, 0x2079, 0x0020, 0x0016,
+       0x2009, 0x0207, 0x210c, 0xd194, 0x0158, 0x2009, 0x020c, 0x210c,
+       0xa184, 0x0003, 0x0128, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102,
+       0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x1110,
+       0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0d18, 0x080c, 0x1ff4, 0x7000,
+       0xa086, 0x0000, 0x19e8, 0x001e, 0x7803, 0x0004, 0x7804, 0xd0ac,
+       0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee,
+       0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071,
+       0xb01e, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0540, 0x7004,
+       0x2060, 0x6010, 0x2068, 0x080c, 0x9596, 0x0158, 0x6850, 0xc0b5,
+       0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, 0x7a18, 0xa206,
+       0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803,
+       0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c, 0x929c, 0x20e1,
+       0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x00fe,
+       0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, 0x6a14, 0xa205,
+       0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, 0x1e6e, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x2069, 0xafc7, 0x6833, 0x0000, 0x683f, 0x0000, 0x08f8,
+       0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a,
+       0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x2186, 0x2045, 0x88ff,
+       0x090c, 0x14f6, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841,
+       0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005,
+       0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
+       0x2196, 0x2045, 0x88ff, 0x090c, 0x14f6, 0x0005, 0x0000, 0x0011,
+       0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
+       0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x217b,
+       0x2177, 0x0000, 0x0000, 0x2185, 0x0000, 0x217b, 0x0000, 0x2182,
+       0x217f, 0x0000, 0x0000, 0x0000, 0x2185, 0x2182, 0x0000, 0x217d,
+       0x217d, 0x0000, 0x0000, 0x2185, 0x0000, 0x217d, 0x0000, 0x2183,
+       0x2183, 0x0000, 0x0000, 0x0000, 0x2185, 0x2183, 0x00a6, 0x0096,
+       0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, 0x2237, 0x2d60,
+       0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2186, 0xa986, 0x0007, 0x0130,
+       0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422,
+       0x6060, 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2237,
+       0x6004, 0xa065, 0x0904, 0x2237, 0x0c18, 0x2805, 0xa005, 0x01a8,
+       0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020,
+       0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150,
+       0x8a51, 0x0904, 0x2237, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904,
+       0x2237, 0x0830, 0x8a51, 0x0904, 0x2237, 0x8840, 0x2805, 0xa005,
+       0x1158, 0x6004, 0xa065, 0x0904, 0x2237, 0x6034, 0xa0cc, 0x000f,
+       0xa9c0, 0x2186, 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, 0x14f6, 0x6800, 0xa420, 0x6804,
+       0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+       0x0a0c, 0x14f6, 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, 0x224b, 0x224c, 0x224f, 0x2252, 0x2257,
+       0x225a, 0x225f, 0x2264, 0x0005, 0x080c, 0x1ff4, 0x0005, 0x080c,
+       0x1a6c, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4, 0x0005, 0x080c,
+       0x16f8, 0x0005, 0x080c, 0x1ff4, 0x080c, 0x16f8, 0x0005, 0x080c,
+       0x1a6c, 0x080c, 0x16f8, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4,
+       0x080c, 0x16f8, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200,
+       0x2071, 0xb280, 0x2069, 0xad00, 0x2009, 0x0004, 0x7912, 0x7817,
+       0x0004, 0x080c, 0x2651, 0x781b, 0x0002, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x20a9, 0x0080, 0x782f, 0x0000, 0x1f04, 0x2283, 0x20e1,
+       0x9080, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, 0x0005, 0x0126,
+       0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2335, 0xa084, 0x0007,
+       0x0002, 0x22b3, 0x22a1, 0x22a4, 0x22a7, 0x22ac, 0x22ae, 0x22b0,
+       0x22b2, 0x080c, 0x5fb7, 0x0078, 0x080c, 0x5ff0, 0x0060, 0x080c,
+       0x5fb7, 0x080c, 0x5ff0, 0x0038, 0x0041, 0x0028, 0x0031, 0x0018,
+       0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, 0x0016, 0x0026,
+       0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, 0x9040, 0x04a0, 0xa184,
+       0x0030, 0x01e0, 0x6a00, 0xa286, 0x0003, 0x1108, 0x00a0, 0x080c,
+       0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+       0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+       0x0010, 0x080c, 0x485e, 0x20e1, 0x9010, 0x00a8, 0xa184, 0x00c0,
+       0x0168, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c,
+       0x1d22, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0028, 0xa184, 0x0300,
+       0x0110, 0x20e1, 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005,
+       0x0016, 0x00e6, 0x00f6, 0x2071, 0xad00, 0x7128, 0x2001, 0xaf90,
+       0x2102, 0x2001, 0xaf98, 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,
+       0x2651, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x14f6,
+       0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0xad00, 0x6024,
+       0x6026, 0x6053, 0x0030, 0x080c, 0x2690, 0x6050, 0xa084, 0xfe7f,
+       0x6052, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26a0, 0x60e7,
+       0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000,
+       0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0e9f, 0x601b, 0x001e,
+       0x600f, 0x00ff, 0x2001, 0xaf8c, 0x2003, 0x00ff, 0x602b, 0x002f,
+       0x012e, 0x0005, 0x2001, 0xad31, 0x2003, 0x0000, 0x2001, 0xad30,
+       0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
+       0x0026, 0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a,
+       0xa195, 0x0004, 0xa284, 0x0007, 0x0002, 0x23a7, 0x238d, 0x2390,
+       0x2393, 0x2398, 0x239a, 0x239e, 0x23a2, 0x080c, 0x6699, 0x00b8,
+       0x080c, 0x6774, 0x00a0, 0x080c, 0x6774, 0x080c, 0x6699, 0x0078,
+       0x0099, 0x0068, 0x080c, 0x6699, 0x0079, 0x0048, 0x080c, 0x6774,
+       0x0059, 0x0028, 0x080c, 0x6774, 0x080c, 0x6699, 0x0029, 0x002e,
+       0x001e, 0x000e, 0x012e, 0x0005, 0x6124, 0xd19c, 0x1904, 0x25bf,
+       0x080c, 0x574f, 0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024,
+       0xa084, 0x1800, 0x0178, 0x080c, 0x5775, 0x0118, 0x080c, 0x5761,
+       0x1148, 0x6027, 0x0020, 0x6043, 0x0000, 0x2001, 0xaf9d, 0x2003,
+       0xaaaa, 0x0458, 0x080c, 0x5775, 0x15d0, 0x6024, 0xa084, 0x1800,
+       0x1108, 0x04a8, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e,
+       0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a,
+       0x0804, 0x25bf, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4,
+       0x1188, 0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x7088, 0xa086, 0x0028,
+       0x1110, 0x080c, 0x58da, 0x0804, 0x25bf, 0x2001, 0xaf9e, 0x2003,
+       0x0000, 0x0048, 0x2001, 0xaf9e, 0x2003, 0x0002, 0x0020, 0x080c,
+       0x584d, 0x0804, 0x25bf, 0x080c, 0x597a, 0x0804, 0x25bf, 0xd1ac,
+       0x0904, 0x2507, 0x080c, 0x574f, 0x11d8, 0x6027, 0x0020, 0x0006,
+       0x0026, 0x0036, 0x080c, 0x576b, 0x1170, 0x2001, 0xaf9e, 0x2003,
+       0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a, 0x003e,
+       0x002e, 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5726,
+       0x0016, 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061,
+       0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74ca, 0xa48c,
+       0xff00, 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x7038,
+       0xd084, 0x1148, 0xc085, 0x703a, 0x0036, 0x2418, 0x2011, 0x8016,
+       0x080c, 0x3c5c, 0x003e, 0xa196, 0xff00, 0x05b8, 0x7050, 0xa084,
+       0x00ff, 0x810f, 0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011,
+       0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xad52,
+       0x2214, 0xd2ac, 0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248,
+       0xa294, 0xff00, 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
+       0x24d2, 0x7034, 0xd08c, 0x1140, 0x2001, 0xad0c, 0x200c, 0xd1ac,
+       0x1904, 0x24d2, 0xc1ad, 0x2102, 0x0036, 0x73c8, 0x2011, 0x8013,
+       0x080c, 0x3c5c, 0x003e, 0x0804, 0x24d2, 0x7034, 0xd08c, 0x1140,
+       0x2001, 0xad0c, 0x200c, 0xd1ac, 0x1904, 0x24d2, 0xc1ad, 0x2102,
+       0x0036, 0x73c8, 0x2011, 0x8013, 0x080c, 0x3c5c, 0x003e, 0x7130,
+       0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x01d0, 0x0016,
+       0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019, 0x000e,
+       0x080c, 0xa8eb, 0xa484, 0x00ff, 0xa080, 0x2be6, 0x200d, 0xa18c,
+       0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xa96c,
+       0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004,
+       0x080c, 0x2aac, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009,
+       0x0000, 0x080c, 0x4cdc, 0x1110, 0x080c, 0x493a, 0x8108, 0x1f04,
+       0x24c9, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x7adf,
+       0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581,
+       0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3, 0x0000,
+       0x001e, 0x2001, 0xad00, 0x2014, 0xa296, 0x0004, 0x1128, 0xd19c,
+       0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xad22,
+       0x2003, 0x0000, 0x6027, 0x0020, 0x080c, 0x5775, 0x1140, 0x0016,
+       0x2009, 0x07d0, 0x2011, 0x567b, 0x080c, 0x6593, 0x001e, 0xd194,
+       0x0904, 0x25bf, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2570, 0x080c,
+       0x6581, 0x080c, 0x7834, 0x6027, 0x0004, 0x00f6, 0x2019, 0xafd0,
+       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, 0x6b73, 0x080c, 0x6c50, 0x7810, 0x2070, 0x7037, 0x0103,
+       0x2f60, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
+       0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
+       0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061,
+       0xafc7, 0x6028, 0xa09a, 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce,
+       0x080c, 0x7827, 0x0804, 0x25be, 0x2019, 0xafd0, 0x2304, 0xa065,
+       0x0120, 0x2009, 0x0027, 0x080c, 0x80a7, 0x00ce, 0x0804, 0x25be,
+       0xd2bc, 0x0904, 0x25be, 0x080c, 0x658e, 0x6014, 0xa084, 0x0184,
+       0xa085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140,
+       0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000,
+       0x00de, 0x00c6, 0x2061, 0xafc7, 0x6044, 0xa09a, 0x00c8, 0x12f0,
+       0x8000, 0x6046, 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0,
+       0x080c, 0x6586, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138,
+       0x6114, 0xa18c, 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114,
+       0xa18c, 0x0184, 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019,
+       0x0001, 0x080c, 0x7a64, 0x003e, 0x2019, 0xafd6, 0x2304, 0xa065,
+       0x0120, 0x2009, 0x004f, 0x080c, 0x80a7, 0x00ce, 0x001e, 0xd19c,
+       0x0904, 0x261a, 0x7034, 0xd0ac, 0x1560, 0x0016, 0x0156, 0x6027,
+       0x0008, 0x602f, 0x0020, 0x20a9, 0x0006, 0x1d04, 0x25cd, 0x2091,
+       0x6000, 0x1f04, 0x25cd, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400,
+       0x6052, 0x20a9, 0x0366, 0x1d04, 0x25db, 0x2091, 0x6000, 0x6020,
+       0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0490,
+       0x080c, 0x2760, 0x1f04, 0x25db, 0x015e, 0x6152, 0x001e, 0x6027,
+       0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c,
+       0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c,
+       0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3,
+       0x0000, 0x080c, 0xac8d, 0x080c, 0xaca8, 0xa085, 0x0001, 0x080c,
+       0x5793, 0x2001, 0xad00, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c,
+       0x12cc, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005, 0x0006, 0x0016,
+       0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00,
+       0x71c0, 0x70c2, 0xa116, 0x01f0, 0x81ff, 0x0128, 0x2011, 0x8011,
+       0x080c, 0x3c5c, 0x00b8, 0x2011, 0x8012, 0x080c, 0x3c5c, 0x2001,
+       0xad71, 0x2004, 0xd0fc, 0x1170, 0x0036, 0x00c6, 0x080c, 0x26eb,
+       0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0000, 0x080c, 0x2aac,
+       0x00ce, 0x003e, 0x012e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e,
+       0x0005, 0x00c6, 0x00f6, 0x0006, 0x0026, 0x2061, 0x0100, 0xa190,
+       0x2664, 0x2205, 0x60f2, 0x2011, 0x2671, 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,
+       0x6278, 0x0038, 0xa080, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f,
+       0xa006, 0x0005, 0xa080, 0x2be6, 0x200d, 0xa18c, 0x00ff, 0x0005,
+       0x00d6, 0x2069, 0x0140, 0x2001, 0xad14, 0x2003, 0x00ef, 0x20a9,
+       0x0010, 0xa006, 0x6852, 0x6856, 0x1f04, 0x269b, 0x00de, 0x0005,
+       0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0xad14, 0x2102,
+       0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000,
+       0xa006, 0x82ff, 0x1128, 0xa184, 0x000f, 0xa080, 0xacae, 0x2005,
+       0x6856, 0x8211, 0x1f04, 0x26b0, 0x002e, 0x00de, 0x000e, 0x0005,
+       0x00c6, 0x2061, 0xad00, 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, 0x26e0, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e,
+       0x00de, 0x015e, 0x0005, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+       0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c,
+       0xa96c, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140,
+       0x78c4, 0xd0dc, 0x0548, 0xa084, 0x0700, 0xa08e, 0x0300, 0x1520,
+       0x2011, 0x0000, 0x2009, 0x0002, 0x2300, 0xa080, 0x0020, 0x2018,
+       0x2300, 0x080c, 0x6665, 0x2011, 0x0030, 0x2200, 0x8007, 0xa085,
+       0x004c, 0x78c2, 0x2009, 0x0204, 0x210c, 0x2200, 0xa100, 0x2009,
+       0x0138, 0x200a, 0x080c, 0x574f, 0x1118, 0x2009, 0xaf8e, 0x200a,
+       0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126,
+       0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c,
+       0x8000, 0x2014, 0xa184, 0x0003, 0x0110, 0x0804, 0x1a6a, 0x002e,
+       0x001e, 0x000e, 0x012e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004,
+       0xa082, 0x0005, 0x000e, 0x0268, 0x2001, 0x0170, 0x200c, 0xa18c,
+       0x00ff, 0xa18e, 0x004c, 0x1128, 0x200c, 0xa18c, 0xff00, 0x810f,
+       0x0010, 0x2009, 0x0000, 0x2001, 0x0204, 0x2004, 0xa108, 0x0005,
+       0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854,
+       0xd08c, 0x1110, 0x1f04, 0x2767, 0x00fe, 0x015e, 0x000e, 0x0005,
+       0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x6030, 0x0006, 0x6048,
+       0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60f0,
+       0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028,
+       0x0006, 0x60e0, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xe000,
+       0xe000, 0xe000, 0xe000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e,
+       0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
+       0x60ee, 0x000e, 0x60f2, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e,
+       0x60e6, 0x000e, 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c,
+       0x26a0, 0x000e, 0x00ce, 0x001e, 0x0005, 0x2845, 0x2849, 0x284d,
+       0x2853, 0x2859, 0x285f, 0x2865, 0x286d, 0x2875, 0x287b, 0x2881,
+       0x2889, 0x2891, 0x2899, 0x28a1, 0x28ab, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b7, 0x28b7, 0x28bc,
+       0x28bc, 0x28c3, 0x28c3, 0x28ca, 0x28ca, 0x28d3, 0x28d3, 0x28da,
+       0x28da, 0x28e3, 0x28e3, 0x28ec, 0x28ec, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x0106, 0x0006, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x2373, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106,
+       0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x223d, 0x080c,
+       0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c,
+       0x223d, 0x080c, 0x228f, 0x0804, 0x28f7, 0xe000, 0x0cf0, 0x0106,
+       0x0006, 0x080c, 0x272f, 0x04d8, 0x0106, 0x0006, 0x080c, 0x272f,
+       0x080c, 0x2373, 0x04a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+       0x223d, 0x0468, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+       0x080c, 0x223d, 0x0420, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+       0x228f, 0x00e8, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+       0x080c, 0x228f, 0x00a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+       0x223d, 0x080c, 0x228f, 0x0058, 0x0106, 0x0006, 0x080c, 0x272f,
+       0x080c, 0x2373, 0x080c, 0x223d, 0x080c, 0x228f, 0x0000, 0x000e,
+       0x010e, 0x000d, 0x00c6, 0x0026, 0x0046, 0x2021, 0x0000, 0x080c,
+       0x502d, 0x1904, 0x29d4, 0x72d0, 0x2001, 0xaf9d, 0x2004, 0xa005,
+       0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x29d4,
+       0x080c, 0x29d8, 0x0804, 0x29d4, 0x080c, 0x574f, 0x1120, 0x709b,
+       0xffff, 0x0804, 0x29d4, 0xd294, 0x0120, 0x709b, 0xffff, 0x0804,
+       0x29d4, 0x2001, 0xad14, 0x203c, 0x7284, 0xd284, 0x0904, 0x2976,
+       0xd28c, 0x1904, 0x2976, 0x0036, 0x7398, 0xa38e, 0xffff, 0x1110,
+       0x2019, 0x0001, 0x8314, 0xa2e0, 0xb3c0, 0x2c04, 0xa38c, 0x0001,
+       0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e,
+       0x0560, 0xa08e, 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230,
+       0xd284, 0x1538, 0x7284, 0xc28d, 0x7286, 0x709b, 0xffff, 0x003e,
+       0x0428, 0x2009, 0x0000, 0x080c, 0x2676, 0x080c, 0x4c80, 0x11b8,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c,
+       0x0118, 0x6000, 0xd0bc, 0x0120, 0x080c, 0x29eb, 0x0140, 0x0028,
+       0x080c, 0x2b1a, 0x080c, 0x2a19, 0x0110, 0x8318, 0x0818, 0x739a,
+       0x0010, 0x709b, 0xffff, 0x003e, 0x0804, 0x29d4, 0xa780, 0x2be6,
+       0x203d, 0xa7bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x7098, 0xa096,
+       0xffff, 0x1120, 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220,
+       0x2008, 0xa802, 0x20a8, 0x0020, 0x709b, 0xffff, 0x0804, 0x29d4,
+       0x2700, 0x0156, 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x4cdc,
+       0x0120, 0x080c, 0x4c80, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000,
+       0xd0bc, 0x11d0, 0x7284, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff,
+       0xa082, 0x0006, 0x02b0, 0xd484, 0x1118, 0x080c, 0x4c9f, 0x0028,
+       0x080c, 0x2b9c, 0x0170, 0x080c, 0x2bc9, 0x0058, 0x080c, 0x2b1a,
+       0x080c, 0x2a19, 0x0170, 0x0028, 0x080c, 0x2b9c, 0x0110, 0x0419,
+       0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2990, 0x709b, 0xffff,
+       0x0018, 0x001e, 0x015e, 0x719a, 0x004e, 0x002e, 0x00ce, 0x0005,
+       0x00c6, 0x0016, 0x709b, 0x0000, 0x2009, 0x007e, 0x080c, 0x4c80,
+       0x1138, 0x080c, 0x2b1a, 0x04a9, 0x0118, 0x70d0, 0xc0bd, 0x70d2,
+       0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68,
+       0x2001, 0xad56, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807,
+       0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2001,
+       0x0000, 0x080c, 0x4c1e, 0x2001, 0x0000, 0x080c, 0x4c30, 0x0126,
+       0x2091, 0x8000, 0x7094, 0x8000, 0x7096, 0x012e, 0x2009, 0x0004,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+       0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xad56,
+       0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807, 0x0550, 0x2d00,
+       0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140,
+       0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2ad9,
+       0x080c, 0x9956, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e,
+       0x2001, 0x0002, 0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x7094,
+       0x8000, 0x7096, 0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+       0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026,
+       0x2009, 0x0080, 0x080c, 0x4c80, 0x1120, 0x0031, 0x0110, 0x70d7,
+       0xffff, 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
+       0x2c68, 0x080c, 0x8022, 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956,
+       0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002,
+       0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x70d8, 0x8000, 0x70da,
+       0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce,
+       0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091,
+       0x8000, 0x2009, 0x007f, 0x080c, 0x4c80, 0x1190, 0x2c68, 0x080c,
+       0x8022, 0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+       0x080c, 0x9956, 0x2009, 0x0022, 0x080c, 0x80a7, 0xa085, 0x0001,
+       0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036,
+       0x0026, 0x080c, 0x68f3, 0x080c, 0x689d, 0x080c, 0x8a15, 0x2130,
+       0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1120, 0x080c,
+       0x4ecf, 0x080c, 0x493a, 0x001e, 0x8108, 0x1f04, 0x2ac3, 0x86ff,
+       0x1110, 0x080c, 0x11d4, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee,
+       0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270,
+       0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+       0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x001e,
+       0x2e60, 0x080c, 0x4ecf, 0x6210, 0x6314, 0x080c, 0x493a, 0x6212,
+       0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
+       0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150,
+       0x2071, 0xad00, 0x7094, 0xa005, 0x0110, 0x8001, 0x7096, 0x000e,
+       0x00ee, 0x0005, 0x2071, 0xad00, 0x70d8, 0xa005, 0x0dc0, 0x8001,
+       0x70da, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6,
+       0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
+       0x20a9, 0x0001, 0x0098, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+       0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c,
+       0xa96c, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e,
+       0x007e, 0x05c8, 0xa28e, 0x007f, 0x05b0, 0xa28e, 0x0080, 0x0598,
+       0xa288, 0xae34, 0x210c, 0x81ff, 0x0570, 0x8fff, 0x05c1, 0x00c6,
+       0x2160, 0x2001, 0x0001, 0x080c, 0x5037, 0x00ce, 0x2019, 0x0029,
+       0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x00c6,
+       0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x1118,
+       0x6007, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206,
+       0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, 0xa712, 0x001e, 0x007e,
+       0x2160, 0x080c, 0x4ecf, 0x002e, 0x8210, 0x1f04, 0x2b3e, 0x015e,
+       0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046,
+       0x0026, 0x0016, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0148, 0xd0a4,
+       0x0138, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x080c, 0xa96c,
+       0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
+       0x7284, 0x82ff, 0x01f8, 0x2011, 0xad52, 0x2214, 0xd2ac, 0x11d0,
+       0x2100, 0x080c, 0x268a, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314,
+       0xa2e0, 0xb3c0, 0x2c04, 0xd384, 0x0120, 0xa084, 0xff00, 0x8007,
+       0x0010, 0xa084, 0x00ff, 0xa116, 0x0138, 0xa096, 0x00ff, 0x0110,
+       0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e,
+       0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0xa180, 0xae34,
+       0x2004, 0xa065, 0x0178, 0x0016, 0x00c6, 0x080c, 0x9807, 0x001e,
+       0x090c, 0x14f6, 0x611a, 0x080c, 0x2ad9, 0x080c, 0x8078, 0x001e,
+       0x080c, 0x4c9f, 0x012e, 0x00ce, 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, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0xad81,
+       0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033,
+       0xad91, 0x7037, 0xad91, 0x7007, 0x0001, 0x2061, 0xadd1, 0x6003,
+       0x0002, 0x0005, 0x1004, 0x2d0c, 0x0e04, 0x2d0c, 0x2071, 0xad81,
+       0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069,
+       0x1904, 0x2df1, 0x0804, 0x2d8a, 0x0005, 0x2071, 0xad81, 0x7004,
+       0x0002, 0x2d15, 0x2d16, 0x2d1f, 0x2d30, 0x0005, 0x1004, 0x2d1e,
+       0x0e04, 0x2d1e, 0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78,
+       0x2061, 0xadd1, 0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200,
+       0x0904, 0x2deb, 0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807,
+       0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60,
+       0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210,
+       0x61c0, 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04, 0x2de8, 0x61c0,
+       0x0804, 0x2d8a, 0x2dcc, 0x2df7, 0x2dff, 0x2e03, 0x2e0b, 0x2e11,
+       0x2e15, 0x2e21, 0x2e24, 0x2e2e, 0x2e31, 0x2de8, 0x2de8, 0x2de8,
+       0x2e34, 0x2de8, 0x2e43, 0x2e5a, 0x2e71, 0x2ee8, 0x2eed, 0x2f16,
+       0x2f67, 0x2f78, 0x2f96, 0x2fcd, 0x2fd7, 0x2fe4, 0x2ff7, 0x3018,
+       0x3021, 0x3057, 0x305d, 0x2de8, 0x3086, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x308d, 0x3097, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x309f, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x30b1, 0x30b9, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x0002, 0x30cb, 0x311f, 0x317a, 0x318a, 0x2de8,
+       0x31a4, 0x35cb, 0x3fbb, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x2de8, 0x2e2e, 0x2e31, 0x35cd, 0x2de8, 0x35da,
+       0x403c, 0x4097, 0x40fb, 0x2de8, 0x415a, 0x4180, 0x419f, 0x2de8,
+       0x2de8, 0x2de8, 0x2de8, 0x35de, 0x376b, 0x3785, 0x37a3, 0x3804,
+       0x3858, 0x3863, 0x389a, 0x38a9, 0x38b8, 0x38bb, 0x38de, 0x3928,
+       0x398e, 0x399b, 0x3a9c, 0x3bb3, 0x3bdc, 0x3cda, 0x3cfc, 0x3d08,
+       0x3d41, 0x3e05, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x3e6d, 0x3e88,
+       0x3efa, 0x3fac, 0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x3c39,
+       0x0126, 0x2091, 0x8000, 0x0e04, 0x2dd8, 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, 0x3c46, 0x7823,
+       0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824,
+       0x7930, 0x0804, 0x3c49, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804,
+       0x2dcc, 0x7924, 0x2114, 0x0804, 0x2dcc, 0x2099, 0x0009, 0x20a1,
+       0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0804,
+       0x2dcc, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0001,
+       0x2019, 0x001b, 0x783b, 0x0017, 0x0804, 0x2dcc, 0x7d38, 0x7c3c,
+       0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061, 0x1000, 0xe10c, 0xa006,
+       0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904,
+       0x2dcc, 0x0804, 0x2dee, 0x2069, 0xad51, 0x7824, 0x7930, 0xa11a,
+       0x1a04, 0x2df4, 0x8019, 0x0904, 0x2df4, 0x684a, 0x6942, 0x782c,
+       0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x5a1c,
+       0x0804, 0x2dcc, 0x2069, 0xad51, 0x7824, 0x7934, 0xa11a, 0x1a04,
+       0x2df4, 0x8019, 0x0904, 0x2df4, 0x684e, 0x6946, 0x782c, 0x6862,
+       0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c, 0x50d9, 0x0804,
+       0x2dcc, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2df1, 0x7924, 0x7b28,
+       0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xad88, 0x41a1, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x2009, 0x0020, 0x080c, 0x3c46, 0x701b, 0x2e89,
+       0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0120,
+       0xa096, 0x0019, 0x1904, 0x2df1, 0x810f, 0xa18c, 0x00ff, 0x0904,
+       0x2df1, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x2009, 0x0020, 0x2061, 0xadd1, 0x6224, 0x6328,
+       0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000,
+       0xa5a9, 0x0000, 0x080c, 0x3c46, 0x701b, 0x2eb7, 0x0005, 0x6834,
+       0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904,
+       0x2df1, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c,
+       0x4b7c, 0x1128, 0x7007, 0x0003, 0x701b, 0x2ed1, 0x0005, 0x080c,
+       0x51df, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xad88,
+       0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+       0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x012e, 0x0804, 0x3c49,
+       0x61a8, 0x7824, 0x60aa, 0x0804, 0x2dcc, 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,
+       0x2df1, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x1904,
+       0x2df4, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804,
+       0x2df4, 0x7c28, 0x7d2c, 0x080c, 0x4e96, 0xd28c, 0x1118, 0x080c,
+       0x4e41, 0x0010, 0x080c, 0x4e6f, 0x1518, 0x2061, 0xb400, 0x0126,
+       0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d,
+       0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e,
+       0xace0, 0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1a04, 0x2df1,
+       0x0c30, 0x080c, 0x929c, 0x012e, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+       0xa00e, 0x2001, 0x0005, 0x080c, 0x51df, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x9803, 0x080c, 0x510c, 0x012e, 0x0804, 0x2dcc, 0x81ff,
+       0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96,
+       0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+       0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+       0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0005, 0x080c, 0x4ebd, 0x0904,
+       0x2df1, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x8003, 0x800b,
+       0x810b, 0xa108, 0x080c, 0x6519, 0x0804, 0x2dcc, 0x0126, 0x2091,
+       0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0448, 0x2029, 0x00ff,
+       0x644c, 0x2400, 0xa506, 0x01f0, 0x2508, 0x080c, 0x4cdc, 0x11d0,
+       0x080c, 0x4f0d, 0x1128, 0x2009, 0x0002, 0x62b0, 0x2518, 0x00b8,
+       0x2019, 0x0004, 0x080c, 0x4ebd, 0x1118, 0x2009, 0x0006, 0x0078,
+       0x7824, 0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108,
+       0x080c, 0x6519, 0x8529, 0x1ae8, 0x012e, 0x0804, 0x2dcc, 0x012e,
+       0x0804, 0x2df1, 0x012e, 0x0804, 0x2df4, 0x080c, 0x3c1a, 0x0904,
+       0x2df4, 0x080c, 0x4dfc, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff,
+       0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4ded,
+       0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c,
+       0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e71, 0x0904, 0x2df1, 0x080c,
+       0x4bc0, 0x080c, 0x4e3a, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x080c,
+       0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x62a0,
+       0x2019, 0x0005, 0x00c6, 0x080c, 0x4ecf, 0x2061, 0x0000, 0x080c,
+       0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2009, 0x0000,
+       0x080c, 0xa712, 0x007e, 0x00ce, 0x080c, 0x4e96, 0x0804, 0x2dcc,
+       0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e96, 0x2208, 0x0804,
+       0x2dcc, 0x0156, 0x00d6, 0x00e6, 0x2069, 0xae13, 0x6810, 0x6914,
+       0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019,
+       0x0000, 0x20a9, 0x007e, 0x2069, 0xae34, 0x2d04, 0xa075, 0x0130,
+       0x704c, 0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04,
+       0x3035, 0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2dcc,
+       0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c,
+       0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+       0xae13, 0x6910, 0x62ac, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1,
+       0x614c, 0xa190, 0x2be6, 0x2215, 0xa294, 0x00ff, 0x636c, 0x83ff,
+       0x0108, 0x6270, 0x67d0, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090,
+       0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031,
+       0x0002, 0x0040, 0x080c, 0x574f, 0x1118, 0x2031, 0x0004, 0x0010,
+       0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2dcc, 0x613c, 0x6240,
+       0x2019, 0xafa3, 0x231c, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+       0x6134, 0xa006, 0x2010, 0x2018, 0x012e, 0x0804, 0x2dcc, 0x080c,
+       0x3c2a, 0x0904, 0x2df4, 0x6244, 0x6338, 0x0804, 0x2dcc, 0x613c,
+       0x6240, 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xad51, 0x831f,
+       0xa305, 0x6816, 0x782c, 0x2069, 0xafa3, 0x2d1c, 0x206a, 0x0804,
+       0x2dcc, 0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x012e, 0x0804,
+       0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x7828, 0xa00d, 0x0904,
+       0x2df4, 0x782c, 0xa005, 0x0904, 0x2df4, 0x6244, 0x6146, 0x6338,
+       0x603a, 0x0804, 0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003,
+       0x1904, 0x2df1, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c,
+       0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xad14, 0x2004, 0xa085,
+       0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, 0x2be6, 0x210d,
+       0xa18c, 0x00ff, 0x2001, 0xad14, 0x2004, 0xa116, 0x0550, 0x810f,
+       0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x8022, 0x000e,
+       0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c, 0x3c05,
+       0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+       0xc0fd, 0x683a, 0x701b, 0x3173, 0x2d00, 0x6012, 0x2009, 0x0032,
+       0x080c, 0x80a7, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
+       0x2df1, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x8078, 0x0cb0, 0x2001,
+       0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00c6, 0x2061,
+       0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130,
+       0x2001, 0xad14, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f,
+       0x16a0, 0xa188, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x2001, 0xad14,
+       0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000,
+       0x0006, 0x080c, 0x8022, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05,
+       0x601f, 0x0001, 0x080c, 0x3c05, 0x01d8, 0x6837, 0x0000, 0x7007,
+       0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x3173,
+       0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x80a7, 0x012e, 0x00ce,
+       0x0005, 0x012e, 0x00ce, 0x0804, 0x2df1, 0x00ce, 0x0804, 0x2df4,
+       0x080c, 0x8078, 0x0cb0, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1,
+       0x0804, 0x2dcc, 0x2061, 0xb048, 0x0126, 0x2091, 0x8000, 0x6000,
+       0xd084, 0x0128, 0x6104, 0x6208, 0x012e, 0x0804, 0x2dcc, 0x012e,
+       0x0804, 0x2df4, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0904,
+       0x2df1, 0x0126, 0x2091, 0x8000, 0x6244, 0x6064, 0xa202, 0x0248,
+       0xa085, 0x0001, 0x080c, 0x26c0, 0x080c, 0x436e, 0x012e, 0x0804,
+       0x2dcc, 0x012e, 0x0804, 0x2df4, 0x0126, 0x2091, 0x8000, 0x7824,
+       0xa084, 0x0007, 0x0002, 0x31b6, 0x31bf, 0x31c6, 0x31b3, 0x31b3,
+       0x31b3, 0x31b3, 0x31b3, 0x012e, 0x0804, 0x2df4, 0x2009, 0x0114,
+       0x2104, 0xa085, 0x0800, 0x200a, 0x080c, 0x332f, 0x0070, 0x2009,
+       0x010b, 0x200b, 0x0010, 0x080c, 0x332f, 0x0038, 0x81ff, 0x0128,
+       0x012e, 0x2021, 0x400b, 0x0804, 0x2dce, 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, 0x3570, 0x080c, 0x34da, 0xa03e, 0x2720, 0x00f6,
+       0x00e6, 0x00c6, 0x2d60, 0x2071, 0xb01e, 0x2079, 0x0020, 0x00d6,
+       0x2069, 0x0000, 0x6824, 0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004,
+       0x783e, 0x2001, 0x007c, 0x2004, 0x783a, 0x00de, 0x2011, 0x0001,
+       0x080c, 0x3486, 0x080c, 0x3486, 0x00ce, 0x00ee, 0x00fe, 0x080c,
+       0x33d5, 0x080c, 0x34ae, 0x080c, 0x342b, 0x080c, 0x3394, 0x080c,
+       0x33c5, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x0530, 0x7814,
+       0xa084, 0x0184, 0xa085, 0x0010, 0x7816, 0x2079, 0x0140, 0x080c,
+       0x330d, 0x1110, 0x00fe, 0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079,
+       0x0100, 0x7827, 0x0086, 0x7814, 0xa084, 0x0184, 0xa085, 0x0032,
+       0x7816, 0x080c, 0x330d, 0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc,
+       0x0dc0, 0x7827, 0x0080, 0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130,
+       0x8b58, 0x080c, 0x3317, 0x00fe, 0x0804, 0x32d7, 0x00fe, 0x080c,
+       0x330d, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001, 0x007b,
+       0x2502, 0x080c, 0x3317, 0x0088, 0x87ff, 0x0140, 0x2001, 0x0201,
+       0x2004, 0xa005, 0x1904, 0x3211, 0x8739, 0x0038, 0x2001, 0xaffd,
+       0x2004, 0xa086, 0x0000, 0x1904, 0x3211, 0x2001, 0x0033, 0x2003,
+       0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904, 0x32d7,
+       0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904, 0x32d7,
+       0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac,
+       0x1148, 0x2001, 0xaffd, 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, 0x0004, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001, 0x0203,
+       0x2004, 0x1f04, 0x32ac, 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, 0x31ef, 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, 0x2dcc,
+       0x012e, 0x2021, 0x400c, 0x0804, 0x2dce, 0xa085, 0x0001, 0x1d04,
+       0x3316, 0x2091, 0x6000, 0x8420, 0xa486, 0x0064, 0x0005, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001,
+       0x0020, 0x2003, 0x0004, 0x2001, 0xaffd, 0x2003, 0x0000, 0x2001,
+       0xb01e, 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6,
+       0x2079, 0x0100, 0x2001, 0xad14, 0x200c, 0x7932, 0x7936, 0x080c,
+       0x26a0, 0x7850, 0xa084, 0x0980, 0xa085, 0x0030, 0x7852, 0x2019,
+       0x01f4, 0x8319, 0x1df0, 0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad,
+       0x782e, 0x20a9, 0x0046, 0x1d04, 0x334b, 0x2091, 0x6000, 0x1f04,
+       0x334b, 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, 0x3368, 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, 0x7827, 0x0020, 0x7843, 0x0000, 0x2003, 0x0000,
+       0x7827, 0x0048, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6,
+       0x00e6, 0x2071, 0xaffd, 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, 0xad14, 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, 0x34ae, 0x080c, 0x330d, 0x1110, 0x8421, 0x0028, 0x7024,
+       0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071, 0xaffd,
+       0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4, 0x0120,
+       0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011, 0x080c,
+       0x3486, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ee, 0x00fe, 0x7017,
+       0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xaffd, 0x2079,
+       0x0030, 0x7904, 0xd1fc, 0x0904, 0x3483, 0x7803, 0x0002, 0xa026,
+       0xd19c, 0x1904, 0x347f, 0x7000, 0x0002, 0x3483, 0x3441, 0x3465,
+       0x347f, 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, 0x33b1, 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, 0xb01e, 0x2079, 0x0020, 0x7904, 0xd1fc, 0x01f0,
+       0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x34d6, 0x34c1,
+       0x34cd, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c,
+       0x3486, 0x0160, 0x080c, 0x3486, 0x0048, 0x8001, 0x7002, 0x7804,
+       0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x3486, 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, 0x3c05,
+       0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+       0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+       0x000d, 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3c05,
+       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, 0x3c05, 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, 0x3c05, 0x2d60,
+       0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+       0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+       0x000d, 0x080c, 0x353e, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c,
+       0x3c05, 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, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
+       0x0009, 0x00ee, 0x0005, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+       0x20a9, 0x0011, 0x2001, 0xad40, 0x20a0, 0xa006, 0x40a4, 0x012e,
+       0x0804, 0x2dcc, 0x7d38, 0x7c3c, 0x0804, 0x2e73, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c, 0x491f, 0x2009,
+       0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b,
+       0x35f2, 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x2df4,
+       0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x2df4, 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,
+       0x2df4, 0xa288, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x6156, 0xd0dc,
+       0x0130, 0x6828, 0xa08a, 0x007f, 0x1a04, 0x2df4, 0x604e, 0x6808,
+       0xa08a, 0x0100, 0x0a04, 0x2df4, 0xa08a, 0x0841, 0x1a04, 0x2df4,
+       0xa084, 0x0007, 0x1904, 0x2df4, 0x680c, 0xa005, 0x0904, 0x2df4,
+       0x6810, 0xa005, 0x0904, 0x2df4, 0x6848, 0x6940, 0xa10a, 0x1a04,
+       0x2df4, 0x8001, 0x0904, 0x2df4, 0x684c, 0x6944, 0xa10a, 0x1a04,
+       0x2df4, 0x8001, 0x0904, 0x2df4, 0x6804, 0xd0fc, 0x0560, 0x080c,
+       0x3c05, 0x0904, 0x2df1, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c,
+       0x7d38, 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3c46, 0x701b,
+       0x3672, 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069,
+       0xad6d, 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xad71,
+       0x200c, 0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085,
+       0x0b00, 0x6006, 0x00ce, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xad51,
+       0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084,
+       0x00ff, 0x6042, 0x080c, 0x5a1c, 0x080c, 0x5070, 0x080c, 0x50d9,
+       0x6000, 0xa086, 0x0000, 0x1904, 0x3755, 0x6808, 0x602a, 0x080c,
+       0x22f8, 0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e,
+       0x0268, 0x2009, 0x0170, 0x200b, 0x0080, 0xe000, 0xe000, 0x200b,
+       0x0000, 0x0036, 0x6b08, 0x080c, 0x26fb, 0x003e, 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, 0x8007, 0x810f, 0x8217, 0x831f,
+       0x20a9, 0x0004, 0x20a1, 0xafad, 0x40a1, 0x080c, 0x659c, 0x6904,
+       0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70,
+       0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c,
+       0x5fa9, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007,
+       0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003,
+       0x0010, 0x6003, 0x0001, 0x1f04, 0x36f3, 0x00ce, 0x2069, 0xad51,
+       0x2001, 0xaf9d, 0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000, 0x0170,
+       0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, 0x0140, 0x2003, 0xaaaa,
+       0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x0008, 0x2102, 0x00c6,
+       0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c,
+       0x574f, 0x0128, 0x080c, 0x3e5f, 0x0110, 0x080c, 0x26c0, 0x60c4,
+       0xa005, 0x01b0, 0x6003, 0x0001, 0x2009, 0x373f, 0x00c0, 0x080c,
+       0x574f, 0x1158, 0x2011, 0x566e, 0x080c, 0x650d, 0x2001, 0xaf9e,
+       0x2003, 0x0000, 0x080c, 0x569a, 0x0040, 0x080c, 0x485e, 0x0028,
+       0x6003, 0x0004, 0x2009, 0x3755, 0x0010, 0x0804, 0x2dcc, 0x2001,
+       0x0100, 0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004,
+       0xa084, 0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817,
+       0x2091, 0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x2df1,
+       0x2069, 0xad51, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc,
+       0x0118, 0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c,
+       0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0xa006, 0x080c, 0x26c0,
+       0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x1178, 0x2001, 0xaf9e,
+       0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085, 0x0001,
+       0x080c, 0x5793, 0x080c, 0x569a, 0x0020, 0x080c, 0x491f, 0x080c,
+       0x485e, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f,
+       0x1110, 0x0804, 0x2df1, 0x6184, 0x81ff, 0x0198, 0x703f, 0x0000,
+       0x2001, 0xb3c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x3c49, 0x701b, 0x2dca, 0x012e,
+       0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0xb3c0, 0x20a9, 0x0040,
+       0x20a1, 0xb3c0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2be6,
+       0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100,
+       0xa506, 0x01a8, 0x080c, 0x4cdc, 0x1190, 0x6014, 0x821c, 0x0238,
+       0xa398, 0xb3c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0038, 0xa398,
+       0xb3c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108,
+       0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105,
+       0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb3c0,
+       0x080c, 0x48be, 0x0804, 0x37b0, 0x080c, 0x3c2a, 0x0904, 0x2df4,
+       0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x2001, 0xad52, 0x2004, 0xd0b4, 0x01f0, 0x6000, 0xd08c,
+       0x11d8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x970b, 0x1120, 0x2009,
+       0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3830, 0x0005,
+       0x080c, 0x3c2a, 0x0904, 0x2df4, 0x20a9, 0x002b, 0x2c98, 0xade8,
+       0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098,
+       0xad80, 0x0006, 0x20a0, 0x080c, 0x48be, 0x20a9, 0x0004, 0xac80,
+       0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x48be, 0x2d00,
+       0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+       0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c,
+       0x4eab, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x7828, 0xa08a,
+       0x1000, 0x1a04, 0x2df4, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+       0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0004, 0x080c, 0x4ebd, 0x7924,
+       0x810f, 0x7a28, 0x0011, 0x0804, 0x2dcc, 0xa186, 0x00ff, 0x0110,
+       0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0xad00, 0x644c, 0x2400,
+       0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c,
+       0x4cdc, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c,
+       0x6519, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904,
+       0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4eb4, 0x0804,
+       0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4,
+       0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0804, 0x2dcc,
+       0x6100, 0x0804, 0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x2001,
+       0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00d6, 0xace8,
+       0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007,
+       0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
+       0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x2dcc, 0x7824, 0xa09c,
+       0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2df1, 0x624c, 0xa294, 0x00ff,
+       0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0xad40, 0x2009,
+       0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x81ff,
+       0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+       0x00ce, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+       0x080c, 0x96b7, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3919,
+       0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0xad80, 0x000e,
+       0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+       0xa006, 0x080c, 0x26c0, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+       0x0118, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c,
+       0x491f, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x7924, 0xa18c,
+       0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f, 0x1a04,
+       0x2df4, 0x2100, 0x080c, 0x268a, 0x0026, 0x00c6, 0x0126, 0x2091,
+       0x8000, 0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c,
+       0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+       0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+       0x00a0, 0x2061, 0x0100, 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff,
+       0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
+       0x002d, 0x2011, 0x4883, 0x080c, 0x6593, 0x7924, 0xa18c, 0xff00,
+       0x810f, 0x080c, 0x574f, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c,
+       0x387d, 0x012e, 0x00ce, 0x002e, 0x0804, 0x2dcc, 0x7924, 0xa18c,
+       0xff00, 0x810f, 0x00c6, 0x080c, 0x4c80, 0x2c08, 0x00ce, 0x1904,
+       0x2df4, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+       0x2df1, 0x60d0, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
+       0x0804, 0x2df1, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46,
+       0x701b, 0x39bb, 0x0005, 0x2009, 0x0080, 0x080c, 0x4cdc, 0x1130,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a,
+       0x0804, 0x2dce, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c,
+       0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x3a32,
+       0xa0be, 0x0112, 0x0904, 0x3a32, 0xa0be, 0x0113, 0x0904, 0x3a32,
+       0xa0be, 0x0114, 0x0904, 0x3a32, 0xa0be, 0x0117, 0x0904, 0x3a32,
+       0xa0be, 0x011a, 0x0904, 0x3a32, 0xa0be, 0x011c, 0x0904, 0x3a32,
+       0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171,
+       0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830,
+       0x8007, 0x6832, 0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213,
+       0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be,
+       0x021a, 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300,
+       0x01c8, 0x00de, 0x0804, 0x2df4, 0xad80, 0x0010, 0x20a9, 0x0007,
+       0x080c, 0x3a78, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3a78,
+       0x0048, 0xad80, 0x000c, 0x080c, 0x3a86, 0x0050, 0xad80, 0x000e,
+       0x080c, 0x3a86, 0xad80, 0x000c, 0x20a9, 0x0001, 0x080c, 0x3a78,
+       0x00c6, 0x080c, 0x3c05, 0x0568, 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, 0x6804, 0x2068, 0x080c, 0x96d3, 0x1120,
+       0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3a6f,
+       0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6820,
+       0xa086, 0x8001, 0x1904, 0x2dcc, 0x2009, 0x0004, 0x0804, 0x2df1,
+       0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108,
+       0x280a, 0x8108, 0x1f04, 0x3a7a, 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, 0x2df1, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60d0,
+       0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182, 0x00ff,
+       0x1a04, 0x2df4, 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x1140, 0x6070,
+       0xa24e, 0x0904, 0x2df4, 0xa9cc, 0xff00, 0x0904, 0x2df4, 0x00c6,
+       0x080c, 0x3b58, 0x2c68, 0x00ce, 0x0538, 0xa0c6, 0x4000, 0x1180,
+       0x00c6, 0x0006, 0x2d60, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108,
+       0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x0088,
+       0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118,
+       0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001,
+       0x4006, 0x2020, 0x0804, 0x2dce, 0x2d00, 0x7022, 0x0016, 0x00b6,
+       0x00c6, 0x00e6, 0x2c70, 0x080c, 0x8022, 0x05d8, 0x2d00, 0x601a,
+       0x080c, 0x9956, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x3c05,
+       0x00ce, 0x2b70, 0x1150, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00be,
+       0x001e, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6837, 0x0000, 0x683b,
+       0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c,
+       0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9,
+       0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001,
+       0x0002, 0x080c, 0x4c30, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+       0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, 0x2009, 0x0003,
+       0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3b3f, 0x0005, 0x6830,
+       0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204,
+       0xa294, 0x00ff, 0x0804, 0x2df1, 0x2009, 0x0000, 0x080c, 0x4f6e,
+       0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x2dcc,
+       0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, 0xad34, 0x2004, 0xd0ac,
+       0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34, 0x0030,
+       0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xaeb4, 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,
+       0x3b6e, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001,
+       0x0030, 0x080c, 0x4c80, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005,
+       0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824,
+       0xa005, 0x0904, 0x2df4, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004,
+       0x1a04, 0x2df4, 0x2010, 0x2d18, 0x080c, 0x2a8c, 0x0904, 0x2df1,
+       0x7007, 0x0003, 0x701b, 0x3bd5, 0x0005, 0x6830, 0xa086, 0x0100,
+       0x0904, 0x2df1, 0x0804, 0x2dcc, 0x7924, 0xa18c, 0xff00, 0x810f,
+       0x60d0, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182,
+       0x00ff, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x080c, 0x95c6,
+       0x1188, 0xa190, 0xae34, 0x2204, 0xa065, 0x0160, 0x080c, 0x493a,
+       0x2001, 0xad34, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e,
+       0x0804, 0x2dcc, 0x012e, 0x0804, 0x2df1, 0x080c, 0x15d9, 0x0188,
+       0xa006, 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016,
+       0x0030, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80,
+       0x000d, 0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+       0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066,
+       0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+       0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff,
+       0x0005, 0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c,
+       0x15f0, 0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001,
+       0x0010, 0x2031, 0x0000, 0x2061, 0xadd1, 0x6606, 0x6112, 0x600e,
+       0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007,
+       0x0002, 0x701b, 0x2dcc, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000,
+       0x2079, 0x0000, 0x2001, 0xad8f, 0x2004, 0xa005, 0x1168, 0x0e04,
+       0x3c74, 0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b,
+       0x0001, 0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071,
+       0xad81, 0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078,
+       0x7030, 0xa0e0, 0x0004, 0xac82, 0xadd1, 0x0210, 0x2061, 0xad91,
+       0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262,
+       0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005,
+       0x00e6, 0x2071, 0xad81, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091,
+       0x8000, 0x0e04, 0x3ccb, 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, 0xad91, 0x7037, 0xad91, 0x00ce,
+       0x0048, 0xac80, 0x0004, 0xa0fa, 0xadd1, 0x0210, 0x2001, 0xad91,
+       0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001,
+       0xad52, 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3c5c,
+       0x002e, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x0126, 0x2091, 0x8000,
+       0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x574f, 0x1178,
+       0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001,
+       0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x0010, 0x080c,
+       0x485e, 0x012e, 0x0804, 0x2dcc, 0x7824, 0x2008, 0xa18c, 0xfffd,
+       0x1128, 0x61dc, 0xa10d, 0x61de, 0x0804, 0x2dcc, 0x0804, 0x2df4,
+       0x81ff, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x1904, 0x2df1,
+       0x2001, 0xad52, 0x2004, 0xd0ac, 0x1904, 0x2df1, 0x080c, 0x3c2a,
+       0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120,
+       0x7828, 0xa005, 0x0904, 0x2dcc, 0x00c6, 0x080c, 0x3c05, 0x00ce,
+       0x0904, 0x2df1, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x080c, 0x979c, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+       0x3d3a, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0x0804,
+       0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1,
+       0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c05, 0x0904,
+       0x2df1, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f,
+       0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x4cdc, 0x1904,
+       0x3db4, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4,
+       0xff00, 0xa8c6, 0x0600, 0x1904, 0x3db4, 0x2001, 0xad52, 0x2004,
+       0xd0ac, 0x1128, 0x080c, 0x4f6e, 0x1110, 0xd79c, 0x05e8, 0xd794,
+       0x1110, 0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+       0x0004, 0x53a3, 0x080c, 0x3a86, 0xd794, 0x0148, 0xac80, 0x000a,
+       0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3a86, 0x21a2,
+       0xd794, 0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002,
+       0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098,
+       0x3400, 0x20a9, 0x0002, 0x53a3, 0x080c, 0x3a78, 0xac80, 0x0026,
+       0x2098, 0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110,
+       0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186,
+       0x0100, 0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118,
+       0xa686, 0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x3d5d,
+       0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x702f, 0x0001,
+       0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xadd1, 0x6007,
+       0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532,
+       0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b, 0x3df0, 0x0005,
+       0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031,
+       0x0000, 0x2061, 0xadd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804,
+       0x3d5d, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x2029, 0x007e, 0x7924,
+       0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020,
+       0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa184, 0x00ff, 0xa0e2,
+       0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa284, 0xff00,
+       0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4,
+       0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04,
+       0x2df4, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4,
+       0xa502, 0x0a04, 0x2df4, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04,
+       0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0xff00, 0x8007, 0xa0e2,
+       0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0x00ff,
+       0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0x2061,
+       0xafa6, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2dcc, 0x0006,
+       0x2001, 0xad52, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001,
+       0xad71, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6164, 0x7a24, 0x6300,
+       0x82ff, 0x1118, 0x7926, 0x0804, 0x2dcc, 0x83ff, 0x1904, 0x2df4,
+       0x2001, 0xfff0, 0xa200, 0x1a04, 0x2df4, 0x2019, 0xffff, 0x6068,
+       0xa302, 0xa200, 0x0a04, 0x2df4, 0x7926, 0x6266, 0x0804, 0x2dcc,
+       0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x7c28,
+       0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x2009,
+       0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
+       0x0003, 0x7026, 0x20a0, 0xa1e0, 0xae34, 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, 0x2dcc, 0x702f, 0x0001, 0x711e,
+       0x7020, 0xa300, 0x7022, 0x2061, 0xadd1, 0x6007, 0x0000, 0x6312,
+       0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c,
+       0x1624, 0x7007, 0x0002, 0x701b, 0x3ee6, 0x0005, 0x702c, 0xa005,
+       0x1168, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xadd1,
+       0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x3ea3, 0x7120, 0x810c,
+       0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x60d0, 0xd0ac, 0x1118,
+       0xd09c, 0x0904, 0x2df1, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x7924,
+       0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b, 0x3f11,
+       0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148,
+       0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804,
+       0x2df4, 0x6820, 0x6924, 0x080c, 0x2676, 0x1510, 0x080c, 0x4c80,
+       0x11f8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3c05,
+       0x01b8, 0x080c, 0x3c05, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000,
+       0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c,
+       0x96ef, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3f4b, 0x0005,
+       0x00de, 0x0804, 0x2df1, 0x7120, 0x080c, 0x2bc9, 0x6820, 0xa086,
+       0x8001, 0x0904, 0x2df1, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002,
+       0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x48be, 0x000e,
+       0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xadd1,
+       0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018,
+       0xa7c6, 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2df4, 0x2009,
+       0x0004, 0x0804, 0x3c49, 0xa7c6, 0x7200, 0x1904, 0x2df4, 0xa6c2,
+       0x0054, 0x0a04, 0x2df4, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a,
+       0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b,
+       0x3f92, 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004,
+       0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c,
+       0x48be, 0x000e, 0x2009, 0x002a, 0x2061, 0xadd1, 0x6224, 0x6328,
+       0x642c, 0x6530, 0x0804, 0x3c49, 0x81ff, 0x1904, 0x2df1, 0x080c,
+       0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c,
+       0x4ec6, 0x0804, 0x2dcc, 0x7824, 0xd084, 0x0904, 0x3804, 0x080c,
+       0x3c2a, 0x0904, 0x2df4, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120,
+       0x2009, 0x0002, 0x0804, 0x2df1, 0x6004, 0xa084, 0x00ff, 0xa086,
+       0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005, 0x1508,
+       0x2001, 0xad52, 0x2004, 0xd0b4, 0x0904, 0x3834, 0x6000, 0xd08c,
+       0x1904, 0x3834, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
+       0x970b, 0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003,
+       0x701b, 0x3ff3, 0x0005, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x0804,
+       0x3834, 0x2009, 0xad30, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001,
+       0x0804, 0x2df1, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x0120,
+       0x2009, 0x0007, 0x0804, 0x2df1, 0x2001, 0xad52, 0x2004, 0xd0ac,
+       0x0120, 0x2009, 0x0008, 0x0804, 0x2df1, 0x609c, 0xd0a4, 0x1118,
+       0xd0ac, 0x1904, 0x3834, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
+       0xc0fd, 0x683a, 0x080c, 0x979c, 0x1120, 0x2009, 0x0003, 0x0804,
+       0x2df1, 0x7007, 0x0003, 0x701b, 0x402e, 0x0005, 0x6830, 0xa086,
+       0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2df1, 0x080c, 0x3c2a,
+       0x0904, 0x2df4, 0x0804, 0x3fd8, 0x81ff, 0x2009, 0x0001, 0x1904,
+       0x2df1, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x2df1,
+       0x2001, 0xad52, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x2df1,
+       0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086,
+       0x0006, 0x2009, 0x0009, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+       0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6833,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c,
+       0x00ff, 0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956,
+       0x0048, 0xa28e, 0x0100, 0x1904, 0x2df4, 0xc0e5, 0x6853, 0x0000,
+       0x6857, 0x0000, 0x683e, 0x080c, 0x9957, 0x2009, 0x0003, 0x0904,
+       0x2df1, 0x7007, 0x0003, 0x701b, 0x408e, 0x0005, 0x6830, 0xa086,
+       0x0100, 0x2009, 0x0004, 0x0904, 0x2df1, 0x0804, 0x2dcc, 0x81ff,
+       0x2009, 0x0001, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x2009,
+       0x0007, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004,
+       0xa084, 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2df1,
+       0x00c6, 0x080c, 0x3c05, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1,
+       0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x080c, 0x3c46, 0x701b, 0x40c5, 0x0005, 0x00d6, 0xade8, 0x000f,
+       0x6800, 0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808,
+       0xa084, 0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x2df4, 0x00de,
+       0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6,
+       0x080c, 0x3c2a, 0x1118, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x99a6,
+       0x2009, 0x0003, 0x00ce, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+       0x40f2, 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904,
+       0x2df1, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+       0x2df1, 0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804,
+       0x2df1, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c,
+       0x4cdc, 0x1904, 0x2df4, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2df1,
+       0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9726,
+       0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b,
+       0x413a, 0x0005, 0x6808, 0x8007, 0xa086, 0x0100, 0x1120, 0x2009,
+       0x0004, 0x0804, 0x2df1, 0x68b0, 0x6836, 0x6810, 0x8007, 0xa084,
+       0x00ff, 0x808e, 0x6814, 0x8007, 0xa084, 0x00ff, 0x8086, 0xa080,
+       0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x0804, 0x3c49, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x7924, 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff,
+       0x0110, 0x0804, 0x2df4, 0x2009, 0x001a, 0x7a2c, 0x7b28, 0x7c3c,
+       0x7d38, 0x080c, 0x3c46, 0x701b, 0x4176, 0x0005, 0xad80, 0x000d,
+       0x2098, 0x20a9, 0x001a, 0x20a1, 0xafad, 0x53a3, 0x0804, 0x2dcc,
+       0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804, 0x2df1, 0x7924,
+       0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804,
+       0x2df4, 0x2099, 0xafad, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009,
+       0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x7824,
+       0xa08a, 0x1000, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x8003,
+       0x800b, 0x810b, 0xa108, 0x00c6, 0x2061, 0xafda, 0x6142, 0x00ce,
+       0x012e, 0x0804, 0x2dcc, 0x00c6, 0x080c, 0x574f, 0x1188, 0x2001,
+       0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085,
+       0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x080c, 0x14f6, 0x0038,
+       0x2061, 0xad00, 0x6030, 0xc09d, 0x6032, 0x080c, 0x485e, 0x00ce,
+       0x0005, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+       0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x4348, 0x0068,
+       0xd08c, 0x0118, 0x080c, 0x4269, 0x0040, 0xd094, 0x0118, 0x080c,
+       0x423a, 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, 0x0490, 0xa294,
+       0xff00, 0xa296, 0xf700, 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240,
+       0xa295, 0x0100, 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7,
+       0x080c, 0x48de, 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0040,
+       0x6042, 0x6043, 0x0000, 0x7077, 0x0000, 0x7093, 0x0001, 0x70b7,
+       0x0000, 0x70d3, 0x0000, 0x2009, 0xb3c0, 0x200b, 0x0000, 0x7087,
+       0x0000, 0x707b, 0x000a, 0x2009, 0x000a, 0x2011, 0x4814, 0x080c,
+       0x6593, 0x0005, 0x0156, 0x2001, 0xad73, 0x2004, 0xd08c, 0x0110,
+       0x704f, 0xffff, 0x7078, 0xa005, 0x1510, 0x2011, 0x4814, 0x080c,
+       0x650d, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9,
+       0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x4251, 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,
+       0x14f6, 0x0005, 0x4275, 0x42c5, 0x4347, 0x00f6, 0x707f, 0x0001,
+       0x20e1, 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x22f8, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x2079, 0xb200, 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, 0xb20c, 0x207b,
+       0x1101, 0x7807, 0x0000, 0x2099, 0xad05, 0x20a1, 0xb20e, 0x20a9,
+       0x0004, 0x53a3, 0x2079, 0xb212, 0x207b, 0x0000, 0x7807, 0x0000,
+       0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3,
+       0x000c, 0x600f, 0x0000, 0x080c, 0x4845, 0x00fe, 0x7083, 0x0000,
+       0x6043, 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7080, 0x7083,
+       0x0000, 0xa025, 0x0904, 0x432f, 0x6020, 0xd0b4, 0x1904, 0x432d,
+       0x7190, 0x81ff, 0x0904, 0x431d, 0xa486, 0x000c, 0x1904, 0x4328,
+       0xa480, 0x0018, 0x8004, 0x20a8, 0x2011, 0xb280, 0x2019, 0xb200,
+       0x220c, 0x2304, 0xa106, 0x11b8, 0x8210, 0x8318, 0x1f04, 0x42e0,
+       0x6043, 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006,
+       0x707f, 0x0002, 0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x481b,
+       0x080c, 0x6593, 0x0490, 0x2069, 0xb280, 0x6930, 0xa18e, 0x1101,
+       0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118,
+       0x6804, 0xa005, 0x0190, 0x2011, 0xb28e, 0x2019, 0xad05, 0x20a9,
+       0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318,
+       0x1f04, 0x4311, 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6,
+       0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00de, 0x0005, 0x6040,
+       0xa085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c,
+       0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x20e1, 0x9080,
+       0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x0c30, 0x0005,
+       0x7088, 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x14f6,
+       0x0005, 0x437b, 0x438a, 0x43b2, 0x43cb, 0x43ef, 0x4417, 0x443b,
+       0x446c, 0x4490, 0x44b8, 0x44ef, 0x4517, 0x4533, 0x4549, 0x4569,
+       0x457c, 0x4584, 0x45b1, 0x45d5, 0x45fd, 0x4621, 0x4652, 0x468f,
+       0x46be, 0x46da, 0x4719, 0x4739, 0x4752, 0x4753, 0x00c6, 0x2061,
+       0xad00, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
+       0x6006, 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043,
+       0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x481b, 0x080c,
+       0x6593, 0x0005, 0x00f6, 0x7080, 0xa086, 0x0014, 0x1508, 0x6043,
+       0x0000, 0x6020, 0xd0b4, 0x11e0, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1102, 0x11a0, 0x7834, 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128,
+       0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x2011, 0x481b, 0x080c,
+       0x650d, 0x708b, 0x0010, 0x080c, 0x4584, 0x0010, 0x080c, 0x485e,
+       0x00fe, 0x0005, 0x708b, 0x0003, 0x6043, 0x0004, 0x2011, 0x481b,
+       0x080c, 0x650d, 0x080c, 0x48c6, 0x20a3, 0x1102, 0x20a3, 0x0000,
+       0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x43c2, 0x60c3, 0x0014,
+       0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011,
+       0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280,
+       0x7a30, 0xa296, 0x1102, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38,
+       0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b,
+       0x0004, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+       0x0005, 0x080c, 0x48c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430,
+       0x2011, 0xb28e, 0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148,
+       0x714c, 0xa186, 0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c,
+       0x48f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6,
+       0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+       0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1103, 0x1178,
+       0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+       0x1110, 0x70b7, 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, 0x080c,
+       0x485e, 0x00fe, 0x0005, 0x708b, 0x0007, 0x080c, 0x48c6, 0x20a3,
+       0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917,
+       0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170,
+       0xa180, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df,
+       0x0128, 0x080c, 0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008,
+       0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0,
+       0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079,
+       0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, 0x1160,
+       0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+       0x708b, 0x0008, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005,
+       0x708b, 0x0009, 0x080c, 0x48c6, 0x20a3, 0x1105, 0x20a3, 0x0100,
+       0x3430, 0x080c, 0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c,
+       0x4754, 0x1170, 0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008,
+       0x2099, 0xb28e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0014, 0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005,
+       0x00f6, 0x7080, 0xa005, 0x0588, 0x2011, 0x481b, 0x080c, 0x650d,
+       0xa086, 0x0014, 0x1540, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1105,
+       0x1510, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc,
+       0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x000a,
+       0x00b1, 0x0098, 0xa005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b4,
+       0xa005, 0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x708b, 0x000e,
+       0x080c, 0x4569, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+       0x000b, 0x2011, 0xb20e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff,
+       0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x48c6,
+       0x20a3, 0x1106, 0x20a3, 0x0000, 0x080c, 0x4917, 0x0118, 0x2013,
+       0x0000, 0x0020, 0x7050, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9,
+       0x0042, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4845, 0x0005, 0x00f6,
+       0x7080, 0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+       0x0084, 0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138,
+       0x7834, 0xa005, 0x1120, 0x708b, 0x000c, 0x0029, 0x0010, 0x080c,
+       0x485e, 0x00fe, 0x0005, 0x708b, 0x000d, 0x080c, 0x48c6, 0x20a3,
+       0x1107, 0x20a3, 0x0000, 0x2099, 0xb28e, 0x20a9, 0x0040, 0x53a6,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+       0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+       0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+       0x48b8, 0x708b, 0x000e, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+       0x0005, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, 0xbc85, 0x608f,
+       0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
+       0x481b, 0x080c, 0x6501, 0x0005, 0x7080, 0xa005, 0x0120, 0x2011,
+       0x481b, 0x080c, 0x650d, 0x0005, 0x708b, 0x0011, 0x080c, 0x4917,
+       0x1188, 0x716c, 0x81ff, 0x0170, 0x2009, 0x0000, 0x7070, 0xa084,
+       0x00ff, 0x080c, 0x2676, 0xa186, 0x0080, 0x0120, 0x2011, 0xb28e,
+       0x080c, 0x47df, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+       0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084,
+       0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, 0x4845,
+       0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c,
+       0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+       0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x0012, 0x0029,
+       0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b, 0x0013, 0x080c,
+       0x48d2, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e,
+       0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c, 0xa186,
+       0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c, 0x48f5, 0x20a9,
+       0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005,
+       0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8,
+       0x2079, 0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005,
+       0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7,
+       0x0001, 0x708b, 0x0014, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+       0x0005, 0x708b, 0x0015, 0x080c, 0x48d2, 0x20a3, 0x1104, 0x20a3,
+       0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917, 0x11a8, 0x7074,
+       0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x2be6,
+       0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df, 0x0128, 0x080c,
+       0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2298, 0x26a0,
+       0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c,
+       0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05b8, 0x2011, 0x481b,
+       0x080c, 0x650d, 0xa086, 0x0014, 0x1570, 0x2079, 0xb280, 0x7a30,
+       0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1148,
+       0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+       0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+       0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0138,
+       0x2001, 0xad73, 0x2004, 0xd0a4, 0x1110, 0x70d3, 0x0008, 0x708b,
+       0x0016, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9,
+       0x000e, 0x53a6, 0x3430, 0x2011, 0xb28e, 0x708b, 0x0017, 0x080c,
+       0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c, 0x4754, 0x1170,
+       0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2099, 0xb28e,
+       0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005, 0x00f6, 0x7080,
+       0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0084,
+       0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834,
+       0xa005, 0x1120, 0x708b, 0x0018, 0x0029, 0x0010, 0x080c, 0x485e,
+       0x00fe, 0x0005, 0x708b, 0x0019, 0x080c, 0x48d2, 0x20a3, 0x1106,
+       0x20a3, 0x0000, 0x3430, 0x2099, 0xb28e, 0x2039, 0xb20e, 0x27a0,
+       0x20a9, 0x0040, 0x53a3, 0x080c, 0x4917, 0x11e8, 0x2728, 0x2514,
+       0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
+       0xa205, 0x202a, 0x7050, 0x2310, 0x8214, 0xa2a0, 0xb20e, 0x2414,
+       0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff,
+       0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+       0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+       0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+       0x48b8, 0x708b, 0x001a, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+       0x0005, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+       0xb280, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
+       0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c,
+       0x4845, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0xad52,
+       0x252c, 0x20a9, 0x0008, 0x2041, 0xb20e, 0x28a0, 0x2099, 0xb28e,
+       0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011,
+       0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4,
+       0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4769, 0x0804, 0x47d7,
+       0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020,
+       0xa1a6, 0x3fff, 0x0904, 0x47d7, 0xa18d, 0xc000, 0x20a9, 0x0010,
+       0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4,
+       0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319,
+       0x0008, 0x8318, 0x1f04, 0x478f, 0x04d0, 0x23a8, 0x2021, 0x0001,
+       0x8426, 0x8425, 0x1f04, 0x47a1, 0x2328, 0x8529, 0xa2be, 0x0007,
+       0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8,
+       0xa5a8, 0x0010, 0x1f04, 0x47b0, 0x754e, 0xa5c8, 0x2be6, 0x292d,
+       0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
+       0x26a0, 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, 0x14f6, 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,
+       0x2be6, 0x242d, 0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016,
+       0x2508, 0x080c, 0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7077,
+       0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x707b,
+       0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071,
+       0x0140, 0x080c, 0x7834, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003,
+       0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000, 0x2071, 0xad22,
+       0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c,
+       0x48de, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42,
+       0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1,
+       0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x2009,
+       0x07d0, 0x2011, 0x481b, 0x080c, 0x6593, 0x0005, 0x0016, 0x0026,
+       0x00c6, 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x48de,
+       0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xad00,
+       0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010,
+       0x2009, 0x002d, 0x2011, 0x4883, 0x080c, 0x6501, 0x012e, 0x00ce,
+       0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000,
+       0x2071, 0x0100, 0x080c, 0x7834, 0x2071, 0x0140, 0x7004, 0xa084,
+       0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x5757,
+       0x01a8, 0x080c, 0x5775, 0x1190, 0x2001, 0xaf9d, 0x2003, 0xaaaa,
+       0x0016, 0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x001e, 0x2001,
+       0xaf9e, 0x2003, 0x0000, 0x080c, 0x569a, 0x0030, 0x2001, 0x0001,
+       0x080c, 0x261e, 0x080c, 0x485e, 0x012e, 0x000e, 0x00ee, 0x0005,
+       0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb28e, 0x3304, 0x8007,
+       0x20a2, 0x9398, 0x94a0, 0x1f04, 0x48be, 0x0005, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x000c,
+       0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+       0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6, 0x0006,
+       0x2061, 0x0100, 0x810f, 0x2001, 0xad30, 0x2004, 0xa005, 0x1138,
+       0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185,
+       0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x2001,
+       0xad52, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
+       0x080c, 0xa96c, 0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019,
+       0x002a, 0x2009, 0x0000, 0x080c, 0x2aac, 0x004e, 0x001e, 0x0005,
+       0x080c, 0x485e, 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006,
+       0x2001, 0xad0c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006,
+       0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d,
+       0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x0156, 0x20a9,
+       0x00ff, 0x2009, 0xae34, 0xa006, 0x200a, 0x8108, 0x1f04, 0x4934,
+       0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069,
+       0xad51, 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012,
+       0xa198, 0x2be6, 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, 0x60ae, 0x61a2, 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c,
+       0x15f0, 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0,
+       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, 0x4a49, 0xa18c, 0xff00,
+       0x810f, 0xa182, 0x00ff, 0x1a04, 0x4a4e, 0x2001, 0xad0c, 0x2004,
+       0xa084, 0x0003, 0x01c0, 0x2001, 0xad0c, 0x2004, 0xd084, 0x1904,
+       0x4a31, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904, 0x4a31, 0x6004,
+       0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a31, 0x6000, 0xd0c4,
+       0x0904, 0x4a31, 0x0068, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904,
+       0x4a15, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a1a,
+       0x60a4, 0xa00d, 0x0118, 0x080c, 0x4ef9, 0x05d0, 0x60a8, 0xa00d,
+       0x0188, 0x080c, 0x4f43, 0x1170, 0x694c, 0xd1fc, 0x1118, 0x080c,
+       0x4c11, 0x0448, 0x080c, 0x4bd3, 0x694c, 0xd1ec, 0x1520, 0x080c,
+       0x4ded, 0x0408, 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec, 0x0140,
+       0xd1fc, 0x0118, 0x080c, 0x4dfc, 0x0028, 0x080c, 0x4dfc, 0x0028,
+       0xd1fc, 0x0118, 0x080c, 0x4bd3, 0x0070, 0x6050, 0xa00d, 0x0130,
+       0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00, 0x6052,
+       0x604e, 0x6803, 0x0000, 0x080c, 0x67c5, 0xa006, 0x012e, 0x0005,
+       0x2001, 0x0005, 0x2009, 0x0000, 0x04e8, 0x2001, 0x0028, 0x2009,
+       0x0000, 0x04c0, 0xa082, 0x0006, 0x12a0, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x1160, 0x60a0, 0xd0bc, 0x1148, 0x6100, 0xd1fc, 0x0904,
+       0x49d0, 0x2001, 0x0029, 0x2009, 0x1000, 0x0420, 0x2001, 0x0028,
+       0x00a8, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+       0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029,
+       0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0060, 0x2009, 0x0000,
+       0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029,
+       0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126, 0x2091,
+       0x8000, 0x6844, 0x8007, 0xa084, 0x00ff, 0x2008, 0xa182, 0x00ff,
+       0x1a04, 0x4aa8, 0xa188, 0xae34, 0x2104, 0xa065, 0x01c0, 0x6004,
+       0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8, 0x2c70, 0x080c, 0x8022,
+       0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012, 0x600b, 0xffff, 0x601f,
+       0x000a, 0x2009, 0x0003, 0x080c, 0x80a7, 0xa006, 0x0460, 0x2001,
+       0x0028, 0x0440, 0xa082, 0x0006, 0x1298, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc, 0x09e8,
+       0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090,
+       0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050,
+       0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010,
+       0x2001, 0x0029, 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c,
+       0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2011, 0x0000,
+       0x2079, 0xad00, 0x6944, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x1a04, 0x4b77, 0x2001, 0xad0c, 0x2004, 0xa084, 0x0003, 0x1904,
+       0x4b65, 0x080c, 0x4cdc, 0x1180, 0x6004, 0xa084, 0x00ff, 0xa082,
+       0x0006, 0x1250, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1904, 0x4b60,
+       0x60a0, 0xd0bc, 0x1904, 0x4b60, 0x6864, 0xa0c6, 0x006f, 0x0118,
+       0x2008, 0x0804, 0x4b28, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f,
+       0x78d0, 0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff,
+       0x16b8, 0x6a70, 0x6b6c, 0x786c, 0xa306, 0x1160, 0x7870, 0xa24e,
+       0x1118, 0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208,
+       0x2310, 0x0430, 0x080c, 0x3b58, 0x2c70, 0x0550, 0x2009, 0x0000,
+       0x2011, 0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c,
+       0x4f6e, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e,
+       0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008,
+       0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010,
+       0x2001, 0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0458,
+       0x080c, 0x8022, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011,
+       0x0000, 0x0c80, 0x2e00, 0x601a, 0x080c, 0x9956, 0x2d00, 0x6012,
+       0x601f, 0x0001, 0xa006, 0xd88c, 0x0110, 0x2001, 0x4000, 0x683a,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9, 0x012e, 0x2001, 0x0000,
+       0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x2009, 0x0002,
+       0x080c, 0x80a7, 0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005,
+       0x2001, 0x0028, 0x2009, 0x0000, 0x0cb0, 0x2009, 0xad0c, 0x210c,
+       0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
+       0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001,
+       0x0029, 0x2009, 0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff,
+       0xa082, 0x4000, 0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x12e0, 0xa188, 0xae34, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084,
+       0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c,
+       0x4dfc, 0x04c9, 0x0030, 0x04b9, 0x684c, 0xd0fc, 0x0110, 0x080c,
+       0x4ded, 0x080c, 0x4e3a, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009,
+       0x0000, 0x00a0, 0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20,
+       0x2001, 0x0029, 0x2009, 0x1000, 0x0048, 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, 0xafc7, 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, 0x0006,
+       0xa086, 0x0006, 0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xad52,
+       0x2004, 0xd0a4, 0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007,
+       0x1110, 0x2011, 0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206,
+       0x0006, 0xa086, 0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c,
+       0x14f6, 0x000e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091,
+       0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178,
+       0x609c, 0xd0a4, 0x0160, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1138,
+       0xa284, 0x00ff, 0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e,
+       0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005,
+       0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190,
+       0xae34, 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15c0,
+       0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000,
+       0x60ab, 0x0000, 0x080c, 0x493a, 0xa006, 0x002e, 0x0005, 0x0126,
+       0x2091, 0x8000, 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001,
+       0x0480, 0x00d6, 0xa190, 0xae34, 0x2204, 0xa06d, 0x0540, 0x2013,
+       0x0000, 0x00d6, 0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c,
+       0x15f0, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0, 0x00ce, 0x00de,
+       0x00d6, 0x00c6, 0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006,
+       0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x1600, 0x080c,
+       0x8078, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x080c, 0x15f0, 0x00de,
+       0xa006, 0x002e, 0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218,
+       0xa085, 0x0001, 0x0030, 0xa188, 0xae34, 0x2104, 0xa065, 0x0dc0,
+       0xa006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b,
+       0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x574f,
+       0x1538, 0x60a0, 0xa086, 0x007e, 0x2069, 0xb290, 0x0130, 0x2001,
+       0xad34, 0x2004, 0xd0ac, 0x11e0, 0x0098, 0x2d04, 0xd0e4, 0x01c0,
+       0x00d6, 0x2069, 0xb28e, 0x00c6, 0x2061, 0xaf9f, 0x6810, 0x2062,
+       0x6814, 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de,
+       0x8d69, 0x2d04, 0x2069, 0x0140, 0x6886, 0x2069, 0xad00, 0x68a2,
+       0x2069, 0xb28e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a,
+       0x0208, 0x603a, 0x6814, 0x6066, 0x2099, 0xb296, 0xac88, 0x000a,
+       0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xb29a, 0xac88, 0x0006,
+       0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xb2ae, 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, 0x0016, 0x0026, 0x00e6, 0x2071, 0xb28d, 0x2e04,
+       0x6896, 0x2071, 0xb28e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00,
+       0x2009, 0xad71, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad,
+       0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, 0x0110, 0xc2bd, 0x0008,
+       0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, 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, 0x4da8, 0x080c,
+       0x14f6, 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x15d9, 0x01a8,
+       0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010,
+       0x200b, 0xffff, 0x8108, 0x1f04, 0x4dc0, 0x6807, 0x0001, 0x6e12,
+       0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126,
+       0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800,
+       0xa005, 0x1160, 0x080c, 0x4ef9, 0x1168, 0x200b, 0xffff, 0x6804,
+       0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x15f0,
+       0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x4f56, 0x0010, 0x080c, 0x4bc0, 0x080c, 0x4e71, 0x1dd8,
+       0x080c, 0x4e3a, 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, 0x4e0e, 0x080c, 0x14f6, 0x260a,
+       0x8210, 0x6a56, 0x0098, 0x080c, 0x15d9, 0x01d0, 0x2d00, 0x60aa,
+       0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff,
+       0x8108, 0x1f04, 0x4e26, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c,
+       0x4c11, 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005,
+       0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x67c5, 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,
+       0x4ef3, 0x1110, 0x2011, 0x0001, 0x080c, 0x4f3d, 0x1110, 0xa295,
+       0x0002, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x964b, 0x0010,
+       0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x95e4,
+       0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c,
+       0x962e, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118,
+       0x080c, 0x9600, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e,
+       0x0118, 0x080c, 0x9667, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126,
+       0x0006, 0x00d6, 0x2091, 0x8000, 0x6080, 0xa06d, 0x01a0, 0x6800,
+       0x0006, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd,
+       0x0006, 0x6000, 0xd0fc, 0x0110, 0x080c, 0xac03, 0x000e, 0x080c,
+       0x510c, 0x000e, 0x0c50, 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, 0x4f02,
+       0xa085, 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091,
+       0x8000, 0x60a4, 0xa06d, 0x1128, 0x080c, 0x15d9, 0x01a0, 0x2d00,
+       0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9,
+       0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x4f21, 0xa085, 0x0001,
+       0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091,
+       0x8000, 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x15f0,
+       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, 0x4f4c, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091,
+       0x8000, 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068,
+       0x6854, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c,
+       0x15f0, 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4,
+       0x0005, 0x00f6, 0x080c, 0x574f, 0x01b0, 0x71b4, 0x81ff, 0x1198,
+       0x71d0, 0xd19c, 0x0180, 0x2001, 0x007e, 0xa080, 0xae34, 0x2004,
+       0xa07d, 0x0148, 0x7804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1118,
+       0x7800, 0xc0ed, 0x7802, 0x2079, 0xad51, 0x7804, 0xd0a4, 0x01e8,
+       0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c,
+       0x4cdc, 0x1168, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+       0x0118, 0xa086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e,
+       0x8108, 0x1f04, 0x4f96, 0x00ce, 0x015e, 0x080c, 0x502d, 0x0120,
+       0x2001, 0xafa2, 0x200c, 0x0038, 0x2079, 0xad51, 0x7804, 0xd0a4,
+       0x0130, 0x2009, 0x07d0, 0x2011, 0x4fc1, 0x080c, 0x6593, 0x00fe,
+       0x0005, 0x2011, 0x4fc1, 0x080c, 0x650d, 0x080c, 0x502d, 0x01f0,
+       0x2001, 0xaeb2, 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102,
+       0x2001, 0xad52, 0x2004, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011,
+       0x4fc1, 0x080c, 0x6593, 0x00e6, 0x2071, 0xad00, 0x706f, 0x0000,
+       0x7073, 0x0000, 0x080c, 0x28fa, 0x00ee, 0x04b0, 0x0156, 0x00c6,
+       0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1530,
+       0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227,
+       0xa006, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6000, 0xc0e5, 0xc0ec,
+       0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019,
+       0x0029, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d,
+       0x2009, 0x0000, 0x080c, 0xa712, 0x007e, 0x004e, 0x001e, 0x8108,
+       0x1f04, 0x4fec, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, 0x2060,
+       0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac,
+       0x0005, 0x7818, 0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001, 0xaeb2,
+       0x2004, 0xa07d, 0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126,
+       0x0026, 0x2091, 0x8000, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008,
+       0xc2fc, 0x6202, 0x002e, 0x012e, 0x0005, 0x2071, 0xae13, 0x7003,
+       0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b,
+       0x0000, 0x701f, 0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f,
+       0x0000, 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071,
+       0xaf7c, 0x7003, 0xae13, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f,
+       0xaf5c, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005,
+       0x0016, 0x00e6, 0x2071, 0xaf34, 0xa00e, 0x7186, 0x718a, 0x7097,
+       0x0001, 0x2001, 0xad52, 0x2004, 0xd0fc, 0x1150, 0x2001, 0xad52,
+       0x2004, 0xa00e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0804, 0x50d6,
+       0x2001, 0xad71, 0x200c, 0xa184, 0x000f, 0x2009, 0xad72, 0x210c,
+       0x0002, 0x507e, 0x50b1, 0x50b8, 0x50c2, 0x50c7, 0x507e, 0x507e,
+       0x507e, 0x50a1, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e,
+       0x507e, 0x7003, 0x0004, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+       0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+       0x0428, 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, 0xae13, 0x684c, 0xa005, 0x1130, 0x7028,
+       0xc085, 0x702a, 0xa085, 0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64,
+       0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c,
+       0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000,
+       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, 0x5165, 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071,
+       0xad00, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00,
+       0x81ff, 0x1dc8, 0x702e, 0x70b0, 0xa200, 0x70b2, 0x00de, 0x2071,
+       0xae13, 0x701c, 0xa005, 0x1904, 0x5175, 0x20a9, 0x0032, 0x0f04,
+       0x5173, 0x0e04, 0x512f, 0x2071, 0xaf34, 0x7200, 0x82ff, 0x05d8,
+       0x6934, 0xa186, 0x0103, 0x1904, 0x5183, 0x6948, 0x6844, 0xa105,
+       0x1540, 0x2009, 0x8020, 0x2200, 0x0002, 0x5173, 0x514a, 0x519b,
+       0x51a7, 0x5173, 0x2071, 0x0000, 0x20a9, 0x0032, 0x0f04, 0x5173,
+       0x7018, 0xd084, 0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+       0x701b, 0x0001, 0x2091, 0x4080, 0x2071, 0xad00, 0x702c, 0x206a,
+       0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x002e, 0x00ee, 0x015e,
+       0x0005, 0x6844, 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118,
+       0x2009, 0x8020, 0x0880, 0x2071, 0xae13, 0x2d08, 0x206b, 0x0000,
+       0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902,
+       0x0008, 0x711e, 0x0c10, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130,
+       0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc,
+       0x0d10, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009,
+       0x8021, 0x0804, 0x5143, 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, 0x515c, 0x718c, 0x7084, 0xa10a, 0x0a04, 0x515c, 0x2071,
+       0x0000, 0x7018, 0xd084, 0x1904, 0x515c, 0x2071, 0xaf34, 0x7000,
+       0xa086, 0x0002, 0x1150, 0x080c, 0x5426, 0x2071, 0x0000, 0x701b,
+       0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x080c, 0x5450, 0x2071,
+       0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x0006,
+       0x684c, 0x0006, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011,
+       0x20a0, 0x2001, 0x0000, 0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e,
+       0x000e, 0x684a, 0x6952, 0x0005, 0x2071, 0xae13, 0x7004, 0x0002,
+       0x5202, 0x5213, 0x5411, 0x5412, 0x541f, 0x5425, 0x5203, 0x5402,
+       0x5398, 0x53ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5212,
+       0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001,
+       0x700b, 0x0000, 0x012e, 0x2069, 0xafda, 0x683c, 0xa005, 0x03f8,
+       0x11f0, 0x0126, 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001,
+       0xae1f, 0x2004, 0xa10a, 0x0170, 0x0e04, 0x5236, 0x2069, 0x0000,
+       0x6818, 0xd084, 0x1158, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001,
+       0x2091, 0x4080, 0x2069, 0xafda, 0x683f, 0xffff, 0x012e, 0x2069,
+       0xad00, 0x6844, 0x6964, 0xa102, 0x2069, 0xaf34, 0x688a, 0x6984,
+       0x701c, 0xa06d, 0x0120, 0x81ff, 0x0904, 0x528c, 0x00a0, 0x81ff,
+       0x0904, 0x5352, 0x2071, 0xaf34, 0x7184, 0x7088, 0xa10a, 0x1258,
+       0x7190, 0x2071, 0xafda, 0x7038, 0xa005, 0x0128, 0x1b04, 0x5352,
+       0x713a, 0x0804, 0x5352, 0x2071, 0xaf34, 0x718c, 0x0126, 0x2091,
+       0x8000, 0x7084, 0xa10a, 0x0a04, 0x536d, 0x0e04, 0x530e, 0x2071,
+       0x0000, 0x7018, 0xd084, 0x1904, 0x530e, 0x2001, 0xffff, 0x2071,
+       0xafda, 0x703a, 0x2071, 0xaf34, 0x7000, 0xa086, 0x0002, 0x1150,
+       0x080c, 0x5426, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+       0x0804, 0x530e, 0x080c, 0x5450, 0x2071, 0x0000, 0x701b, 0x0001,
+       0x2091, 0x4080, 0x0804, 0x530e, 0x2071, 0xaf34, 0x7000, 0xa005,
+       0x0904, 0x5334, 0x6934, 0xa186, 0x0103, 0x1904, 0x5311, 0x684c,
+       0xd0bc, 0x1904, 0x5334, 0x6948, 0x6844, 0xa105, 0x1904, 0x5329,
+       0x2009, 0x8020, 0x2071, 0xaf34, 0x7000, 0x0002, 0x5334, 0x52f4,
+       0x52cc, 0x52de, 0x52ab, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+       0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+       0x2071, 0xaf7c, 0xad80, 0x000f, 0x700e, 0x7013, 0x0002, 0x7007,
+       0x0002, 0x700b, 0x0000, 0x2e10, 0x080c, 0x1624, 0x2071, 0xae13,
+       0x7007, 0x0009, 0x0804, 0x5352, 0x7084, 0x8008, 0xa092, 0x001e,
+       0x1a04, 0x5352, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x7186,
+       0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x7084, 0x8008,
+       0xa092, 0x000f, 0x1a04, 0x5352, 0xae90, 0x0003, 0x8003, 0xa210,
+       0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7186, 0x2071, 0xae13,
+       0x080c, 0x54a7, 0x0804, 0x5352, 0x0126, 0x2091, 0x8000, 0x0e04,
+       0x530e, 0x2071, 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c,
+       0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e,
+       0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x012e, 0x0804,
+       0x5352, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e,
+       0x0118, 0xa18e, 0x001f, 0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850,
+       0xa084, 0x00ff, 0xa086, 0x0001, 0x1178, 0x2009, 0x8021, 0x0804,
+       0x52a2, 0x6844, 0xa086, 0x0100, 0x1138, 0x6868, 0xa005, 0x1120,
+       0x2009, 0x8020, 0x0804, 0x52a2, 0x2071, 0xae13, 0x080c, 0x54b9,
+       0x01c8, 0x2071, 0xae13, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff,
+       0xa086, 0x0003, 0x1130, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108,
+       0x710e, 0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100,
+       0x0904, 0x5412, 0x0126, 0x2091, 0x8000, 0x2071, 0xae13, 0x7008,
+       0xa086, 0x0001, 0x1180, 0x0e04, 0x536b, 0x2009, 0x000d, 0x7030,
+       0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+       0x1110, 0x7007, 0x0001, 0x012e, 0x0005, 0x2071, 0xae13, 0x080c,
+       0x54b9, 0x0518, 0x2071, 0xaf34, 0x7084, 0x700a, 0x20a9, 0x0020,
+       0x2099, 0xaf35, 0x20a1, 0xaf5c, 0x53a3, 0x7087, 0x0000, 0x2071,
+       0xae13, 0x2069, 0xaf7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074,
+       0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, 0x1624, 0x7007, 0x0008,
+       0x2001, 0xffff, 0x2071, 0xafda, 0x703a, 0x012e, 0x0804, 0x5352,
+       0x2069, 0xaf7c, 0x6808, 0xa08e, 0x0000, 0x0904, 0x53ed, 0xa08e,
+       0x0200, 0x0904, 0x53eb, 0xa08e, 0x0100, 0x1904, 0x53ed, 0x0126,
+       0x2091, 0x8000, 0x0e04, 0x53e9, 0x2069, 0x0000, 0x6818, 0xd084,
+       0x15c0, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034,
+       0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e,
+       0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b,
+       0x0000, 0x2001, 0xaf59, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069,
+       0xaf34, 0x689c, 0x699e, 0x2069, 0xafda, 0xa102, 0x1118, 0x683c,
+       0xa005, 0x1368, 0x2001, 0xaf5a, 0x200c, 0x810d, 0x693e, 0x0038,
+       0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007,
+       0x0001, 0x012e, 0x0010, 0x7007, 0x0005, 0x0005, 0x2001, 0xaf7e,
+       0x2004, 0xa08e, 0x0100, 0x1128, 0x7007, 0x0001, 0x080c, 0x54a7,
+       0x0005, 0xa08e, 0x0000, 0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007,
+       0x0005, 0x0005, 0x701c, 0xa06d, 0x0158, 0x080c, 0x54b9, 0x0140,
+       0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100, 0x0110,
+       0x0005, 0x0005, 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, 0x0004,
+       0x0030, 0xa086, 0x0200, 0x1110, 0x7007, 0x0005, 0x0005, 0x080c,
+       0x5475, 0x7006, 0x080c, 0x54a7, 0x0005, 0x0005, 0x00e6, 0x0156,
+       0x2071, 0xaf34, 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, 0xae80,
+       0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04,
+       0x544a, 0x2014, 0x722a, 0x8000, 0x0f04, 0x544a, 0x2014, 0x722e,
+       0x8000, 0x0f04, 0x544a, 0x2014, 0x723a, 0x8000, 0x0f04, 0x544a,
+       0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, 0x0005,
+       0x00e6, 0x0156, 0x2071, 0xaf34, 0x7184, 0x81ff, 0x01d8, 0xa006,
+       0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226,
+       0x8000, 0x2014, 0x722a, 0x8000, 0x0f04, 0x546c, 0x2014, 0x723a,
+       0x8000, 0x2014, 0x723e, 0x0018, 0x2001, 0x8020, 0x0010, 0x2001,
+       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, 0x1180, 0x0126, 0x2091,
+       0x8000, 0x0e04, 0x54a1, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080,
+       0x2001, 0x0001, 0x700b, 0x0000, 0x012e, 0x0005, 0x2001, 0x0007,
+       0x0005, 0x2001, 0x0006, 0x700b, 0x0001, 0x012e, 0x0005, 0x701c,
+       0xa06d, 0x0170, 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012,
+       0x2d04, 0x701e, 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x15f0,
+       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, 0xafec, 0x2104, 0xc08d,
+       0x200a, 0x012e, 0x080c, 0x163c, 0x0005, 0x7088, 0xa08a, 0x0029,
+       0x1220, 0xa082, 0x001d, 0x0033, 0x0010, 0x080c, 0x14f6, 0x6027,
+       0x1e00, 0x0005, 0x55c1, 0x555b, 0x5571, 0x5595, 0x55b4, 0x55e6,
+       0x55f8, 0x5571, 0x55d2, 0x54ff, 0x552d, 0x54fe, 0x0005, 0x00d6,
+       0x2069, 0x0200, 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518,
+       0x708b, 0x0028, 0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x584d,
+       0x6028, 0xa085, 0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069,
+       0xafac, 0x2d04, 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6,
+       0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e,
+       0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200,
+       0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708b, 0x0028,
+       0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x58da, 0x6028, 0xa085,
+       0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069, 0xafac, 0x2d04,
+       0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046,
+       0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e, 0x004e, 0x003e,
+       0x00ee, 0x00de, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1e4, 0x1180,
+       0x080c, 0x5663, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140,
+       0x708b, 0x0020, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f,
+       0x0005, 0x6803, 0x0088, 0x6124, 0xd1cc, 0x11c8, 0xd1dc, 0x11a0,
+       0xd1e4, 0x1178, 0xa184, 0x1e00, 0x11b8, 0x60e3, 0x0001, 0x600c,
+       0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x708b, 0x0028,
+       0x0058, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, 0x708b,
+       0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x60e3, 0x0001, 0x600c,
+       0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x6124, 0xd1d4,
+       0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0xa184, 0x1e00, 0x1158,
+       0x708b, 0x0028, 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d,
+       0x0010, 0x708b, 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1dc,
+       0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d,
+       0x0005, 0x080c, 0x568d, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x5663,
+       0xd1d4, 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b,
+       0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1d4, 0x1160, 0xd1cc,
+       0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028,
+       0x708b, 0x001d, 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x568d,
+       0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b,
+       0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005,
+       0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc,
+       0x1128, 0xd1e4, 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d,
+       0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x0016,
+       0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140,
+       0x2071, 0xad00, 0x2091, 0x8000, 0x080c, 0x574f, 0x11e8, 0x2001,
+       0xad0c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, 0x2102, 0x6027, 0x0200,
+       0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, 0x6803, 0x00a0, 0x2001,
+       0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0428,
+       0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x576b, 0x0150, 0x080c,
+       0x5761, 0x1138, 0x2001, 0x0001, 0x080c, 0x261e, 0x080c, 0x5726,
+       0x00a0, 0x080c, 0x568a, 0x0178, 0x2001, 0x0001, 0x080c, 0x261e,
+       0x7088, 0xa086, 0x001e, 0x0120, 0x7088, 0xa086, 0x0022, 0x1118,
+       0x708b, 0x0025, 0x0010, 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de,
+       0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011,
+       0x566e, 0x080c, 0x6501, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6,
+       0x0016, 0x080c, 0x7834, 0x2071, 0xad00, 0x080c, 0x560f, 0x001e,
+       0x00fe, 0x00ee, 0x0005, 0x2001, 0xad00, 0x2004, 0xa086, 0x0004,
+       0x0140, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+       0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6803, 0x00c0, 0x0156,
+       0x20a9, 0x002d, 0x1d04, 0x5692, 0x2091, 0x6000, 0x1f04, 0x5692,
+       0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
+       0x0140, 0x2071, 0xad00, 0x2001, 0xaf9e, 0x200c, 0xa186, 0x0000,
+       0x0158, 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186,
+       0x0003, 0x0158, 0x0804, 0x5714, 0x708b, 0x0022, 0x0040, 0x708b,
+       0x0021, 0x0028, 0x708b, 0x0023, 0x0020, 0x708b, 0x0024, 0x6043,
+       0x0000, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
+       0x26cb, 0x0026, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002,
+       0x080c, 0x7ae9, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b,
+       0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
+       0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04d0,
+       0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130,
+       0x6803, 0x0100, 0x1f04, 0x56e2, 0x080c, 0x57a0, 0x012e, 0x015e,
+       0x080c, 0x5761, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006,
+       0xa085, 0x0020, 0x6052, 0x080c, 0x57a0, 0xa006, 0x8001, 0x1df0,
+       0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x57a0,
+       0x2001, 0xaf9e, 0x2003, 0x0004, 0x080c, 0x54e5, 0x080c, 0x5761,
+       0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0xaf9e,
+       0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+       0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x2001,
+       0xaf9d, 0x2003, 0x0000, 0x2001, 0xaf8e, 0x2003, 0x0000, 0x708b,
+       0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c,
+       0x26cb, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
+       0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006,
+       0x2001, 0xaf9d, 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006,
+       0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e,
+       0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086,
+       0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084,
+       0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71,
+       0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001,
+       0xad0c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x26eb, 0x0036, 0x0016,
+       0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2aac, 0x001e, 0x003e,
+       0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xad0c, 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, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006,
+       0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000,
+       0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26cb, 0x6800, 0xa084,
+       0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, 0x6052, 0x6050,
+       0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
+       0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x6020, 0xa084,
+       0x0080, 0x0138, 0x2001, 0xad0c, 0x200c, 0xc1bd, 0x2102, 0x0804,
+       0x5845, 0x2001, 0xad0c, 0x200c, 0xc1bc, 0x2102, 0x6028, 0xa084,
+       0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, 0x20a9, 0x0384,
+       0x6024, 0xd0cc, 0x1518, 0x1d04, 0x57f8, 0x2091, 0x6000, 0x1f04,
+       0x57f8, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+       0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+       0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+       0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x0438, 0x60e3, 0x0000,
+       0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x6803, 0x0080,
+       0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024,
+       0xa10c, 0x0138, 0x1d04, 0x582a, 0x2091, 0x6000, 0x1f04, 0x582a,
+       0x0840, 0x6028, 0xa085, 0x1e00, 0x602a, 0x70a0, 0xa005, 0x1118,
+       0x6887, 0x0001, 0x0008, 0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce,
+       0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
+       0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+       0x2069, 0x0140, 0x6020, 0xa084, 0x00c0, 0x0120, 0x6884, 0xa005,
+       0x1904, 0x58a1, 0x6803, 0x0088, 0x60e3, 0x0000, 0x6887, 0x0000,
+       0x2001, 0x0000, 0x080c, 0x26cb, 0x2069, 0x0200, 0x6804, 0xa005,
+       0x1118, 0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a,
+       0x6027, 0x0400, 0x2069, 0xafac, 0x7000, 0x206a, 0x708b, 0x0026,
+       0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x5884, 0x2091, 0x6000,
+       0x1f04, 0x5884, 0x0804, 0x58d2, 0x2069, 0x0140, 0x20a9, 0x0384,
+       0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0530,
+       0xa084, 0x1a00, 0x1518, 0x1d04, 0x5890, 0x2091, 0x6000, 0x1f04,
+       0x5890, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+       0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+       0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+       0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x00a0, 0x6803, 0x0080,
+       0x2069, 0x0140, 0x60e3, 0x0000, 0x70a0, 0xa005, 0x1118, 0x6887,
+       0x0001, 0x0008, 0x6886, 0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb,
+       0x60e2, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+       0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
+       0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x6020, 0xa084, 0x00c0,
+       0x01f0, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+       0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+       0x7a64, 0x2069, 0x0140, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003,
+       0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0804, 0x5972, 0x2001,
+       0xad0c, 0x200c, 0xd1b4, 0x1150, 0xc1b5, 0x2102, 0x080c, 0x5663,
+       0x2069, 0x0140, 0x6803, 0x0080, 0x60e3, 0x0000, 0x2069, 0x0200,
+       0x6804, 0xa005, 0x1118, 0x6808, 0xa005, 0x01b8, 0x6028, 0xa084,
+       0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0xafac, 0x7000, 0x206a,
+       0x708b, 0x0027, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x592e,
+       0x2091, 0x6000, 0x1f04, 0x592e, 0x04e8, 0x6027, 0x1e00, 0x2009,
+       0x1e00, 0xe000, 0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0,
+       0x1d04, 0x5935, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c,
+       0x64a2, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071,
+       0xafda, 0x7018, 0x00ee, 0xa005, 0x1d00, 0x01e0, 0x0026, 0x2011,
+       0x566e, 0x080c, 0x650d, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000,
+       0x70a0, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001,
+       0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x2001, 0xad0c, 0x200c,
+       0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+       0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6,
+       0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x7130, 0xd184, 0x1180,
+       0x2011, 0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011,
+       0xad52, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x59df,
+       0x7130, 0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x0530,
+       0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019,
+       0x000e, 0x080c, 0xa8eb, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000,
+       0xa186, 0x007e, 0x0170, 0xa186, 0x0080, 0x0158, 0x080c, 0x4cdc,
+       0x1140, 0x8127, 0xa006, 0x0016, 0x2009, 0x000e, 0x080c, 0xa96c,
+       0x001e, 0x8108, 0x1f04, 0x59b0, 0x015e, 0x001e, 0xd1ac, 0x1148,
+       0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2aac, 0x001e,
+       0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, 0x4cdc,
+       0x1110, 0x080c, 0x493a, 0x8108, 0x1f04, 0x59d6, 0x015e, 0x2011,
+       0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c,
+       0x79e1, 0x080c, 0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64,
+       0x003e, 0x60e3, 0x0000, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c,
+       0x569a, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e,
+       0x0005, 0x2071, 0xade1, 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, 0xade1, 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, 0xade1, 0x7004, 0x0043, 0x700c, 0x0002, 0x5a5b, 0x5a52,
+       0x5a52, 0x5a52, 0x5a52, 0x0005, 0x5ab1, 0x5ab2, 0x5ae4, 0x5ae5,
+       0x5aaf, 0x5b33, 0x5b38, 0x5b69, 0x5b6a, 0x5b85, 0x5b86, 0x5b87,
+       0x5b88, 0x5b89, 0x5b8a, 0x5c40, 0x5c67, 0x700c, 0x0002, 0x5a74,
+       0x5aaf, 0x5aaf, 0x5ab0, 0x5ab0, 0x7830, 0x7930, 0xa106, 0x0120,
+       0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8, 0x1210,
+       0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x15c0, 0x01b0,
+       0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000,
+       0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc085,
+       0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x163c, 0x0005, 0x080c,
+       0x15c0, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x15c0, 0x1108, 0x0c10,
+       0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8, 0x0005,
+       0x0005, 0x0005, 0x700c, 0x0002, 0x5ab9, 0x5abc, 0x5aca, 0x5ae3,
+       0x5ae3, 0x080c, 0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058,
+       0x0006, 0x080c, 0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d,
+       0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058,
+       0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834,
+       0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, 0x00db, 0x012e, 0x0005,
+       0x012e, 0x080c, 0x5b8b, 0x0005, 0x0005, 0x0005, 0x00e6, 0x2071,
+       0xade1, 0x700c, 0x0002, 0x5af0, 0x5af0, 0x5af0, 0x5af2, 0x5af5,
+       0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002, 0x00ee,
+       0x0005, 0x5b8b, 0x5b8b, 0x5ba7, 0x5b8b, 0x5d22, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x5d64, 0x5da7, 0x5df0, 0x5e04,
+       0x5b8b, 0x5b8b, 0x5bc3, 0x5ba7, 0x5b8b, 0x5b8b, 0x5c1d, 0x5ead,
+       0x5ec8, 0x5b8b, 0x5bc3, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5c13,
+       0x5ec8, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5bd7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5bec, 0x7020, 0x2068, 0x080c, 0x15f0, 0x0005,
+       0x700c, 0x0002, 0x5b3f, 0x5b42, 0x5b50, 0x5b68, 0x5b68, 0x080c,
+       0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c,
+       0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d, 0x00de, 0x0048,
+       0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058, 0x2068, 0x7084,
+       0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+       0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e, 0x0419,
+       0x0005, 0x0005, 0x0005, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5ba7,
+       0x5b8b, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5ba7, 0x5ba7,
+       0x5ba7, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5b8b,
+       0x5ba7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x0005, 0x0005, 0x0005,
+       0x0005, 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff,
+       0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e,
+       0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007,
+       0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838,
+       0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c,
+       0x510c, 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0988,
+       0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x5cd0, 0x7007, 0x0006,
+       0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5cd0, 0x0005, 0x6834,
+       0x8007, 0xa084, 0x00ff, 0x0904, 0x5b99, 0x8001, 0x1120, 0x7007,
+       0x0001, 0x0804, 0x5ced, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+       0x701a, 0x704b, 0x5ced, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff,
+       0xa086, 0x0001, 0x1904, 0x5b99, 0x7007, 0x0001, 0x2009, 0xad30,
+       0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853,
+       0x0000, 0x080c, 0x4ab1, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x6837, 0x0139, 0x684a, 0x6952, 0x080c, 0x510c, 0x012e, 0x0ca0,
+       0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, 0x00c0, 0xa086, 0x00c0,
+       0x1120, 0x7007, 0x0001, 0x0804, 0x5ee0, 0x2d00, 0x7016, 0x701a,
+       0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, 0xae0c, 0x53a3,
+       0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, 0x5bb5, 0x6a84, 0xa28a,
+       0x0002, 0x1a04, 0x5bb5, 0x82ff, 0x1138, 0x6888, 0x698c, 0xa105,
+       0x0118, 0x2001, 0x5ca3, 0x0018, 0xa280, 0x5c99, 0x2005, 0x70c6,
+       0x7010, 0xa015, 0x0904, 0x5c85, 0x080c, 0x15c0, 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, 0x1624, 0x7090,
+       0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118, 0x7007, 0x0010,
+       0x0005, 0x7020, 0x2068, 0x080c, 0x15f0, 0x7014, 0x2068, 0x0804,
+       0x5bb5, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08,
+       0x2068, 0x6906, 0x711a, 0x0804, 0x5c40, 0x7014, 0x2068, 0x7007,
+       0x0001, 0x6884, 0xa005, 0x1128, 0x6888, 0x698c, 0xa105, 0x0108,
+       0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0904, 0x5ee0,
+       0x04b8, 0x5c9b, 0x5c9f, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a,
+       0x000f, 0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x00f6,
+       0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, 0x6e8c, 0x6804, 0x2060,
+       0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816,
+       0x7008, 0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a,
+       0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0c78, 0x6004,
+       0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+       0x2009, 0xad30, 0x210c, 0x81ff, 0x1198, 0x6838, 0xa084, 0x00ff,
+       0x683a, 0x080c, 0x4993, 0x1108, 0x0005, 0x080c, 0x51df, 0x0126,
+       0x2091, 0x8000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x012e, 0x0ca0,
+       0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0xad30, 0x210c,
+       0x81ff, 0x11b0, 0x6858, 0xa005, 0x01b0, 0x6838, 0xa084, 0x00ff,
+       0x683a, 0x6853, 0x0000, 0x080c, 0x4a55, 0x1108, 0x0005, 0x0126,
+       0x2091, 0x8000, 0x080c, 0x51df, 0x080c, 0x510c, 0x012e, 0x0cb0,
+       0x2001, 0x0028, 0x0ca0, 0x2001, 0x0000, 0x0c88, 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, 0x00ff, 0xa096, 0x0002, 0x0178, 0xa005,
+       0x11f0, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x11b8,
+       0x0066, 0x6e50, 0x080c, 0x4dcf, 0x006e, 0x0088, 0x0046, 0x2011,
+       0xad0c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x4cdc,
+       0x1110, 0x080c, 0x4f2d, 0x8108, 0x1f04, 0x5d4e, 0x00ce, 0x684c,
+       0xd084, 0x1118, 0x080c, 0x15f0, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x510c, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
+       0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0580, 0x2061, 0xb048,
+       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, 0x5f7f, 0x012e, 0x0804,
+       0x5f79, 0x012e, 0x0804, 0x5f73, 0x012e, 0x0804, 0x5f76, 0x0126,
+       0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4,
+       0x05e0, 0x2061, 0xb048, 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, 0x5f7f, 0x012e, 0x0804, 0x5f7c, 0x012e, 0x0804, 0x5f79,
+       0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xb048, 0x6300,
+       0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804,
+       0x5f8d, 0x012e, 0x0804, 0x5f7c, 0x0126, 0x00c6, 0x2091, 0x8000,
+       0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0xb048,
+       0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce, 0x0448, 0x6858, 0xa005,
+       0x05d0, 0x685c, 0xa065, 0x0598, 0x2001, 0xad30, 0x2004, 0xa005,
+       0x0118, 0x080c, 0x974e, 0x0068, 0x6013, 0x0400, 0x6057, 0x0000,
+       0x694c, 0xd1a4, 0x0110, 0x6950, 0x6156, 0x2009, 0x0041, 0x080c,
+       0x80a7, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x1140, 0x0026,
+       0x2009, 0x0000, 0x2011, 0xfdff, 0x080c, 0x663f, 0x002e, 0x684c,
+       0xd0c4, 0x0148, 0x2061, 0xb048, 0x6000, 0xd08c, 0x1120, 0x6008,
+       0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x0804, 0x5f7f, 0x00ce,
+       0x012e, 0x0804, 0x5f79, 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186,
+       0x002d, 0x0d28, 0xa186, 0x0045, 0x0510, 0xa186, 0x002a, 0x1130,
+       0x2001, 0xad0c, 0x200c, 0xc194, 0x2102, 0x08c8, 0xa186, 0x0020,
+       0x0170, 0xa186, 0x0029, 0x1d18, 0x6944, 0xa18c, 0xff00, 0x810f,
+       0x080c, 0x4cdc, 0x1960, 0x6000, 0xc0e4, 0x6002, 0x0840, 0x685c,
+       0xa065, 0x09a8, 0x2001, 0xafa3, 0x2004, 0x6016, 0x0800, 0x685c,
+       0xa065, 0x0968, 0x00e6, 0x6860, 0xa075, 0x2001, 0xad30, 0x2004,
+       0xa005, 0x0150, 0x080c, 0x974e, 0x8eff, 0x0118, 0x2e60, 0x080c,
+       0x974e, 0x00ee, 0x0804, 0x5e3f, 0x6020, 0xc0dc, 0xc0d5, 0x6022,
+       0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b,
+       0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x00ee, 0x0804, 0x5e3f, 0x2061, 0xb048, 0x6000,
+       0xd084, 0x0190, 0xd08c, 0x1904, 0x5f8d, 0x0126, 0x2091, 0x8000,
+       0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x5f8d, 0x012e,
+       0x6853, 0x0016, 0x0804, 0x5f86, 0x6853, 0x0007, 0x0804, 0x5f86,
+       0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5b99, 0x0078,
+       0x2030, 0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007,
+       0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5ee0, 0x0005,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x2009, 0xad30, 0x210c, 0x81ff,
+       0x1904, 0x5f5b, 0x2009, 0xad0c, 0x210c, 0xd194, 0x1904, 0x5f63,
+       0x6848, 0x2070, 0xae82, 0xb400, 0x0a04, 0x5f4f, 0x2001, 0xad16,
+       0x2004, 0xae02, 0x1a04, 0x5f4f, 0x2061, 0xb048, 0x6100, 0xa184,
+       0x0301, 0xa086, 0x0001, 0x15a8, 0x711c, 0xa186, 0x0006, 0x15b0,
+       0x7018, 0xa005, 0x0904, 0x5f5b, 0x2004, 0xd0e4, 0x1904, 0x5f5e,
+       0x7020, 0xd0dc, 0x1904, 0x5f66, 0x6853, 0x0000, 0x6803, 0x0000,
+       0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, 0xd0f4, 0x1904,
+       0x5f69, 0x2e60, 0x080c, 0x65aa, 0x012e, 0x00ee, 0x0005, 0x2068,
+       0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x15c8,
+       0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006, 0x0804,
+       0x5f86, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8, 0x6944, 0xa18c,
+       0xff00, 0x810f, 0x080c, 0x4cdc, 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, 0x0418, 0x6853, 0x002a, 0x0cd0, 0x6853, 0x0045,
+       0x0cb8, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x080c, 0xa566,
+       0x012e, 0x00ee, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004,
+       0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009,
+       0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x080c, 0x15f0, 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, 0x65a1, 0x00de, 0x0005, 0x00d6, 0x2011,
+       0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1,
+       0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118,
+       0xa086, 0x1000, 0x1540, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00,
+       0x8217, 0xa084, 0xf000, 0xa086, 0x3000, 0x1118, 0x080c, 0x61c6,
+       0x00b0, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84,
+       0x0007, 0x1188, 0xac82, 0xb400, 0x0270, 0x6858, 0xac02, 0x1258,
+       0x6120, 0xd1f4, 0x1160, 0x2009, 0x0047, 0x080c, 0x80a7, 0x7a1c,
+       0xd284, 0x1968, 0x0005, 0xa016, 0x080c, 0x1824, 0x0cc0, 0x0cd8,
+       0x781c, 0xd08c, 0x0500, 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000,
+       0x3d20, 0x3e28, 0xa584, 0x0076, 0x1530, 0xa484, 0x7000, 0xa086,
+       0x1000, 0x11a8, 0x080c, 0x604e, 0x01f0, 0x20e1, 0x3000, 0x7828,
+       0x7828, 0x080c, 0x606a, 0x014e, 0x013e, 0x015e, 0x2009, 0xafcf,
+       0x2104, 0xa005, 0x1108, 0x0005, 0x080c, 0x6c50, 0x0ce0, 0xa484,
+       0x7000, 0x1518, 0x0499, 0x01b8, 0x7000, 0xa084, 0xff00, 0xa086,
+       0x8100, 0x0d18, 0x0080, 0xd5a4, 0x0158, 0x080c, 0x1d86, 0x20e1,
+       0x9010, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0048,
+       0x00e9, 0x6883, 0x0000, 0x080c, 0xac59, 0x20e1, 0x3000, 0x7828,
+       0x7828, 0x014e, 0x013e, 0x015e, 0x08b0, 0x0081, 0x1130, 0x7000,
+       0xa084, 0xff00, 0xa086, 0x8100, 0x1d70, 0x080c, 0xac59, 0x20e1,
+       0x3000, 0x7828, 0x7828, 0x080c, 0x642d, 0x0c58, 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, 0x62cf, 0x0005, 0xa196, 0x2000,
+       0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x41d1, 0x0ca8,
+       0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x6372, 0x0c68,
+       0x00c6, 0x6a80, 0x82ff, 0x0904, 0x61c0, 0x7110, 0xa18c, 0xff00,
+       0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x61c0,
+       0xa08e, 0x0023, 0x1570, 0x080c, 0x6408, 0x0904, 0x61c0, 0x7124,
+       0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904,
+       0x61c0, 0x2009, 0x0015, 0x080c, 0x80a7, 0x0804, 0x61c0, 0xa08e,
+       0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c,
+       0x80a7, 0x0804, 0x61c0, 0xa08e, 0x0100, 0x1904, 0x61c0, 0x7034,
+       0xa005, 0x1904, 0x61c0, 0x2009, 0x0016, 0x080c, 0x80a7, 0x0804,
+       0x61c0, 0xa08e, 0x0022, 0x1904, 0x61c0, 0x7030, 0xa08e, 0x0300,
+       0x1580, 0x68d0, 0xd0a4, 0x0528, 0xc0b5, 0x68d2, 0x7100, 0xa18c,
+       0x00ff, 0x696e, 0x7004, 0x6872, 0x00f6, 0x2079, 0x0100, 0x79e6,
+       0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26a0,
+       0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2676, 0x694e,
+       0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0xad00, 0x70a2,
+       0x00ee, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0017, 0x0804,
+       0x6193, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, 0x1904, 0x61c0,
+       0x68d0, 0xc0a5, 0x68d2, 0x2009, 0x0030, 0x0804, 0x6193, 0xa08e,
+       0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0018,
+       0x0804, 0x6193, 0xa08e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804,
+       0x6193, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x6193,
+       0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009,
+       0x001b, 0x0804, 0x6193, 0xa08e, 0x5000, 0x1140, 0x7034, 0xa005,
+       0x1904, 0x61c0, 0x2009, 0x001c, 0x0804, 0x6193, 0xa08e, 0x1300,
+       0x1120, 0x2009, 0x0034, 0x0804, 0x6193, 0xa08e, 0x1200, 0x1140,
+       0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0024, 0x0804, 0x6193,
+       0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d, 0x04d8,
+       0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a, 0x0498,
+       0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, 0xa08e, 0x5300,
+       0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, 0xb28d, 0x8208,
+       0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015,
+       0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3c5c, 0x004e, 0x8108,
+       0x1f04, 0x6176, 0x2009, 0x0023, 0x0070, 0xa08e, 0x6000, 0x1118,
+       0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, 0x2009, 0x0045,
+       0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xb283, 0x2204, 0x8211,
+       0x220c, 0x080c, 0x2676, 0x1530, 0x080c, 0x4c80, 0x1518, 0x6612,
+       0x6516, 0x86ff, 0x0180, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158,
+       0x686c, 0xa606, 0x1140, 0x6870, 0xa506, 0xa084, 0xff00, 0x1118,
+       0x6000, 0xc0f5, 0x6002, 0x00c6, 0x080c, 0x8022, 0x0168, 0x001e,
+       0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x80a7,
+       0x00ce, 0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046,
+       0x080c, 0x6221, 0x1904, 0x621e, 0xa184, 0xff00, 0x8007, 0xa086,
+       0x0008, 0x1904, 0x621e, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x6408,
+       0x0904, 0x621e, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140,
+       0x7034, 0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x80a7, 0x04b0,
+       0xa08e, 0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016,
+       0x080c, 0x80a7, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e,
+       0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xb283, 0x2204,
+       0x8211, 0x220c, 0x080c, 0x2676, 0x11c0, 0x080c, 0x4c80, 0x11a8,
+       0x6612, 0x6516, 0x00c6, 0x080c, 0x8022, 0x0170, 0x001e, 0x611a,
+       0x080c, 0x9956, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c,
+       0x80a7, 0x080c, 0x6c50, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
+       0x0005, 0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156,
+       0x3c00, 0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1df2,
+       0x1590, 0x080c, 0x1ce2, 0x05c8, 0x04d9, 0x1130, 0x7908, 0xa18c,
+       0x1fff, 0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000,
+       0x2ea0, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a,
+       0x2004, 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0401,
+       0x1120, 0xa08a, 0x0140, 0x1a0c, 0x14f6, 0x80ac, 0x20e1, 0x6000,
+       0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803,
+       0x0004, 0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e,
+       0x001e, 0x002e, 0x00de, 0x00fe, 0x0005, 0xa085, 0x0001, 0x0c98,
+       0x0006, 0x2001, 0x0111, 0x2004, 0xa084, 0x0003, 0x000e, 0x0005,
+       0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696, 0x00ff, 0x1198,
+       0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x62ca, 0xa596,
+       0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, 0xa596, 0xfffc, 0x1118,
+       0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, 0x2019, 0xad34, 0x231c,
+       0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34,
+       0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0xaeb5, 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, 0x62a7, 0x82ff, 0x1118, 0xa085, 0x0001, 0x0018,
+       0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, 0x004e, 0x0005, 0xa084,
+       0x0007, 0x000a, 0x0005, 0x62db, 0x62db, 0x62db, 0x641a, 0x62db,
+       0x62dc, 0x62f1, 0x635d, 0x0005, 0x7110, 0xd1bc, 0x0188, 0x7120,
+       0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, 0xb400, 0x0248, 0x6858,
+       0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0x80a7,
+       0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x6344, 0x2011, 0xb283,
+       0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1904, 0x6344, 0x080c,
+       0x4c80, 0x1904, 0x6344, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15e0,
+       0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c,
+       0x574f, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0,
+       0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0530,
+       0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x2009,
+       0x0044, 0x080c, 0x80a7, 0x00c0, 0x00c6, 0x080c, 0x8022, 0x001e,
+       0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
+       0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x080c, 0x6c50, 0x00ce, 0x0005, 0x00c6, 0x080c,
+       0x9807, 0x001e, 0x0dc8, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
+       0x7130, 0x6152, 0x6013, 0x0300, 0x6003, 0x0001, 0x6007, 0x0041,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c38, 0x7110, 0xd1bc, 0x0188,
+       0x7020, 0x2060, 0xac84, 0x0007, 0x1160, 0xac82, 0xb400, 0x0248,
+       0x6858, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c,
+       0x80a7, 0x0005, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000,
+       0x1130, 0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b, 0x0005,
+       0x6386, 0x6387, 0x6386, 0x6386, 0x63f0, 0x63fc, 0x0005, 0x7110,
+       0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x63ef, 0x700c, 0x7108,
+       0x080c, 0x2676, 0x1904, 0x63ef, 0x080c, 0x4c80, 0x1904, 0x63ef,
+       0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c, 0x00ff,
+       0xa186, 0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6, 0x080c,
+       0x6408, 0x00ce, 0x0904, 0x63ef, 0x00c6, 0x080c, 0x8022, 0x001e,
+       0x05f0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0002, 0x7120, 0x610a,
+       0x2009, 0x0088, 0x080c, 0x80a7, 0x0490, 0xa28c, 0x00ff, 0xa186,
+       0x0006, 0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00, 0x8217,
+       0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6, 0x080c,
+       0x8022, 0x001e, 0x01e0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0005,
+       0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x80a7, 0x0080, 0x00c6,
+       0x080c, 0x8022, 0x001e, 0x0158, 0x611a, 0x080c, 0x9956, 0x601f,
+       0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x80a7, 0x0005,
+       0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a, 0x2009,
+       0x0089, 0x080c, 0x80a7, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x0041,
+       0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x80a7, 0x0005,
+       0x7020, 0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xb400, 0x0240,
+       0x2001, 0xad16, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, 0x0005,
+       0xa006, 0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060, 0xac84,
+       0x0007, 0x1150, 0xac82, 0xb400, 0x0238, 0x6858, 0xac02, 0x1220,
+       0x2009, 0x0051, 0x080c, 0x80a7, 0x0005, 0x2031, 0x0105, 0x0069,
+       0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029,
+       0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6, 0x00f6,
+       0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c, 0x8022,
+       0x0598, 0x0066, 0x00c6, 0x0046, 0x2011, 0xb283, 0x2204, 0x8211,
+       0x220c, 0x080c, 0x2676, 0x1580, 0x080c, 0x4c80, 0x1568, 0x6612,
+       0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0x9956, 0x080c,
+       0x15d9, 0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837, 0x0000,
+       0x6c3a, 0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3,
+       0x006e, 0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x080c, 0x6c50, 0x00fe, 0x00de, 0x00ce, 0x0005,
+       0x080c, 0x8078, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x2071,
+       0xafda, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+       0x7017, 0xb400, 0x7007, 0x0000, 0x7026, 0x702b, 0x7841, 0x7032,
+       0x7037, 0x789d, 0x703b, 0xffff, 0x703f, 0xffff, 0x7042, 0x7047,
+       0x41b3, 0x0005, 0x2071, 0xafda, 0x1d04, 0x64fc, 0x2091, 0x6000,
+       0x700c, 0x8001, 0x700e, 0x1180, 0x700f, 0x0361, 0x7007, 0x0001,
+       0x0126, 0x2091, 0x8000, 0x7040, 0xa00d, 0x0148, 0x8109, 0x7142,
+       0x1130, 0x7044, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
+       0xa00d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
+       0x8109, 0x7126, 0xa186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
+       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, 0x6522, 0x6523,
+       0x653b, 0x00e6, 0x2071, 0xafda, 0x7018, 0xa005, 0x1120, 0x711a,
+       0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
+       0xafda, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee,
+       0x0005, 0x00e6, 0x2071, 0xafda, 0x6088, 0xa102, 0x0208, 0x618a,
+       0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x4cdc, 0x1158, 0x6088,
+       0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c,
+       0x6c50, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007,
+       0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000,
+       0x603c, 0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c, 0x9846,
+       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, 0x9350, 0x012e, 0xac88, 0x0018, 0x7116, 0x2001,
+       0xe400, 0xa102, 0x0220, 0x7017, 0xb400, 0x7007, 0x0000, 0x0005,
+       0x00e6, 0x2071, 0xafda, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
+       0x0005, 0x2001, 0xafe3, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
+       0xafda, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0xafe6,
+       0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0xafda, 0x711a, 0x721e,
+       0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0xb048, 0x00ce,
+       0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0xb048,
+       0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999,
+       0xa005, 0x1150, 0x00c6, 0x2061, 0xb048, 0x6014, 0x00ce, 0xa005,
+       0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006,
+       0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0,
+       0xa18e, 0x00c0, 0x05b0, 0xd0b4, 0x1138, 0xd0bc, 0x1528, 0x2009,
+       0x0006, 0x080c, 0x661a, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+       0x0118, 0xa086, 0x0003, 0x15c0, 0x6020, 0xd0d4, 0x0130, 0xc0d4,
+       0x6022, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xad73, 0x2104,
+       0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x80a7, 0x0005, 0x2009,
+       0x0043, 0x080c, 0x80a7, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+       0x0118, 0xa086, 0x0003, 0x11c0, 0x2009, 0x0042, 0x080c, 0x80a7,
+       0x0005, 0xd0fc, 0x0150, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0138,
+       0x2009, 0x0041, 0x080c, 0x80a7, 0x0005, 0x0051, 0x0ce8, 0x2009,
+       0x0043, 0x080c, 0x80a7, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005,
+       0x2009, 0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068,
+       0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c,
+       0x8100, 0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb048, 0x6200,
+       0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c,
+       0x510c, 0x6010, 0xa06d, 0x190c, 0x65aa, 0x00de, 0x0005, 0x0156,
+       0x00c6, 0x2061, 0xb048, 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, 0x665c, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
+       0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
+       0x1220, 0x1f04, 0x666c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
+       0x666c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
+       0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091,
+       0x2800, 0x2079, 0xafc7, 0x012e, 0x00d6, 0x2069, 0xafc7, 0x6803,
+       0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de,
+       0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, 0x0002,
+       0x66aa, 0x66cb, 0x671e, 0x66b0, 0x66cb, 0x66aa, 0x66a8, 0x66a8,
+       0x080c, 0x14f6, 0x080c, 0x6581, 0x080c, 0x6c50, 0x00ce, 0x0005,
+       0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x481b, 0x080c,
+       0x650d, 0x7828, 0xa092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c,
+       0x4855, 0x0c88, 0x080c, 0x481b, 0x7807, 0x0003, 0x7827, 0x0000,
+       0x782b, 0x0000, 0x0c40, 0x080c, 0x6581, 0x3c00, 0x0006, 0x2011,
+       0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178,
+       0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c,
+       0x14f6, 0x2009, 0x0013, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x3900,
+       0xa082, 0xb0e8, 0x1210, 0x080c, 0x7d8d, 0x00c6, 0x7824, 0xa065,
+       0x090c, 0x14f6, 0x7804, 0xa086, 0x0004, 0x0904, 0x675e, 0x7828,
+       0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce, 0x080c, 0x7827,
+       0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6, 0x2071, 0xad00,
+       0x70dc, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100,
+       0x2071, 0xad00, 0x080c, 0x485e, 0x00ee, 0x00ce, 0x080c, 0xaca2,
+       0x2009, 0x0014, 0x080c, 0x80a7, 0x00ce, 0x0838, 0x2001, 0xafe3,
+       0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
+       0xa065, 0x090c, 0x14f6, 0x2009, 0x0013, 0x080c, 0x80fb, 0x00ce,
+       0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0xb0e8, 0x1210, 0x080c,
+       0x7d8d, 0x7824, 0xa005, 0x090c, 0x14f6, 0x781c, 0xa06d, 0x090c,
+       0x14f6, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x080c, 0x8078,
+       0x693c, 0x81ff, 0x090c, 0x14f6, 0x8109, 0x693e, 0x6854, 0xa015,
+       0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827,
+       0x0000, 0x00de, 0x00ce, 0x080c, 0x6c50, 0x0888, 0x6104, 0xa186,
+       0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804, 0x66f7, 0x7808,
+       0xac06, 0x0904, 0x66f7, 0x080c, 0x6b73, 0x080c, 0x67ee, 0x00ce,
+       0x080c, 0x6c50, 0x0804, 0x66e5, 0x00c6, 0x6027, 0x0002, 0x62c8,
+       0x60c4, 0xa205, 0x1178, 0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009,
+       0x0049, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x2011, 0xafe6, 0x2013,
+       0x0000, 0x0cc8, 0x3908, 0xa192, 0xb0e8, 0x1210, 0x080c, 0x7d8d,
+       0x793c, 0x81ff, 0x0d90, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e,
+       0x0006, 0x1138, 0x6014, 0xa084, 0x0184, 0xa085, 0x0012, 0x6016,
+       0x0c10, 0x6014, 0xa084, 0x0184, 0xa085, 0x0016, 0x6016, 0x08d8,
+       0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
+       0x2c08, 0x2061, 0xafc7, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+       0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e,
+       0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0xafc7,
+       0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001,
+       0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x6c56,
+       0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000,
+       0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0xafc7, 0x0c18,
+       0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016,
+       0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
+       0xafc7, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080,
+       0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005,
+       0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061,
+       0xafc7, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136,
+       0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6,
+       0x00c6, 0x0076, 0x0066, 0x0026, 0x0016, 0x0006, 0x0126, 0x2071,
+       0xafc7, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904,
+       0x6889, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6884,
+       0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6884, 0x703c, 0xac06,
+       0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 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, 0x9596, 0x0198, 0x6010, 0x2068, 0x601c, 0xa086,
+       0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+       0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c, 0x9742, 0x080c,
+       0x974e, 0x00ce, 0x0804, 0x682e, 0x2c78, 0x600c, 0x2060, 0x0804,
+       0x682e, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, 0x007e, 0x00ce,
+       0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19d0,
+       0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x0006, 0x0066, 0x00c6,
+       0x00d6, 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079,
+       0xafc7, 0x7838, 0xa065, 0x0558, 0x600c, 0x0006, 0x600f, 0x0000,
+       0x783c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64,
+       0x7833, 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000,
+       0x003e, 0x080c, 0x9596, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086,
+       0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+       0x510c, 0x080c, 0x9742, 0x080c, 0x974e, 0x000e, 0x0898, 0x7e3a,
+       0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005,
+       0x601c, 0xa086, 0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c60, 0x0016,
+       0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x69a9, 0x008e,
+       0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0xafc7, 0x2091,
+       0x8000, 0x080c, 0x6a36, 0x080c, 0x6aa8, 0x012e, 0x00fe, 0x0005,
+       0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
+       0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x8cff,
+       0x0904, 0x6985, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904,
+       0x6980, 0x88ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6980, 0x7024,
+       0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c,
+       0x6581, 0x080c, 0x7834, 0x68c3, 0x0000, 0x080c, 0x7ca8, 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,
+       0x04b8, 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, 0x9596, 0x0188,
+       0x601c, 0xa086, 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847,
+       0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c,
+       0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804, 0x690f,
+       0x2c78, 0x600c, 0x2060, 0x0804, 0x690f, 0x012e, 0x000e, 0x001e,
+       0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+       0x0006, 0x1128, 0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x601c,
+       0xa086, 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x0968, 0x08c8,
+       0x601c, 0xa086, 0x0005, 0x19a8, 0x6004, 0xa086, 0x0085, 0x0d50,
+       0x0880, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0xae34,
+       0x2004, 0xa065, 0x0904, 0x6a32, 0x00f6, 0x00e6, 0x00d6, 0x0066,
+       0x2071, 0xafc7, 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, 0x4c07, 0x0904, 0x6a2e, 0x7624, 0x86ff, 0x05e8,
+       0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834, 0x68c3,
+       0x0000, 0x080c, 0x7ca8, 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, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
+       0x0009, 0x630a, 0x00ce, 0x0804, 0x69d9, 0x8dff, 0x0158, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa,
+       0x080c, 0x510c, 0x080c, 0x7b88, 0x0804, 0x69d9, 0x006e, 0x00de,
+       0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066,
+       0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x6a88,
+       0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069,
+       0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x6581, 0x080c, 0x7834,
+       0x68c3, 0x0000, 0x080c, 0x7ca8, 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, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8,
+       0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+       0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x000e, 0x0804, 0x6a3d,
+       0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c,
+       0xa086, 0x0006, 0x1118, 0x080c, 0xa91f, 0x0c58, 0x601c, 0xa086,
+       0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x09d0, 0x0c10, 0x601c,
+       0xa086, 0x0005, 0x19f0, 0x6004, 0xa086, 0x0085, 0x0d60, 0x08c8,
+       0x0006, 0x0066, 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6b0e,
+       0x6054, 0x0006, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4,
+       0xc0dc, 0x6002, 0x080c, 0x4c07, 0x0904, 0x6b0b, 0x7e24, 0x86ff,
+       0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069,
+       0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834,
+       0x68c3, 0x0000, 0x080c, 0x7ca8, 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, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660,
+       0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6aba, 0x8dff, 0x0138,
+       0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+       0x7b88, 0x0804, 0x6aba, 0x000e, 0x0804, 0x6aad, 0x781e, 0x781a,
+       0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066,
+       0x6000, 0xd0dc, 0x0188, 0x604c, 0xa06d, 0x0170, 0x6848, 0xa606,
+       0x1158, 0x2071, 0xafc7, 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, 0x7834, 0x78c3,
+       0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140,
+       0x7b04, 0xa384, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000,
+       0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
+       0x7ca8, 0x003e, 0x080c, 0x4c07, 0x00c6, 0x603c, 0xa005, 0x0110,
+       0x8001, 0x603e, 0x2660, 0x080c, 0x8078, 0x00ce, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x080c,
+       0x7b88, 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071, 0xafc7, 0x7004,
+       0xa084, 0x0007, 0x0002, 0x6b85, 0x6b88, 0x6b9e, 0x6bb7, 0x6bf0,
+       0x6b85, 0x6b83, 0x6b83, 0x080c, 0x14f6, 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, 0x4c07, 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, 0x7b88, 0x600c,
+       0xa015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0428, 0x720e, 0x720a,
+       0x0410, 0x7014, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c, 0xa015,
+       0x0120, 0x7216, 0x600f, 0x0000, 0x00b0, 0x7216, 0x7212, 0x0098,
+       0x6018, 0x2060, 0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x080c,
+       0x7b88, 0x701c, 0xa065, 0x0138, 0x6054, 0xa015, 0x0110, 0x721e,
+       0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
+       0x7024, 0xa065, 0x0140, 0x080c, 0x7b88, 0x600c, 0xa015, 0x0150,
+       0x720e, 0x600f, 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x00ce,
+       0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0xafc7,
+       0x6830, 0xa084, 0x0003, 0x0002, 0x6c12, 0x6c14, 0x6c38, 0x6c10,
+       0x080c, 0x14f6, 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086, 0x0001,
+       0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, 0xa015, 0x0170, 0x6a3a,
+       0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0xafe6,
+       0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90,
+       0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, 0x6003, 0x0003, 0x0c50,
+       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, 0xafc7, 0x6804, 0xa084, 0x0007, 0x0002, 0x6c61,
+       0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cff, 0x6c5f, 0x6c5f, 0x080c,
+       0x14f6, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c,
+       0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
+       0x6d49, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, 0x6807,
+       0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x6d49, 0x00ce, 0x00de,
+       0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x6cf9,
+       0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075,
+       0x0120, 0xa20e, 0x0904, 0x6cf9, 0x0028, 0x6818, 0xa20e, 0x0904,
+       0x6cf9, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70,
+       0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, 0x804f,
+       0x0904, 0x6cf9, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180,
+       0x0014, 0x2004, 0xa084, 0x00ff, 0x605a, 0xa180, 0x0014, 0x2003,
+       0x0000, 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001,
+       0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6,
+       0x2c78, 0x71a0, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd1bc,
+       0x0150, 0x7100, 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040,
+       0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c, 0x00ff,
+       0x2061, 0x0100, 0x619a, 0x080c, 0x736f, 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, 0x6d49, 0x00ce, 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069,
+       0xafc7, 0x6830, 0xa086, 0x0000, 0x11c0, 0x2001, 0xad0c, 0x200c,
+       0xd1bc, 0x1550, 0x6838, 0xa07d, 0x0180, 0x6833, 0x0001, 0x683e,
+       0x6847, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+       0x1ee6, 0x1130, 0x012e, 0x080c, 0x76a5, 0x00de, 0x00fe, 0x0005,
+       0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015,
+       0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
+       0x0c60, 0x683a, 0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x080c, 0x57d1,
+       0x0888, 0x601c, 0xa084, 0x000f, 0x000b, 0x0005, 0x6d57, 0x6d5c,
+       0x7210, 0x732c, 0x6d5c, 0x7210, 0x732c, 0x6d57, 0x6d5c, 0x080c,
+       0x6b73, 0x080c, 0x6c50, 0x0005, 0x0156, 0x0136, 0x0146, 0x00c6,
+       0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x6118, 0x2178,
+       0x79a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150,
+       0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009,
+       0x0000, 0x0028, 0xa1f8, 0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78,
+       0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x1a04, 0x6dd0, 0x0033,
+       0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x6e7c, 0x6ec7,
+       0x6ef4, 0x6fc1, 0x6fef, 0x6ff7, 0x701d, 0x702e, 0x703f, 0x7047,
+       0x705d, 0x7047, 0x70b7, 0x702e, 0x70d8, 0x70e0, 0x703f, 0x70e0,
+       0x70f1, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce,
+       0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x790d, 0x7932, 0x7947, 0x796a,
+       0x798b, 0x701d, 0x6dce, 0x701d, 0x7047, 0x6dce, 0x6ef4, 0x6fc1,
+       0x6dce, 0x7daa, 0x7047, 0x6dce, 0x7dca, 0x7047, 0x6dce, 0x703f,
+       0x6e75, 0x6de0, 0x6dce, 0x7def, 0x7e64, 0x7f3b, 0x6dce, 0x7f4c,
+       0x7018, 0x7f68, 0x6dce, 0x79a0, 0x7fc3, 0x6dce, 0x080c, 0x14f6,
+       0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005,
+       0x6dde, 0x6dde, 0x6dde, 0x6e14, 0x6e32, 0x6e48, 0x080c, 0x14f6,
+       0x00d6, 0x20a1, 0x020b, 0x080c, 0x710e, 0x7810, 0x2068, 0x20a3,
+       0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850,
+       0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0018, 0x080c, 0x7821, 0x00de, 0x0005, 0x00d6, 0x7818, 0x2068,
+       0x68a0, 0x2069, 0xad00, 0x6ad0, 0xd2ac, 0x1110, 0xd0bc, 0x0110,
+       0xa085, 0x0001, 0x00de, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c,
+       0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f,
+       0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2,
+       0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x080c, 0x7821,
+       0x00de, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x20a3, 0x7800, 0x20a3, 0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3,
+       0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+       0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200,
+       0x20a3, 0x0000, 0x20a3, 0xdf10, 0x20a3, 0x0034, 0x2099, 0xad05,
+       0x20a9, 0x0004, 0x53a6, 0x2099, 0xad01, 0x20a9, 0x0004, 0x53a6,
+       0x2099, 0xafad, 0x20a9, 0x001a, 0x3304, 0x8007, 0x20a2, 0x9398,
+       0x1f04, 0x6e64, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c,
+       0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x2001, 0xad14, 0x2004,
+       0x609a, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0xad51, 0x6804,
+       0xd084, 0x0150, 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, 0x268a,
+       0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+       0x2099, 0xad01, 0x53a6, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1138,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001,
+       0xad1b, 0x20a6, 0x2001, 0xad1c, 0x20a6, 0x0040, 0x20a3, 0x0000,
+       0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001,
+       0xad34, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004,
+       0xa082, 0x007f, 0x0238, 0x2001, 0xad1b, 0x20a6, 0x2001, 0xad1c,
+       0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xad14, 0x2004, 0xa084,
+       0x00ff, 0x20a2, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x60c3,
+       0x0010, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x00c6, 0x7818, 0x2060, 0x2001, 0x0000, 0x080c, 0x5037, 0x00ce,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3,
+       0x0400, 0x620c, 0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3,
+       0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1904,
+       0x6f83, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x01c8, 0x2099, 0xaf8d,
+       0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000,
+       0x20a2, 0x9398, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001,
+       0x2710, 0x20a2, 0x9398, 0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099,
+       0xaf8d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0x080c, 0x574f,
+       0x1118, 0xa084, 0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398,
+       0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+       0x2099, 0xad01, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04,
+       0x6f5d, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6f63, 0x2099,
+       0xaf95, 0x3304, 0xc0dd, 0x20a2, 0x2001, 0xad71, 0x2004, 0xd0e4,
+       0x0158, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398,
+       0x33a6, 0x20a9, 0x0004, 0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000,
+       0x1f04, 0x6f7e, 0x0468, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x0140,
+       0x2001, 0xaf8e, 0x2004, 0x60e3, 0x0000, 0x080c, 0x26cb, 0x60e2,
+       0x2099, 0xaf8d, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099,
+       0xad05, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xad01, 0x53a6, 0x20a9,
+       0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fa1, 0x20a9, 0x0008, 0x20a3,
+       0x0000, 0x1f04, 0x6fa7, 0x2099, 0xaf95, 0x20a9, 0x0008, 0x53a6,
+       0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fb2, 0x20a9, 0x000a,
+       0x20a3, 0x0000, 0x1f04, 0x6fb8, 0x60c3, 0x0074, 0x080c, 0x7821,
+       0x0005, 0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x2010, 0x20a3,
+       0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51, 0x7904, 0x00fe,
+       0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010,
+       0xa085, 0x0002, 0x00d6, 0x0804, 0x7099, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x710e, 0x20a3, 0x5000, 0x0804, 0x6f0f, 0x20a1,
+       0x020b, 0x080c, 0x710e, 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, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x080c, 0x71a2, 0x0020, 0x20a1, 0x020b, 0x080c,
+       0x71aa, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b,
+       0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003,
+       0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6f0f, 0x20a1,
+       0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828,
+       0xa005, 0x0110, 0x20a2, 0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2,
+       0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x00d6, 0x20a1, 0x020b,
+       0x080c, 0x71aa, 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, 0xad51,
+       0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110,
+       0xa085, 0x0010, 0x2009, 0xad73, 0x210c, 0xd184, 0x1110, 0xa085,
+       0x0002, 0x0026, 0x2009, 0xad71, 0x210c, 0xd1e4, 0x0130, 0xc0c5,
+       0xa094, 0x0030, 0xa296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094,
+       0x0030, 0xa296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2,
+       0x20a2, 0x60c3, 0x0014, 0x080c, 0x7821, 0x00de, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x71aa, 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, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6e82,
+       0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821,
+       0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c,
+       0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+       0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x0026, 0x0036,
+       0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0038, 0x0026, 0x0036,
+       0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x11a0,
+       0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011,
+       0xad14, 0x2214, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x0118, 0x2011,
+       0xad1c, 0x2214, 0x22a2, 0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6,
+       0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0xad34,
+       0x2004, 0xd0ac, 0x1110, 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6,
+       0x1130, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8,
+       0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069,
+       0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8,
+       0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de,
+       0x20a3, 0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0029,
+       0x20a2, 0x004e, 0x003e, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+       0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x002e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000,
+       0x20a3, 0x02ff, 0x2011, 0xfffc, 0x22a2, 0x00d6, 0x2069, 0xad1b,
+       0x2da6, 0x8d68, 0x2da6, 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000,
+       0x08e0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3,
+       0x0000, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021,
+       0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021,
+       0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+       0x02d8, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2,
+       0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, 0x1128,
+       0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0xad1b, 0x2da6,
+       0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+       0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+       0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3,
+       0x0000, 0x004e, 0x003e, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000,
+       0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e,
+       0x0005, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+       0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
+       0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a,
+       0x008c, 0x1a0c, 0x14f6, 0x6118, 0x2178, 0x79a0, 0x2011, 0xad34,
+       0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120,
+       0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8,
+       0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a,
+       0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x7247, 0x7251,
+       0x726c, 0x7245, 0x7245, 0x7245, 0x7247, 0x080c, 0x14f6, 0x0146,
+       0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000, 0x080c, 0x7821, 0x014e,
+       0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x72b8, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+       0x080c, 0x7821, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c,
+       0x72f2, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x014e, 0x0005, 0x0026,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+       0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, 0x7175,
+       0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+       0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8400,
+       0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+       0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+       0x8400, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011,
+       0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000,
+       0x0804, 0x7201, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+       0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+       0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6,
+       0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+       0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3,
+       0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2,
+       0x20a3, 0x0000, 0x0804, 0x7201, 0x00c6, 0x00f6, 0x2c78, 0x7804,
+       0xa08a, 0x0040, 0x0a0c, 0x14f6, 0xa08a, 0x0053, 0x1a0c, 0x14f6,
+       0x7918, 0x2160, 0x61a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+       0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff,
+       0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c,
+       0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe,
+       0x00ce, 0x0005, 0x736f, 0x747b, 0x7418, 0x761a, 0x736d, 0x736d,
+       0x736d, 0x736d, 0x736d, 0x736d, 0x736d, 0x7b41, 0x7b51, 0x7b61,
+       0x7b71, 0x736d, 0x7f79, 0x736d, 0x7b30, 0x080c, 0x14f6, 0x00d6,
+       0x0156, 0x0146, 0x780b, 0xffff, 0x20a1, 0x020b, 0x080c, 0x73cf,
+       0x7910, 0x2168, 0x6948, 0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2,
+       0x22a2, 0x694c, 0xa184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040,
+       0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0xa084, 0x0006, 0x8004,
+       0x0016, 0x2008, 0x7858, 0xa084, 0x00ff, 0x8007, 0xa105, 0x001e,
+       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, 0xafe3, 0x2003, 0x07d0, 0x2001, 0xafe2, 0x2003,
+       0x0009, 0x080c, 0x17bf, 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
+       0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004,
+       0x2019, 0xad34, 0x231c, 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+       0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814,
+       0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2,
+       0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2009, 0xad14, 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, 0x7821, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+       0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+       0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814,
+       0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+       0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, 0x2214,
+       0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+       0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x7810,
+       0xa06d, 0x080c, 0x5025, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086,
+       0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c,
+       0x75d0, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+       0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043,
+       0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
+       0x74b2, 0x7547, 0x7550, 0x7579, 0x758c, 0x75a7, 0x75b0, 0x74b0,
+       0x080c, 0x14f6, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118,
+       0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5,
+       0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804,
+       0x7583, 0xa186, 0x0001, 0x190c, 0x14f6, 0x6b78, 0x7820, 0xd0cc,
+       0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+       0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+       0x0300, 0x0904, 0x7541, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc,
+       0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020,
+       0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x74f0, 0x015e, 0x22a2,
+       0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7541, 0x20a1, 0x020b,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889,
+       0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7810, 0x22a2, 0x20a3,
+       0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7821, 0x0005, 0x2011,
+       0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0488,
+       0x2011, 0x0302, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016,
+       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, 0x7821,
+       0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2,
+       0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
+       0x0018, 0x080c, 0x7821, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc,
+       0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+       0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2,
+       0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7821, 0x0005, 0x2011,
+       0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888,
+       0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001,
+       0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808,
+       0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108,
+       0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7583,
+       0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010,
+       0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7810, 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, 0x7634, 0x7634, 0x7636, 0x7634,
+       0x7634, 0x7634, 0x7658, 0x7634, 0x080c, 0x14f6, 0x7910, 0xa18c,
+       0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+       0x00f9, 0x00d6, 0x2069, 0xad51, 0x6804, 0xd0bc, 0x0130, 0x682c,
+       0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de,
+       0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80,
+       0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c,
+       0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+       0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xad00, 0x7150,
+       0x7818, 0x2068, 0x68a0, 0x2028, 0x76d0, 0xd6ac, 0x1130, 0xd0bc,
+       0x1120, 0x6910, 0x6a14, 0x7450, 0x0020, 0x6910, 0x6a14, 0x736c,
+       0x7470, 0x781c, 0xa0be, 0x0006, 0x0904, 0x775b, 0xa0be, 0x000a,
+       0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
+       0x2029, 0x6077, 0x0000, 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,
+       0x609f, 0x0000, 0x080c, 0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084,
+       0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x6586, 0x003e,
+       0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d0, 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,
+       0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110,
+       0x2009, 0x1b58, 0x080c, 0x6586, 0x003e, 0x004e, 0x005e, 0x00ce,
+       0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003,
+       0xa086, 0x0002, 0x0904, 0x77b1, 0x2001, 0xad34, 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, 0x7834, 0x607e, 0x2f00, 0x6086,
+       0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6,
+       0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928,
+       0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+       0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
+       0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8011, 0x0804,
+       0x7749, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138,
+       0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185,
+       0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5025,
+       0x0180, 0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020,
+       0xa086, 0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889,
+       0x0010, 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, 0x7820, 0xd0cc, 0x0120,
+       0x080c, 0x8014, 0x0804, 0x7749, 0x080c, 0x8011, 0x0804, 0x7749,
+       0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
+       0x8217, 0x0005, 0x00d6, 0x2069, 0xafc7, 0x6843, 0x0001, 0x00de,
+       0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019,
+       0x080c, 0x6578, 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, 0x2061, 0x0100, 0x2069,
+       0x0140, 0x080c, 0x574f, 0x1178, 0x2001, 0xafe3, 0x2004, 0xa005,
+       0x1598, 0x080c, 0x57d1, 0x1118, 0x080c, 0x6578, 0x0468, 0x00c6,
+       0x2061, 0xafc7, 0x00d8, 0x6904, 0xa194, 0x4000, 0x0550, 0x08a1,
+       0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, 0x2061, 0xafc7, 0x6128,
+       0xa192, 0x00c8, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff,
+       0x0198, 0x080c, 0x6578, 0x080c, 0x782b, 0x0070, 0x6124, 0xa1e5,
+       0x0000, 0x0140, 0x080c, 0xaca2, 0x2009, 0x0014, 0x080c, 0x80a7,
+       0x080c, 0x6581, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce,
+       0x0005, 0x2001, 0xafe3, 0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061,
+       0xafc7, 0x6128, 0xa192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce,
+       0x080c, 0x6578, 0x080c, 0x485e, 0x0c38, 0x00c6, 0x00d6, 0x00e6,
+       0x0016, 0x0026, 0x080c, 0x658e, 0x2071, 0xafc7, 0x713c, 0x81ff,
+       0x0570, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x574f, 0x1188,
+       0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c, 0x2160,
+       0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x080c, 0x57d1,
+       0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803,
+       0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c,
+       0x2160, 0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x002e,
+       0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x00e6, 0x00d6,
+       0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000,
+       0x6018, 0x2068, 0x6ca0, 0x2071, 0xafc7, 0x7018, 0x2068, 0x8dff,
+       0x0198, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010,
+       0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x080c, 0x4e41, 0x0120,
+       0x080c, 0x7b88, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
+       0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b, 0x080c,
+       0x710e, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+       0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xad14, 0x2004,
+       0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+       0x20a2, 0x1f04, 0x7928, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x080c,
+       0x7821, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+       0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x0156,
+       0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x20a3,
+       0x0000, 0x20a9, 0x0006, 0x2011, 0xad40, 0x2019, 0xad41, 0x23a6,
+       0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7957, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x014e,
+       0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b,
+       0x080c, 0x7183, 0x080c, 0x7199, 0x7810, 0xa080, 0x0000, 0x2004,
+       0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+       0xa080, 0x0004, 0x8003, 0x60c2, 0x080c, 0x7821, 0x002e, 0x001e,
+       0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c,
+       0x710e, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+       0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+       0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+       0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7821,
+       0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006,
+       0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x700c, 0x2060, 0x8cff,
+       0x0178, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x600c, 0x0006,
+       0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x7b88, 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, 0xafc7, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7834,
+       0x68c3, 0x0000, 0x080c, 0x6581, 0x2009, 0x0013, 0x080c, 0x80a7,
+       0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804,
+       0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
+       0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x7a02, 0x7804,
+       0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+       0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
+       0x012e, 0x0005, 0x2001, 0xad00, 0x2004, 0xa096, 0x0001, 0x0550,
+       0xa096, 0x0004, 0x0538, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
+       0x481b, 0x080c, 0x650d, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158,
+       0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000,
+       0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010,
+       0x1f04, 0x7a3d, 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, 0xafc7, 0x703c, 0x2060, 0x8cff,
+       0x0904, 0x7ad5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0,
+       0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x658e, 0x080c, 0x20b5,
+       0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404,
+       0xa084, 0x000f, 0xa086, 0x0004, 0x11b0, 0x68c7, 0x0000, 0x68cb,
+       0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, 0x2071, 0xb01e, 0x6814,
+       0xa084, 0x0184, 0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003,
+       0x0000, 0x00fe, 0x00ee, 0x200b, 0x0000, 0x004e, 0xa39d, 0x0000,
+       0x1120, 0x2009, 0x0049, 0x080c, 0x80a7, 0x20a9, 0x03e8, 0x6824,
+       0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0,
+       0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827,
+       0x0002, 0x0010, 0x1f04, 0x7ab7, 0x7804, 0xa084, 0x1000, 0x0120,
+       0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e,
+       0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
+       0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a06, 0x012e, 0x00de,
+       0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a32,
+       0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006,
+       0x0126, 0x2071, 0xafc7, 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,
+       0x974e, 0x080c, 0x7b88, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060,
+       0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+       0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, 0x20a2,
+       0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804,
+       0x7b80, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000,
+       0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000,
+       0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400,
+       0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+       0x0089, 0x60c3, 0x0020, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+       0x00e6, 0x2071, 0xafc7, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022,
+       0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x7b94, 0x20a2,
+       0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
+       0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660,
+       0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x7c24, 0x8cff, 0x0904,
+       0x7c24, 0x601c, 0xa086, 0x0006, 0x1904, 0x7c1f, 0x88ff, 0x0138,
+       0x2800, 0xac06, 0x1904, 0x7c1f, 0x2039, 0x0000, 0x0050, 0x6018,
+       0xa206, 0x1904, 0x7c1f, 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904,
+       0x7c1f, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005,
+       0x01f0, 0x080c, 0x6581, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c,
+       0x7ca8, 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, 0x0460, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616,
+       0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012,
+       0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
+       0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f, 0x0000, 0x6010,
+       0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e,
+       0x080c, 0x7b88, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x7bab, 0x2c78,
+       0x600c, 0x2060, 0x0804, 0x7bab, 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, 0xafc7,
+       0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x7c98, 0x601c, 0xa086,
+       0x0006, 0x1904, 0x7c93, 0x87ff, 0x0128, 0x2700, 0xac06, 0x1904,
+       0x7c93, 0x0040, 0x6018, 0xa206, 0x15f0, 0x85ff, 0x0118, 0x6050,
+       0xa106, 0x15c8, 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001,
+       0x080c, 0x7a64, 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,
+       0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e, 0x87ff, 0x1190,
+       0x00ce, 0x0804, 0x7c43, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7c43,
+       0xa006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+       0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa7bd, 0x0001, 0x0c88,
+       0x00e6, 0x2071, 0xafc7, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002,
+       0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005,
+       0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
+       0x8000, 0x2071, 0xafc7, 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, 0xafc7, 0x760c,
+       0x2660, 0x2678, 0x8cff, 0x0904, 0x7d7e, 0x6018, 0xa080, 0x0028,
+       0x2004, 0xa206, 0x1904, 0x7d79, 0x7024, 0xac06, 0x1508, 0x2069,
+       0x0100, 0x68c0, 0xa005, 0x0904, 0x7d55, 0x080c, 0x7834, 0x68c3,
+       0x0000, 0x080c, 0x7ca8, 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, 0x9778, 0x1158, 0x080c, 0x2aff, 0x080c,
+       0x9789, 0x11f0, 0x080c, 0x85f3, 0x00d8, 0x080c, 0x7ca8, 0x08c0,
+       0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0090, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742,
+       0x080c, 0x994e, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804,
+       0x7d02, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7d02, 0x012e, 0x000e,
+       0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+       0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c18, 0x0036, 0x0156, 0x0136,
+       0x0146, 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x28f9,
+       0x1118, 0x8210, 0x8000, 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020,
+       0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e,
+       0x003e, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+       0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x2099, 0xafa6, 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004,
+       0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x080c, 0x7821,
+       0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0214,
+       0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7821, 0x0005, 0x00d6,
+       0x0016, 0x2f68, 0x2009, 0x0035, 0x080c, 0x9a34, 0x1904, 0x7e5d,
+       0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x1300, 0x20a3, 0x0000,
+       0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0580, 0x7818, 0xa080,
+       0x0028, 0x2014, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x11d0, 0xa286,
+       0x007e, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x04b8, 0xa286,
+       0x007f, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0478, 0xd2bc,
+       0x0180, 0xa286, 0x0080, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffc,
+       0x0428, 0xa2e8, 0xae34, 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2,
+       0x00e8, 0x20a3, 0x0000, 0x6098, 0x20a2, 0x00c0, 0x2001, 0xad34,
+       0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
+       0x007e, 0x0240, 0x00d6, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+       0x00de, 0x0020, 0x20a3, 0x0000, 0x6034, 0x20a2, 0x7834, 0x20a2,
+       0x7838, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+       0x080c, 0x7821, 0x001e, 0x00de, 0x0005, 0x7817, 0x0001, 0x7803,
+       0x0006, 0x001e, 0x00de, 0x0005, 0x00d6, 0x0026, 0x7928, 0x2168,
+       0x691c, 0xa186, 0x0006, 0x01c0, 0xa186, 0x0003, 0x0904, 0x7ed3,
+       0xa186, 0x0005, 0x0904, 0x7ebc, 0xa186, 0x0004, 0x05b8, 0xa186,
+       0x0008, 0x0904, 0x7ec4, 0x7807, 0x0037, 0x7813, 0x1700, 0x080c,
+       0x7f3b, 0x002e, 0x00de, 0x0005, 0x080c, 0x7ef7, 0x2009, 0x4000,
+       0x6800, 0x0002, 0x7e9d, 0x7ea8, 0x7e9f, 0x7ea8, 0x7ea4, 0x7e9d,
+       0x7e9d, 0x7ea8, 0x7ea8, 0x7ea8, 0x7ea8, 0x7e9d, 0x7e9d, 0x7e9d,
+       0x7e9d, 0x7e9d, 0x7ea8, 0x7e9d, 0x7ea8, 0x080c, 0x14f6, 0x6820,
+       0xd0e4, 0x0110, 0xd0cc, 0x0110, 0xa00e, 0x0010, 0x2009, 0x2000,
+       0x6828, 0x20a2, 0x682c, 0x20a2, 0x0804, 0x7eed, 0x080c, 0x7ef7,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x6a00, 0xa286,
+       0x0002, 0x1108, 0xa00e, 0x0488, 0x04d1, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x2009, 0x4000, 0x0448, 0x0491, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x2009, 0x4000, 0xa286, 0x0005, 0x0118, 0xa286, 0x0002,
+       0x1108, 0xa00e, 0x00d0, 0x0419, 0x6810, 0x2068, 0x697c, 0x6810,
+       0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, 0x22a2, 0x7928, 0xa180,
+       0x0000, 0x2004, 0xa08e, 0x0002, 0x0130, 0xa08e, 0x0004, 0x0118,
+       0x2009, 0x4000, 0x0010, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000,
+       0x60c3, 0x0018, 0x080c, 0x7821, 0x002e, 0x00de, 0x0005, 0x0036,
+       0x0046, 0x0056, 0x0066, 0x20a1, 0x020b, 0x080c, 0x71aa, 0xa006,
+       0x20a3, 0x0200, 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818,
+       0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+       0xa092, 0x007e, 0x0268, 0x00d6, 0x2069, 0xad1b, 0x2d2c, 0x8d68,
+       0x2d34, 0xa0e8, 0xae34, 0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0030,
+       0x2019, 0x0000, 0x6498, 0x2029, 0x0000, 0x6634, 0x7828, 0xa080,
+       0x0007, 0x2004, 0xa086, 0x0003, 0x1128, 0x25a2, 0x26a2, 0x23a2,
+       0x24a2, 0x0020, 0x23a2, 0x24a2, 0x25a2, 0x26a2, 0x006e, 0x005e,
+       0x004e, 0x003e, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+       0x0100, 0x20a3, 0x0000, 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3,
+       0x0008, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7106,
+       0x20a3, 0x1400, 0x20a3, 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2,
+       0x7828, 0x20a2, 0x782c, 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007,
+       0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0010, 0x080c, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x080c, 0x71a2, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x7828, 0x20a2, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821,
+       0x0005, 0x0146, 0x20a1, 0x020b, 0x0031, 0x60c3, 0x0000, 0x080c,
+       0x7821, 0x014e, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+       0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+       0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68,
+       0x2da6, 0x00de, 0x0078, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+       0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+       0x6234, 0x22a2, 0x20a3, 0x0819, 0x20a3, 0x0000, 0x080c, 0x7810,
+       0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x7a08, 0x22a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2,
+       0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575,
+       0x080c, 0x782b, 0x080c, 0x6578, 0x0005, 0x0156, 0x0136, 0x0036,
+       0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7854, 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, 0xb400, 0x2a70, 0x7064, 0x7046, 0x704b,
+       0xb400, 0x0005, 0x00e6, 0x0126, 0x2071, 0xad00, 0x2091, 0x8000,
+       0x7544, 0xa582, 0x0010, 0x0608, 0x7048, 0x2060, 0x6000, 0xa086,
+       0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0,
+       0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8,
+       0x0018, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, 0x0001, 0x012e,
+       0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6,
+       0x2071, 0xad00, 0x7544, 0xa582, 0x0010, 0x0600, 0x7048, 0x2060,
+       0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02,
+       0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529,
+       0x7546, 0xaca8, 0x0018, 0x7058, 0xa502, 0x1228, 0x754a, 0xa085,
+       0x0001, 0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc8, 0xa006, 0x0cc8,
+       0xac82, 0xb400, 0x0a0c, 0x14f6, 0x2001, 0xad16, 0x2004, 0xac02,
+       0x1a0c, 0x14f6, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016,
+       0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6052, 0x6056, 0x6022,
+       0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x2061,
+       0xad00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, 0x0005,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0cc0, 0x601c,
+       0xa084, 0x000f, 0x0002, 0x80b6, 0x80c5, 0x80e0, 0x80fb, 0x9a61,
+       0x9a7c, 0x9a97, 0x80b6, 0x80c5, 0x80b6, 0x8116, 0xa186, 0x0013,
+       0x1128, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x0005, 0xa18e, 0x0047,
+       0x1118, 0xa016, 0x080c, 0x1824, 0x0005, 0x0066, 0x6000, 0xa0b2,
+       0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x80de, 0x8478,
+       0x862d, 0x80de, 0x86a2, 0x81cf, 0x80de, 0x80de, 0x840a, 0x8a91,
+       0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x080c, 0x14f6,
+       0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e,
+       0x0005, 0x80f9, 0x909a, 0x80f9, 0x80f9, 0x80f9, 0x80f9, 0x80f9,
+       0x80f9, 0x9045, 0x9200, 0x80f9, 0x90c7, 0x913e, 0x90c7, 0x913e,
+       0x80f9, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
+       0x14f6, 0x0013, 0x006e, 0x0005, 0x8114, 0x8ad2, 0x8b98, 0x8cb8,
+       0x8e12, 0x8114, 0x8114, 0x8114, 0x8aac, 0x8ff5, 0x8ff8, 0x8114,
+       0x8114, 0x8114, 0x8114, 0x9022, 0x080c, 0x14f6, 0x0066, 0x6000,
+       0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x812f,
+       0x812f, 0x812f, 0x8152, 0x81a5, 0x812f, 0x812f, 0x812f, 0x8131,
+       0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x080c,
+       0x14f6, 0xa186, 0x0003, 0x190c, 0x14f6, 0x00d6, 0x6003, 0x0003,
+       0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a, 0x6880,
+       0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x00de, 0x2c10, 0x080c,
+       0x1e6e, 0x080c, 0x680b, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d0d,
+       0x012e, 0x0005, 0xa182, 0x0047, 0x0002, 0x815e, 0x815e, 0x8160,
+       0x817f, 0x815e, 0x815e, 0x815e, 0x815e, 0x8191, 0x080c, 0x14f6,
+       0x00d6, 0x0016, 0x080c, 0x6c05, 0x080c, 0x6d0d, 0x6003, 0x0004,
+       0x6110, 0x2168, 0x6854, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+       0x684f, 0x0020, 0x685c, 0x685a, 0x6874, 0x687e, 0x6878, 0x6882,
+       0x6897, 0x0000, 0x689b, 0x0000, 0x001e, 0x00de, 0x0005, 0x080c,
+       0x6c05, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0120, 0x684b,
+       0x0006, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c, 0x6d0d,
+       0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110, 0x2168,
+       0x080c, 0x9596, 0x0120, 0x684b, 0x0029, 0x080c, 0x510c, 0x00de,
+       0x080c, 0x8078, 0x080c, 0x6d0d, 0x0005, 0xa182, 0x0047, 0x0002,
+       0x81b3, 0x81c2, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1,
+       0x81b1, 0x080c, 0x14f6, 0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4,
+       0x684e, 0x00de, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c,
+       0x1824, 0x0005, 0x00d6, 0x6110, 0x2168, 0x684b, 0x0000, 0x6853,
+       0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x0005, 0xa1b6,
+       0x0015, 0x1118, 0x080c, 0x8078, 0x0030, 0xa1b6, 0x0016, 0x190c,
+       0x14f6, 0x080c, 0x8078, 0x0005, 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, 0x81ea, 0x00e6, 0x080c,
+       0x9596, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
+       0x00ee, 0x080c, 0x8078, 0x0005, 0x00d6, 0x0036, 0x7330, 0xa386,
+       0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd,
+       0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103,
+       0x6b32, 0x080c, 0x8078, 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, 0x8078, 0x001e, 0x0005, 0x0016, 0x2009,
+       0x0000, 0x7030, 0xa086, 0x0100, 0x0140, 0x7038, 0xa084, 0x00ff,
+       0x808e, 0x703c, 0xa084, 0x00ff, 0x8086, 0xa080, 0x0004, 0xa108,
+       0x21a8, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0,
+       0x080c, 0x48be, 0x00e6, 0x080c, 0x9596, 0x0140, 0x6010, 0x2070,
+       0x7007, 0x0000, 0x7034, 0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c,
+       0x8078, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68,
+       0x0016, 0x2009, 0x0035, 0x080c, 0x9a34, 0x001e, 0x1168, 0x0026,
+       0x6228, 0x2268, 0x002e, 0x2071, 0xb28c, 0x6b1c, 0xa386, 0x0003,
+       0x0130, 0xa386, 0x0006, 0x0128, 0x080c, 0x8078, 0x0020, 0x0031,
+       0x0010, 0x080c, 0x8323, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810,
+       0x2078, 0xa186, 0x0015, 0x0904, 0x830c, 0xa18e, 0x0016, 0x1904,
+       0x8321, 0x700c, 0xa084, 0xff00, 0xa086, 0x1700, 0x1904, 0x82eb,
+       0x8fff, 0x0904, 0x831f, 0x6808, 0xa086, 0xffff, 0x1904, 0x830e,
+       0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810,
+       0xa106, 0x1904, 0x830e, 0x7980, 0x7814, 0xa106, 0x1904, 0x830e,
+       0x080c, 0x9742, 0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4,
+       0x784e, 0x0026, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6665,
+       0x7854, 0xa20a, 0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138,
+       0x00c6, 0x2d60, 0x080c, 0x9374, 0x00ce, 0x0804, 0x831f, 0x00c6,
+       0x00d6, 0x2f68, 0x6838, 0xd0fc, 0x1118, 0x080c, 0x4993, 0x0010,
+       0x080c, 0x4b7c, 0x00de, 0x00ce, 0x1548, 0x00c6, 0x2d60, 0x080c,
+       0x8078, 0x00ce, 0x04a0, 0x7008, 0xa086, 0x000b, 0x11a0, 0x6018,
+       0x200c, 0xc1bc, 0x2102, 0x00c6, 0x2d60, 0x7853, 0x0003, 0x6007,
+       0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8, 0x080c,
+       0x6c50, 0x00ce, 0x00e0, 0x700c, 0xa086, 0x2a00, 0x1138, 0x2001,
+       0xafa5, 0x2004, 0x683e, 0x0098, 0x0471, 0x0098, 0x8fff, 0x090c,
+       0x14f6, 0x00c6, 0x00d6, 0x2d60, 0x2f68, 0x684b, 0x0003, 0x080c,
+       0x926f, 0x080c, 0x9742, 0x080c, 0x974e, 0x00de, 0x00ce, 0x080c,
+       0x8078, 0x00fe, 0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xafa5,
+       0x2004, 0x683e, 0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00,
+       0x2060, 0x080c, 0xabb4, 0x080c, 0x6618, 0x080c, 0x8078, 0x00ce,
+       0x080c, 0x8078, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80,
+       0x7b7c, 0xd2f4, 0x0130, 0x2001, 0xafa5, 0x2004, 0x683e, 0x0804,
+       0x839d, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x6804, 0xa086,
+       0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+       0x0050, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x04f0, 0x6800,
+       0xa086, 0x000f, 0x01c8, 0x8fff, 0x090c, 0x14f6, 0x6820, 0xd0dc,
+       0x1198, 0x6800, 0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180,
+       0x784c, 0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852,
+       0x2001, 0x0001, 0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0,
+       0x784c, 0xd0b4, 0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0,
+       0x0c38, 0xd2ec, 0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406,
+       0x0d58, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e,
+       0x080c, 0x9894, 0x080c, 0x6c50, 0x0010, 0x080c, 0x8078, 0x004e,
+       0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068,
+       0x6a1c, 0xa286, 0x0007, 0x0904, 0x83ee, 0xa286, 0x0002, 0x05f0,
+       0xa286, 0x0000, 0x05d8, 0x6808, 0x6338, 0xa306, 0x15b8, 0x2071,
+       0xb28c, 0xa186, 0x0015, 0x0560, 0xa18e, 0x0016, 0x1190, 0x6030,
+       0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c, 0xa086, 0x2a00,
+       0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd, 0xc1f5, 0x2102,
+       0x00b8, 0x00c6, 0x6034, 0x2060, 0x6010, 0x2068, 0x080c, 0x9596,
+       0x090c, 0x14f6, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b,
+       0x601f, 0x0002, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x0030,
+       0x6034, 0x2070, 0x2001, 0xafa5, 0x2004, 0x703e, 0x080c, 0x8078,
+       0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9, 0x000e, 0x2e98,
+       0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1148, 0x6018, 0x2068,
+       0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x00de,
+       0x0804, 0x81f6, 0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b2,
+       0x0040, 0x1a04, 0x846e, 0x0002, 0x8462, 0x8456, 0x8462, 0x8462,
+       0x8462, 0x8462, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8462, 0x8462, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8462,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8462, 0x8454, 0x8454, 0x080c, 0x14f6, 0x6003, 0x0001,
+       0x6106, 0x080c, 0x67ee, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+       0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x67ee, 0x0126,
+       0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x2600, 0x0002,
+       0x8462, 0x8476, 0x8476, 0x8462, 0x8462, 0x8476, 0x080c, 0x14f6,
+       0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x0904,
+       0x8518, 0xa1b6, 0x0027, 0x1904, 0x84de, 0x080c, 0x6b73, 0x6004,
+       0x080c, 0x9778, 0x0188, 0x080c, 0x9789, 0x0904, 0x84d8, 0xa08e,
+       0x0021, 0x0904, 0x84db, 0xa08e, 0x0022, 0x0904, 0x84d8, 0xa08e,
+       0x003d, 0x0904, 0x84db, 0x04a8, 0x080c, 0x2aff, 0x2001, 0x0007,
+       0x080c, 0x4c30, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+       0xa186, 0x007e, 0x1148, 0x2001, 0xad34, 0x2014, 0xc285, 0x080c,
+       0x574f, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110,
+       0x2019, 0x0028, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c,
+       0x681d, 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, 0x4ecf, 0x00ce,
+       0x2c08, 0x080c, 0xa712, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c,
+       0x4c9f, 0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+       0x080c, 0x85f3, 0x0cb0, 0x080c, 0x8621, 0x0c98, 0xa186, 0x0014,
+       0x1db0, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x080c, 0x9778, 0x1188,
+       0x080c, 0x2aff, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+       0xa186, 0x007e, 0x1128, 0x2001, 0xad34, 0x200c, 0xc185, 0x2102,
+       0x08c0, 0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0890, 0x6004,
+       0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+       0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e,
+       0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c, 0x85f3, 0x0804, 0x84d1,
+       0xa0b2, 0x0040, 0x1a04, 0x85db, 0x2008, 0x0002, 0x8560, 0x8561,
+       0x8564, 0x8567, 0x856a, 0x856d, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x8570, 0x857f, 0x855e, 0x8581,
+       0x857f, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x857f, 0x857f,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x85bb, 0x857f, 0x855e, 0x857b, 0x855e, 0x855e, 0x855e, 0x857c,
+       0x855e, 0x855e, 0x855e, 0x857f, 0x85b2, 0x855e, 0x080c, 0x14f6,
+       0x00f0, 0x2001, 0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001,
+       0x0005, 0x0430, 0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400,
+       0x080c, 0x6b73, 0x6003, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e,
+       0x080c, 0x6c50, 0x00a0, 0x0018, 0x0010, 0x080c, 0x4c30, 0x0804,
+       0x85cc, 0x080c, 0x6b73, 0x2001, 0xafa3, 0x2004, 0x6016, 0x2001,
+       0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x080c, 0x6c50, 0x0005,
+       0x080c, 0x4c30, 0x080c, 0x6b73, 0x6003, 0x0002, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x0036, 0x2019, 0xad5c, 0x2304, 0xa084, 0xff00,
+       0x1120, 0x2001, 0xafa3, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004,
+       0x0ec0, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c,
+       0x6c50, 0x08e8, 0x080c, 0x6b73, 0x080c, 0x994e, 0x080c, 0x8078,
+       0x080c, 0x6c50, 0x08a0, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+       0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x080c, 0x6b73, 0x080c,
+       0x8078, 0x080c, 0x6c50, 0x0818, 0x080c, 0x6b73, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x6003, 0x0002, 0x2001, 0xafa3, 0x2004, 0x6016,
+       0x080c, 0x6c50, 0x0005, 0x2600, 0x2008, 0x0002, 0x85e6, 0x85e4,
+       0x85e4, 0x85cc, 0x85cc, 0x85e4, 0x080c, 0x14f6, 0x080c, 0x6b73,
+       0x00d6, 0x6010, 0x2068, 0x080c, 0x15f0, 0x00de, 0x080c, 0x8078,
+       0x080c, 0x6c50, 0x0005, 0x00e6, 0x0026, 0x0016, 0x080c, 0x9596,
+       0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139, 0x1148, 0x2001,
+       0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c, 0x9a05, 0x0090,
+       0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, 0x6004, 0xa08e,
+       0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e, 0x7037, 0x0103,
+       0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, 0x001e, 0x0009,
+       0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037,
+       0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668,
+       0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x14f6,
+       0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0x99c1, 0x0804, 0x8692,
+       0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0x9971, 0x0804, 0x8692,
+       0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x97b9, 0x0804, 0x8692,
+       0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x97d0, 0x04d8, 0x6604,
+       0xa6b6, 0x001f, 0x1118, 0x080c, 0x81dc, 0x04a0, 0x6604, 0xa6b6,
+       0x0000, 0x1118, 0x080c, 0x83f4, 0x0468, 0x6604, 0xa6b6, 0x0022,
+       0x1118, 0x080c, 0x8204, 0x0430, 0x6604, 0xa6b6, 0x0035, 0x1118,
+       0x080c, 0x826b, 0x00f8, 0x6604, 0xa6b6, 0x0039, 0x1118, 0x080c,
+       0x83a3, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x821e,
+       0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c, 0x823e, 0x0050,
+       0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016, 0x1118,
+       0x0804, 0x883f, 0x0005, 0x080c, 0x80be, 0x0ce0, 0x86b9, 0x86bc,
+       0x86b9, 0x86fe, 0x86b9, 0x87cc, 0x884d, 0x86b9, 0x86b9, 0x881b,
+       0x86b9, 0x882f, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005, 0x3d18,
+       0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x00e6, 0xacf0, 0x0004,
+       0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x8078,
+       0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x7080,
+       0xa086, 0x0074, 0x1530, 0x080c, 0xa6e9, 0x11b0, 0x00d6, 0x6018,
+       0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110, 0xc0c5,
+       0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c,
+       0x2aff, 0x080c, 0x8078, 0x0078, 0x2001, 0x000a, 0x080c, 0x4c30,
+       0x080c, 0x2aff, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee,
+       0x0010, 0x080c, 0x87bd, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168,
+       0x2001, 0x0000, 0x080c, 0x4c1e, 0x2069, 0xad51, 0x6804, 0xd0a4,
+       0x0120, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x0005, 0x00d6, 0x2011,
+       0xad20, 0x2204, 0xa086, 0x0074, 0x1904, 0x87ba, 0x6018, 0x2068,
+       0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x894d, 0x0804, 0x875e,
+       0x080c, 0x8943, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286,
+       0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
+       0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200,
+       0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078,
+       0x0804, 0x87bb, 0x00e6, 0x2071, 0xad34, 0x2e04, 0xd09c, 0x0188,
+       0x2071, 0xb280, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284,
+       0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112,
+       0x7216, 0x00ee, 0x6010, 0xa005, 0x0128, 0x2068, 0x6838, 0xd0f4,
+       0x0108, 0x0880, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+       0x6007, 0x0003, 0x080c, 0x67ee, 0x0804, 0x87bb, 0x685c, 0xd0e4,
+       0x01d0, 0x080c, 0x9903, 0x080c, 0x574f, 0x0110, 0xd0dc, 0x1900,
+       0x2011, 0xad34, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xaf8e, 0x2004,
+       0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x26cb, 0x78e2,
+       0x00fe, 0x0804, 0x8728, 0x080c, 0x9937, 0x2011, 0xad34, 0x2204,
+       0xc0a5, 0x2012, 0x0006, 0x080c, 0xa801, 0x000e, 0x1904, 0x8728,
+       0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x00c6, 0x2009,
+       0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe,
+       0x080c, 0x26a0, 0x00f6, 0x2079, 0xad00, 0x7972, 0x2100, 0x2009,
+       0x0000, 0x080c, 0x2676, 0x794e, 0x00fe, 0x8108, 0x080c, 0x4c80,
+       0x2c00, 0x00ce, 0x1904, 0x8728, 0x601a, 0x2001, 0x0002, 0x080c,
+       0x4c30, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+       0x67ee, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0xad00, 0x2004,
+       0xa086, 0x0003, 0x0120, 0x2001, 0x0007, 0x080c, 0x4c30, 0x080c,
+       0x2aff, 0x080c, 0x8078, 0x0005, 0x00e6, 0x0026, 0x0016, 0x2071,
+       0xad00, 0x7080, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086, 0x0003,
+       0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3cce, 0x00d6, 0x6018,
+       0x2068, 0x080c, 0x4d72, 0x080c, 0x86ed, 0x00de, 0x080c, 0x89f7,
+       0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, 0x0518,
+       0x2001, 0x0006, 0x080c, 0x4c30, 0x00e6, 0x6010, 0xa075, 0x01a8,
+       0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001, 0x0000,
+       0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0x9a05, 0x0030, 0x7007,
+       0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2aff,
+       0x080c, 0x8078, 0x0020, 0x080c, 0x85f3, 0x080c, 0x87bd, 0x001e,
+       0x002e, 0x00ee, 0x0005, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+       0x1158, 0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007,
+       0x0001, 0x080c, 0x67ee, 0x0010, 0x080c, 0x87bd, 0x0005, 0x2011,
+       0xad20, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c,
+       0x4c30, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x000b,
+       0x0005, 0x86b9, 0x8854, 0x86b9, 0x888a, 0x86b9, 0x88ff, 0x884d,
+       0x86b9, 0x86b9, 0x8912, 0x86b9, 0x8922, 0x6604, 0xa6b6, 0x001e,
+       0x1110, 0x080c, 0x8078, 0x0005, 0x00d6, 0x00c6, 0x080c, 0x8932,
+       0x1178, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+       0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x00f8,
+       0x2009, 0xb28e, 0x2104, 0xa086, 0x0009, 0x1160, 0x6018, 0x2068,
+       0x6840, 0xa084, 0x00ff, 0xa005, 0x0180, 0x8001, 0x6842, 0x6017,
+       0x000a, 0x0068, 0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086,
+       0x1900, 0x1118, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x00ce,
+       0x00de, 0x0005, 0x080c, 0x8940, 0x00d6, 0x2069, 0xaf9d, 0x2d04,
+       0xa005, 0x0168, 0x6018, 0x2068, 0x68a0, 0xa086, 0x007e, 0x1138,
+       0x2069, 0xad1c, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de,
+       0x0078, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+       0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x0428,
+       0x080c, 0x85f3, 0x2009, 0xb28e, 0x2134, 0xa6b4, 0x00ff, 0xa686,
+       0x0005, 0x01e0, 0xa686, 0x000b, 0x01b0, 0x2009, 0xb28f, 0x2104,
+       0xa084, 0xff00, 0x1118, 0xa686, 0x0009, 0x0180, 0xa086, 0x1900,
+       0x1150, 0xa686, 0x0009, 0x0150, 0x2001, 0x0004, 0x080c, 0x4c30,
+       0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x00d6, 0x6010,
+       0x2068, 0x080c, 0x9596, 0x0128, 0x6838, 0xd0fc, 0x0110, 0x00de,
+       0x0c90, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0140,
+       0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, 0x0c28,
+       0x68a0, 0xa086, 0x007e, 0x1138, 0x00e6, 0x2071, 0xad00, 0x080c,
+       0x48f5, 0x00ee, 0x0010, 0x080c, 0x2ad9, 0x00de, 0x08a0, 0x080c,
+       0x8940, 0x1158, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+       0x6007, 0x0003, 0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c,
+       0x87bd, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c, 0x4c30,
+       0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x67ee, 0x0010, 0x080c,
+       0x87bd, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c, 0x4c30,
+       0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010, 0x080c,
+       0x87bd, 0x0005, 0x2009, 0xb28e, 0x2104, 0xa086, 0x0003, 0x1138,
+       0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x0005,
+       0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006, 0x2164,
+       0x080c, 0x4ceb, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6,
+       0x0036, 0x0016, 0x6018, 0x2068, 0x2071, 0xad34, 0x2e04, 0xa085,
+       0x0003, 0x2072, 0x080c, 0x89cc, 0x0538, 0x2001, 0xad52, 0x2004,
+       0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, 0x080c, 0xa96c,
+       0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
+       0x0001, 0x080c, 0x2aac, 0x2071, 0xad00, 0x080c, 0x28fa, 0x00c6,
+       0x0156, 0x20a9, 0x0081, 0x2009, 0x007f, 0x080c, 0x2bc9, 0x8108,
+       0x1f04, 0x897d, 0x015e, 0x00ce, 0x080c, 0x8943, 0x6813, 0x00ff,
+       0x6817, 0xfffe, 0x2071, 0xb280, 0x2079, 0x0100, 0x2e04, 0xa084,
+       0x00ff, 0x2069, 0xad1b, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
+       0x2069, 0xad1c, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0xa084,
+       0xff00, 0x001e, 0xa105, 0x2009, 0xad27, 0x200a, 0x2200, 0xa084,
+       0x00ff, 0x2008, 0x080c, 0x26a0, 0x080c, 0x574f, 0x0170, 0x2069,
+       0xb28e, 0x2071, 0xaf9f, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+       0x700a, 0x681c, 0x700e, 0x080c, 0x9903, 0x0040, 0x2001, 0x0006,
+       0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078, 0x001e, 0x003e,
+       0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036, 0x00e6, 0x0156,
+       0x2019, 0xad27, 0x231c, 0x83ff, 0x01e8, 0x2071, 0xb280, 0x2e14,
+       0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x1190,
+       0x2011, 0xb296, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c,
+       0x1148, 0x2011, 0xb29a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c,
+       0x8a7c, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x0005, 0x00e6,
+       0x2071, 0xb28c, 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, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400,
+       0x2071, 0xad00, 0x7244, 0x7064, 0xa202, 0x16f0, 0x080c, 0xa990,
+       0x05a0, 0x671c, 0xa786, 0x0001, 0x0580, 0xa786, 0x0007, 0x0568,
+       0x2500, 0xac06, 0x0550, 0x2400, 0xac06, 0x0538, 0x00c6, 0x6000,
+       0xa086, 0x0004, 0x1110, 0x080c, 0x190b, 0xa786, 0x0008, 0x1148,
+       0x080c, 0x9789, 0x1130, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x974e,
+       0x00a0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0160, 0xa786, 0x0003,
+       0x11e8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c,
+       0x080c, 0x9742, 0x080c, 0x974e, 0x00ce, 0xace0, 0x0018, 0x7058,
+       0xac02, 0x1210, 0x0804, 0x8a2a, 0x012e, 0x000e, 0x002e, 0x004e,
+       0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0xa786, 0x0006,
+       0x1d00, 0x080c, 0xa91f, 0x0c30, 0x220c, 0x2304, 0xa106, 0x1130,
+       0x8210, 0x8318, 0x1f04, 0x8a7c, 0xa006, 0x0005, 0x2304, 0xa102,
+       0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0xa18d, 0x0001,
+       0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x080c, 0x9778,
+       0x0120, 0x080c, 0x9789, 0x0168, 0x0028, 0x080c, 0x2aff, 0x080c,
+       0x9789, 0x0138, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50,
+       0x0005, 0x080c, 0x85f3, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x8ac2,
+       0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2,
+       0x8ac2, 0x8ac2, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac2, 0x8ac2,
+       0x8ac2, 0x8ac4, 0x080c, 0x14f6, 0x600b, 0xffff, 0x6003, 0x0001,
+       0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+       0x012e, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0040,
+       0x0804, 0x8b5e, 0xa186, 0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c,
+       0x2ad9, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0168, 0x6837,
+       0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e,
+       0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x080c,
+       0x6c50, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040,
+       0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045, 0x0120, 0xa186,
+       0x0047, 0x190c, 0x14f6, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198,
+       0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+       0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, 0xa086, 0x0002,
+       0x1110, 0x0804, 0x8b98, 0x080c, 0x80be, 0x0005, 0x0002, 0x8b3c,
+       0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a,
+       0x8b3a, 0x8b3a, 0x8b57, 0x8b57, 0x8b57, 0x8b57, 0x8b3a, 0x8b57,
+       0x8b3a, 0x8b57, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x00d6, 0x6110,
+       0x2168, 0x080c, 0x9596, 0x0168, 0x6837, 0x0103, 0x684b, 0x0006,
+       0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c, 0x510c, 0x080c,
+       0x9742, 0x00de, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+       0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x0002, 0x8b74,
+       0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72,
+       0x8b72, 0x8b72, 0x8b86, 0x8b86, 0x8b86, 0x8b86, 0x8b72, 0x8b91,
+       0x8b72, 0x8b86, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c50, 0x6010, 0xa088,
+       0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x6b73,
+       0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x000f, 0x080c, 0x6c50,
+       0x0005, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+       0xa182, 0x0040, 0x0002, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+       0x8bb0, 0x8c88, 0x8ca9, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+       0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x080c, 0x14f6,
+       0x00e6, 0x00d6, 0x603f, 0x0000, 0x2071, 0xb280, 0x7124, 0x610a,
+       0x2071, 0xb28c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff,
+       0x0904, 0x8c54, 0xa68c, 0x0c00, 0x01e8, 0x00f6, 0x2c78, 0x080c,
+       0x5029, 0x00fe, 0x0198, 0x684c, 0xd0ac, 0x0180, 0x6020, 0xd0dc,
+       0x1168, 0x6850, 0xd0bc, 0x1150, 0x7318, 0x6814, 0xa306, 0x1904,
+       0x8c66, 0x731c, 0x6810, 0xa306, 0x1904, 0x8c66, 0x7318, 0x6b62,
+       0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0518, 0xa186,
+       0x0028, 0x1128, 0x080c, 0x9767, 0x684b, 0x001c, 0x00e8, 0xd6dc,
+       0x01a0, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0170, 0x6914, 0x6a10,
+       0x2100, 0xa205, 0x0148, 0x7018, 0xa106, 0x1118, 0x701c, 0xa206,
+       0x0118, 0x6962, 0x6a5e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0x684b,
+       0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e,
+       0xd6c4, 0x01f0, 0xa686, 0x0100, 0x1140, 0x2001, 0xb299, 0x2004,
+       0xa005, 0x1118, 0xc6c4, 0x0804, 0x8bbf, 0x7328, 0x732c, 0x6b56,
+       0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
+       0x2308, 0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e,
+       0xd6cc, 0x0904, 0x8c79, 0x7124, 0x695a, 0x81ff, 0x0904, 0x8c79,
+       0xa192, 0x0021, 0x1250, 0x2071, 0xb298, 0x831c, 0x2300, 0xae18,
+       0xad90, 0x001d, 0x080c, 0x927f, 0x04a0, 0x6838, 0xd0fc, 0x0120,
+       0x2009, 0x0020, 0x695a, 0x0c78, 0x00f6, 0x2d78, 0x080c, 0x9224,
+       0x00fe, 0x080c, 0x926f, 0x0438, 0x00f6, 0x2c78, 0x080c, 0x5029,
+       0x00fe, 0x0188, 0x684c, 0xd0ac, 0x0170, 0x6020, 0xd0dc, 0x1158,
+       0x6850, 0xd0bc, 0x1140, 0x684c, 0xd0f4, 0x1128, 0x080c, 0x9866,
+       0x00de, 0x00ee, 0x00e0, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46,
+       0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c,
+       0x8e04, 0x080c, 0x510c, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
+       0x080c, 0x9834, 0x00de, 0x00ee, 0x1110, 0x080c, 0x8078, 0x0005,
+       0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00, 0x7e0c,
+       0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0120, 0x6003, 0x0002,
+       0x00fe, 0x0005, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x603f,
+       0x0000, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b, 0x080c, 0x6d0d,
+       0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110,
+       0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005,
+       0xa182, 0x0040, 0x0002, 0x8cce, 0x8cce, 0x8cce, 0x8cce, 0x8cce,
+       0x8cd0, 0x8d61, 0x8cce, 0x8cce, 0x8d77, 0x8ddb, 0x8cce, 0x8cce,
+       0x8cce, 0x8cce, 0x8dea, 0x8cce, 0x8cce, 0x8cce, 0x080c, 0x14f6,
+       0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c, 0x6110, 0x2178,
+       0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
+       0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x8d5c, 0xa694,
+       0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e,
+       0xa284, 0x0300, 0x0904, 0x8d5c, 0x080c, 0x15d9, 0x090c, 0x14f6,
+       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, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff,
+       0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
+       0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc,
+       0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250,
+       0x2071, 0xb298, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c,
+       0x927f, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a,
+       0x0c78, 0x2d78, 0x080c, 0x9224, 0x00de, 0x00ee, 0x00fe, 0x007e,
+       0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00,
+       0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
+       0x00fe, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x781a, 0x0005, 0x00d6,
+       0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c05, 0x080c, 0x6d0d,
+       0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x8dd9, 0xd1cc, 0x0540,
+       0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850,
+       0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156,
+       0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x8da1, 0x015e,
+       0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600,
+       0x0418, 0x0016, 0x080c, 0x1600, 0x00de, 0x080c, 0x926f, 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, 0x510c, 0x080c, 0x9834, 0x1110, 0x080c,
+       0x8078, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x7a64, 0x6003,
+       0x0002, 0x2001, 0xafa5, 0x2004, 0x603e, 0x080c, 0x6c05, 0x080c,
+       0x6d0d, 0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110,
+       0x2168, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029,
+       0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+       0x8078, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138,
+       0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+       0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x8e28, 0x8e28, 0x8e28,
+       0x8e28, 0x8e28, 0x8e2a, 0x8e28, 0x8ee3, 0x8eef, 0x8e28, 0x8e28,
+       0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28,
+       0x080c, 0x14f6, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c,
+       0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x00f6, 0x2c78, 0x080c,
+       0x5029, 0x00fe, 0x0150, 0xa684, 0x00ff, 0x1138, 0x6020, 0xd0f4,
+       0x0120, 0x080c, 0x9866, 0x0804, 0x8ede, 0x7e46, 0x7f4c, 0xc7e5,
+       0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904,
+       0x8ed4, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862,
+       0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x8ed2, 0xa686, 0x0100,
+       0x1140, 0x2001, 0xb299, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46,
+       0x0c28, 0x080c, 0x15d9, 0x090c, 0x14f6, 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, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a,
+       0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xb298,
+       0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc, 0x01d8, 0x7124,
+       0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071, 0xb298,
+       0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x927f, 0x0050,
+       0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78,
+       0x080c, 0x9224, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001, 0x0001,
+       0x2071, 0xb28c, 0x7218, 0x731c, 0x080c, 0x186f, 0x00de, 0x00ee,
+       0x00fe, 0x007e, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x20e1,
+       0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x2001,
+       0xafa5, 0x2004, 0x603e, 0x00d6, 0x6003, 0x0002, 0x6110, 0x2168,
+       0x694c, 0xd1e4, 0x0904, 0x8ff3, 0x603f, 0x0000, 0x00f6, 0x2c78,
+       0x080c, 0x5029, 0x00fe, 0x0548, 0x6814, 0x6910, 0xa115, 0x0528,
+       0x6a60, 0xa206, 0x1118, 0x685c, 0xa106, 0x01f8, 0x684c, 0xc0e4,
+       0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000, 0x697c,
+       0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6020,
+       0xc0f5, 0x6022, 0x00d6, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+       0x00de, 0x080c, 0x9866, 0x0804, 0x8ff3, 0x694c, 0xd1cc, 0x0904,
+       0x8fc3, 0x6948, 0x6838, 0xd0fc, 0x0904, 0x8f88, 0x0016, 0x684c,
+       0x0006, 0x6850, 0x0006, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c,
+       0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b,
+       0x0015, 0x080c, 0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080,
+       0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c,
+       0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04,
+       0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d,
+       0xaf98, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, 0x2012,
+       0x8318, 0x8210, 0x1f04, 0x8f76, 0x015e, 0x00fe, 0x000e, 0x6852,
+       0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600, 0x0804, 0x8fee,
+       0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
+       0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c,
+       0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c,
+       0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128,
+       0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130,
+       0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04, 0x6860, 0x7862,
+       0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, 0x080c, 0x1600, 0x00de,
+       0x080c, 0x926f, 0x0458, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x01b0, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c,
+       0x00d8, 0xd1dc, 0x0148, 0x684b, 0x0015, 0x080c, 0x99ee, 0x0118,
+       0x6944, 0xc1dc, 0x6946, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007,
+       0x0058, 0x684b, 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914,
+       0xa115, 0x0110, 0x080c, 0x8e04, 0x080c, 0x510c, 0x080c, 0x9834,
+       0x1110, 0x080c, 0x8078, 0x00de, 0x0005, 0x080c, 0x6b73, 0x0010,
+       0x080c, 0x6c05, 0x080c, 0x9596, 0x01c0, 0x00d6, 0x6110, 0x2168,
+       0x6837, 0x0103, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x11c0, 0xd184,
+       0x1198, 0x6108, 0x694a, 0xa18e, 0x0029, 0x1110, 0x080c, 0xabfa,
+       0x6847, 0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c,
+       0x6c50, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b,
+       0x0004, 0x0c70, 0xa182, 0x0040, 0x0002, 0x9038, 0x9038, 0x9038,
+       0x9038, 0x9038, 0x903a, 0x9038, 0x903d, 0x9038, 0x9038, 0x9038,
+       0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038,
+       0x080c, 0x14f6, 0x080c, 0x8078, 0x0005, 0x0006, 0x0026, 0xa016,
+       0x080c, 0x1824, 0x002e, 0x000e, 0x0005, 0xa182, 0x0085, 0x0002,
+       0x9051, 0x904f, 0x904f, 0x905d, 0x904f, 0x904f, 0x904f, 0x080c,
+       0x14f6, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
+       0x00e6, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0x9586,
+       0x01a0, 0x2268, 0x6800, 0xa086, 0x0000, 0x0178, 0x6018, 0x6d18,
+       0xa52e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x0128,
+       0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003,
+       0x0001, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00f6, 0x2278, 0x080c,
+       0x5029, 0x00fe, 0x0150, 0x6820, 0xd0ec, 0x0138, 0x00c6, 0x2260,
+       0x603f, 0x0000, 0x080c, 0x9866, 0x00ce, 0x00ee, 0x00de, 0x005e,
+       0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085,
+       0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c, 0x14f6, 0xa082, 0x0085,
+       0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x14f6,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x90be,
+       0x90c0, 0x90c0, 0x90be, 0x90be, 0x90be, 0x90be, 0x080c, 0x14f6,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa186,
+       0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04a8, 0xa186,
+       0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x00d6, 0x6010,
+       0x2068, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000,
+       0x684b, 0x0029, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+       0x8078, 0x080c, 0x6c50, 0x0005, 0x080c, 0x80be, 0x0ce0, 0xa186,
+       0x0014, 0x1dd0, 0x080c, 0x6b73, 0x00d6, 0x6010, 0x2068, 0x080c,
+       0x9596, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006,
+       0x6850, 0xc0ec, 0x6852, 0x08f0, 0x0002, 0x910e, 0x910c, 0x910c,
+       0x910c, 0x910c, 0x910c, 0x9126, 0x080c, 0x14f6, 0x080c, 0x6b73,
+       0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+       0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+       0x6016, 0x6003, 0x000c, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73,
+       0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+       0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+       0x6016, 0x6003, 0x000e, 0x080c, 0x6c50, 0x0005, 0xa182, 0x008c,
+       0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x80be, 0x0005,
+       0x914f, 0x914f, 0x914f, 0x914f, 0x9151, 0x91a4, 0x914f, 0x080c,
+       0x14f6, 0x00d6, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0168,
+       0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+       0x0035, 0x1118, 0x00de, 0x0804, 0x91b7, 0x080c, 0x9742, 0x080c,
+       0x9596, 0x01c8, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4,
+       0x0128, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118,
+       0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847,
+       0x0000, 0x080c, 0x510c, 0x2c68, 0x080c, 0x8022, 0x01c0, 0x6003,
+       0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0xb28e, 0x210c,
+       0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x6918, 0x611a, 0x080c,
+       0x9956, 0x6950, 0x6152, 0x601f, 0x0001, 0x080c, 0x67a8, 0x2d60,
+       0x080c, 0x8078, 0x00de, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029,
+       0x00fe, 0x0598, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+       0x0130, 0xa186, 0x001e, 0x0118, 0xa186, 0x0039, 0x1530, 0x00d6,
+       0x2c68, 0x080c, 0x9a34, 0x1904, 0x91fc, 0x080c, 0x8022, 0x01d8,
+       0x6106, 0x6003, 0x0001, 0x601f, 0x0001, 0x6918, 0x611a, 0x6928,
+       0x612a, 0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934,
+       0x6136, 0x6938, 0x613a, 0x6950, 0x6152, 0x080c, 0x9956, 0x080c,
+       0x67a8, 0x080c, 0x6c50, 0x2d60, 0x00f8, 0x00d6, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128,
+       0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b,
+       0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847, 0x0000,
+       0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x0005,
+       0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0140, 0x6837,
+       0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x510c, 0x00de,
+       0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186,
+       0x0027, 0x0118, 0x080c, 0x80be, 0x0030, 0x080c, 0x6b73, 0x080c,
+       0x974e, 0x080c, 0x6c50, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6,
+       0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100,
+       0x2130, 0x2069, 0xb298, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
+       0xaf90, 0x001d, 0x080c, 0x927f, 0xa6b2, 0x0020, 0x7804, 0xa06d,
+       0x0110, 0x080c, 0x1600, 0x080c, 0x15d9, 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,
+       0x510c, 0x2f68, 0x0cb8, 0x080c, 0x510c, 0x00fe, 0x0005, 0x0156,
+       0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007,
+       0x2012, 0x8318, 0x8210, 0x1f04, 0x9286, 0x015e, 0x0005, 0x0066,
+       0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x601c, 0xa084, 0x000f,
+       0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066,
+       0x2031, 0x0000, 0x601c, 0xa084, 0x000f, 0x001b, 0x006e, 0x012e,
+       0x0005, 0x92c3, 0x92c3, 0x92be, 0x92e5, 0x92b1, 0x92be, 0x92e5,
+       0x92be, 0x080c, 0x14f6, 0x0036, 0x2019, 0x0010, 0x080c, 0xa566,
+       0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0xa006, 0x0005,
+       0xa085, 0x0001, 0x0005, 0x00d6, 0x86ff, 0x11d8, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x01c0, 0x6834, 0xa086, 0x0139, 0x1128, 0x684b,
+       0x0005, 0x6853, 0x0000, 0x0028, 0xa00e, 0x2001, 0x0005, 0x080c,
+       0x51df, 0x080c, 0x9803, 0x080c, 0x510c, 0x080c, 0x8078, 0xa085,
+       0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010,
+       0x1a0c, 0x14f6, 0x000b, 0x0005, 0x92fc, 0x9319, 0x92fe, 0x9338,
+       0x9316, 0x92fc, 0x92be, 0x92c3, 0x92c3, 0x92be, 0x92be, 0x92be,
+       0x92be, 0x92be, 0x92be, 0x92be, 0x080c, 0x14f6, 0x86ff, 0x1198,
+       0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x9803,
+       0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c,
+       0x67a8, 0x080c, 0x6c50, 0xa085, 0x0001, 0x0005, 0x080c, 0x190b,
+       0x0c28, 0x00e6, 0x2071, 0xafc7, 0x7024, 0xac06, 0x1110, 0x080c,
+       0x79e1, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, 0x1150, 0x0086,
+       0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x7b9a, 0x009e, 0x008e,
+       0x0010, 0x080c, 0x78de, 0x00ee, 0x1948, 0x080c, 0x92be, 0x0005,
+       0x0036, 0x00e6, 0x2071, 0xafc7, 0x703c, 0xac06, 0x1140, 0x2019,
+       0x0000, 0x080c, 0x7a64, 0x00ee, 0x003e, 0x0804, 0x92fe, 0x080c,
+       0x7cb8, 0x00ee, 0x003e, 0x1904, 0x92fe, 0x080c, 0x92be, 0x0005,
+       0x00c6, 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9369,
+       0x93d3, 0x9501, 0x9374, 0x974e, 0x9369, 0xa558, 0x8078, 0x93d3,
+       0x9362, 0x955f, 0x080c, 0x14f6, 0x080c, 0x9789, 0x1110, 0x080c,
+       0x85f3, 0x0005, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x080c, 0x8078,
+       0x0005, 0x6017, 0x0001, 0x0005, 0x6010, 0xa080, 0x0019, 0x2c02,
+       0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x938f,
+       0x9391, 0x93b1, 0x93c3, 0x93d0, 0x938f, 0x9369, 0x9369, 0x9369,
+       0x93c3, 0x93c3, 0x938f, 0x938f, 0x938f, 0x938f, 0x93cd, 0x080c,
+       0x14f6, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071,
+       0xafc7, 0x7024, 0xac06, 0x0190, 0x080c, 0x78de, 0x6007, 0x0085,
+       0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xafa4, 0x2004, 0x6016,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x6017, 0x0001,
+       0x0cd8, 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de,
+       0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068,
+       0x6850, 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005,
+       0x080c, 0x190b, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6,
+       0x000b, 0x0005, 0x93ea, 0x9371, 0x93ec, 0x93ea, 0x93ec, 0x93ec,
+       0x936a, 0x93ea, 0x9364, 0x9364, 0x93ea, 0x93ea, 0x93ea, 0x93ea,
+       0x93ea, 0x93ea, 0x080c, 0x14f6, 0x00d6, 0x6018, 0x2068, 0x6804,
+       0xa084, 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x14f6, 0x000b,
+       0x0005, 0x9405, 0x94a7, 0x9407, 0x9441, 0x9407, 0x9441, 0x9407,
+       0x9411, 0x9405, 0x9441, 0x9405, 0x942d, 0x080c, 0x14f6, 0x6004,
+       0xa08e, 0x0016, 0x0588, 0xa08e, 0x0004, 0x0570, 0xa08e, 0x0002,
+       0x0558, 0x6004, 0x080c, 0x9789, 0x0904, 0x94c0, 0xa08e, 0x0021,
+       0x0904, 0x94c4, 0xa08e, 0x0022, 0x0904, 0x94c0, 0xa08e, 0x003d,
+       0x0904, 0x94c4, 0xa08e, 0x0039, 0x0904, 0x94c8, 0xa08e, 0x0035,
+       0x0904, 0x94c8, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001, 0x1150,
+       0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa086,
+       0x0006, 0x0110, 0x080c, 0x2ad9, 0x080c, 0x85f3, 0x080c, 0x974e,
+       0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904, 0x9498,
+       0xa186, 0x0002, 0x1518, 0x6018, 0x2068, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x1904, 0x94ea, 0x68a0, 0xd0bc, 0x1904, 0x94ea, 0x6840,
+       0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013, 0x0000,
+       0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c, 0x8022,
+       0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de, 0x00ce,
+       0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028, 0x2004,
+       0xa086, 0x007e, 0x1170, 0x2009, 0xad34, 0x2104, 0xc085, 0x200a,
+       0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x00ee, 0x080c, 0x85f3,
+       0x0020, 0x080c, 0x85f3, 0x080c, 0x2ad9, 0x00e6, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x2aff, 0x012e, 0x00ee, 0x080c, 0x974e, 0x0005,
+       0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002,
+       0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x0c80, 0x00c6,
+       0x00d6, 0x6104, 0xa186, 0x0016, 0x0d58, 0x6018, 0x2068, 0x6840,
+       0xa084, 0x00ff, 0xa005, 0x0904, 0x946e, 0x8001, 0x6842, 0x6003,
+       0x0001, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x08b8,
+       0x080c, 0x85f3, 0x0804, 0x943e, 0x080c, 0x8621, 0x0804, 0x943e,
+       0x00d6, 0x2c68, 0x6104, 0x080c, 0x9a34, 0x00de, 0x0118, 0x080c,
+       0x8078, 0x00b8, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
+       0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038,
+       0x600a, 0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c,
+       0x6c50, 0x0005, 0x00de, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x2ad9,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2aff, 0x6013, 0x0000,
+       0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x012e, 0x00ee,
+       0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005,
+       0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518,
+       0x9518, 0x9369, 0x9518, 0x9371, 0x951a, 0x9371, 0x9527, 0x9518,
+       0x080c, 0x14f6, 0x6004, 0xa086, 0x008b, 0x0148, 0x6007, 0x008b,
+       0x6003, 0x000d, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0005, 0x080c,
+       0x9742, 0x080c, 0x9596, 0x0580, 0x080c, 0x2ad9, 0x00d6, 0x080c,
+       0x9596, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+       0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, 0x510c, 0x2c68,
+       0x080c, 0x8022, 0x0150, 0x6818, 0x601a, 0x080c, 0x9956, 0x00c6,
+       0x2d60, 0x080c, 0x974e, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013,
+       0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+       0x67ee, 0x080c, 0x6c50, 0x0010, 0x080c, 0x974e, 0x0005, 0x6000,
+       0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x9576, 0x9576,
+       0x9576, 0x9578, 0x9579, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576,
+       0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x080c, 0x14f6,
+       0x0005, 0x080c, 0x7cb8, 0x190c, 0x14f6, 0x6110, 0x2168, 0x684b,
+       0x0006, 0x080c, 0x510c, 0x080c, 0x8078, 0x0005, 0xa284, 0x0007,
+       0x1158, 0xa282, 0xb400, 0x0240, 0x2001, 0xad16, 0x2004, 0xa202,
+       0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210,
+       0xa294, 0xf000, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006,
+       0x0126, 0x2091, 0x8000, 0x2061, 0xb400, 0x2071, 0xad00, 0x7344,
+       0x7064, 0xa302, 0x12a8, 0x601c, 0xa206, 0x1160, 0x080c, 0x98e3,
+       0x0148, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x00c6, 0x080c,
+       0x8078, 0x00ce, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0c38,
+       0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
+       0x0016, 0xa188, 0xae34, 0x210c, 0x81ff, 0x0170, 0x2061, 0xb400,
+       0x2071, 0xad00, 0x0016, 0x080c, 0x8022, 0x001e, 0x0138, 0x611a,
+       0x080c, 0x2ad9, 0x080c, 0x8078, 0xa006, 0x0010, 0xa085, 0x0001,
+       0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091,
+       0x8000, 0x00c6, 0x080c, 0x8022, 0x005e, 0x0180, 0x6612, 0x651a,
+       0x080c, 0x9956, 0x601f, 0x0003, 0x2009, 0x004b, 0x080c, 0x80a7,
+       0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0,
+       0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c,
+       0x8022, 0x005e, 0x0508, 0x6013, 0x0000, 0x651a, 0x080c, 0x9956,
+       0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x4ecf, 0x00ce, 0x080c,
+       0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c,
+       0xa712, 0x007e, 0x2009, 0x004c, 0x080c, 0x80a7, 0xa085, 0x0001,
+       0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6,
+       0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0180, 0x7e12,
+       0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x080c, 0x9683,
+       0x2f60, 0x2009, 0x004d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+       0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c,
+       0x8022, 0x2c78, 0x00ce, 0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f,
+       0x0003, 0x2021, 0x0005, 0x0439, 0x2f60, 0x2009, 0x004e, 0x080c,
+       0x80a7, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
+       0x00c6, 0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0178,
+       0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0004, 0x0059,
+       0x2f60, 0x2009, 0x0052, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+       0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x4e71, 0x0118, 0x2001, 0x9688, 0x0028, 0x080c, 0x4e43,
+       0x0158, 0x2001, 0x968e, 0x0006, 0xa00e, 0x2400, 0x080c, 0x51df,
+       0x080c, 0x510c, 0x000e, 0x0807, 0x2418, 0x080c, 0x6b15, 0x62a0,
+       0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x6900,
+       0x008e, 0x080c, 0x681d, 0x2f08, 0x2648, 0x080c, 0xa712, 0x613c,
+       0x81ff, 0x090c, 0x69a9, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
+       0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+       0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+       0x2009, 0x001f, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+       0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+       0x080c, 0x8022, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0x9956,
+       0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x80a7,
+       0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6,
+       0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+       0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+       0x2009, 0x003d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+       0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+       0x080c, 0x9807, 0x001e, 0x0180, 0x611a, 0x080c, 0x9956, 0x601f,
+       0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x80a7, 0xa085,
+       0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
+       0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188, 0x660a,
+       0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
+       0x0044, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
+       0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff,
+       0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6000,
+       0xa086, 0x0000, 0x0190, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001,
+       0xafa3, 0x2004, 0x0006, 0xa082, 0x0051, 0x000e, 0x0208, 0x8004,
+       0x6016, 0x080c, 0xabb4, 0x603f, 0x0000, 0x000e, 0x0005, 0x0066,
+       0x00c6, 0x00d6, 0x2031, 0xad52, 0x2634, 0xd6e4, 0x0128, 0x6618,
+       0x2660, 0x6e48, 0x080c, 0x4dfc, 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, 0x0148, 0x6834, 0xa086,
+       0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110, 0xa006, 0x0010, 0xa085,
+       0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+       0x00c6, 0x080c, 0x8022, 0x001e, 0x0190, 0x611a, 0x080c, 0x9956,
+       0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2ad9, 0x2009, 0x0028,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+       0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0xad20, 0x2204, 0xa086,
+       0x0074, 0x1148, 0x080c, 0x8943, 0x6003, 0x0001, 0x6007, 0x0029,
+       0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x0005,
+       0xa186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x4c30, 0x00e8,
+       0xa186, 0x0015, 0x11e8, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+       0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c, 0x4d72, 0x00de, 0x080c,
+       0x89f7, 0x1170, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005,
+       0x0138, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x81f6, 0x0020,
+       0x080c, 0x85f3, 0x080c, 0x8078, 0x0005, 0x6848, 0xa086, 0x0005,
+       0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, 0x0005, 0x00e6,
+       0x0126, 0x2071, 0xad00, 0x2091, 0x8000, 0x7544, 0xa582, 0x0001,
+       0x0608, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0,
+       0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98,
+       0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0018, 0x7058, 0xa502,
+       0x1230, 0x754a, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704b,
+       0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb28c, 0x7014,
+       0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x00c6, 0x00f6,
+       0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x601c, 0xa084, 0x000f,
+       0x0013, 0x00ce, 0x0005, 0x9369, 0x985e, 0x9861, 0x9864, 0xa9a7,
+       0xa9c2, 0xa9c5, 0x9369, 0x9369, 0x080c, 0x14f6, 0xe000, 0xe000,
+       0x0005, 0xe000, 0xe000, 0x0005, 0x0009, 0x0005, 0x00f6, 0x2c78,
+       0x080c, 0x5029, 0x0538, 0x080c, 0x8022, 0x1128, 0x2001, 0xafa5,
+       0x2004, 0x783e, 0x00f8, 0x7818, 0x601a, 0x080c, 0x9956, 0x781c,
+       0xa086, 0x0003, 0x0128, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0020,
+       0x7808, 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007,
+       0x0035, 0x6003, 0x0001, 0x7950, 0x6152, 0x080c, 0x67a8, 0x080c,
+       0x6c50, 0x2f60, 0x00fe, 0x0005, 0x0016, 0x00f6, 0x682c, 0x6032,
+       0xa08e, 0x0001, 0x0138, 0xa086, 0x0005, 0x0140, 0xa006, 0x602a,
+       0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5, 0x6822, 0x6810, 0x2078,
+       0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x1e78, 0x6834,
+       0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036,
+       0x6808, 0x603a, 0x6918, 0x611a, 0x6950, 0x6152, 0x601f, 0x0001,
+       0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x67a8, 0x6803, 0x0002,
+       0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x1118,
+       0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4, 0x1150, 0xc0f5, 0x6022,
+       0x6010, 0x2078, 0x7828, 0x603a, 0x782c, 0x6036, 0x080c, 0x190b,
+       0xa006, 0x00fe, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0034,
+       0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e, 0x0036, 0x0188, 0xa08e,
+       0x0037, 0x0170, 0xa08e, 0x0038, 0x0158, 0xa08e, 0x0039, 0x0140,
+       0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b, 0x0110, 0xa085, 0x0001,
+       0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6,
+       0x2001, 0xaf9f, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c,
+       0x6665, 0x2001, 0xafa3, 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202,
+       0x2001, 0xafa1, 0x200c, 0x8000, 0x2014, 0x2071, 0xaf8d, 0x711a,
+       0x721e, 0x2001, 0x0064, 0x080c, 0x6665, 0x2001, 0xafa4, 0x82ff,
+       0x1110, 0x2011, 0x0002, 0x2202, 0x2009, 0xafa5, 0xa280, 0x000a,
+       0x200a, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006,
+       0x00e6, 0x2001, 0xafa3, 0x2003, 0x0028, 0x2001, 0xafa4, 0x2003,
+       0x0014, 0x2071, 0xaf8d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+       0xafa5, 0x2003, 0x001e, 0x00ee, 0x000e, 0x0005, 0x00d6, 0x6054,
+       0xa06d, 0x0110, 0x080c, 0x15f0, 0x00de, 0x0005, 0x0005, 0x00c6,
+       0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0178,
+       0x611a, 0x0ca1, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+       0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+       0x1500, 0x7080, 0xa086, 0x0018, 0x11e0, 0x6010, 0x2068, 0x6a3c,
+       0xd2e4, 0x1160, 0x2c78, 0x080c, 0x6e05, 0x01d8, 0x706c, 0x6a50,
+       0xa206, 0x1160, 0x7070, 0x6a54, 0xa206, 0x1140, 0x6218, 0xa290,
+       0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2b1e, 0x080c, 0x81f6,
+       0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+       0x0005, 0x7050, 0x6a54, 0xa206, 0x0d48, 0x0c80, 0x00c6, 0x0126,
+       0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0180, 0x611a,
+       0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0043,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+       0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+       0x11c0, 0x7080, 0xa086, 0x0004, 0x11a0, 0x6010, 0xa0e8, 0x000f,
+       0x2c78, 0x080c, 0x6e05, 0x01a8, 0x706c, 0x6a08, 0xa206, 0x1130,
+       0x7070, 0x6a0c, 0xa206, 0x1110, 0x080c, 0x2ad9, 0x080c, 0x81f6,
+       0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+       0x0005, 0x7050, 0x6a0c, 0xa206, 0x0d78, 0x0c80, 0x0016, 0x0026,
+       0x684c, 0xd0ac, 0x0178, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0150,
+       0x6860, 0xa106, 0x1118, 0x685c, 0xa206, 0x0120, 0x6962, 0x6a5e,
+       0xa085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0036, 0x6310,
+       0x2368, 0x684a, 0x6952, 0xa29e, 0x4000, 0x1188, 0x00c6, 0x6318,
+       0x2360, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108, 0xc185, 0x6000,
+       0xd0bc, 0x0108, 0xc18d, 0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66,
+       0x3918, 0xa398, 0x0006, 0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6,
+       0x6318, 0x2360, 0x6004, 0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c,
+       0x510c, 0x003e, 0x00de, 0x0005, 0x00c6, 0x0026, 0x0016, 0xa186,
+       0x0035, 0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c, 0x9586, 0x01f0,
+       0x2260, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x1190,
+       0x6834, 0xa206, 0x0140, 0x6838, 0xa206, 0x1160, 0x6108, 0x6834,
+       0xa106, 0x1140, 0x0020, 0x6008, 0x6938, 0xa106, 0x1118, 0x6018,
+       0x6918, 0xa106, 0x001e, 0x002e, 0x00ce, 0x0005, 0xa085, 0x0001,
+       0x0cc8, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013,
+       0x006e, 0x0005, 0x9a7a, 0x9eff, 0xa027, 0x9a7a, 0x9a7a, 0x9a7a,
+       0x9a7a, 0x9a7a, 0x9ab2, 0xa0a3, 0x9a7a, 0x9a7a, 0x9a7a, 0x9a7a,
+       0x9a7a, 0x9a7a, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010,
+       0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x9a95, 0xa4fd, 0x9a95,
+       0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0xa4c1, 0xa545, 0x9a95,
+       0xaaea, 0xab1a, 0xaaea, 0xab1a, 0x9a95, 0x080c, 0x14f6, 0x0066,
+       0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005,
+       0x9ab0, 0xa1d8, 0xa295, 0xa2c2, 0xa346, 0x9ab0, 0xa433, 0xa3de,
+       0xa0af, 0xa497, 0xa4ac, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0,
+       0x080c, 0x14f6, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0x2100, 0xa1b2,
+       0x0040, 0x1a04, 0x9e79, 0x0002, 0x9afc, 0x9cab, 0x9afc, 0x9afc,
+       0x9afc, 0x9cb2, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+       0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+       0x9afc, 0x9afc, 0x9afc, 0x9afe, 0x9b5a, 0x9b65, 0x9ba6, 0x9bc0,
+       0x9c3e, 0x9c9c, 0x9afc, 0x9afc, 0x9cb5, 0x9afc, 0x9afc, 0x9cc4,
+       0x9ccb, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9d42, 0x9afc,
+       0x9afc, 0x9d4d, 0x9afc, 0x9afc, 0x9d18, 0x9afc, 0x9afc, 0x9afc,
+       0x9d61, 0x9afc, 0x9afc, 0x9afc, 0x9dd5, 0x9afc, 0x9afc, 0x9afc,
+       0x9afc, 0x9afc, 0x9afc, 0x9e40, 0x080c, 0x14f6, 0x080c, 0x502d,
+       0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+       0x1140, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804,
+       0x9ca6, 0x080c, 0x501d, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
+       0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7,
+       0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712,
+       0x007e, 0x001e, 0x2e60, 0x080c, 0x4ecf, 0x001e, 0x002e, 0x003e,
+       0x00ce, 0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4ceb, 0x00ce,
+       0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278,
+       0x080c, 0xa656, 0x1904, 0x9ba0, 0x080c, 0xa5f6, 0x1120, 0x6007,
+       0x0008, 0x0804, 0x9ca6, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c,
+       0xa801, 0x0128, 0x080c, 0xa656, 0x0d78, 0x0804, 0x9ba0, 0x6013,
+       0x1900, 0x0c88, 0x6106, 0x080c, 0xa5a6, 0x6007, 0x0006, 0x0804,
+       0x9ca6, 0x6007, 0x0007, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+       0x9e76, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+       0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04, 0xa6b4,
+       0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128, 0xa686,
+       0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xa6b4, 0x11a0, 0xa686,
+       0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+       0x0000, 0x080c, 0x2b1e, 0x002e, 0x080c, 0x4d72, 0x6007, 0x000a,
+       0x00de, 0x0804, 0x9ca6, 0x6007, 0x000b, 0x00de, 0x0804, 0x9ca6,
+       0x080c, 0x2ad9, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x080c, 0xab4e,
+       0x1904, 0x9e76, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686,
+       0x0707, 0x0d70, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+       0x0000, 0x080c, 0x2b1e, 0x002e, 0x6007, 0x000c, 0x0804, 0x9ca6,
+       0x080c, 0x502d, 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009,
+       0xa086, 0x0008, 0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618,
+       0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06e8,
+       0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x002e, 0x0050,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006,
+       0x1904, 0x9ba0, 0x080c, 0xa6c1, 0x1120, 0x6007, 0x000e, 0x0804,
+       0x9ca6, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+       0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+       0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+       0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+       0x004e, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x2001, 0x0001, 0x080c,
+       0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
+       0xad05, 0x2011, 0xb290, 0x080c, 0x8a7c, 0x003e, 0x002e, 0x001e,
+       0x015e, 0xa005, 0x0168, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004,
+       0x0a04, 0x9ba0, 0xa682, 0x0007, 0x0a04, 0x9bea, 0x0804, 0x9ba0,
+       0x6013, 0x1900, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c, 0x502d,
+       0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+       0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618, 0xa6b0, 0x0001,
+       0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06b0, 0xa6b4, 0xff00,
+       0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x9ba0,
+       0x080c, 0xa6e9, 0x1130, 0x080c, 0xa5f6, 0x1118, 0x6007, 0x0010,
+       0x04e8, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+       0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+       0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+       0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+       0x004e, 0x6007, 0x0001, 0x00d0, 0x080c, 0xa801, 0x0140, 0xa6b4,
+       0xff00, 0x8637, 0xa686, 0x0006, 0x0958, 0x0804, 0x9ba0, 0x6013,
+       0x1900, 0x6007, 0x0009, 0x0050, 0x080c, 0xab4e, 0x1904, 0x9e76,
+       0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0012, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+       0x67ee, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c, 0xab4e, 0x1904,
+       0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0020, 0x6003,
+       0x0001, 0x080c, 0x67ee, 0x0005, 0x6007, 0x0023, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x0005, 0x080c, 0xab4e, 0x1904, 0x9e76, 0x080c,
+       0x9e98, 0x1904, 0x9ba0, 0x0016, 0x0026, 0x2011, 0xb291, 0x2214,
+       0xa286, 0xffff, 0x0190, 0x2c08, 0x080c, 0x9586, 0x01d8, 0x2260,
+       0x2011, 0xb290, 0x2214, 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190,
+       0x0006, 0x2214, 0xa206, 0x01e0, 0x0068, 0x2011, 0xb290, 0x2214,
+       0x2c08, 0x080c, 0xa940, 0x11a0, 0x2011, 0xb291, 0x2214, 0xa286,
+       0xffff, 0x01a0, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011,
+       0xb289, 0x2214, 0xa296, 0xffff, 0x1160, 0x6007, 0x0025, 0x0048,
+       0x601c, 0xa086, 0x0007, 0x1d70, 0x080c, 0x8078, 0x2160, 0x6007,
+       0x0025, 0x6003, 0x0001, 0x080c, 0x67ee, 0x002e, 0x001e, 0x0005,
+       0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036,
+       0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c, 0x8a7c,
+       0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804,
+       0x9ca6, 0x080c, 0x87bd, 0x080c, 0x574f, 0x1158, 0x0006, 0x0026,
+       0x0036, 0x080c, 0x576b, 0x0110, 0x080c, 0x5726, 0x003e, 0x002e,
+       0x000e, 0x0005, 0x6106, 0x080c, 0x9eb4, 0x6007, 0x002b, 0x0804,
+       0x9ca6, 0x6007, 0x002c, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+       0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6106, 0x080c, 0x9eb8,
+       0x1120, 0x6007, 0x002e, 0x0804, 0x9ca6, 0x6007, 0x002f, 0x0804,
+       0x9ca6, 0x00e6, 0x00d6, 0x00c6, 0x6018, 0xa080, 0x0001, 0x200c,
+       0xa184, 0x00ff, 0xa086, 0x0006, 0x0158, 0xa184, 0xff00, 0x8007,
+       0xa086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0x9cab,
+       0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904, 0x9dd2, 0x2071, 0xb28c,
+       0x7010, 0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xad52,
+       0x2004, 0xd0a4, 0x0140, 0x6018, 0x2068, 0x6810, 0xa106, 0x1118,
+       0x6814, 0xa206, 0x01f8, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1580,
+       0x2069, 0xad00, 0x6870, 0xa206, 0x1558, 0x686c, 0xa106, 0x1540,
+       0x7210, 0x080c, 0x9586, 0x0548, 0x080c, 0xa9d4, 0x0530, 0x622a,
+       0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x67a8, 0x00ce, 0x00de,
+       0x00ee, 0x0005, 0x7214, 0xa286, 0xffff, 0x0150, 0x080c, 0x9586,
+       0x01a0, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x1170, 0x0c08,
+       0x7210, 0x2c08, 0x080c, 0xa940, 0x2c10, 0x2160, 0x0130, 0x08c8,
+       0x6007, 0x0037, 0x6013, 0x1500, 0x08e8, 0x6007, 0x0037, 0x6013,
+       0x1700, 0x08c0, 0x6007, 0x0012, 0x08a8, 0x6018, 0xa080, 0x0001,
+       0x2004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x1904, 0x9cab,
+       0x00e6, 0x00d6, 0x00c6, 0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904,
+       0x9e38, 0x2069, 0xad00, 0x2071, 0xb28c, 0x7008, 0x6036, 0x720c,
+       0x623a, 0xa286, 0xffff, 0x1140, 0x7208, 0x00c6, 0x2c08, 0x080c,
+       0xa940, 0x2c10, 0x00ce, 0x0588, 0x080c, 0x9586, 0x0570, 0x00c6,
+       0x0026, 0x2260, 0x080c, 0x928f, 0x002e, 0x00ce, 0x7118, 0xa18c,
+       0xff00, 0x810f, 0xa186, 0x0001, 0x0158, 0xa186, 0x0005, 0x0118,
+       0xa186, 0x0007, 0x1178, 0xa280, 0x0004, 0x2004, 0xa005, 0x0150,
+       0x0056, 0x7510, 0x7614, 0x080c, 0xa9eb, 0x005e, 0x00ce, 0x00de,
+       0x00ee, 0x0005, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+       0x6003, 0x0001, 0x080c, 0x67a8, 0x0c88, 0x6007, 0x003b, 0x602b,
+       0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x080c, 0x67a8, 0x0c30,
+       0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0804, 0x9daa,
+       0x00e6, 0x0026, 0x080c, 0x502d, 0x0558, 0x080c, 0x501d, 0x080c,
+       0xabc5, 0x1520, 0x2071, 0xad00, 0x70d0, 0xc085, 0x70d2, 0x00f6,
+       0x2079, 0x0100, 0x729c, 0xa284, 0x00ff, 0x706e, 0x78e6, 0xa284,
+       0xff00, 0x7270, 0xa205, 0x7072, 0x78ea, 0x00fe, 0x70db, 0x0000,
+       0x2001, 0xad52, 0x2004, 0xd0a4, 0x0120, 0x2011, 0xafe0, 0x2013,
+       0x07d0, 0xd0ac, 0x1128, 0x080c, 0x28fa, 0x0010, 0x080c, 0xabf1,
+       0x002e, 0x00ee, 0x080c, 0x8078, 0x0804, 0x9caa, 0x080c, 0x8078,
+       0x0005, 0x2600, 0x0002, 0x9e81, 0x9e81, 0x9e81, 0x9e81, 0x9e81,
+       0x9e83, 0x080c, 0x14f6, 0x080c, 0xab4e, 0x1d80, 0x0089, 0x1138,
+       0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005, 0x080c,
+       0x2ad9, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005,
+       0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+       0xa686, 0x0006, 0x0170, 0xa686, 0x0004, 0x0158, 0x6e04, 0xa6b4,
+       0x00ff, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085,
+       0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0449, 0x00de, 0x0005,
+       0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084,
+       0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0118, 0x2009,
+       0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824,
+       0x080c, 0x2676, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x2b1e,
+       0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069,
+       0xb28d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085,
+       0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0xb28c,
+       0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x1140, 0x6800, 0xa084,
+       0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e, 0x0010, 0x0005, 0x6004,
+       0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x1130, 0x2008,
+       0xa1b2, 0x0040, 0x1a04, 0x9ffb, 0x0092, 0xa1b6, 0x0027, 0x0120,
+       0xa1b6, 0x0014, 0x190c, 0x14f6, 0x2001, 0x0007, 0x080c, 0x4c5d,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x9f5f,
+       0x9f61, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f6f, 0x9ff4, 0x9fbf,
+       0x9ff4, 0x9fd0, 0x9ff4, 0x9f6f, 0x9ff4, 0x9fec, 0x9ff4, 0x9fec,
+       0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f,
+       0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f5f, 0x9ff4,
+       0x9f5f, 0x9f5f, 0x9ff4, 0x9f5f, 0x9ff1, 0x9ff4, 0x9f5f, 0x9f5f,
+       0x9f5f, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f,
+       0x9f69, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9ff0, 0x9ff4, 0x9f5f,
+       0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x080c,
+       0x14f6, 0x080c, 0x6b73, 0x6003, 0x0002, 0x080c, 0x6c50, 0x0804,
+       0x9ffa, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x0804, 0x9ff4, 0x00f6,
+       0x2079, 0xad51, 0x7804, 0x00fe, 0xd0ac, 0x1904, 0x9ff4, 0x2001,
+       0x0000, 0x080c, 0x4c1e, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086,
+       0x00ff, 0x1140, 0x00f6, 0x2079, 0xad00, 0x7894, 0x8000, 0x7896,
+       0x00fe, 0x00e0, 0x00c6, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x1140,
+       0x6010, 0xa005, 0x0128, 0x00ce, 0x080c, 0x3cce, 0x0804, 0x9ff4,
+       0x00ce, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002, 0x1138, 0x00f6,
+       0x2079, 0xad00, 0x7894, 0x8000, 0x7896, 0x00fe, 0x2001, 0x0002,
+       0x080c, 0x4c30, 0x080c, 0x6b73, 0x601f, 0x0001, 0x6003, 0x0001,
+       0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00c6, 0x6118,
+       0x2160, 0x2009, 0x0001, 0x080c, 0x6519, 0x00ce, 0x04d8, 0x6618,
+       0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0006, 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410,
+       0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3cce,
+       0x2001, 0x0006, 0x0489, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006,
+       0x0048, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x00e9, 0x0020,
+       0x0018, 0x0010, 0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x8078,
+       0x080c, 0x6c50, 0x0005, 0x2600, 0x0002, 0xa003, 0xa003, 0xa003,
+       0xa003, 0xa003, 0xa005, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x080c,
+       0x8078, 0x080c, 0x6c50, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168,
+       0x6900, 0xd184, 0x0188, 0x6104, 0xa18e, 0x000a, 0x1128, 0x699c,
+       0xd1a4, 0x1110, 0x2001, 0x0007, 0x080c, 0x4c30, 0x2001, 0x0000,
+       0x080c, 0x4c1e, 0x080c, 0x2aff, 0x00de, 0x001e, 0x0005, 0x00d6,
+       0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2,
+       0x000c, 0x1a0c, 0x14f6, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028,
+       0xa1b6, 0x0016, 0x190c, 0x14f6, 0x006b, 0x0005, 0x86b9, 0x86b9,
+       0x86b9, 0x86b9, 0x86b9, 0x86b9, 0xa08f, 0xa056, 0x86b9, 0x86b9,
+       0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9,
+       0xa08f, 0xa096, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x00f6, 0x2079,
+       0xad51, 0x7804, 0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8, 0x7800,
+       0xd0f4, 0x1118, 0x7810, 0xa005, 0x1198, 0x2001, 0x0000, 0x080c,
+       0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x601f, 0x0001, 0x6003,
+       0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00a8,
+       0x2011, 0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1168,
+       0x00c6, 0x080c, 0x4cdc, 0x0120, 0x00ce, 0x080c, 0x8078, 0x0028,
+       0x080c, 0x493a, 0x00ce, 0x080c, 0x8078, 0x00fe, 0x0005, 0x6604,
+       0xa6b6, 0x001e, 0x1110, 0x080c, 0x8078, 0x0005, 0x080c, 0x8940,
+       0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010,
+       0x080c, 0x8078, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa182,
+       0x0040, 0x0002, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c7, 0xa0c5,
+       0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5,
+       0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0x080c, 0x14f6, 0x00d6,
+       0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6218, 0xa280, 0x002b,
+       0x2004, 0xa005, 0x0120, 0x2021, 0x0000, 0x080c, 0xab96, 0x6106,
+       0x2071, 0xb280, 0x7444, 0xa4a4, 0xff00, 0x0904, 0xa129, 0xa486,
+       0x2000, 0x1130, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x663f,
+       0x080c, 0x15d9, 0x090c, 0x14f6, 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, 0x510c, 0x001e, 0xa486, 0x2000, 0x1130, 0x2019, 0x0017,
+       0x080c, 0xa8eb, 0x0804, 0xa186, 0xa486, 0x0400, 0x1130, 0x2019,
+       0x0002, 0x080c, 0xa89d, 0x0804, 0xa186, 0xa486, 0x0200, 0x1110,
+       0x080c, 0xa882, 0xa486, 0x1000, 0x1110, 0x080c, 0xa8d0, 0x0804,
+       0xa186, 0x2069, 0xb048, 0x6a00, 0xd284, 0x0904, 0xa1d5, 0xa284,
+       0x0300, 0x1904, 0xa1cf, 0x6804, 0xa005, 0x0904, 0xa1c0, 0x2d78,
+       0x6003, 0x0007, 0x080c, 0x15c0, 0x0904, 0xa18d, 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, 0x7928,
+       0x698a, 0x792c, 0x698e, 0x7930, 0x6992, 0x7934, 0x6996, 0x6853,
+       0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, 0x684f,
+       0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, 0x0010,
+       0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0xb290, 0xad90, 0x0015,
+       0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0xa178, 0x200c,
+       0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x510c, 0x002e, 0x004e,
+       0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x6013, 0x0100, 0x6003,
+       0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c70,
+       0x2069, 0xb292, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x11a8,
+       0x2069, 0xb280, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110, 0xa18c,
+       0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x0888, 0x6013, 0x0200, 0x6003,
+       0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0830,
+       0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007,
+       0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0804, 0xa186, 0x6013,
+       0x0500, 0x0c98, 0x6013, 0x0600, 0x0818, 0x6013, 0x0200, 0x0800,
+       0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c, 0x14f6,
+       0xa08a, 0x0053, 0x1a0c, 0x14f6, 0xa082, 0x0040, 0x2008, 0x0804,
+       0xa252, 0xa186, 0x0051, 0x0138, 0xa186, 0x0047, 0x11d8, 0x6004,
+       0xa086, 0x0041, 0x0518, 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0,
+       0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+       0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086, 0x0002, 0x1170,
+       0x0804, 0xa295, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c,
+       0x14f6, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a, 0x080c, 0x80be,
+       0x0005, 0xa22c, 0xa22e, 0xa22e, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+       0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+       0xa22c, 0xa22c, 0xa22c, 0xa22c, 0x080c, 0x14f6, 0x080c, 0x6b73,
+       0x080c, 0x6c50, 0x0036, 0x00d6, 0x6010, 0xa06d, 0x01c0, 0xad84,
+       0xf000, 0x01a8, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc, 0x1178,
+       0x2019, 0x0004, 0x080c, 0xa91f, 0x6013, 0x0000, 0x6014, 0xa005,
+       0x1120, 0x2001, 0xafa4, 0x2004, 0x6016, 0x6003, 0x0007, 0x00de,
+       0x003e, 0x0005, 0x0002, 0xa266, 0xa283, 0xa26f, 0xa28f, 0xa266,
+       0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266,
+       0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0x080c, 0x14f6,
+       0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x080c,
+       0x6b73, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003,
+       0x0007, 0x2009, 0x0043, 0x080c, 0x80a7, 0x0010, 0x6003, 0x0002,
+       0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73, 0x080c, 0xab55, 0x1120,
+       0x080c, 0x6618, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+       0x6b73, 0x2009, 0x0041, 0x0804, 0xa3de, 0xa182, 0x0040, 0x0002,
+       0xa2ab, 0xa2ad, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ae,
+       0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab,
+       0xa2ab, 0xa2b9, 0xa2ab, 0x080c, 0x14f6, 0x0005, 0x6003, 0x0004,
+       0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824,
+       0x0005, 0x00d6, 0x080c, 0x6618, 0x00de, 0x080c, 0xabb4, 0x080c,
+       0x8078, 0x0005, 0xa182, 0x0040, 0x0002, 0xa2d8, 0xa2d8, 0xa2d8,
+       0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa2da, 0xa2d8, 0xa2dd, 0xa316,
+       0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa316, 0xa2d8, 0xa2d8, 0xa2d8,
+       0x080c, 0x14f6, 0x080c, 0x80be, 0x0005, 0x2001, 0xad71, 0x2004,
+       0xd0e4, 0x0158, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x0228,
+       0x2001, 0x011f, 0x2004, 0x6036, 0x0010, 0x6037, 0x0000, 0x080c,
+       0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x684c, 0xd0fc,
+       0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0168, 0x2009, 0x0041,
+       0x00de, 0x0804, 0xa3de, 0x6003, 0x0007, 0x6017, 0x0000, 0x080c,
+       0x6618, 0x00de, 0x0005, 0x080c, 0xab55, 0x0110, 0x00de, 0x0005,
+       0x080c, 0x6618, 0x080c, 0x8078, 0x00de, 0x0ca0, 0x0036, 0x080c,
+       0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x6018, 0x2004,
+       0xd0bc, 0x0188, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0140,
+       0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a,
+       0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xa91f, 0x6014,
+       0xa005, 0x1128, 0x2001, 0xafa4, 0x2004, 0x8003, 0x6016, 0x6013,
+       0x0000, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013,
+       0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x080c, 0x6b73,
+       0x080c, 0x6c50, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014,
+       0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x2001, 0x0007,
+       0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50,
+       0x0005, 0xa182, 0x0040, 0x0002, 0xa37f, 0xa37f, 0xa37f, 0xa37f,
+       0xa37f, 0xa37f, 0xa37f, 0xa381, 0xa38d, 0xa37f, 0xa37f, 0xa37f,
+       0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0x080c,
+       0x14f6, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+       0x080c, 0x1824, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068,
+       0x6810, 0x6a14, 0x0006, 0x0046, 0x0056, 0x6c7c, 0xa422, 0x6d80,
+       0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a,
+       0x005e, 0x004e, 0x000e, 0xa20d, 0x1178, 0x684c, 0xd0fc, 0x0120,
+       0x2009, 0x0041, 0x00de, 0x0490, 0x6003, 0x0007, 0x6017, 0x0000,
+       0x080c, 0x6618, 0x00de, 0x0005, 0x0006, 0x00f6, 0x2c78, 0x080c,
+       0x5029, 0x00fe, 0x000e, 0x0120, 0x6003, 0x0002, 0x00de, 0x0005,
+       0x2009, 0xad0d, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010,
+       0x6003, 0x0006, 0x0021, 0x080c, 0x661a, 0x00de, 0x0005, 0xd2fc,
+       0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009,
+       0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040,
+       0x0208, 0x0062, 0xa186, 0x0013, 0x0120, 0xa186, 0x0014, 0x190c,
+       0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005, 0xa401, 0xa408,
+       0xa414, 0xa420, 0xa401, 0xa401, 0xa401, 0xa42f, 0xa401, 0xa403,
+       0xa403, 0xa401, 0xa401, 0xa401, 0xa401, 0xa403, 0xa401, 0xa403,
+       0xa401, 0x080c, 0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005,
+       0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x6c50, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
+       0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005,
+       0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x680b, 0x080c, 0x6d0d, 0x012e, 0x0005, 0xa016,
+       0x080c, 0x1824, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x00d6,
+       0xa182, 0x0040, 0x0023, 0x00de, 0x003e, 0x012e, 0x0005, 0xa44f,
+       0xa451, 0xa463, 0xa47e, 0xa44f, 0xa44f, 0xa44f, 0xa493, 0xa44f,
+       0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0x080c,
+       0x14f6, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x01f8, 0xa09c, 0x0003,
+       0xa39e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x0498, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0168,
+       0xa09c, 0x0003, 0xa39e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x0408, 0x6013, 0x0000, 0x6017,
+       0x0000, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00c0, 0x6010, 0x2068,
+       0x684c, 0xd0fc, 0x0d90, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0d68,
+       0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b,
+       0x080c, 0x6d0d, 0x0018, 0xa016, 0x080c, 0x1824, 0x0005, 0x080c,
+       0x6b73, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa,
+       0x0036, 0x2019, 0x0029, 0x080c, 0xa91f, 0x003e, 0x00de, 0x080c,
+       0x974e, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6c05, 0x6110, 0x81ff,
+       0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa, 0x0036, 0x2019, 0x0029,
+       0x080c, 0xa91f, 0x003e, 0x00de, 0x080c, 0x974e, 0x080c, 0x6d0d,
+       0x0005, 0xa182, 0x0085, 0x0002, 0xa4cd, 0xa4cb, 0xa4cb, 0xa4d9,
+       0xa4cb, 0xa4cb, 0xa4cb, 0x080c, 0x14f6, 0x6003, 0x000b, 0x6106,
+       0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e,
+       0x0005, 0x0026, 0x00e6, 0x080c, 0xab4e, 0x0118, 0x080c, 0x8078,
+       0x00c8, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0xa7ce,
+       0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296,
+       0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160,
+       0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c,
+       0x14f6, 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186,
+       0x0014, 0x0118, 0x080c, 0x80be, 0x0050, 0x2001, 0x0007, 0x080c,
+       0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+       0xa527, 0xa529, 0xa529, 0xa527, 0xa527, 0xa527, 0xa527, 0x080c,
+       0x14f6, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+       0xa182, 0x0085, 0x0a0c, 0x14f6, 0xa182, 0x008c, 0x1a0c, 0x14f6,
+       0xa182, 0x0085, 0x0002, 0xa542, 0xa542, 0xa542, 0xa544, 0xa542,
+       0xa542, 0xa542, 0x080c, 0x14f6, 0x0005, 0xa186, 0x0013, 0x0148,
+       0xa186, 0x0014, 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x80be,
+       0x0030, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+       0x0036, 0x080c, 0xabb4, 0x603f, 0x0000, 0x2019, 0x000b, 0x0031,
+       0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036,
+       0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x2049, 0x0000, 0x080c,
+       0x7b9a, 0x009e, 0x008e, 0x1578, 0x0076, 0x2c38, 0x080c, 0x7c34,
+       0x007e, 0x1548, 0x6000, 0xa086, 0x0000, 0x0528, 0x601c, 0xa086,
+       0x0007, 0x0508, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c,
+       0xabb4, 0x601f, 0x0007, 0x2001, 0xafa3, 0x2004, 0x6016, 0x080c,
+       0x190b, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f,
+       0x00de, 0x6013, 0x0000, 0x080c, 0xabb4, 0x601f, 0x0007, 0x2001,
+       0xafa3, 0x2004, 0x6016, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6,
+       0x0036, 0x0156, 0x2079, 0xb280, 0x7938, 0x783c, 0x080c, 0x2676,
+       0x1904, 0xa5f1, 0x0016, 0x00c6, 0x080c, 0x4cdc, 0x15c0, 0x2011,
+       0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1578,
+       0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x7cf4,
+       0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x007e,
+       0x001e, 0x0076, 0x2039, 0x0000, 0x080c, 0xa712, 0x007e, 0x080c,
+       0x4ecf, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
+       0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x2b87, 0x002e,
+       0x001e, 0x080c, 0x493a, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce,
+       0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6,
+       0x00e6, 0x0016, 0x2009, 0xad20, 0x2104, 0xa086, 0x0074, 0x1904,
+       0xa64b, 0x2069, 0xb28e, 0x690c, 0xa182, 0x0100, 0x06c0, 0x6908,
+       0xa184, 0x8000, 0x05e8, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x1160,
+       0x6018, 0x2070, 0x7010, 0xa084, 0x00ff, 0x0118, 0x7000, 0xd0f4,
+       0x0118, 0xa184, 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610,
+       0x6914, 0x2069, 0xb2ae, 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, 0x00ee, 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, 0x4ceb, 0x00ce, 0x04c0, 0x2011, 0xb296, 0xad98,
+       0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1580, 0x2011, 0xb29a,
+       0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1538, 0x0046,
+       0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xad52,
+       0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6800,
+       0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+       0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x2001,
+       0x0007, 0x080c, 0x4c5d, 0x001e, 0x004e, 0xa006, 0x015e, 0x003e,
+       0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, 0xb28e, 0x6800,
+       0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008, 0xa006, 0x00de,
+       0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
+       0xb28c, 0x7930, 0x7834, 0x080c, 0x2676, 0x11a0, 0x080c, 0x4cdc,
+       0x1188, 0x2011, 0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c,
+       0x8a7c, 0x1140, 0x2011, 0xb294, 0xac98, 0x0006, 0x20a9, 0x0004,
+       0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce,
+       0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
+       0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x11a0, 0x080c,
+       0x4cdc, 0x1188, 0x2011, 0xb296, 0xac98, 0x000a, 0x20a9, 0x0004,
+       0x080c, 0x8a7c, 0x1140, 0x2011, 0xb29a, 0xac98, 0x0006, 0x20a9,
+       0x0004, 0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e,
+       0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056,
+       0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0xafd0,
+       0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400, 0x2071, 0xad00,
+       0x7644, 0x7064, 0x81ff, 0x0128, 0x8001, 0xa602, 0x1a04, 0xa78e,
+       0x0018, 0xa606, 0x0904, 0xa78e, 0x2100, 0xac06, 0x0904, 0xa785,
+       0x080c, 0xa990, 0x0904, 0xa785, 0x671c, 0xa786, 0x0001, 0x0904,
+       0xa7a5, 0xa786, 0x0004, 0x0904, 0xa7a5, 0xa786, 0x0007, 0x05e8,
+       0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c, 0xa9a0,
+       0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6, 0x6000,
+       0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x190b, 0x001e, 0xa786,
+       0x0008, 0x1148, 0x080c, 0x9789, 0x1130, 0x080c, 0x85f3, 0x00de,
+       0x080c, 0x974e, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0190,
+       0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+       0x080c, 0xabfa, 0x0016, 0x080c, 0x97fd, 0x080c, 0x510c, 0x001e,
+       0x080c, 0x9742, 0x00de, 0x080c, 0x974e, 0xace0, 0x0018, 0x2001,
+       0xad16, 0x2004, 0xac02, 0x1210, 0x0804, 0xa726, 0x012e, 0x002e,
+       0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
+       0xa786, 0x0006, 0x19c0, 0xa386, 0x0005, 0x0128, 0x080c, 0xabfa,
+       0x080c, 0xa91f, 0x08f8, 0x00de, 0x0c00, 0x080c, 0xa9a0, 0x19e8,
+       0x81ff, 0x09d8, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x0130,
+       0xa180, 0x0001, 0x2004, 0xa086, 0x002d, 0x1978, 0x6000, 0xa086,
+       0x0002, 0x1958, 0x080c, 0x9778, 0x0130, 0x080c, 0x9789, 0x1928,
+       0x080c, 0x85f3, 0x0038, 0x080c, 0x2aff, 0x080c, 0x9789, 0x1110,
+       0x080c, 0x85f3, 0x080c, 0x974e, 0x0804, 0xa785, 0x00c6, 0x00e6,
+       0x0016, 0x2c08, 0x2170, 0x080c, 0xa940, 0x001e, 0x0120, 0x601c,
+       0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xa7e6, 0xa7e6,
+       0xa7e6, 0xa7e6, 0xa7e6, 0xa7e6, 0xa7e8, 0xa7e6, 0xa006, 0x0005,
+       0x0046, 0x0016, 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff,
+       0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, 0xa96c, 0x001e, 0x004e,
+       0x0036, 0x2019, 0x0002, 0x080c, 0xa566, 0x003e, 0xa085, 0x0001,
+       0x0005, 0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026,
+       0x0036, 0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c,
+       0x8a7c, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6,
+       0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0026, 0x0126, 0x2091,
+       0x8000, 0x2740, 0x2061, 0xb400, 0x2079, 0x0001, 0x8fff, 0x0904,
+       0xa875, 0x2071, 0xad00, 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04,
+       0xa875, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15b0, 0x2079, 0x0000,
+       0x080c, 0xa990, 0x0588, 0x2400, 0xac06, 0x0570, 0x671c, 0xa786,
+       0x0006, 0x1550, 0xa786, 0x0007, 0x0538, 0x88ff, 0x1140, 0x6018,
+       0xa206, 0x1510, 0x85ff, 0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6,
+       0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xabb4, 0x601f, 0x0007,
+       0x2001, 0xafa3, 0x2004, 0x6016, 0x080c, 0x190b, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x0120, 0x0046, 0x080c, 0xa91f, 0x004e, 0x00de,
+       0x080c, 0x974e, 0x88ff, 0x1198, 0xace0, 0x0018, 0x2001, 0xad16,
+       0x2004, 0xac02, 0x1210, 0x0804, 0xa826, 0xa006, 0x012e, 0x002e,
+       0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5,
+       0x0001, 0x0ca0, 0x0076, 0x0056, 0x0086, 0x2041, 0x0000, 0x2029,
+       0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x0096, 0x2049, 0x0000,
+       0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x7c34,
+       0x080c, 0xa817, 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056,
+       0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009,
+       0x0000, 0x0016, 0x0036, 0x080c, 0x4cdc, 0x11b0, 0x2c10, 0x0056,
+       0x0086, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x0096, 0x2049,
+       0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+       0x7c34, 0x080c, 0xa817, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04,
+       0xa8a9, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005,
+       0x0076, 0x0056, 0x6218, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001,
+       0x2019, 0x0048, 0x0096, 0x2049, 0x0000, 0x080c, 0x7b9a, 0x009e,
+       0x008e, 0x2039, 0x0000, 0x080c, 0x7c34, 0x2c20, 0x080c, 0xa817,
+       0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6,
+       0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036,
+       0x080c, 0x4cdc, 0x11c0, 0x2c10, 0x0086, 0x2041, 0x0000, 0x2828,
+       0x0046, 0x2021, 0x0001, 0x080c, 0xab96, 0x004e, 0x0096, 0x2049,
+       0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+       0x7c34, 0x080c, 0xa817, 0x003e, 0x001e, 0x8108, 0x1f04, 0xa8f6,
+       0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016,
+       0x00f6, 0x3800, 0xd08c, 0x0130, 0xad82, 0x1000, 0x02b0, 0xad82,
+       0xad00, 0x0230, 0xad82, 0xe400, 0x0280, 0xad82, 0xffff, 0x1268,
+       0x6800, 0xa07d, 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x510c,
+       0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x510c, 0x00fe, 0x001e, 0x0005,
+       0x00e6, 0x0046, 0x0036, 0x2061, 0xb400, 0x2071, 0xad00, 0x7444,
+       0x7064, 0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000,
+       0xa086, 0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0,
+       0x0006, 0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xad16,
+       0x2004, 0xac02, 0x1220, 0x0c08, 0xa085, 0x0001, 0x0008, 0xa006,
+       0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15d9,
+       0x000e, 0x090c, 0x14f6, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010,
+       0x080c, 0x9586, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014,
+       0x2004, 0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006,
+       0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x510c, 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, 0x0016,
+       0x6004, 0xa08e, 0x001e, 0x11a0, 0x8007, 0x6130, 0xa18c, 0x00ff,
+       0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005,
+       0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c, 0x6c50,
+       0x001e, 0x0005, 0xe000, 0xe000, 0x0005, 0x6020, 0xd0e4, 0x0158,
+       0xd0cc, 0x0118, 0x080c, 0x9866, 0x0030, 0x080c, 0xabb4, 0x080c,
+       0x6618, 0x080c, 0x8078, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084,
+       0x000f, 0x0002, 0xa9e3, 0xa9e3, 0xa9e3, 0xa9e8, 0xa9e3, 0xa9e5,
+       0xa9e5, 0xa9e3, 0xa9e5, 0xa006, 0x0005, 0x00c6, 0x2260, 0x00ce,
+       0xa085, 0x0001, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f,
+       0x0002, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xaa05,
+       0xa9fa, 0xa9fa, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+       0x6003, 0x0001, 0x080c, 0x67a8, 0x0005, 0x00c6, 0x2260, 0x080c,
+       0xabb4, 0x603f, 0x0000, 0x6020, 0xc0f4, 0xc0cc, 0x6022, 0x6037,
+       0x0000, 0x00ce, 0x00d6, 0x2268, 0xa186, 0x0007, 0x1904, 0xaa60,
+       0x6810, 0xa005, 0x0138, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x1110,
+       0x00de, 0x08c0, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002, 0x1904,
+       0xaae7, 0x6010, 0xa005, 0x1138, 0x6000, 0xa086, 0x0007, 0x190c,
+       0x14f6, 0x0804, 0xaae7, 0xa08c, 0xf000, 0x1130, 0x0028, 0x2068,
+       0x6800, 0xa005, 0x1de0, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084,
+       0x0003, 0xa086, 0x0002, 0x1180, 0x6010, 0x2068, 0x684c, 0xc0dc,
+       0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043,
+       0x080c, 0xa3de, 0x0804, 0xaae7, 0x2009, 0x0041, 0x0804, 0xaae1,
+       0xa186, 0x0005, 0x15f0, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
+       0x1118, 0x00de, 0x0804, 0xa9fa, 0xd0b4, 0x0128, 0xd0fc, 0x090c,
+       0x14f6, 0x0804, 0xaa18, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c,
+       0x67a8, 0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002,
+       0x0120, 0xa186, 0x0004, 0x1904, 0xaae7, 0x2071, 0xaffd, 0x7000,
+       0xa086, 0x0003, 0x1128, 0x7004, 0xac06, 0x1110, 0x7003, 0x0000,
+       0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+       0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0804,
+       0xaae1, 0x0036, 0x00d6, 0x00d6, 0x080c, 0x15d9, 0x003e, 0x090c,
+       0x14f6, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+       0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+       0x2360, 0x6020, 0xc0dd, 0x6022, 0x6018, 0xa080, 0x0028, 0x2004,
+       0xa084, 0x00ff, 0x8007, 0x6350, 0x6b4a, 0x6846, 0x684f, 0x0000,
+       0x6d6a, 0x6e66, 0x686f, 0x0001, 0x080c, 0x510c, 0x2019, 0x0045,
+       0x6008, 0x2068, 0x080c, 0xa566, 0x2d00, 0x600a, 0x601f, 0x0006,
+       0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x00de, 0x003e,
+       0x0038, 0x603f, 0x0000, 0x6003, 0x0007, 0x080c, 0xa3de, 0x00ce,
+       0x00de, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085,
+       0x2008, 0x00c2, 0xa186, 0x0027, 0x1178, 0x080c, 0x6b73, 0x0036,
+       0x00d6, 0x6010, 0x2068, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00de,
+       0x003e, 0x080c, 0x6c50, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c,
+       0x80be, 0x0005, 0xab13, 0xab11, 0xab11, 0xab11, 0xab11, 0xab11,
+       0xab13, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x6003, 0x000c, 0x080c,
+       0x6c50, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208,
+       0x001a, 0x080c, 0x80be, 0x0005, 0xab2b, 0xab2b, 0xab2b, 0xab2b,
+       0xab2d, 0xab4b, 0xab2b, 0x080c, 0x14f6, 0x00d6, 0x2c68, 0x080c,
+       0x8022, 0x01a0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xb28e,
+       0x210c, 0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x600b, 0xffff,
+       0x6918, 0x611a, 0x601f, 0x0004, 0x080c, 0x67a8, 0x2d60, 0x080c,
+       0x8078, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005, 0x00e6, 0x6018,
+       0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x6010, 0xa080, 0x0013,
+       0x200c, 0xd1ec, 0x05d0, 0x2001, 0xad71, 0x2004, 0xd0ec, 0x05a8,
+       0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac, 0x0180, 0x00f6,
+       0x2c78, 0x080c, 0x5025, 0x00fe, 0x0150, 0x2001, 0xafa5, 0x2004,
+       0x603e, 0x2009, 0xad71, 0x210c, 0xd1f4, 0x11e8, 0x0080, 0x2009,
+       0xad71, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4, 0x6022, 0xa006,
+       0x00a0, 0x2001, 0xafa5, 0x200c, 0x8103, 0xa100, 0x603e, 0x6018,
+       0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088, 0x0003, 0x0cd0,
+       0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005, 0x0016, 0x00c6,
+       0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060, 0x8cff, 0x0180,
+       0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c, 0x2072, 0x080c,
+       0x6618, 0x080c, 0x8078, 0x0010, 0xacf0, 0x0003, 0x2e64, 0x0c70,
+       0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018, 0xa0e8, 0x002b,
+       0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04, 0xa0e8, 0x0003,
+       0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
+       0x2011, 0xad27, 0x2204, 0xa084, 0x00ff, 0x2019, 0xb28e, 0x2334,
+       0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084, 0xff00, 0xa636,
+       0x11a0, 0x2011, 0xb290, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004,
+       0x080c, 0x8a7c, 0x1150, 0x2011, 0xb294, 0x6018, 0xa098, 0x0006,
+       0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1100, 0x015e, 0x003e, 0x002e,
+       0x0005, 0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x080c, 0x28fa,
+       0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0108,
+       0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852, 0x0005, 0x00e6,
+       0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126,
+       0x2091, 0x8000, 0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424,
+       0x2061, 0xb400, 0x2071, 0xad00, 0x7644, 0x7064, 0xa606, 0x0578,
+       0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008, 0x1500, 0x2500,
+       0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c, 0xa990, 0x01b8,
+       0x080c, 0xa9a0, 0x11a0, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016,
+       0x080c, 0x190b, 0x001e, 0x080c, 0x9778, 0x1110, 0x080c, 0x2aff,
+       0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x080c, 0x974e, 0xace0,
+       0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1208, 0x0858, 0x012e,
+       0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee,
+       0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xad40,
+       0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030,
+       0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a, 0x0451, 0x00ee,
+       0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+       0x2071, 0xad40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4,
+       0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a,
+       0x0081, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
+       0x2091, 0x8000, 0x2071, 0xad42, 0x0021, 0x00ee, 0x000e, 0x012e,
+       0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000,
+       0x2072, 0x0005, 0x00e6, 0x2071, 0xad40, 0x0c99, 0x00ee, 0x0005,
+       0x00e6, 0x2071, 0xad44, 0x0c69, 0x00ee, 0x0005, 0x0001, 0x0002,
+       0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
+       0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x8529
+};
+
index e48d1b0..6c210f5 100644 (file)
@@ -2532,13 +2532,18 @@ static char *
 sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 {
        char *resp = NULL;
-       int page_mask = lowDma ? (GFP_ATOMIC | GFP_DMA) : GFP_ATOMIC;
+       int page_mask;
        int order, a_size;
        int resSz = rqSz;
 
        if (rqSz <= 0)
                return resp;
 
+       if (lowDma)
+               page_mask = GFP_ATOMIC | GFP_DMA | __GFP_NOWARN;
+       else
+               page_mask = GFP_ATOMIC | __GFP_NOWARN;
+
        for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
             order++, a_size <<= 1) ;
        resp = (char *) __get_free_pages(page_mask, order);
index b2ec2ae..bd8c00b 100644 (file)
@@ -420,7 +420,9 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
 
 static void serial_pnp_remove(struct pnp_dev * dev)
 {
-       return;
+       int line = (int)pnp_get_drvdata(dev);
+       if (line)
+               unregister_serial(line - 1);
 }
 
 static struct pnp_driver serial_pnp_driver = {
@@ -437,7 +439,7 @@ static int __init serial8250_pnp_init(void)
 
 static void __exit serial8250_pnp_exit(void)
 {
-       /* FIXME */
+       pnp_unregister_driver(&serial_pnp_driver);
 }
 
 module_init(serial8250_pnp_init);
index 7c789e0..e4b2c2f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/serial.h>
 #include <linux/console.h>
 #include <linux/slab.h>
+#include <linux/delay.h> /* for udelay */
 #include <asm/io.h>
 #include <asm/parisc-device.h>
 
 #define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
 #define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
 
-#define UART_NR 8
-struct mux_card {
-       struct uart_port ports[UART_NR];
-       struct uart_driver drv;
-       struct mux_card *next;
-};
-
-static struct mux_card mux_card_head = {
-       .next = NULL,
+#define MUX_NR 256
+static unsigned int port_cnt = 0;
+static struct uart_port mux_ports[MUX_NR];
+
+static struct uart_driver mux_driver = {
+       .owner = THIS_MODULE,
+       .driver_name = "ttyB",
+       .dev_name = "ttyB",
+       .major = MUX_MAJOR,
+       .minor = 0,
+       .nr = MUX_NR,
 };
 
 static struct timer_list mux_timer;
@@ -181,7 +184,7 @@ static void mux_write(struct uart_port *port)
                return;
        }
 
-       count = (port->fifosize >> 1) - UART_GET_FIFO_CNT(port);
+       count = (port->fifosize) - UART_GET_FIFO_CNT(port);
        do {
                UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -191,6 +194,9 @@ static void mux_write(struct uart_port *port)
 
        } while(--count > 0);
 
+       while(UART_GET_FIFO_CNT(port)) 
+               udelay(1);
+
        if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
@@ -361,28 +367,46 @@ static int mux_verify_port(struct uart_port *port, struct serial_struct *ser)
 static void mux_poll(unsigned long unused)
 {  
        int i;
-       struct mux_card *card = &mux_card_head;
 
-       while(card) {
-               for(i = 0; i < UART_NR; ++i) {
-                       if(!card->ports[i].info)
-                               continue;
+       for(i = 0; i < port_cnt; ++i) {
+               if(!mux_ports[i].info)
+                       continue;
 
-                       mux_read(&card->ports[i]);
-                       mux_write(&card->ports[i]);
-               }
-               card = card->next;
+               mux_read(&mux_ports[i]);
+               mux_write(&mux_ports[i]);
        }
+
        mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
 }
 
 
 #ifdef CONFIG_SERIAL_MUX_CONSOLE
+static void mux_console_write(struct console *co, const char *s, unsigned count)
+{
+        while(count--)
+                pdc_iodc_putc(*s++);
+}
+
+static int mux_console_setup(struct console *co, char *options)
+{
+        return 0;
+}
+
+struct tty_driver *mux_console_device(struct console *co, int *index)
+{
+        *index = co->index;
+       return mux_driver.tty_driver;
+}
+
 static struct console mux_console = {
        .name =         "ttyB",
-       .flags =        CON_PRINTBUFFER,
+       .write =        mux_console_write,
+       .device =       mux_console_device,
+       .setup =        mux_console_setup,
+       .flags =        CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
        .index =        0,
 };
+
 #define MUX_CONSOLE    &mux_console
 #else
 #define MUX_CONSOLE    NULL
@@ -416,77 +440,53 @@ static struct uart_ops mux_pops = {
  */
 static int __init mux_probe(struct parisc_device *dev)
 {
-       int i, j, ret, ports, port_cnt = 0;
-       u8 iodc_data[8];
+       int i, status, ports;
+       u8 iodc_data[32];
        unsigned long bytecnt;
        struct uart_port *port;
-       struct mux_card *card = &mux_card_head;
 
-       ret = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 8);
-       if(ret != PDC_OK) {
+       status = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 32);
+       if(status != PDC_OK) {
                printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
                return 1;
        }
 
        ports = GET_MUX_PORTS(iodc_data);
-       printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.2\n",
-               ports);
-
-       if(!card->drv.nr) {
-               init_timer(&mux_timer);
-               mux_timer.function = mux_poll;
-       } else {
-               port_cnt += UART_NR;
-               while(card->next) {
-                       card = card->next;
-                       port_cnt += UART_NR;
-               } 
-       }
-
-       for(i = 0; i < ports / UART_NR; ++i) {
-               if(card->drv.nr) {
-                       card->next = kmalloc(sizeof(struct mux_card), GFP_KERNEL);
-                       if(!card->next) {
-                               printk(KERN_ERR "Serial mux: Unable to allocate memory.\n");
-                               return 1;
-                       }
-                       memset(card->next, '\0', sizeof(struct mux_card));
-                       card = card->next;
-               }
+       printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.3\n", ports);
 
-               card->drv.owner = THIS_MODULE;
-               card->drv.driver_name = "ttyB";
-               card->drv.dev_name = "ttyB";
-               card->drv.major = MUX_MAJOR;
-               card->drv.minor = port_cnt;
-               card->drv.nr = UART_NR;
-               card->drv.cons = MUX_CONSOLE;
+       if(!port_cnt) {
+               mux_driver.cons = MUX_CONSOLE;
 
-               ret = uart_register_driver(&card->drv);
-               if(ret) {
+               status = uart_register_driver(&mux_driver);
+               if(status) {
                        printk(KERN_ERR "Serial mux: Unable to register driver.\n");
                        return 1;
                }
 
-               for(j = 0; j < UART_NR; ++j) {
-                       port = &card->ports[j];
-
-                       port->iobase    = 0;
-                       port->mapbase   = dev->hpa + MUX_OFFSET + (j * MUX_LINE_OFFSET);
-                       port->membase   = ioremap(port->mapbase, MUX_LINE_OFFSET);
-                       port->iotype    = SERIAL_IO_MEM;
-                       port->type      = PORT_MUX;
-                       port->irq       = SERIAL_IRQ_NONE;
-                       port->uartclk   = 0;
-                       port->fifosize  = MUX_FIFO_SIZE;
-                       port->ops       = &mux_pops;
-                       port->flags     = UPF_BOOT_AUTOCONF;
-                       port->line      = j;
-                       ret = uart_add_one_port(&card->drv, port);
-                       BUG_ON(ret);
-               }
-               port_cnt += UART_NR;
+               init_timer(&mux_timer);
+               mux_timer.function = mux_poll;
+       }
+
+       for(i = 0; i < ports; ++i, ++port_cnt) {
+               port = &mux_ports[port_cnt];
+               port->iobase    = 0;
+               port->mapbase   = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET);
+               port->membase   = ioremap(port->mapbase, MUX_LINE_OFFSET);
+               port->iotype    = SERIAL_IO_MEM;
+               port->type      = PORT_MUX;
+               port->irq       = SERIAL_IRQ_NONE;
+               port->uartclk   = 0;
+               port->fifosize  = MUX_FIFO_SIZE;
+               port->ops       = &mux_pops;
+               port->flags     = UPF_BOOT_AUTOCONF;
+               port->line      = port_cnt;
+               status = uart_add_one_port(&mux_driver, port);
+               BUG_ON(status);
        }
+
+#ifdef CONFIG_SERIAL_MUX_CONSOLE
+        register_console(&mux_console);
+#endif
        return 0;
 }
 
@@ -497,7 +497,7 @@ static struct parisc_device_id mux_tbl[] = {
 
 MODULE_DEVICE_TABLE(parisc, mux_tbl);
 
-static struct parisc_driver mux_driver = {
+static struct parisc_driver serial_mux_driver = {
        .name =         "Serial MUX",
        .id_table =     mux_tbl,
        .probe =        mux_probe,
@@ -510,7 +510,7 @@ static struct parisc_driver mux_driver = {
  */
 static int __init mux_init(void)
 {
-       return register_parisc_driver(&mux_driver);
+       return register_parisc_driver(&serial_mux_driver);
 }
 
 /**
@@ -521,13 +521,12 @@ static int __init mux_init(void)
 static void __exit mux_exit(void)
 {
        int i;
-       struct mux_card *card = &mux_card_head;
 
-       for (i = 0; i < UART_NR; i++) {
-               uart_remove_one_port(&card->drv, &card->ports[i]);
+       for (i = 0; i < port_cnt; i++) {
+               uart_remove_one_port(&mux_driver, &mux_ports[i]);
        }
 
-       uart_unregister_driver(&card->drv);
+       uart_unregister_driver(&mux_driver);
 }
 
 module_init(mux_init);
index 7d64b7c..a41f578 100644 (file)
@@ -1798,9 +1798,7 @@ eth_bind (struct usb_gadget *gadget)
        /* network device setup */
        dev->net = net;
        SET_MODULE_OWNER (net);
-       net->priv = dev;
        strcpy (net->name, "usb%d");
-       ether_setup (net);
 
        /* one random address for the gadget device ... both of these could
         * reasonably come from an id prom or a module parameter.
index edd58d9..7702968 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_VT)                  += console/
 obj-$(CONFIG_LOGO)               += logo/
 obj-$(CONFIG_BOOTSPLASH)         += bootsplash/
 
-obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o modedb.o softcursor.o
+obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
 # Only include macmodes.o if we have FB support and are PPC
 ifeq ($(CONFIG_FB),y)
 obj-$(CONFIG_PPC)                 += macmodes.o
index 7bbf41c..5d9a6e8 100644 (file)
@@ -588,18 +588,18 @@ sti_select_font(struct sti_cooked_rom *rom,
 static void __init 
 sti_dump_rom(struct sti_rom *rom)
 {
-        printk(KERN_INFO "STI id %04x-%04x, conforms to spec rev. %d.%02x\n",
+        printk(KERN_INFO "    id %04x-%04x, conforms to spec rev. %d.%02x\n",
                rom->graphics_id[0], 
                rom->graphics_id[1],
                rom->revno[0] >> 4, 
                rom->revno[0] & 0x0f);
-       DPRINTK((" supports %d monitors\n", rom->num_mons));
-       DPRINTK((" font start %08x\n", rom->font_start));
-       DPRINTK((" region list %08x\n", rom->region_list));
-       DPRINTK((" init_graph %08x\n", rom->init_graph));
-       DPRINTK((" bus support %02x\n", rom->bus_support));
-       DPRINTK((" ext bus support %02x\n", rom->ext_bus_support));
-       DPRINTK((" alternate code type %d\n", rom->alt_code_type));
+       DPRINTK(("      supports %d monitors\n", rom->num_mons));
+       DPRINTK(("      font start %08x\n", rom->font_start));
+       DPRINTK(("      region list %08x\n", rom->region_list));
+       DPRINTK(("      init_graph %08x\n", rom->init_graph));
+       DPRINTK(("      bus support %02x\n", rom->bus_support));
+       DPRINTK(("      ext bus support %02x\n", rom->ext_bus_support));
+       DPRINTK(("      alternate code type %d\n", rom->alt_code_type));
 }
 
 
@@ -869,14 +869,14 @@ test_rom:
        ok = 0;
        
        if ((sig & 0xff) == 0x01) {
-               printk(KERN_INFO "STI byte mode ROM at %08lx, hpa at %08lx\n",
-                      address, hpa);
+               DPRINTK(("    byte mode ROM at %08lx, hpa at %08lx\n",
+                      address, hpa));
                ok = sti_read_rom(0, sti, address);
        }
 
        if ((sig & 0xffff) == 0x0303) {
-               printk(KERN_INFO "STI word mode ROM at %08lx, hpa at %08lx\n",
-                      address, hpa);
+               DPRINTK(("    word mode ROM at %08lx, hpa at %08lx\n",
+                      address, hpa));
                ok = sti_read_rom(1, sti, address);
        }
 
@@ -903,7 +903,7 @@ test_rom:
        sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
        sti_dump_outptr(sti);
        
-       printk(KERN_INFO "STI device: %s\n", sti->outptr.dev_name );
+       printk(KERN_INFO "    graphics card name: %s\n", sti->outptr.dev_name );
 
        sti_roms[num_sti_roms] = sti;
        num_sti_roms++;
index c119e3b..daee75c 100644 (file)
@@ -98,14 +98,14 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
        if (!len)
            return 0;
        if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
-           return -1;
+           goto fail;
        if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
-           return -1;
+           goto fail;
        if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-           return -1;
+           goto fail;
        if (transp) {
            if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
-               return -1;
+               goto fail;
        } else
            cmap->transp = NULL;
     }
@@ -113,6 +113,10 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
     cmap->len = len;
     fb_copy_cmap(fb_default_cmap(len), cmap, 0);
     return 0;
+
+fail:
+    fb_dealloc_cmap(cmap);
+    return -1;
 }
 
 /**
@@ -126,14 +130,10 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
 
 void fb_dealloc_cmap(struct fb_cmap *cmap)
 {
-       if (cmap->red)
-               kfree(cmap->red);
-       if (cmap->green)
-               kfree(cmap->green);
-       if (cmap->blue)
-               kfree(cmap->blue);
-       if (cmap->transp)
-               kfree(cmap->transp);
+       kfree(cmap->red);
+       kfree(cmap->green);
+       kfree(cmap->blue);
+       kfree(cmap->transp);
 
        cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
        cmap->len = 0;
index 9c08576..a3b3a86 100644 (file)
@@ -1247,6 +1247,9 @@ register_framebuffer(struct fb_info *fb_info)
                        break;
        fb_info->node = i;
        
+       if (fb_add_class_device(fb_info))
+               return -EINVAL;
+       
        if (fb_info->pixmap.addr == NULL) {
                fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
                if (fb_info->pixmap.addr) {
@@ -1295,6 +1298,7 @@ unregister_framebuffer(struct fb_info *fb_info)
                kfree(fb_info->pixmap.addr);
        registered_fb[i]=NULL;
        num_registered_fb--;
+       class_device_del(&fb_info->class_dev);
        return 0;
 }
 
@@ -1319,6 +1323,8 @@ fbmem_init(void)
        if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
                printk("unable to get major %d for fb devs\n", FB_MAJOR);
 
+       class_register(&fb_class);
+       
 #ifdef CONFIG_FB_OF
        if (ofonly) {
                offb_init();
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
new file mode 100644 (file)
index 0000000..13a51f3
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * fbsysfs.c - framebuffer device class and attributes
+ *
+ * Copyright (c) 2004 James Simmons <jsimmons@infradead.org>
+ * 
+ *     This program is free software you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/fb.h>
+
+#define to_fb_info(class) container_of(class, struct fb_info, class_dev)
+
+static void release_fb_info(struct class_device *class_dev)
+{
+       struct fb_info *info = to_fb_info(class_dev);
+
+       /* This doesn't harm */
+       fb_dealloc_cmap(&info->cmap);
+
+       kfree(info);
+}
+
+struct class fb_class = {
+       .name           = "graphics",
+       .release        = &release_fb_info,
+};
+
+static ssize_t show_dev(struct class_device *class_dev, char *buf)
+{
+       struct fb_info *info = to_fb_info(class_dev);
+
+       return sprintf(buf, "%u:%u\n", FB_MAJOR, info->node);
+}
+
+static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+
+int fb_add_class_device(struct fb_info *info)
+{
+       int retval;
+
+       info->class_dev.class = &fb_class;
+       snprintf(info->class_dev.class_id, BUS_ID_SIZE, "fb%d",
+                info->node);
+       retval = class_device_register(&info->class_dev);
+       if (retval)
+               return retval;
+       return class_device_create_file(&info->class_dev,
+                                       &class_device_attr_dev);
+}
+
+/**
+ * framebuffer_alloc - creates a new frame buffer info structure
+ *
+ * @size: size of driver private data, can be zero
+ * @dev: pointer to the device for this fb, this can be NULL
+ *
+ * Creates a new frame buffer info structure. Also reserves @size bytes
+ * for driver private data (info->par). info->par (if any) will be
+ * aligned to sizeof(long).
+ *
+ * Returns the new structure, or NULL if an error occured.
+ *
+ */
+struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
+{
+#define BYTES_PER_LONG (BITS_PER_LONG/8)
+#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
+       int fb_info_size = sizeof(struct fb_info);
+       struct fb_info *info;
+       char *p;
+
+       if (size)
+               fb_info_size += PADDING;
+
+       p = kmalloc(fb_info_size + size, GFP_KERNEL);
+       if (!p)
+               return NULL;
+       memset(p, 0, fb_info_size + size);
+       info = (struct fb_info *) p;
+       info->class_dev.dev = dev;
+
+       if (size)
+               info->par = p + fb_info_size;
+
+       return info;
+#undef PADDING
+#undef BYTES_PER_LONG
+}
+
+/**
+ * framebuffer_release - marks the structure available for freeing
+ *
+ * @info: frame buffer info structure
+ *
+ * Drop the reference count of the class_device embedded in the
+ * framebuffer info structure.
+ *
+ */
+void framebuffer_release(struct fb_info *info)
+{
+       class_device_put(&info->class_dev);
+}
+
+EXPORT_SYMBOL(framebuffer_release);
+EXPORT_SYMBOL(framebuffer_alloc);
index f5ee95c..0546df3 100644 (file)
@@ -114,6 +114,7 @@ enum radeon_chips {
        RADEON_Ie,
        RADEON_If,
        RADEON_Ig,
+       RADEON_Ya,
        RADEON_Yd,
        RADEON_Ld,
        RADEON_Le,
@@ -208,6 +209,7 @@ static struct pci_device_id radeonfb_pci_table[] = {
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ya, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ya},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
index 4f978a2..77ad472 100644 (file)
@@ -52,7 +52,7 @@
 #error This driver requires PCI support.
 #endif
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_PPC_PMAC
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <asm/prom.h>
index 4694912..9a15615 100644 (file)
@@ -3,7 +3,7 @@
  * Low level Frame buffer driver for HP workstations with 
  * STI (standard text interface) video firmware.
  *
- * Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
+ * Copyright (C) 2001-2004 Helge Deller <deller@gmx.de>
  * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
  * 
  * Based on:
  */
 
 /* TODO:
- *     - remove the static fb_info to support multiple cards
  *     - 1bpp mode is completely untested
  *     - add support for h/w acceleration
  *     - add hardware cursor
+ *     - automatically disable double buffering (e.g. on RDI precisionbook laptop)
  */
 
 
@@ -51,6 +51,8 @@
  * #undef  FALLBACK_TO_1BPP to reject support for unsupported cards */
 #undef FALLBACK_TO_1BPP
 
+#undef DEBUG_STIFB_REGS                /* debug sti register accesses */
+
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -154,8 +156,27 @@ static int __initdata stifb_force_bpp[MAX_STI_ROMS];
 
 #define READ_BYTE(fb,reg)              __raw_readb((fb)->info.fix.mmio_start + (reg))
 #define READ_WORD(fb,reg)              __raw_readl((fb)->info.fix.mmio_start + (reg))
-#define WRITE_BYTE(value,fb,reg)       __raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
-#define WRITE_WORD(value,fb,reg)       __raw_writel((value),(fb)->info.fix.mmio_start + (reg))
+
+
+#ifndef DEBUG_STIFB_REGS
+# define  DEBUG_OFF()
+# define  DEBUG_ON()
+# define WRITE_BYTE(value,fb,reg)      __raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
+# define WRITE_WORD(value,fb,reg)      __raw_writel((value),(fb)->info.fix.mmio_start + (reg))
+#else
+  static int debug_on = 1;
+# define  DEBUG_OFF() debug_on=0
+# define  DEBUG_ON()  debug_on=1
+# define WRITE_BYTE(value,fb,reg)      do { if (debug_on) \
+                                               printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \
+                                                       __FUNCTION__, reg, value, READ_BYTE(fb,reg));             \
+                                       __raw_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
+# define WRITE_WORD(value,fb,reg)      do { if (debug_on) \
+                                               printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \
+                                                       __FUNCTION__, reg, value, READ_WORD(fb,reg));             \
+                                       __raw_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
+#endif /* DEBUG_STIFB_REGS */
+
 
 #define ENABLE 1       /* for enabling/disabling screen */     
 #define DISABLE 0
@@ -390,7 +411,7 @@ ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
        WRITE_WORD(val, fb, REG_6)
 
 #define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) (               \
-       (u32) (fbaddrbase) +                            \
+       (u32) (fbaddrbase) +                                    \
            (   (unsigned int)  ( (y) << 13      ) |            \
                (unsigned int)  ( (x) << 2       )      )       \
        )
@@ -449,6 +470,13 @@ SETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber)
 static void
 SET_ATTR_SIZE(struct stifb_info *fb, int width, int height) 
 {
+       /* REG_6 seems to have special values when run on a 
+          RDI precisionbook parisc laptop (INTERNAL_EG_DX1024 or
+          INTERNAL_EG_X1024).  The values are:
+               0x2f0: internal (LCD) & external display enabled
+               0x2a0: external display only
+               0x000: zero on standard artist graphic cards
+       */ 
        WRITE_WORD(0x00000000, fb, REG_6);
        WRITE_WORD((width<<16) | height, fb, REG_9);
        WRITE_WORD(0x05000000, fb, REG_6);
@@ -730,7 +758,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
                controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */
 
        switch (enable) {
-       case 1:         /* ENABLE */
+       case ENABLE:
                /* clear screen */
                if (IS_24_DEVICE(fb))
                        ngleDepth24_ClearImagePlanes(fb);
@@ -750,7 +778,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
                hyperUndoITE(fb);
                break;
 
-       case 0:         /* DISABLE */
+       case DISABLE:
                /* clear screen */
                if (IS_24_DEVICE(fb))
                        ngleDepth24_ClearImagePlanes(fb);
@@ -974,6 +1002,8 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
        green >>= 8;
        blue  >>= 8;
 
+       DEBUG_OFF();
+
        START_IMAGE_COLORMAP_ACCESS(fb);
        
        if (fb->info.var.grayscale) {
@@ -1005,6 +1035,8 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
                FINISH_IMAGE_COLORMAP_ACCESS(fb);
        }
 
+       DEBUG_ON();
+
        return 0;
 }
 
@@ -1144,17 +1176,28 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
 
        /* only supported cards are allowed */
        switch (fb->id) {
+       case CRT_ID_VISUALIZE_EG:
+               /* look for a double buffering device like e.g. the 
+                  "INTERNAL_EG_DX1024" in the RDI precisionbook laptop
+                  which won't work. The same device in non-double 
+                  buffering mode returns "INTERNAL_EG_X1024". */
+               if (strstr(sti->outptr.dev_name, "EG_DX")) {
+                  printk(KERN_WARNING 
+                       "stifb: ignoring '%s'. Disable double buffering in IPL menu.\n",
+                       sti->outptr.dev_name);
+                  goto out_err0;
+               }
+               /* fall though */
        case S9000_ID_ARTIST:
        case S9000_ID_HCRX:
        case S9000_ID_TIMBER:
        case S9000_ID_A1659A:
        case S9000_ID_A1439A:
-       case CRT_ID_VISUALIZE_EG:
                break;
        default:
-               printk(KERN_WARNING "stifb: Unsupported gfx card id 0x%08x\n",
-                       fb->id);
-               goto out_err1;
+               printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",
+                       sti->outptr.dev_name, fb->id);
+               goto out_err0;
        }
        
        /* default to 8 bpp on most graphic chips */
@@ -1232,7 +1275,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
                        "stifb: Unsupported graphics card (id=0x%08x) "
                                "- skipping.\n",
                        fb->id);
-               goto out_err1;
+               goto out_err0;
 #endif
        }
 
@@ -1306,12 +1349,13 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
        sti->info = info; /* save for unregister_framebuffer() */
 
        printk(KERN_INFO 
-           "fb%d: %s %dx%d-%d frame buffer device, id: %04x, mmio: 0x%04lx\n",
+           "fb%d: %s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
                fb->info.node, 
                fix->id,
                var->xres, 
                var->yres,
                var->bits_per_pixel,
+               sti->outptr.dev_name,
                fb->id, 
                fix->mmio_start);
 
@@ -1324,16 +1368,24 @@ out_err2:
        release_mem_region(fix->smem_start, fix->smem_len);
 out_err1:
        fb_dealloc_cmap(&info->cmap);
+out_err0:
        kfree(fb);
        return -ENXIO;
 }
 
+static int stifb_disabled __initdata;
+
 int __init
 stifb_init(void)
 {
        struct sti_struct *sti;
        int i;
        
+       if (stifb_disabled) {
+               printk(KERN_INFO "stifb: disabled by \"stifb=off\" kernel parameter\n");
+               return -ENXIO;
+       }
+       
        for (i = 1; i < MAX_STI_ROMS; i++) {
                sti = sti_get_rom(i);
                if (!sti)
@@ -1379,6 +1431,11 @@ stifb_setup(char *options)
        if (!options || !*options)
                return 0;
        
+       if (strncmp(options, "off", 3) == 0) {
+               stifb_disabled = 1;
+               options += 3;
+       }
+
        if (strncmp(options, "bpp", 3) == 0) {
                options += 3;
                for (i = 0; i < MAX_STI_ROMS; i++) {
index 9cdd106..d244205 100644 (file)
@@ -1341,6 +1341,7 @@ int vga16fb_setup(char *options)
 int __init vga16fb_init(void)
 {
        int i;
+       int ret;
 
        printk(KERN_DEBUG "vga16fb: initializing\n");
 
@@ -1349,7 +1350,8 @@ int __init vga16fb_init(void)
         vga16fb.screen_base = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
        if (!vga16fb.screen_base) {
                printk(KERN_ERR "vga16fb: unable to map device\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_ioremap;
        }
        printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
 
@@ -1371,30 +1373,45 @@ int __init vga16fb_init(void)
        vga16fb.flags = FBINFO_FLAG_DEFAULT;
 
        i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
-       fb_alloc_cmap(&vga16fb.cmap, i, 0);
+       ret = fb_alloc_cmap(&vga16fb.cmap, i, 0);
+       if (ret) {
+               printk(KERN_ERR "vga16fb: unable to allocate colormap\n");
+               ret = -ENOMEM;
+               goto err_alloc_cmap;
+       }
 
        if (vga16fb_check_var(&vga16fb.var, &vga16fb)) {
-               iounmap(vga16fb.screen_base);
-               return -EINVAL;
+               printk(KERN_ERR "vga16fb: unable to validate variable\n");
+               ret = -EINVAL;
+               goto err_check_var;
        }
 
        vga16fb_update_fix(&vga16fb);
 
        if (register_framebuffer(&vga16fb) < 0) {
-               iounmap(vga16fb.screen_base);
-               return -EINVAL;
+               printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
+               ret = -EINVAL;
+               goto err_check_var;
        }
 
        printk(KERN_INFO "fb%d: %s frame buffer device\n",
               vga16fb.node, vga16fb.fix.id);
 
        return 0;
+
+ err_check_var:
+       fb_dealloc_cmap(&vga16fb.cmap);
+ err_alloc_cmap:
+       iounmap(vga16fb.screen_base);
+ err_ioremap:
+       return ret;
 }
 
 static void __exit vga16fb_exit(void)
 {
     unregister_framebuffer(&vga16fb);
     iounmap(vga16fb.screen_base);
+    fb_dealloc_cmap(&vga16fb.cmap);
     /* XXX unshare VGA regions */
 }
 
index 128465c..be204c5 100644 (file)
@@ -238,6 +238,9 @@ struct epitem {
        /* List header used to link this structure to the eventpoll ready list */
        struct list_head rdllink;
 
+       /* The file descriptor this item refers to */
+       int fd;
+
        /* Number of active wait queue attached to poll operations */
        int nwait;
 
@@ -247,9 +250,6 @@ struct epitem {
        /* The "container" of this item */
        struct eventpoll *ep;
 
-       /* The file descriptor this item refers to */
-       int fd;
-
        /* The file this item refers to */
        struct file *file;
 
index 879d11f..4abd2f0 100644 (file)
@@ -356,6 +356,13 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
                        ext2_inc_count(new_dir);
        }
 
+       /*
+        * Like most other Unix systems, set the ctime for inodes on a
+        * rename.
+        * ext2_dec_count() will mark the inode dirty.
+        */
+       old_inode->i_ctime = CURRENT_TIME;
+
        ext2_delete_entry (old_de, old_page);
        ext2_dec_count(old_inode);
 
index 5734070..abefa1c 100644 (file)
@@ -748,7 +748,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
                                /* The old block is released after updating
                                   the inode.  */
                                ea_bdebug(new_bh, "reusing block");
-                               
+
                                error = -EDQUOT;
                                if (DQUOT_ALLOC_BLOCK(inode, 1)) {
                                        unlock_buffer(new_bh);
index 11b3d25..2c31059 100644 (file)
@@ -40,28 +40,6 @@ static int hfs_get_last_session(struct super_block *sb,
        /* default values */
        *start = 0;
        *size = sb->s_bdev->bd_inode->i_size >> 9;
-       {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               struct gendisk *gd = get_gendisk(sb->s_bdev->bd_inode->i_rdev);
-               if (gd && gd->part) {
-                       printk("size: %ld,%ld\n", *size,
-                               gd->part[MINOR(sb->s_bdev->bd_inode->i_rdev)].nr_sects);
-                       *size = gd->part[MINOR(sb->s_bdev->bd_inode->i_rdev)].nr_sects;
-               }
-#else
-               int part;
-               struct gendisk *gd = get_gendisk(sb->s_bdev->bd_inode->i_rdev, &part);
-               if (gd && part && gd->part) {
-                       printk("size: %ld,%ld\n", *size,
-                               gd->part[part-1]->nr_sects);
-                       //*size = gd->part[part-1]->nr_sects;
-               } else if (gd && !part) {
-                       printk("size: %d,%ld,%ld\n", part, *size,
-                               gd->capacity);
-               }
-               put_disk(gd);
-#endif
-       }
 
        if (HFS_SB(sb)->session >= 0) {
                te.cdte_track = HFS_SB(sb)->session;
index 9ad4b39..8a877ca 100644 (file)
@@ -61,28 +61,6 @@ static int hfsplus_get_last_session(struct super_block *sb,
        /* default values */
        *start = 0;
        *size = sb->s_bdev->bd_inode->i_size >> 9;
-       {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               struct gendisk *gd = get_gendisk(sb->s_bdev->bd_inode->i_rdev);
-               if (gd && gd->part) {
-                       printk("size: %ld,%ld\n", *size,
-                               gd->part[MINOR(sb->s_bdev->bd_inode->i_rdev)].nr_sects);
-                       *size = gd->part[MINOR(sb->s_bdev->bd_inode->i_rdev)].nr_sects;
-               }
-#else
-               int part;
-               struct gendisk *gd = get_gendisk(sb->s_bdev->bd_inode->i_rdev, &part);
-               if (gd && part && gd->part) {
-                       printk("size: %d,%ld,%ld\n", part, *size,
-                               gd->part[part-1]->nr_sects);
-                       //*size = gd->part[part-1]->nr_sects;
-               } else if (gd && !part) {
-                       printk("size: %d,%ld,%ld\n", part, *size,
-                               gd->capacity);
-               }
-               put_disk(gd);
-#endif
-       }
 
        if (HFSPLUS_SB(sb).session >= 0) {
                te.cdte_track = HFSPLUS_SB(sb).session;
index 175d3e8..10adae3 100644 (file)
 #include <asm/uaccess.h>
 
 /*
- * Extended attribute memory allocation wrappers, originally
- * based on the Intermezzo PRESTO_ALLOC/PRESTO_FREE macros.
- * Values larger than a page are uncommon - extended attributes
- * are supposed to be small chunks of metadata, and it is quite
- * unusual to have very many extended attributes, so lists tend
- * to be quite short as well.  The 64K upper limit is derived
- * from the extended attribute size limit used by XFS.
- * Intentionally allow zero @size for value/list size requests.
- */
-static void *
-xattr_alloc(size_t size, size_t limit)
-{
-       void *ptr;
-
-       if (size > limit)
-               return ERR_PTR(-E2BIG);
-
-       if (!size)      /* size request, no buffer is needed */
-               return NULL;
-
-       ptr = kmalloc((unsigned long) size, GFP_KERNEL);
-       if (!ptr)
-               return ERR_PTR(-ENOMEM);
-       return ptr;
-}
-
-static void
-xattr_free(void *ptr, size_t size)
-{
-       if (size)       /* for a size request, no buffer was needed */
-               kfree(ptr);
-}
-
-/*
  * Extended attribute SET operations
  */
 static long
@@ -57,7 +23,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value,
         size_t size, int flags)
 {
        int error;
-       void *kvalue;
+       void *kvalue = NULL;
        char kname[XATTR_NAME_MAX + 1];
 
        if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
@@ -69,13 +35,16 @@ setxattr(struct dentry *d, char __user *name, void __user *value,
        if (error < 0)
                return error;
 
-       kvalue = xattr_alloc(size, XATTR_SIZE_MAX);
-       if (IS_ERR(kvalue))
-               return PTR_ERR(kvalue);
-
-       if (size > 0 && copy_from_user(kvalue, value, size)) {
-               xattr_free(kvalue, size);
-               return -EFAULT;
+       if (size) {
+               if (size > XATTR_SIZE_MAX)
+                       return -E2BIG;
+               kvalue = kmalloc(size, GFP_KERNEL);
+               if (!kvalue)
+                       return -ENOMEM;
+               if (copy_from_user(kvalue, value, size)) {
+                       kfree(kvalue);
+                       return -EFAULT;
+               }
        }
 
        error = -EOPNOTSUPP;
@@ -90,7 +59,8 @@ setxattr(struct dentry *d, char __user *name, void __user *value,
 out:
                up(&d->d_inode->i_sem);
        }
-       xattr_free(kvalue, size);
+       if (kvalue)
+               kfree(kvalue);
        return error;
 }
 
@@ -146,7 +116,7 @@ static ssize_t
 getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
 {
        ssize_t error;
-       void *kvalue;
+       void *kvalue = NULL;
        char kname[XATTR_NAME_MAX + 1];
 
        error = strncpy_from_user(kname, name, sizeof(kname));
@@ -155,9 +125,13 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
        if (error < 0)
                return error;
 
-       kvalue = xattr_alloc(size, XATTR_SIZE_MAX);
-       if (IS_ERR(kvalue))
-               return PTR_ERR(kvalue);
+       if (size) {
+               if (size > XATTR_SIZE_MAX)
+                       size = XATTR_SIZE_MAX;
+               kvalue = kmalloc(size, GFP_KERNEL);
+               if (!kvalue)
+                       return -ENOMEM;
+       }
 
        error = -EOPNOTSUPP;
        if (d->d_inode->i_op && d->d_inode->i_op->getxattr) {
@@ -165,13 +139,18 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
                if (error)
                        goto out;
                error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
+               if (error > 0) {
+                       if (copy_to_user(value, kvalue, error))
+                               error = -EFAULT;
+               } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
+                       /* The file system tried to returned a value bigger
+                          than XATTR_SIZE_MAX bytes. Not possible. */
+                       error = -E2BIG;
+               }
        }
-
-       if (kvalue && error > 0)
-               if (copy_to_user(value, kvalue, error))
-                       error = -EFAULT;
 out:
-       xattr_free(kvalue, size);
+       if (kvalue)
+               kfree(kvalue);
        return error;
 }
 
@@ -226,11 +205,15 @@ static ssize_t
 listxattr(struct dentry *d, char __user *list, size_t size)
 {
        ssize_t error;
-       char *klist;
-
-       klist = (char *)xattr_alloc(size, XATTR_LIST_MAX);
-       if (IS_ERR(klist))
-               return PTR_ERR(klist);
+       char *klist = NULL;
+
+       if (size) {
+               if (size > XATTR_LIST_MAX)
+                       size = XATTR_LIST_MAX;
+               klist = kmalloc(size, GFP_KERNEL);
+               if (!klist)
+                       return -ENOMEM;
+       }
 
        error = -EOPNOTSUPP;
        if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
@@ -238,13 +221,18 @@ listxattr(struct dentry *d, char __user *list, size_t size)
                if (error)
                        goto out;
                error = d->d_inode->i_op->listxattr(d, klist, size);
+               if (error > 0) {
+                       if (copy_to_user(list, klist, error))
+                               error = -EFAULT;
+               } else if (error == -ERANGE && size >= XATTR_LIST_MAX) {
+                       /* The file system tried to returned a list bigger
+                          than XATTR_LIST_MAX bytes. Not possible. */
+                       error = -E2BIG;
+               }
        }
-
-       if (klist && error > 0)
-               if (copy_to_user(list, klist, error))
-                       error = -EFAULT;
 out:
-       xattr_free(klist, size);
+       if (klist)
+               kfree(klist);
        return error;
 }
 
index 985cc06..dab7521 100644 (file)
@@ -9,8 +9,6 @@
 #define ACPI_PROCESSOR_MAX_C2_LATENCY  100
 #define ACPI_PROCESSOR_MAX_C3_LATENCY  1000
 
-#define ACPI_PROCESSOR_MAX_PERFORMANCE 8
-
 #define ACPI_PROCESSOR_MAX_THROTTLING  16
 #define ACPI_PROCESSOR_MAX_THROTTLE    250     /* 25% */
 #define ACPI_PROCESSOR_MAX_DUTY_WIDTH  4
@@ -67,20 +65,22 @@ struct acpi_processor_px {
        acpi_integer            status;                 /* success indicator */
 };
 
+#define ACPI_PDC_REVISION_ID                   0x1
+
 struct acpi_processor_performance {
-       int                     state;
-       int                     platform_limit;
-       u16                     control_register;
-       u16                     status_register;
-       u8                      control_register_bit_width;
-       u8                      status_register_bit_width;
-       int                     state_count;
-       struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE];
-       struct cpufreq_frequency_table freq_table[ACPI_PROCESSOR_MAX_PERFORMANCE];
-       struct acpi_processor   *pr;
+       unsigned int             state;
+       unsigned int             platform_limit;
+       struct acpi_pct_register control_register;
+       struct acpi_pct_register status_register;
+       unsigned int             state_count;
+       struct acpi_processor_px *states;
+
+       /* the _PDC objects passed by the driver, if any */
+       struct acpi_object_list *pdc;
 };
 
 
+
 /* Throttling Control */
 
 struct acpi_processor_tx {
@@ -133,11 +133,11 @@ struct acpi_processor {
        struct acpi_processor_limit limit;
 };
 
-extern int acpi_processor_get_platform_limit (
-       struct acpi_processor*  pr);
 extern int acpi_processor_register_performance (
        struct acpi_processor_performance * performance,
-       struct acpi_processor ** pr,
+       unsigned int cpu);
+extern void acpi_processor_unregister_performance (
+       struct acpi_processor_performance * performance,
        unsigned int cpu);
 
 #endif
index e5179c5..7af2b8d 100644 (file)
@@ -2,11 +2,12 @@
 #define _ALPHA_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 #include <asm/compiler.h>
 
 #ifdef __GNUC__
 
-static __inline __u32 __attribute_const__ __arch__swab32(__u32 x)
+static __inline __attribute_const__ __u32 __arch__swab32(__u32 x)
 {
        /*
         * Unfortunately, we can't use the 6 instruction sequence
diff --git a/include/asm-arm/arch-integrator/cm.h b/include/asm-arm/arch-integrator/cm.h
new file mode 100644 (file)
index 0000000..d31c1a7
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * update the core module control register.
+ */
+void cm_control(u32, u32);
+
+#define CM_CTRL_LED                    (1 << 0)
+#define CM_CTRL_nMBDET                 (1 << 1)
+#define CM_CTRL_REMAP                  (1 << 2)
+#define CM_CTRL_RESET                  (1 << 3)
+
+/*
+ * Integrator/AP,PP2 specific
+ */
+#define CM_CTRL_HIGHVECTORS            (1 << 4)
+#define CM_CTRL_BIGENDIAN              (1 << 5)
+#define CM_CTRL_FASTBUS                        (1 << 6)
+#define CM_CTRL_SYNC                   (1 << 7)
+
+/*
+ * ARM926/946/966 Integrator/CP specific
+ */
+#define CM_CTRL_LCDBIASEN              (1 << 8)
+#define CM_CTRL_LCDBIASUP              (1 << 9)
+#define CM_CTRL_LCDBIASDN              (1 << 10)
+#define CM_CTRL_LCDMUXSEL_MASK         (7 << 11)
+#define CM_CTRL_LCDMUXSEL_GENLCD       (1 << 11)
+#define CM_CTRL_LCDMUXSEL_SHARPLCD1    (3 << 11)
+#define CM_CTRL_LCDMUXSEL_SHARPLCD2    (4 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA          (7 << 11)
+#define CM_CTRL_LCDEN0                 (1 << 14)
+#define CM_CTRL_LCDEN1                 (1 << 15)
+#define CM_CTRL_STATIC1                        (1 << 16)
+#define CM_CTRL_STATIC2                        (1 << 17)
+#define CM_CTRL_STATIC                 (1 << 18)
+#define CM_CTRL_n24BITEN               (1 << 19)
+#define CM_CTRL_EBIWP                  (1 << 20)
index a36789a..ba7b3af 100644 (file)
 #define IRQ_AP_CPINT1                  19
 #define IRQ_AP_LBUSTIMEOUT             20
 #define IRQ_AP_APCINT                  21
+#define IRQ_CP_CLCDCINT                        22
+#define IRQ_CP_MMCIINT0                        23
+#define IRQ_CP_MMCIINT1                        24
+#define IRQ_CP_AACIINT                 25
+#define IRQ_CP_CPPLDINT                        26
+#define IRQ_CP_ETHINT                  27
+#define IRQ_CP_TSPENINT                        28
 #define IRQ_PIC_END                    31
 
 #define IRQ_CIC_START                  32
 #define IRQ_CM_COMMTX                  34
 #define IRQ_CIC_END                    34
 
+/*
+ * IntegratorCP only
+ */
+#define IRQ_SIC_START                  35
+#define IRQ_SIC_CP_SOFTINT             35
+#define IRQ_SIC_CP_RI0                 36
+#define IRQ_SIC_CP_RI1                 37
+#define IRQ_SIC_CP_CARDIN              38
+#define IRQ_SIC_CP_LMINT0              39
+#define IRQ_SIC_CP_LMINT1              40
+#define IRQ_SIC_CP_LMINT2              41
+#define IRQ_SIC_CP_LMINT3              42
+#define IRQ_SIC_CP_LMINT4              43
+#define IRQ_SIC_CP_LMINT5              44
+#define IRQ_SIC_CP_LMINT6              45
+#define IRQ_SIC_CP_LMINT7              46
+#define IRQ_SIC_END                    46
+
 #define NR_IRQS                         47
 
index 904a582..8ea4422 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <asm/arch/platform.h>
+#include <asm/arch/cm.h>
 
 static inline void arch_idle(void)
 {
@@ -34,16 +34,11 @@ static inline void arch_idle(void)
 
 static inline void arch_reset(char mode)
 {
-       unsigned int hdr_ctrl = (IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET);
-       unsigned int val;
-
        /*
         * To reset, we hit the on-board reset register
         * in the system FPGA
         */
-       val = __raw_readl(hdr_ctrl);
-       val |= INTEGRATOR_HDR_CTRL_RESET;
-       __raw_writel(val, hdr_ctrl);
+       cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
 }
 
 #endif
index e361e94..2ecbfa7 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <asm/system.h>
 #include <asm/leds.h>
+#include <asm/mach-types.h>
 
 /*
  * Where is the timer (VA)?
  */
 #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
 #if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 8)           /* Divide by 256 */
-#define TIMER_CTRL     0x88                            /* Enable, Clock / 256 */
 #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
 #elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 4)           /* Divide by 16 */
-#define TIMER_CTRL     0x84                            /* Enable, Clock / 16 */
 #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
 #else
-#define TIMER_RELOAD   (TIMER_INTERVAL)
-#define TIMER_CTRL     0x80                            /* Enable */
 #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
 #endif
 
+#define TIMER_CTRL_IE  (1 << 5)                        /* Interrupt Enable */
+
 /*
  * What does it look like?
  */
@@ -56,6 +53,8 @@ typedef struct TimerStruct {
 
 extern unsigned long (*gettimeoffset)(void);
 
+static unsigned long timer_reload;
+
 /*
  * Returns number of ms since last clock interrupt.  Note that interrupts
  * will have been disabled by do_gettimeoffset()
@@ -81,13 +80,13 @@ static unsigned long integrator_gettimeoffset(void)
        /*
         * Number of ticks since last interrupt.
         */
-       ticks1 = TIMER_RELOAD - ticks2;
+       ticks1 = timer_reload - ticks2;
 
        /*
         * Interrupt pending?  If so, we've reloaded once already.
         */
        if (status & (1 << IRQ_TIMERINT1))
-               ticks1 += TIMER_RELOAD;
+               ticks1 += timer_reload;
 
        /*
         * Convert the ticks to usecs
@@ -121,8 +120,21 @@ void __init time_init(void)
        volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
        volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
        volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
-
-       timer_irq.handler = integrator_timer_interrupt;
+       unsigned int timer_ctrl = 0x80 | 0x40;  /* periodic */
+
+       if (machine_is_integrator()) {
+               timer_reload = 1000000 * TICKS_PER_uSEC / HZ;
+       } else if (machine_is_cintegrator()) {
+               timer_reload = 1000000 / HZ;
+               timer_ctrl |= TIMER_CTRL_IE;
+       }
+       if (timer_reload > 0x100000) {
+               timer_reload >>= 8;
+               timer_ctrl |= 0x08; /* /256 */
+       } else if (timer_reload > 0x010000) {
+               timer_reload >>= 4;
+               timer_ctrl |= 0x04; /* /16 */
+       }
 
        /*
         * Initialise to a known state (all timers off)
@@ -131,12 +143,14 @@ void __init time_init(void)
        timer1->TimerControl = 0;
        timer2->TimerControl = 0;
 
-       timer1->TimerLoad    = TIMER_RELOAD;
-       timer1->TimerControl = TIMER_CTRL | 0x40;       /* periodic */
+       timer1->TimerLoad    = timer_reload;
+       timer1->TimerValue   = timer_reload;
+       timer1->TimerControl = timer_ctrl;
 
        /* 
         * Make irqs happen for the system timer
         */
+       timer_irq.handler = integrator_timer_interrupt;
        setup_irq(IRQ_TIMERINT1, &timer_irq);
        gettimeoffset = integrator_gettimeoffset;
 }
index 174afa5..17bb14b 100644 (file)
 #ifndef ASMARM_AMBA_H
 #define ASMARM_AMBA_H
 
+#define AMBA_NR_IRQS   2
+
 struct amba_device {
        struct device           dev;
        struct resource         res;
-       unsigned int            irq;
        unsigned int            periphid;
+       unsigned int            irq[AMBA_NR_IRQS];
 };
 
 struct amba_id {
@@ -40,5 +42,13 @@ int amba_driver_register(struct amba_driver *);
 void amba_driver_unregister(struct amba_driver *);
 int amba_device_register(struct amba_device *, struct resource *);
 void amba_device_unregister(struct amba_device *);
+struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int);
+int amba_request_regions(struct amba_device *, const char *);
+void amba_release_regions(struct amba_device *);
+
+#define amba_config(d) (((d)->periphid >> 24) & 0xff)
+#define amba_rev(d)    (((d)->periphid >> 20) & 0x0f)
+#define amba_manf(d)   (((d)->periphid >> 12) & 0xff)
+#define amba_part(d)   ((d)->periphid & 0xfff)
 
 #endif
index ad07316..6f60c30 100644 (file)
 #define _SAITR          _SA1111( 0x065c )
 #define _SADR           _SA1111( 0x0680 )
 
-#if LANGUAGE == C
-
 #define SACR0          __CCREG(0x0600)
 #define SACR1          __CCREG(0x0604)
 #define SACR2          __CCREG(0x0608)
 #define SAITR          __CCREG(0x065c)
 #define SADR           __CCREG(0x0680)
 
-#endif  /* LANGUAGE == C */
-
 #define SACR0_ENB      (1<<0)
 #define SACR0_BCKD     (1<<2)
 #define SACR0_RST      (1<<3)
 #define _PC_SDR                _SA1111( 0x1028 )
 #define _PC_SSR                _SA1111( 0x102c )
 
-#if LANGUAGE == C
-
 #define PA_DDR         __CCREG(0x1000)
 #define PA_DRR         __CCREG(0x1004)
 #define PA_DWR         __CCREG(0x1004)
 #define PC_SDR         __CCREG(0x1028)
 #define PC_SSR         __CCREG(0x102c)
 
-#endif  /* LANGUAGE == C */
-
 /*
  * Interrupt Controller
  *
index ac2ed84..5280c8f 100644 (file)
@@ -75,7 +75,7 @@ pci_unmap_single(struct pci_dev *hwdev, dma_addr_t handle, size_t size, int dir)
                return;
        }
 
-       return dma_unmap_single(hwdev ? &hwdev->dev : NULL, handle, size, dir);
+       dma_unmap_single(hwdev ? &hwdev->dev : NULL, handle, size, dir);
 }
 
 static inline int
index 76284ff..2e47880 100644 (file)
@@ -16,12 +16,12 @@ struct semaphore {
        atomic_t count;
        int sleepers;
        wait_queue_head_t wait;
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        long __magic;
 #endif
 };
 
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
 # define __SEM_DEBUG_INIT(name)        .__magic = (long)&(name).__magic
 #else
 # define __SEM_DEBUG_INIT(name)
@@ -46,7 +46,7 @@ static inline void sema_init(struct semaphore *sem, int val)
        atomic_set(&sem->count, val);
        sem->sleepers = 0;
        init_waitqueue_head(&sem->wait);
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        sem->__magic = (long)&sem->__magic;
 #endif
 }
@@ -85,7 +85,7 @@ extern void __up(struct semaphore * sem);
  */
 static inline void down(struct semaphore * sem)
 {
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
        might_sleep();
@@ -98,7 +98,7 @@ static inline void down(struct semaphore * sem)
  */
 static inline int down_interruptible (struct semaphore * sem)
 {
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
        might_sleep();
@@ -107,7 +107,7 @@ static inline int down_interruptible (struct semaphore * sem)
 
 static inline int down_trylock(struct semaphore *sem)
 {
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
 
@@ -122,7 +122,7 @@ static inline int down_trylock(struct semaphore *sem)
  */
 static inline void up(struct semaphore * sem)
 {
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
        CHECK_MAGIC(sem->__magic);
 #endif
 
index 4affa93..bba255b 100644 (file)
 #define __NR_tgkill                    (__NR_SYSCALL_BASE+268)
 #define __NR_utimes                    (__NR_SYSCALL_BASE+269)
 #define __NR_fadvise64_64              (__NR_SYSCALL_BASE+270)
+#define __NR_pciconfig_iobase          (__NR_SYSCALL_BASE+271)
+#define __NR_pciconfig_read            (__NR_SYSCALL_BASE+272)
+#define __NR_pciconfig_write           (__NR_SYSCALL_BASE+273)
 
 /*
  * The following SWIs are ARM private.
index 68fa169..ba8a35f 100644 (file)
@@ -52,6 +52,9 @@
 #ifndef __ASSEMBLY__
 
 #ifdef CONFIG_IOSAPIC
+
+#define NR_IOSAPICS                    256
+
 extern void __init iosapic_system_init (int pcat_compat);
 extern void __init iosapic_init (unsigned long address,
                                    unsigned int gsi_base);
diff --git a/include/asm-ia64/sn/alenlist.h b/include/asm-ia64/sn/alenlist.h
deleted file mode 100644 (file)
index 4ab6c07..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_ALENLIST_H
-#define _ASM_IA64_SN_ALENLIST_H
-
-#include <linux/types.h>
-
-/* Definition of Address/Length List */
-
-/*
- * An Address/Length List is used when setting up for an I/O DMA operation.
- * A driver creates an Address/Length List that describes to the the DMA 
- * interface where in memory the DMA should go.  The bus interface sets up 
- * mapping registers, if required, and returns a suitable list of "physical 
- * addresses" or "I/O address" to the driver.  The driver then uses these 
- * to set up an appropriate scatter/gather operation(s).
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * An Address/Length List Address.  It'll get cast to the appropriate type,
- * and must be big enough to hold the largest possible address in any
- * supported address space.
- */
-typedef u64 alenaddr_t;
-typedef u64 uvaddr_t;
-
-typedef struct alenlist_s *alenlist_t;
-
-/* 
- * For tracking progress as we walk down an address/length list.
- */
-typedef struct alenlist_cursor_s *alenlist_cursor_t;
-
-/*
- * alenlist representation that can be passed via an idl
- */
-struct external_alenlist {
-       alenaddr_t      addr;
-       size_t          len;
-};
-typedef struct external_alenlist *external_alenlist_t;
-
-
-/* Return codes from alenlist routines.  */
-#define ALENLIST_FAILURE (-1)
-#define ALENLIST_SUCCESS 0
-
-
-/* Flags to alenlist routines */
-#define AL_NOSLEEP     0x01            /* Do not sleep, waiting for memory */
-#define AL_NOCOMPACT   0x02            /* Do not try to compact adjacent entries */
-#define AL_LEAVE_CURSOR        0x04            /* Do not update cursor */
-
-
-/* Create an Address/Length List, and clear it of all entries.  */
-extern alenlist_t alenlist_create(unsigned int flags);
-
-/* Grow/shrink an Address/Length List and FIX its size. */
-extern int alenlist_grow(alenlist_t, size_t npairs);
-
-/* Clear an Address/Length List so that it now describes 0 pairs. */
-extern void alenlist_clear(alenlist_t alenlist);
-
-/*
- * Convenience function to create an Address/Length List and then append 
- * the specified Address/Length Pair.  Exactly the same as alenlist_create 
- * followed by alenlist_append.  Can be used when a small list (e.g. 1 pair)
- * is adequate.
- */
-extern alenlist_t
-alenpair_init( alenaddr_t address,                     /* init to this address */
-               size_t length);                         /* init to this length */
-
-/* 
- * Peek at the head of an Address/Length List.  This does *NOT* update
- * the internal cursor.
- */
-extern int
-alenpair_get(  alenlist_t alenlist,            /* in: get from this List */
-               alenaddr_t *address,            /* out: address */
-               size_t *length);                /* out: length */
-
-/* Free the space consumed by an Address/Length List. */
-extern void alenlist_destroy(alenlist_t alenlist);
-
-/*
- * Indicate that we're done using an Address/Length List.
- * If we are the last user, destroy the List.
- */
-extern void
-alenlist_done(alenlist_t alenlist);
-
-/* Append another Pair to a List */
-extern int alenlist_append(alenlist_t alenlist,        /* append to this list */
-                       alenaddr_t address,             /* address to append */
-                       size_t length,                  /* length to append */
-                       unsigned int flags);
-
-/* 
- * Replace a Pair in the middle of a List, and return old values.
- * (not generally useful for drivers; used by bus providers).
- */
-extern int
-alenlist_replace(      alenlist_t alenlist,            /* in: replace in this list */
-                       alenlist_cursor_t cursorp,      /* inout: which item to replace */
-                       alenaddr_t *addrp,              /* inout: address */
-                       size_t *lengthp,                /* inout: length */
-                       unsigned int flags);
-
-
-/* Get the next Pair from a List */
-extern int alenlist_get(alenlist_t alenlist,           /* in: get from this list */
-                       alenlist_cursor_t cursorp,      /* inout: which item to get */
-                       size_t maxlength,               /* in: at most length */
-                       alenaddr_t *addr,               /* out: address */
-                       size_t *length,                 /* out: length */
-                       unsigned int flags);
-
-
-/* Return the number of Pairs stored in this List */
-extern int alenlist_size(alenlist_t alenlist);
-
-/* Concatenate two Lists. */
-extern void alenlist_concat(   alenlist_t from,        /* copy from this list */
-                               alenlist_t to);         /* to this list */
-
-/* Create a copy of an Address/Length List */
-extern alenlist_t alenlist_clone(alenlist_t old,       /* clone this list */
-                                unsigned int flags);
-
-
-/* Allocate and initialize an Address/Length List Cursor */
-extern alenlist_cursor_t alenlist_cursor_create(alenlist_t alenlist, unsigned int flags);
-
-/* Free an Address/Length List Cursor */
-extern void alenlist_cursor_destroy(alenlist_cursor_t cursorp);
-
-/*
- * Initialize an Address/Length List Cursor in order to walk thru an
- * Address/Length List from the beginning.
- */
-extern int alenlist_cursor_init(alenlist_t alenlist, 
-                               size_t offset, 
-                               alenlist_cursor_t cursorp);
-
-/* Clone an Address/Length List Cursor. */
-extern int alenlist_cursor_clone(alenlist_t alenlist, 
-                               alenlist_cursor_t cursorp_in, 
-                               alenlist_cursor_t cursorp_out);
-
-/* 
- * Return the number of bytes passed so far according to the specified
- * Address/Length List Cursor.
- */
-extern size_t alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp);
-
-
-
-
-/* Convert from a Kernel Virtual Address to a Physical Address/Length List */
-extern alenlist_t kvaddr_to_alenlist(  alenlist_t alenlist, 
-                                       caddr_t kvaddr, 
-                                       size_t length, 
-                                       unsigned int flags);
-
-/* Convert from a User Virtual Address to a Physical Address/Length List */
-extern alenlist_t uvaddr_to_alenlist(  alenlist_t alenlist,
-                                       uvaddr_t vaddr, 
-                                       size_t length,
-                                       unsigned int flags);
-
-/* Convert from a buf struct to a Physical Address/Length List */
-struct buf;
-extern alenlist_t buf_to_alenlist(     alenlist_t alenlist, 
-                                       struct buf *buf, 
-                                       unsigned int flags);
-
-
-/* 
- * Tracking position as we walk down an Address/Length List.
- * This structure is NOT generally for use by device drivers.
- */
-struct alenlist_cursor_s {
-       struct alenlist_s       *al_alenlist;   /* which list */
-       size_t                  al_offset;      /* total bytes passed by cursor */
-       struct alenlist_chunk_s *al_chunk;      /* which chunk in alenlist */
-       unsigned int            al_index;       /* which pair in chunk */
-       size_t                  al_bcount;      /* offset into address/length pair */
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ASM_IA64_SN_ALENLIST_H */
index b10d9ea..c6d961e 100644 (file)
 extern vertex_hdl_t hwgraph_root;
 extern vertex_hdl_t linux_busnum;
 
-void hwgraph_debug(char *, char *, int, vertex_hdl_t, vertex_hdl_t, char *, ...);
+void hwgraph_debug(char *, const char *, int, vertex_hdl_t, vertex_hdl_t, char *, ...);
 
 #if 1
-#define HWGRAPH_DEBUG(args) hwgraph_debug args ;
+#define HWGRAPH_DEBUG(args...) hwgraph_debug(args)
 #else   
 #define HWGRAPH_DEBUG(args)
 #endif  
index 550bf7e..f65ac28 100644 (file)
@@ -119,10 +119,6 @@ extern iopaddr_t   pcibr_dmamap_addr(pcibr_dmamap_t dmamap,
                                          paddr_t paddr,
                                          size_t byte_count);
 
-extern alenlist_t      pcibr_dmamap_list(pcibr_dmamap_t dmamap,
-                                         alenlist_t palenlist,
-                                         unsigned flags);
-
 extern void            pcibr_dmamap_done(pcibr_dmamap_t dmamap);
 
 /*
@@ -139,20 +135,12 @@ extern iopaddr_t  pcibr_dmatrans_addr(vertex_hdl_t dev,
                                            size_t byte_count,
                                            unsigned flags);
 
-extern alenlist_t      pcibr_dmatrans_list(vertex_hdl_t dev,
-                                           device_desc_t dev_desc,
-                                           alenlist_t palenlist,
-                                           unsigned flags);
-
 extern void            pcibr_dmamap_drain(pcibr_dmamap_t map);
 
 extern void            pcibr_dmaaddr_drain(vertex_hdl_t vhdl,
                                            paddr_t addr,
                                            size_t bytes);
 
-extern void            pcibr_dmalist_drain(vertex_hdl_t vhdl,
-                                           alenlist_t list);
-
 typedef unsigned       pcibr_intr_ibit_f(pciio_info_t info,
                                          pciio_intr_line_t lines);
 
index f2168a8..24c6ac9 100644 (file)
 
 #ifdef __KERNEL__
 #include <asm/sn/dmamap.h>
-#include <asm/sn/alenlist.h>
 #else
 #include <dmamap.h>
-#include <alenlist.h>
 #endif
 
 typedef int pciio_vendor_id_t;
@@ -99,10 +97,6 @@ typedef int pciio_space_t;           /* PCI address space designation */
  *     sleep waiting for resoruces, return an error
  *     instead. (PIOMAP_NOSLEEP and DMAMAP_NOSLEEP are
  *     the same numeric value and are acceptable).
- * PCIIO_INPLACE: when operating on alenlist structures,
- *     reuse the source alenlist rather than creating a
- *     new one. (PIOMAP_INPLACE and DMAMAP_INPLACE are
- *     the same numeric value and are acceptable).
  *
  * PCIIO_DMA_CMD: configure this stream as a
  *     generic "command" stream. Generally this
@@ -162,7 +156,6 @@ typedef int pciio_space_t;          /* PCI address space designation */
 
 #define        PCIIO_FIXED             DMAMAP_FIXED
 #define        PCIIO_NOSLEEP           DMAMAP_NOSLEEP
-#define        PCIIO_INPLACE           DMAMAP_INPLACE
 
 #define PCIIO_DMA_CMD          0x0010
 #define PCIIO_DMA_DATA         0x0020
@@ -398,9 +391,6 @@ pciio_dmaaddr_drain_f       (vertex_hdl_t vhdl,
                         paddr_t addr,
                         size_t bytes);
 
-typedef void
-pciio_dmalist_drain_f  (vertex_hdl_t vhdl,
-                        alenlist_t list);
 
 /* INTERRUPT MANAGEMENT */
 
@@ -494,7 +484,6 @@ typedef struct pciio_provider_s {
     pciio_dmatrans_addr_f  *dmatrans_addr;
     pciio_dmamap_drain_f   *dmamap_drain;
     pciio_dmaaddr_drain_f  *dmaaddr_drain;
-    pciio_dmalist_drain_f  *dmalist_drain;
 
     /* INTERRUPT MANAGEMENT */
     pciio_intr_alloc_f     *intr_alloc;
@@ -536,7 +525,6 @@ extern pciio_dmamap_done_f pciio_dmamap_done;
 extern pciio_dmatrans_addr_f pciio_dmatrans_addr;
 extern pciio_dmamap_drain_f pciio_dmamap_drain;
 extern pciio_dmaaddr_drain_f pciio_dmaaddr_drain;
-extern pciio_dmalist_drain_f pciio_dmalist_drain;
 extern pciio_intr_alloc_f pciio_intr_alloc;
 extern pciio_intr_free_f pciio_intr_free;
 extern pciio_intr_connect_f pciio_intr_connect;
index 37a3b22..ac3b00a 100644 (file)
@@ -3385,7 +3385,6 @@ typedef ii_icrb0_e_u_t icrbe_t;
 #define IO_PERF_SETS   32
 
 #if __KERNEL__
-#include <asm/sn/alenlist.h>
 #include <asm/sn/dmamap.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/xtalk/xtalk.h>
@@ -3530,11 +3529,6 @@ hub_dmamap_addr(        hub_dmamap_t dmamap,    /* use mapping resources */
                         paddr_t paddr,          /* map for this address */
                         size_t byte_count);     /* map this many bytes */
 
-extern alenlist_t
-hub_dmamap_list(        hub_dmamap_t dmamap,    /* use mapping resources */
-                        alenlist_t alenlist,    /* map this Addr/Length List */
-                        unsigned flags);
-
 extern void
 hub_dmamap_done(        hub_dmamap_t dmamap);   /* done w/ mapping resources */
 
@@ -3545,12 +3539,6 @@ hub_dmatrans_addr(      vertex_hdl_t dev,       /* translate for this device */
                         size_t byte_count,      /* length */
                         unsigned flags);                /* defined in dma.h */
 
-extern alenlist_t
-hub_dmatrans_list(      vertex_hdl_t dev,       /* translate for this device */
-                        device_desc_t dev_desc, /* device descriptor */
-                        alenlist_t palenlist,   /* system addr/length list */
-                        unsigned flags);                /* defined in dma.h */
-
 extern void
 hub_dmamap_drain(       hub_dmamap_t map);
 
@@ -3559,10 +3547,6 @@ hub_dmaaddr_drain(      vertex_hdl_t vhdl,
                         paddr_t addr,
                         size_t bytes);
 
-extern void
-hub_dmalist_drain(      vertex_hdl_t vhdl,
-                        alenlist_t list);
-
 
 /* INTERRUPT MANAGEMENT */
 typedef struct hub_intr_s *hub_intr_t;
index dc6e8b2..b65da04 100644 (file)
@@ -59,7 +59,6 @@ typedef struct xtalk_piomap_s *xtalk_piomap_t;
 
 #include <asm/types.h>
 #include <asm/sn/types.h>
-#include <asm/sn/alenlist.h>
 #include <asm/sn/ioerror.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/dmamap.h>
@@ -78,14 +77,9 @@ struct xwidget_hwid_s;
  *     sleep waiting for resoruces, return an error
  *     instead. (PIOMAP_NOSLEEP and DMAMAP_NOSLEEP are
  *     the same numeric value and are acceptable).
- * XTALK_INPLACE: when operating on alenlist structures,
- *     reuse the source alenlist rather than creating a
- *     new one. (PIOMAP_INPLACE and DMAMAP_INPLACE are
- *     the same numeric value and are acceptable).
  */
 #define        XTALK_FIXED             DMAMAP_FIXED
 #define        XTALK_NOSLEEP           DMAMAP_NOSLEEP
-#define        XTALK_INPLACE           DMAMAP_INPLACE
 
 /* PIO MANAGEMENT */
 typedef xtalk_piomap_t
@@ -139,11 +133,6 @@ xtalk_dmamap_addr_f     (xtalk_dmamap_t dmamap,            /* use these mapping resources
                         paddr_t paddr,         /* map for this address */
                         size_t byte_count);    /* map this many bytes */
 
-typedef alenlist_t
-xtalk_dmamap_list_f     (xtalk_dmamap_t dmamap,                /* use these mapping resources */
-                        alenlist_t alenlist,   /* map this address/length list */
-                        unsigned int flags);
-
 typedef void
 xtalk_dmamap_done_f     (xtalk_dmamap_t dmamap);
 
@@ -154,12 +143,6 @@ xtalk_dmatrans_addr_f   (vertex_hdl_t dev, /* translate for this device */
                         size_t byte_count,     /* length */
                         unsigned int flags);
 
-typedef alenlist_t
-xtalk_dmatrans_list_f   (vertex_hdl_t dev,     /* translate for this device */
-                        device_desc_t dev_desc,        /* device descriptor */
-                        alenlist_t palenlist,  /* system address/length list */
-                        unsigned int flags);
-
 typedef void
 xtalk_dmamap_drain_f   (xtalk_dmamap_t map);   /* drain this map's channel */
 
@@ -168,11 +151,6 @@ xtalk_dmaaddr_drain_f      (vertex_hdl_t vhdl,     /* drain channel from this device */
                         paddr_t addr,          /* to this physical address */
                         size_t bytes);         /* for this many bytes */
 
-typedef void
-xtalk_dmalist_drain_f  (vertex_hdl_t vhdl,     /* drain channel from this device */
-                        alenlist_t list);      /* for this set of physical blocks */
-
-
 /* INTERRUPT MANAGEMENT */
 
 /*
@@ -260,13 +238,10 @@ typedef struct xtalk_provider_s {
     xtalk_dmamap_alloc_f   *dmamap_alloc;
     xtalk_dmamap_free_f    *dmamap_free;
     xtalk_dmamap_addr_f    *dmamap_addr;
-    xtalk_dmamap_list_f    *dmamap_list;
     xtalk_dmamap_done_f    *dmamap_done;
     xtalk_dmatrans_addr_f  *dmatrans_addr;
-    xtalk_dmatrans_list_f  *dmatrans_list;
     xtalk_dmamap_drain_f   *dmamap_drain;
     xtalk_dmaaddr_drain_f  *dmaaddr_drain;
-    xtalk_dmalist_drain_f  *dmalist_drain;
 
     /* INTERRUPT MANAGEMENT */
     xtalk_intr_alloc_f     *intr_alloc;
@@ -289,13 +264,10 @@ extern xtalk_piotrans_addr_f xtalk_piotrans_addr;
 extern xtalk_dmamap_alloc_f xtalk_dmamap_alloc;
 extern xtalk_dmamap_free_f xtalk_dmamap_free;
 extern xtalk_dmamap_addr_f xtalk_dmamap_addr;
-extern xtalk_dmamap_list_f xtalk_dmamap_list;
 extern xtalk_dmamap_done_f xtalk_dmamap_done;
 extern xtalk_dmatrans_addr_f xtalk_dmatrans_addr;
-extern xtalk_dmatrans_list_f xtalk_dmatrans_list;
 extern xtalk_dmamap_drain_f xtalk_dmamap_drain;
 extern xtalk_dmaaddr_drain_f xtalk_dmaaddr_drain;
-extern xtalk_dmalist_drain_f xtalk_dmalist_drain;
 extern xtalk_intr_alloc_f xtalk_intr_alloc;
 extern xtalk_intr_alloc_f xtalk_intr_alloc_nothd;
 extern xtalk_intr_free_f xtalk_intr_free;
index a628896..c62fe66 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <linux/config.h>
 
-#ifndef __ASSEMBLY__
 /*
  * PA 2.0 processors have 64-byte cachelines; PA 1.1 processors have
  * 32-byte cachelines.  The default configuration is not for SMP anyway,
 #define L1_CACHE_SHIFT 5
 #endif
 
+#ifndef __ASSEMBLY__
+
 #define L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
 #define L1_CACHE_SHIFT_MAX 5   /* largest L1 which this arch supports */
 
-#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
-
 extern void flush_data_cache_local(void);  /* flushes local data-cache only */
 extern void flush_instruction_cache_local(void); /* flushes local code-cache only */
 #ifdef CONFIG_SMP
index cbb6963..3edb5db 100644 (file)
@@ -24,6 +24,7 @@ typedef u16   compat_nlink_t;
 typedef u16    compat_ipc_pid_t;
 typedef s32    compat_daddr_t;
 typedef u32    compat_caddr_t;
+typedef u32    compat_timer_t;
 
 typedef s32    compat_int_t;
 typedef s32    compat_long_t;
@@ -101,6 +102,15 @@ struct compat_statfs {
        s32             f_spare[5];
 };
 
+struct compat_sigcontext {
+       compat_int_t sc_flags;
+       compat_int_t sc_gr[32]; /* PSW in sc_gr[0] */
+       u64 sc_fr[32];
+       compat_int_t sc_iasq[2];
+       compat_int_t sc_iaoq[2];
+       compat_int_t sc_sar; /* cr11 */
+};
+
 #define COMPAT_RLIM_INFINITY 0xffffffff
 
 typedef u32            compat_old_sigset_t;    /* at least 32 bits */
@@ -129,9 +139,7 @@ static inline void *compat_ptr(compat_uptr_t uptr)
 static __inline__ void *compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = &current->thread.regs;
-       unsigned long usp = regs->gr[30];
-
-       return (void *)(usp + len);
+       return (void *)regs->gr[30];
 }
 
 #endif /* _ASM_PARISC_COMPAT_H */
diff --git a/include/asm-parisc/compat_rt_sigframe.h b/include/asm-parisc/compat_rt_sigframe.h
new file mode 100644 (file)
index 0000000..81bec28
--- /dev/null
@@ -0,0 +1,50 @@
+#include<linux/compat.h>
+#include<linux/compat_siginfo.h>
+#include<asm/compat_ucontext.h>
+
+#ifndef _ASM_PARISC_COMPAT_RT_SIGFRAME_H
+#define _ASM_PARISC_COMPAT_RT_SIGFRAME_H
+
+/* In a deft move of uber-hackery, we decide to carry the top half of all
+ * 64-bit registers in a non-portable, non-ABI, hidden structure.
+ * Userspace can read the hidden structure if it *wants* but is never
+ * guaranteed to be in the same place. Infact the uc_sigmask from the 
+ * ucontext_t structure may push the hidden register file downards
+ */
+struct compat_regfile {
+       /* Upper half of all the 64-bit registers that were truncated
+          on a copy to a 32-bit userspace */
+       compat_int_t rf_gr[32];
+       compat_int_t rf_iasq[2];
+       compat_int_t rf_iaoq[2];
+       compat_int_t rf_sar;
+};
+
+#define COMPAT_SIGRETURN_TRAMP 4
+#define COMPAT_SIGRESTARTBLOCK_TRAMP 5 
+#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + COMPAT_SIGRESTARTBLOCK_TRAMP)
+
+struct compat_rt_sigframe {
+       /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c 
+               Secondary to that it must protect the ERESTART_RESTARTBLOCK
+               trampoline we left on the stack (we were bad and didn't 
+               change sp so we could run really fast.) */
+       compat_uint_t tramp[COMPAT_TRAMP_SIZE];
+       compat_siginfo_t info;
+       struct compat_ucontext uc;
+       /* Hidden location of truncated registers, *must* be last. */
+       struct compat_regfile regs; 
+};
+
+/*
+ * The 32-bit ABI wants at least 48 bytes for a function call frame:
+ * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of
+ * which Linux/parisc uses is sp-20 for the saved return pointer...)
+ * Then, the stack pointer must be rounded to a cache line (64 bytes).
+ */
+#define SIGFRAME32             64
+#define FUNCTIONCALLFRAME32    48
+#define PARISC_RT_SIGFRAME_SIZE32                                      \
+       (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
+
+#endif
diff --git a/include/asm-parisc/compat_signal.h b/include/asm-parisc/compat_signal.h
new file mode 100644 (file)
index 0000000..6ad02c3
--- /dev/null
@@ -0,0 +1,2 @@
+/* Use generic */
+#include <asm-generic/compat_signal.h>
diff --git a/include/asm-parisc/compat_ucontext.h b/include/asm-parisc/compat_ucontext.h
new file mode 100644 (file)
index 0000000..a1228a3
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _ASM_PARISC_COMPAT_UCONTEXT_H
+#define _ASM_PARISC_COMPAT_UCONTEXT_H
+
+#include<linux/compat.h>
+#include<asm/compat_signal.h>
+
+/* 32-bit ucontext as seen from an 64-bit kernel */
+struct compat_ucontext {
+       compat_uint_t uc_flags;
+       compat_uptr_t uc_link;
+       compat_stack_t uc_stack;        /* struct compat_sigaltstack (12 bytes)*/       
+       /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */
+       compat_uint_t pad[1];
+       struct compat_sigcontext uc_mcontext;
+       compat_sigset_t uc_sigmask;     /* mask last for extensibility */
+};
+
+#endif /* !_ASM_PARISC_COMPAT_UCONTEXT_H */
index aca998a..d5dca01 100644 (file)
@@ -29,7 +29,8 @@
 #ifdef PCI_DEBUG
 #define ASSERT(expr) \
        if(!(expr)) { \
-               printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
+               printk("\n%s:%d: Assertion " #expr " failed!\n", \
+                      __FILE__, __LINE__); \
                panic(#expr); \
        }
 #else
@@ -55,6 +56,12 @@ struct pci_hba_data {
        struct resource io_space;       /* PIOP */
        struct resource lmmio_space;    /* bus addresses < 4Gb */
        struct resource elmmio_space;   /* additional bus addresses < 4Gb */
+       struct resource gmmio_space;    /* bus addresses > 4Gb */
+       /* NOTE: Dino code assumes it can use *all* of the lmmio_space,
+        * elmmio_space and gmmio_space as a contiguous array of
+        * resources.  This #define represents the array size */
+       #define DINO_MAX_LMMIO_RESOURCES        3
+
        unsigned long   lmmio_space_offset;  /* CPU view - PCI view */
        void *          iommu;          /* IOMMU this device is under */
        /* REVISIT - spinlock to protect resources? */
index b3214f1..c49f73b 100644 (file)
@@ -478,7 +478,11 @@ extern int pdc_type;
 #define PDC_TYPE_SYSTEM_MAP     1 /* 32-bit, but supports PDC_SYSTEM_MAP */
 #define PDC_TYPE_SNAKE          2 /* Doesn't support SYSTEM_MAP */
 
-#define is_pdc_pat()    (pdc_type == PDC_TYPE_PAT)
+#ifdef CONFIG_PARISC64
+#define is_pdc_pat()    (PDC_TYPE_PAT == pdc_type)
+#else
+#define is_pdc_pat()    (0)
+#endif
 
 struct pdc_chassis_info {       /* for PDC_CHASSIS_INFO */
        unsigned long actcnt;   /* actual number of bytes returned */
index dc91ca5..eb19624 100644 (file)
@@ -29,7 +29,7 @@ typedef long                  __kernel_time_t;
 typedef unsigned int           __kernel_size_t;
 typedef int                    __kernel_ssize_t;
 typedef int                    __kernel_ptrdiff_t;
-typedef int                    __kernel_time_t;
+typedef long                   __kernel_time_t;
 #endif
 typedef char *                 __kernel_caddr_t;
 
index a9b5193..5623c03 100644 (file)
@@ -1,32 +1,27 @@
 #ifndef _ASM_PARISC_RT_SIGFRAME_H
 #define _ASM_PARISC_RT_SIGFRAME_H
 
+#ifdef CONFIG_COMPAT
+#include <asm/compat_rt_sigframe.h>
+#endif
+
+#define SIGRETURN_TRAMP 4
+#define SIGRESTARTBLOCK_TRAMP 5 
+#define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP)
+
 struct rt_sigframe {
-       unsigned int tramp[4];
+       /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c 
+               Secondary to that it must protect the ERESTART_RESTARTBLOCK
+               trampoline we left on the stack (we were bad and didn't 
+               change sp so we could run really fast.) */
+       unsigned int tramp[TRAMP_SIZE];
        struct siginfo info;
        struct ucontext uc;
 };
 
-/*
- * The 32-bit ABI wants at least 48 bytes for a function call frame:
- * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of
- * which Linux/parisc uses is sp-20 for the saved return pointer...)
- * Then, the stack pointer must be rounded to a cache line (64 bytes).
- */
-#define SIGFRAME32             64
-#define FUNCTIONCALLFRAME32    48
-#define PARISC_RT_SIGFRAME_SIZE32                                      \
-       (((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
-
-#ifdef __LP64__
 #define        SIGFRAME                128
 #define FUNCTIONCALLFRAME      96
 #define PARISC_RT_SIGFRAME_SIZE                                        \
        (((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME) + SIGFRAME) & -SIGFRAME)
-#else
-#define        SIGFRAME                SIGFRAME32
-#define FUNCTIONCALLFRAME      FUNCTIONCALLFRAME32
-#define PARISC_RT_SIGFRAME_SIZE        PARISC_RT_SIGFRAME_SIZE32
-#endif
 
 #endif
index da7dbc4..d4909f5 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _PARISC_SIGINFO_H
 #define _PARISC_SIGINFO_H
 
-#define HAVE_ARCH_COPY_SIGINFO_TO_USER
-
 #include <asm-generic/siginfo.h>
 
 /*
index 3002fac..83cdf60 100644 (file)
@@ -1,25 +1,33 @@
 #ifndef _PARISC_SUPERIO_H
 #define _PARISC_SUPERIO_H
 
-/* Offsets to configuration and base address registers */
 #define IC_PIC1    0x20                /* PCI I/O address of master 8259 */
 #define IC_PIC2    0xA0                /* PCI I/O address of slave */
+
+/* Config Space Offsets to configuration and base address registers */
 #define SIO_CR     0x5A                /* Configuration Register */
-#define SIO_ACPIBAR 0x88               /* ACPI BAR */
+#define SIO_ACPIBAR 0x88       /* ACPI BAR */
 #define SIO_FDCBAR 0x90                /* Floppy Disk Controller BAR */
 #define SIO_SP1BAR 0x94                /* Serial 1 BAR */
 #define SIO_SP2BAR 0x98                /* Serial 2 BAR */
 #define SIO_PPBAR  0x9C                /* Parallel BAR */
 
-/* Interrupt triggers and routing */
 #define TRIGGER_1  0x67                /* Edge/level trigger register 1 */
 #define TRIGGER_2  0x68                /* Edge/level trigger register 2 */
-#define IR_SER     0x69                /* Serial 1 [0:3] and Serial 2 [4:7] */
-#define IR_PFD     0x6a                /* Parallel [0:3] and Floppy [4:7] */
-#define IR_IDE     0x6b                /* IDE1 [0:3] and IDE2 [4:7] */
-#define IR_USB     0x6d         /* USB [4:7] */
-#define IR_LOW     0x69                /* Lowest interrupt routing reg */
-#define IR_HIGH    0x71                /* Highest interrupt routing reg */
+
+/* Interrupt Routing Control registers */
+#define CFG_IR_SER    0x69     /* Serial 1 [0:3] and Serial 2 [4:7] */
+#define CFG_IR_PFD    0x6a     /* Parallel [0:3] and Floppy [4:7] */
+#define CFG_IR_IDE    0x6b     /* IDE1     [0:3] and IDE2 [4:7] */
+#define CFG_IR_INTAB  0x6c     /* PCI INTA [0:3] and INT B [4:7] */
+#define CFG_IR_INTCD  0x6d     /* PCI INTC [0:3] and INT D [4:7] */
+#define CFG_IR_PS2    0x6e     /* PS/2 KBINT [0:3] and Mouse [4:7] */
+#define CFG_IR_FXBUS  0x6f     /* FXIRQ[0] [0:3] and FXIRQ[1] [4:7] */
+#define CFG_IR_USB    0x70     /* FXIRQ[2] [0:3] and USB [4:7] */
+#define CFG_IR_ACPI   0x71     /* ACPI SCI [0:3] and reserved [4:7] */
+
+#define CFG_IR_LOW     CFG_IR_SER      /* Lowest interrupt routing reg */
+#define CFG_IR_HIGH    CFG_IR_ACPI     /* Highest interrupt routing reg */
 
 /* 8259 operational control words */
 #define OCW2_EOI   0x20                /* Non-specific EOI */
 #define SUPERIO_NIRQS   8
 
 struct superio_device {
-       u16 fdc_base;
-       u16 sp1_base;
-       u16 sp2_base;
-       u16 pp_base;
-       u16 acpi_base;
-       int iosapic_irq;
-       int iosapic_irq_enabled;
+       u32 fdc_base;
+       u32 sp1_base;
+       u32 sp2_base;
+       u32 pp_base;
+       u32 acpi_base;
+       int suckyio_irq_enabled;
        struct irq_region *irq_region;
-       struct pci_dev *lio_pdev;       /* pci device for legacy IO fn */
+       struct pci_dev *lio_pdev;       /* pci device for legacy IO (fn 1) */
+       struct pci_dev *usb_pdev;       /* pci device for USB (fn 2) */
 };
 
 /*
index 66510fd..f147bac 100644 (file)
@@ -62,7 +62,7 @@ extern int __put_user_bad(void);
  */
 
 struct exception_table_entry {
-       unsigned long addr;  /* address of insn that is allowed to fault.   */
+       unsigned long insn;  /* address of insn that is allowed to fault.   */
        long skip;           /* pcoq skip | r9 clear flag | r8 -EFAULT flag */
 };
 
@@ -98,7 +98,7 @@ struct exception_table_entry {
 #define __get_kernel_asm(ldx,ptr)                       \
        __asm__("\n1:\t" ldx "\t0(%2),%0\n"             \
                "2:\n"                                  \
-               "\t.section __ex_table,\"a\"\n"         \
+               "\t.section __ex_table,\"aw\"\n"         \
                 "\t.dword\t1b\n"                       \
                 "\t.dword\t(2b-1b)+3\n"                \
                 "\t.previous"                          \
@@ -108,7 +108,7 @@ struct exception_table_entry {
 #define __get_user_asm(ldx,ptr)                         \
        __asm__("\n1:\t" ldx "\t0(%%sr3,%2),%0\n"       \
                "2:\n"                                  \
-               "\t.section __ex_table,\"a\"\n"         \
+               "\t.section __ex_table,\"aw\"\n"         \
                 "\t.dword\t1b\n"                       \
                 "\t.dword\t(2b-1b)+3\n"                \
                 "\t.previous"                          \
@@ -118,7 +118,7 @@ struct exception_table_entry {
 #define __get_kernel_asm(ldx,ptr)                       \
        __asm__("\n1:\t" ldx "\t0(%2),%0\n"             \
                "2:\n"                                  \
-               "\t.section __ex_table,\"a\"\n"         \
+               "\t.section __ex_table,\"aw\"\n"         \
                 "\t.word\t1b\n"                        \
                 "\t.word\t(2b-1b)+3\n"                 \
                 "\t.previous"                          \
@@ -128,13 +128,13 @@ struct exception_table_entry {
 #define __get_user_asm(ldx,ptr)                         \
        __asm__("\n1:\t" ldx "\t0(%%sr3,%2),%0\n"       \
                "2:\n"                                  \
-               "\t.section __ex_table,\"a\"\n"         \
+               "\t.section __ex_table,\"aw\"\n"         \
                 "\t.word\t1b\n"                        \
                 "\t.word\t(2b-1b)+3\n"                 \
                 "\t.previous"                          \
                : "=r"(__gu_val), "=r"(__gu_err)        \
                : "r"(ptr), "1"(__gu_err));
-#endif
+#endif /* !__LP64__ */
 
 #define __put_user(x,ptr)                                       \
 ({                                                             \
@@ -173,7 +173,7 @@ struct exception_table_entry {
        __asm__ __volatile__ (                              \
                "\n1:\t" stx "\t%2,0(%1)\n"                 \
                "2:\n"                                      \
-               "\t.section __ex_table,\"a\"\n"             \
+               "\t.section __ex_table,\"aw\"\n"             \
                 "\t.dword\t1b\n"                           \
                 "\t.dword\t(2b-1b)+1\n"                    \
                 "\t.previous"                              \
@@ -184,7 +184,7 @@ struct exception_table_entry {
        __asm__ __volatile__ (                              \
                "\n1:\t" stx "\t%2,0(%%sr3,%1)\n"           \
                "2:\n"                                      \
-               "\t.section __ex_table,\"a\"\n"             \
+               "\t.section __ex_table,\"aw\"\n"             \
                 "\t.dword\t1b\n"                           \
                 "\t.dword\t(2b-1b)+1\n"                    \
                 "\t.previous"                              \
@@ -195,7 +195,7 @@ struct exception_table_entry {
        __asm__ __volatile__ (                              \
                "\n1:\t" stx "\t%2,0(%1)\n"                 \
                "2:\n"                                      \
-               "\t.section __ex_table,\"a\"\n"             \
+               "\t.section __ex_table,\"aw\"\n"             \
                 "\t.word\t1b\n"                            \
                 "\t.word\t(2b-1b)+1\n"                     \
                 "\t.previous"                              \
@@ -206,7 +206,7 @@ struct exception_table_entry {
        __asm__ __volatile__ (                              \
                "\n1:\t" stx "\t%2,0(%%sr3,%1)\n"           \
                "2:\n"                                      \
-               "\t.section __ex_table,\"a\"\n"             \
+               "\t.section __ex_table,\"aw\"\n"             \
                 "\t.word\t1b\n"                            \
                 "\t.word\t(2b-1b)+1\n"                     \
                 "\t.previous"                              \
@@ -221,7 +221,7 @@ static inline void __put_kernel_asm64(u64 x, void *ptr)
                "\n1:\tstw %1,0(%0)\n"
                "\n2:\tstw %2,4(%0)\n"
                "3:\n"
-               "\t.section __ex_table,\"a\"\n"
+               "\t.section __ex_table,\"aw\"\n"
                 "\t.word\t1b\n"
                 "\t.word\t(3b-1b)+1\n"
                 "\t.word\t2b\n"
@@ -239,7 +239,7 @@ static inline void __put_user_asm64(u64 x, void *ptr)
                "\n1:\tstw %1,0(%%sr3,%0)\n"
                "\n2:\tstw %2,4(%%sr3,%0)\n"
                "3:\n"
-               "\t.section __ex_table,\"a\"\n"
+               "\t.section __ex_table,\"aw\"\n"
                 "\t.word\t1b\n"
                 "\t.word\t(3b-1b)+1\n"
                 "\t.word\t2b\n"
@@ -249,7 +249,7 @@ static inline void __put_user_asm64(u64 x, void *ptr)
 
 }
 
-#endif
+#endif /* !__LP64__ */
 
 
 /*
index bcb11f8..094f45e 100644 (file)
  *  Non-offset'ed vector numbers
  */
 
-//#define OPENPIC_VEC_TIMER    64      /* and up */
-//#define OPENPIC_VEC_IPI              72      /* and up */
-//#define OPENPIC_VEC_SPURIOUS 127
-
 #define OPENPIC_VEC_TIMER      110     /* and up */
 #define OPENPIC_VEC_IPI                118     /* and up */
 #define OPENPIC_VEC_SPURIOUS   127
index 3c1d66d..1ce4293 100644 (file)
@@ -131,6 +131,17 @@ static inline void eeh_writel(u32 val, void *addr) {
        volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
        out_le32(vaddr, val);
 }
+static inline u64 eeh_readq(void *addr) {
+       volatile u64 *vaddr = (volatile u64 *)IO_TOKEN_TO_ADDR(addr);
+       u64 val = in_le64(vaddr);
+       if (EEH_POSSIBLE_ERROR(addr, vaddr, val))
+               return eeh_check_failure(addr, val);
+       return val;
+}
+static inline void eeh_writeq(u64 val, void *addr) {
+       volatile u64 *vaddr = (volatile u64 *)IO_TOKEN_TO_ADDR(addr);
+       out_le64(vaddr, val);
+}
 
 static inline void eeh_memset_io(void *addr, int c, unsigned long n) {
        void *vaddr = (void *)IO_TOKEN_TO_ADDR(addr);
index 8d24669..1fc4474 100644 (file)
@@ -34,6 +34,15 @@ extern unsigned long isa_io_base;
 extern unsigned long pci_io_base;
 
 #ifdef CONFIG_PPC_ISERIES
+/* __raw_* accessors aren't supported on iSeries */
+#define __raw_readb(addr)      { BUG(); 0; }
+#define __raw_readw(addr)       { BUG(); 0; }
+#define __raw_readl(addr)       { BUG(); 0; }
+#define __raw_readq(addr)       { BUG(); 0; }
+#define __raw_writeb(v, addr)   { BUG(); 0; }
+#define __raw_writew(v, addr)   { BUG(); 0; }
+#define __raw_writel(v, addr)   { BUG(); 0; }
+#define __raw_writeq(v, addr)   { BUG(); 0; }
 #define readb(addr)            iSeries_Read_Byte((void*)(addr))  
 #define readw(addr)            iSeries_Read_Word((void*)(addr))  
 #define readl(addr)            iSeries_Read_Long((void*)(addr))
@@ -50,12 +59,22 @@ extern unsigned long pci_io_base;
 #define outw(data,addr)                writew(data,((unsigned long)(addr)))  
 #define outl(data,addr)                writel(data,((unsigned long)(addr)))
 #else
+#define __raw_readb(addr)       (*(volatile unsigned char *)(addr))
+#define __raw_readw(addr)       (*(volatile unsigned short *)(addr))
+#define __raw_readl(addr)       (*(volatile unsigned int *)(addr))
+#define __raw_readq(addr)       (*(volatile unsigned long *)(addr))
+#define __raw_writeb(v, addr)   (*(volatile unsigned char *)(addr) = (v))
+#define __raw_writew(v, addr)   (*(volatile unsigned short *)(addr) = (v))
+#define __raw_writel(v, addr)   (*(volatile unsigned int *)(addr) = (v))
+#define __raw_writeq(v, addr)   (*(volatile unsigned long *)(addr) = (v))
 #define readb(addr)            eeh_readb((void*)(addr))  
 #define readw(addr)            eeh_readw((void*)(addr))  
 #define readl(addr)            eeh_readl((void*)(addr))
+#define readq(addr)            eeh_readq((void*)(addr))
 #define writeb(data, addr)     eeh_writeb((data), ((void*)(addr)))
 #define writew(data, addr)     eeh_writew((data), ((void*)(addr)))
 #define writel(data, addr)     eeh_writel((data), ((void*)(addr)))
+#define writeq(data, addr)     eeh_writeq((data), ((void*)(addr)))
 #define memset_io(a,b,c)       eeh_memset_io((void *)(a),(b),(c))
 #define memcpy_fromio(a,b,c)   eeh_memcpy_fromio((a),(void *)(b),(c))
 #define memcpy_toio(a,b,c)     eeh_memcpy_toio((void *)(a),(b),(c))
@@ -82,6 +101,7 @@ extern unsigned long pci_io_base;
 #define readb_relaxed(addr) readb(addr)
 #define readw_relaxed(addr) readw(addr)
 #define readl_relaxed(addr) readl(addr)
+#define readq_relaxed(addr) readq(addr)
 
 extern void _insb(volatile u8 *port, void *buf, int ns);
 extern void _outsb(volatile u8 *port, const void *buf, int ns);
@@ -186,21 +206,22 @@ static inline int in_8(volatile unsigned char *addr)
 {
        int ret;
 
-       __asm__ __volatile__("eieio; lbz%U1%X1 %0,%1" : "=r" (ret) : "m" (*addr));
+       __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync" :
+                            "=r" (ret) : "m" (*addr));
        return ret;
 }
 
 static inline void out_8(volatile unsigned char *addr, int val)
 {
-       __asm__ __volatile__("stb%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
+       __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
 }
 
 static inline int in_le16(volatile unsigned short *addr)
 {
        int ret;
 
-       __asm__ __volatile__("eieio; lhbrx %0,0,%1" : "=r" (ret) :
-                             "r" (addr), "m" (*addr));
+       __asm__ __volatile__("lhbrx %0,0,%1; twi 0,%0,0; isync" :
+                            "=r" (ret) : "r" (addr), "m" (*addr));
        return ret;
 }
 
@@ -208,27 +229,28 @@ static inline int in_be16(volatile unsigned short *addr)
 {
        int ret;
 
-       __asm__ __volatile__("eieio; lhz%U1%X1 %0,%1" : "=r" (ret) : "m" (*addr));
+       __asm__ __volatile__("lhz%U1%X1 %0,%1; twi 0,%0,0; isync" :
+                            "=r" (ret) : "m" (*addr));
        return ret;
 }
 
 static inline void out_le16(volatile unsigned short *addr, int val)
 {
-       __asm__ __volatile__("sthbrx %1,0,%2" : "=m" (*addr) :
+       __asm__ __volatile__("sthbrx %1,0,%2; eieio" : "=m" (*addr) :
                              "r" (val), "r" (addr));
 }
 
 static inline void out_be16(volatile unsigned short *addr, int val)
 {
-       __asm__ __volatile__("sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
+       __asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
 }
 
 static inline unsigned in_le32(volatile unsigned *addr)
 {
        unsigned ret;
 
-       __asm__ __volatile__("eieio; lwbrx %0,0,%1" : "=r" (ret) :
-                            "r" (addr), "m" (*addr));
+       __asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync" :
+                            "=r" (ret) : "r" (addr), "m" (*addr));
        return ret;
 }
 
@@ -236,19 +258,70 @@ static inline unsigned in_be32(volatile unsigned *addr)
 {
        unsigned ret;
 
-       __asm__ __volatile__("eieio; lwz%U1%X1 %0,%1" : "=r" (ret) : "m" (*addr));
+       __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync" :
+                            "=r" (ret) : "m" (*addr));
        return ret;
 }
 
 static inline void out_le32(volatile unsigned *addr, int val)
 {
-       __asm__ __volatile__("stwbrx %1,0,%2" : "=m" (*addr) :
+       __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
                             "r" (val), "r" (addr));
 }
 
 static inline void out_be32(volatile unsigned *addr, int val)
 {
-       __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
+       __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+}
+
+static inline unsigned long in_le64(volatile unsigned long *addr)
+{
+       unsigned long tmp, ret;
+
+       __asm__ __volatile__(
+                            "ld %1,0(%2)\n"
+                            "twi 0,%1,0\n"
+                            "isync\n"
+                            "rldimi %0,%1,5*8,1*8\n"
+                            "rldimi %0,%1,3*8,2*8\n"
+                            "rldimi %0,%1,1*8,3*8\n"
+                            "rldimi %0,%1,7*8,4*8\n"
+                            "rldicl %1,%1,32,0\n"
+                            "rlwimi %0,%1,8,8,31\n"
+                            "rlwimi %0,%1,24,16,23\n"
+                            : "=r" (ret), "=r" (tmp) : "b" (addr) , "m" (*addr));
+       return ret;
+}
+
+static inline unsigned long in_be64(volatile unsigned long *addr)
+{
+       unsigned long ret;
+
+       __asm__ __volatile__("ld %0,0(%1); twi 0,%0,0; isync" :
+                            "=r" (ret) : "m" (*addr));
+       return ret;
+}
+
+static inline void out_le64(volatile unsigned long *addr, int val)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+                            "rldimi %0,%1,5*8,1*8\n"
+                            "rldimi %0,%1,3*8,2*8\n"
+                            "rldimi %0,%1,1*8,3*8\n"
+                            "rldimi %0,%1,7*8,4*8\n"
+                            "rldicl %1,%1,32,0\n"
+                            "rlwimi %0,%1,8,8,31\n"
+                            "rlwimi %0,%1,24,16,23\n"
+                            "std %0,0(%2)\n"
+                            "eieio\n"
+                            : "=r" (tmp) : "r" (val), "b" (addr) , "m" (*addr));
+}
+
+static inline void out_be64(volatile unsigned long *addr, int val)
+{
+       __asm__ __volatile__("std %1,0(%0); eieio" : "=m" (*addr) : "r" (val));
 }
 
 #ifndef CONFIG_PPC_ISERIES 
index 1babe35..24a2e99 100644 (file)
@@ -64,14 +64,13 @@ struct paca_struct {
         u16 xHwProcNum;                 /* Physical processor number            0x1A */
        u32 default_decr;               /* Default decrementer value            0x1c */ 
        u64 xKsave;                     /* Saved Kernel stack addr or zero      0x20 */
-       u64 pvr;                        /* Processor version register           0x28 */
        struct ItLpQueue *lpQueuePtr;   /* LpQueue handled by this processor    0x30 */
        u64  xTOC;                      /* Kernel TOC address                   0x38 */
        STAB xStab_data;                /* Segment table information            0x40,0x48,0x50 */
        u8 *exception_sp;               /*                                      0x58 */
        u8 xProcEnabled;                /*                                      0x59 */
        u8 prof_enabled;                /* 1=iSeries profiling enabled          0x60 */
-       u8 resv1[30];                   /*                                      0x61-0x7F */
+       u8 resv1[38];                   /*                                      0x61-0x7F */
 
 /*=====================================================================================
  * CACHE_LINE_2 0x0080 - 0x00FF
index 977a99d..5baffb5 100644 (file)
 extern int pcibios_scan_all_fns(struct pci_bus *bus, int devfn);
 #endif
 
+#ifdef CONFIG_PPC_ISERIES
+#define pcibios_scan_all_fns(a, b)     0
+#else
+extern int pcibios_scan_all_fns(struct pci_bus *bus, int devfn);
+#endif
+
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
        /* No special bus mastering setup handling */
index fd68008..bff956c 100644 (file)
@@ -44,8 +44,11 @@ int vio_register_driver(struct vio_driver *drv);
 void vio_unregister_driver(struct vio_driver *drv);
 const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, 
                                                const struct vio_dev *dev);
+
 struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev);
 void __devinit vio_unregister_device(struct vio_dev *dev);
+struct vio_dev *vio_find_node(struct device_node *vnode);
+
 const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length);
 int vio_get_irq(struct vio_dev *dev);
 struct TceTable * vio_build_tce_table(struct vio_dev *dev);
index 044ab5a..6957681 100644 (file)
 #define __NR_timer_create      266
 /* #define __NR_vserver                267 Reserved for VSERVER */
 #define __NR_io_setup          268
-#define __NR_io_destroy                268
-#define __NR_io_submit         269
-#define __NR_io_cancel         270
-#define __NR_io_getevents      271
-/* WARNING: You MAY NOT add syscall numbers larger than 271, since
+#define __NR_io_destroy                269
+#define __NR_io_submit         270
+#define __NR_io_cancel         271
+#define __NR_io_getevents      272
+/* WARNING: You MAY NOT add syscall numbers larger than 272, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 272 entries (starting at zero).  Therefore
- *          find a free slot in the 0-271 range.
+ *          sized to have 273 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-272 range.
  */
 
 #define _syscall0(type,name) \
index defdb10..109d44c 100644 (file)
 #define __NR_timer_create      266
 /* #define __NR_vserver                267 Reserved for VSERVER */
 #define __NR_io_setup          268
-#define __NR_io_destroy                268
-#define __NR_io_submit         269
-#define __NR_io_cancel         270
-#define __NR_io_getevents      271
-/* WARNING: You MAY NOT add syscall numbers larger than 271, since
+#define __NR_io_destroy                269
+#define __NR_io_submit         270
+#define __NR_io_cancel         271
+#define __NR_io_getevents      272
+/* WARNING: You MAY NOT add syscall numbers larger than 272, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 272 entries (starting at zero).  Therefore
- *          find a free slot in the 0-271 range.
+ *          sized to have 273 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-272 range.
  */
 
 #define _syscall0(type,name) \
index bad311b..1ce65d4 100644 (file)
@@ -2,8 +2,8 @@
  * include/asm-v850/delay.h -- Delay routines, using a pre-computed
  *     "loops_per_second" value
  *
- *  Copyright (C) 2001  NEC Corporation
- *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,03  NEC Corporation
+ *  Copyright (C) 2001,03  Miles Bader <miles@gnu.org>
  *  Copyright (C) 1994 Hamish Macdonald
  *
  * This file is subject to the terms and conditions of the GNU General
@@ -18,8 +18,9 @@
 
 extern __inline__ void __delay(unsigned long loops)
 {
-       __asm__ __volatile__ ("1: add -1, %0; bnz 1b"
-                             : "=r" (loops) : "0" (loops));
+       if (loops)
+               __asm__ __volatile__ ("1: add -1, %0; bnz 1b"
+                                     : "=r" (loops) : "0" (loops));
 }
 
 /*
index 9b2e1e3..2c2f494 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/module.h -- Architecture-specific module hooks
  *
- *  Copyright (C) 2001,02,03  NEC Corporation
- *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03,04  NEC Corporation
+ *  Copyright (C) 2001,02,03,04  Miles Bader <miles@gnu.org>
  *  Copyright (C) 2001,03  Rusty Russell
  *
  * This file is subject to the terms and conditions of the GNU General
@@ -50,5 +50,13 @@ search_extable(const struct exception_table_entry *first,
 {
        return 0;
 }
+#define ARCH_HAS_SEARCH_EXTABLE
+static inline void
+sort_extable(struct exception_table_entry *start,
+            struct exception_table_entry *finish)
+{
+       /* nada */
+}
+#define ARCH_HAS_SORT_EXTABLE
 
 #endif /* __V850_MODULE_H__ */
index 8e4eba2..f851b34 100644 (file)
@@ -355,8 +355,8 @@ int acpi_numa_init (void);
 int acpi_table_init (void);
 int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
 int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
-int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler);
-int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler);
+int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
+int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
 void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
 void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
 void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
index 66c7495..3a3759f 100644 (file)
@@ -331,6 +331,7 @@ void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc);
 void arcnet_unregister_proto(struct ArcProto *proto);
 irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 void arcdev_setup(struct net_device *dev);
+struct net_device *alloc_arcdev(char *name);
 void arcnet_rx(struct net_device *dev, int bufnum);
 
 #endif                         /* __KERNEL__ */
index 2c5fc42..c88d530 100644 (file)
@@ -29,7 +29,6 @@
 
 int com20020_check(struct net_device *dev);
 int com20020_found(struct net_device *dev, int shared);
-void com20020_remove(struct net_device *dev);
 
 /* The number of low I/O ports used by the card. */
 #define ARCNET_TOTAL_SIZE 8
index 0b4a80f..3fa7319 100644 (file)
@@ -1,10 +1,7 @@
 #ifndef _LINUX_FB_H
 #define _LINUX_FB_H
 
-#include <linux/tty.h>
-#include <linux/workqueue.h>
 #include <asm/types.h>
-#include <asm/io.h>
 
 /* Definitions of frame buffers                                                */
 
@@ -327,33 +324,21 @@ struct fb_cursor {
        struct fb_image image;  /* Cursor image */
 };
 
-#define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
-#define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
-#define FB_PIXMAP_IO      4     /* memory is iomapped       */
-#define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
-
-struct fb_pixmap {
-        __u8  *addr;                      /* pointer to memory             */  
-       __u32 size;                       /* size of buffer in bytes       */
-       __u32 offset;                     /* current offset to buffer      */
-       __u32 buf_align;                  /* byte alignment of each bitmap */
-       __u32 scan_align;                 /* alignment per scanline        */
-       __u32 flags;                      /* see FB_PIXMAP_*               */
-                                         /* access methods                */
-       void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); 
-       u8   (*inbuf) (u8 *addr);
-       spinlock_t lock;                  /* spinlock                      */
-       atomic_t count;
-};
 #ifdef __KERNEL__
 
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/notifier.h>
+#include <asm/io.h>
 
-struct fb_info;
 struct vm_area_struct;
+struct fb_info;
+struct device;
 struct file;
-struct fb_client;
 
        /*
         * Framebuffer clients. Currently, this is only used
@@ -391,6 +376,33 @@ struct fb_client {
        struct fb_client_ops    *ops;
        void                    *data;
 };
+/*
+ * Pixmap structure definition
+ *
+ * The purpose of this structure is to translate data
+ * from the hardware independent format of fbdev to what
+ * format the hardware needs.
+ */
+
+#define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
+#define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
+#define FB_PIXMAP_IO      4     /* memory is iomapped       */
+#define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
+
+struct fb_pixmap {
+       u8 *addr;               /* pointer to memory                    */
+       u32 size;               /* size of buffer in bytes              */
+       u32 offset;             /* current offset to buffer             */
+       u32 buf_align;          /* byte alignment of each bitmap        */
+       u32 scan_align;         /* alignment per scanline               */
+       u32 access_align;       /* alignment per read/write             */
+       u32 flags;              /* see FB_PIXMAP_*                      */
+                                         /* access methods                */
+       void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); 
+       u8   (*inbuf) (u8 *addr);
+       spinlock_t lock;                  /* spinlock                      */
+       atomic_t count;
+};
 
     /*
      *  Frame buffer operations
@@ -401,57 +413,81 @@ struct fb_ops {
     struct module *owner;
     int (*fb_open)(struct fb_info *info, int user);
     int (*fb_release)(struct fb_info *info, int user);
+
     /* For framebuffers with strange non linear layouts */     
-    ssize_t (*fb_read)(struct file *file, char *buf, size_t count, loff_t *ppos);
-    ssize_t (*fb_write)(struct file *file, const char *buf, size_t count, loff_t *ppos);       
-    /* checks var and creates a par based on it */
-    int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
-    /* set the video mode according to par */
+       ssize_t(*fb_read) (struct file * file, char *buf, size_t count,
+                          loff_t * ppos);
+       ssize_t(*fb_write) (struct file * file, const char *buf,
+                           size_t count, loff_t * ppos);
+
+       /* checks var and eventually tweaks it to something supported,
+        * DO NOT MODIFY PAR */
+       int (*fb_check_var) (struct fb_var_screeninfo * var,
+                            struct fb_info * info);
+       /* set the video mode according to info->var */
     int (*fb_set_par)(struct fb_info *info);
+
     /* set color register */
     int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
-                        unsigned blue, unsigned transp, struct fb_info *info);
+                            unsigned blue, unsigned transp,
+                            struct fb_info * info);
+
     /* blank display */
     int (*fb_blank)(int blank, struct fb_info *info);
+
     /* pan display */
-    int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
+       int (*fb_pan_display) (struct fb_var_screeninfo * var,
+                              struct fb_info * info);
+
     /* draws a rectangle */
-    void (*fb_fillrect)(struct fb_info *info, const struct fb_fillrect *rect); 
+       void (*fb_fillrect) (struct fb_info * info,
+                            const struct fb_fillrect * rect);
     /* Copy data from area to another */
-    void (*fb_copyarea)(struct fb_info *info,const struct fb_copyarea *region); 
+       void (*fb_copyarea) (struct fb_info * info,
+                            const struct fb_copyarea * region);
     /* Draws a image to the display */
-    void (*fb_imageblit)(struct fb_info *info, const struct fb_image *image);
+       void (*fb_imageblit) (struct fb_info * info,
+                             const struct fb_image * image);
+
     /* Draws cursor */
-    int (*fb_cursor)(struct fb_info *info, struct fb_cursor *cursor);
+       int (*fb_cursor) (struct fb_info * info,
+                         struct fb_cursor * cursor);
+
     /* Rotates the display */
     void (*fb_rotate)(struct fb_info *info, int angle);
+
     /* wait for blit idle, optional */
     int (*fb_sync)(struct fb_info *info);              
+
     /* perform fb specific ioctl (optional) */
-    int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
-                   unsigned long arg, struct fb_info *info);
+       int (*fb_ioctl) (struct inode * inode, struct file * file,
+                        unsigned int cmd, unsigned long arg,
+                        struct fb_info * info);
+
     /* perform fb specific mmap */
-    int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+       int (*fb_mmap) (struct fb_info * info, struct file * file,
+                       struct vm_area_struct * vma);
 };
 
 struct fb_info {
-   int node;
-   int flags;
-   int open;                            /* Has this been open already ? */
+       int node;
+       int flags;
+       int open;                       /* Has this been open already ? */
    int suspended;                      /* Is this currently suspended ? */
 #define FBINFO_FLAG_MODULE     1       /* Low-level driver is a module */
-   struct fb_var_screeninfo var;        /* Current var */
-   struct fb_fix_screeninfo fix;        /* Current fix */
-   struct fb_monspecs monspecs;         /* Current Monitor specs */
-   struct fb_cursor cursor;            /* Current cursor */    
-   struct work_struct queue;           /* Framebuffer event queue */
-   struct fb_pixmap pixmap;            /* Current pixmap */
-   struct fb_cmap cmap;                 /* Current cmap */
-   struct fb_ops *fbops;
-   char *screen_base;                   /* Virtual address */
-   struct vc_data *display_fg;         /* Console visible on this display */
-   int currcon;                                /* Current VC. */       
-   void *pseudo_palette;                /* Fake palette of 16 colors */ 
+       struct fb_var_screeninfo var;   /* Current var */
+       struct fb_fix_screeninfo fix;   /* Current fix */
+       struct fb_monspecs monspecs;    /* Current Monitor specs */
+       struct fb_cursor cursor;        /* Current cursor */    
+       struct work_struct queue;       /* Framebuffer event queue */
+       struct fb_pixmap pixmap;        /* Image Hardware Mapper */
+       struct fb_cmap cmap;            /* Current cmap */
+       struct fb_ops *fbops;
+       char *screen_base;              /* Virtual address */
+       struct vc_data *display_fg;     /* Console visible on this display */
+       int currcon;                    /* Current VC. */
+       struct class_device class_dev;  /* Sysfs data */        
+       void *pseudo_palette;           /* Fake palette of 16 colors */ 
 #ifdef CONFIG_BOOTSPLASH
    struct splash_data *splash_data;
    unsigned char *splash_pic;
@@ -460,8 +496,8 @@ struct fb_info {
    char *silent_screen_base;           /* real screen base */
    char fb_cursordata[64];
 #endif
-   /* From here on everything is device dependent */
-   void *par;  
+       /* From here on everything is device dependent */
+       void *par;      
 };
 
 #ifdef MODULE
@@ -534,14 +570,22 @@ extern int unregister_framebuffer(struct fb_info *fb_info);
 extern int fb_prepare_logo(struct fb_info *fb_info);
 extern int fb_show_logo(struct fb_info *fb_info);
 extern u32 fb_get_buffer_offset(struct fb_info *info, u32 size);
-extern void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
-                               u32 height, u32 mask, u32 shift_high, u32 shift_low,
-                               u32 mod, u32 idx);
-extern void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
-                            u32 s_pitch, u32 height);
+extern void move_buf_unaligned(struct fb_info *info, u8 * dst, u8 * src,
+                               u32 d_pitch, u32 height, u32 mask,
+                               u32 shift_high, u32 shift_low, u32 mod,
+                               u32 idx);
+extern void move_buf_aligned(struct fb_info *info, u8 * dst, u8 * src,
+                               u32 d_pitch, u32 s_pitch, u32 height);
 extern struct fb_info *registered_fb[FB_MAX];
 extern int num_registered_fb;
 
+/* drivers/video/fbsysfs.c */
+extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
+extern void framebuffer_release(struct fb_info *info);
+extern int fb_add_class_device(struct fb_info *info);
+
+extern struct class fb_class;
+
 /* drivers/video/fbmon.c */
 #define FB_MAXTIMINGS       0
 #define FB_VSYNCTIMINGS     1
@@ -569,8 +613,7 @@ extern const struct fb_videomode vesa_modes[];
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
 extern void fb_dealloc_cmap(struct fb_cmap *cmap);
-extern int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to,
-                       int fsfromto);
+extern int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
 extern int fb_set_cmap(struct fb_cmap *cmap, int kspc, struct fb_info *fb_info);
 extern struct fb_cmap *fb_default_cmap(int len);
 extern void fb_invert_cmaps(void);
@@ -593,7 +636,8 @@ struct fb_videomode {
 
 #ifdef MODULE
 static inline int fb_find_mode(struct fb_var_screeninfo *var,
-                              struct fb_info *info, const char *mode_option,
+                              struct fb_info *info,
+                              const char *mode_option,
                               const struct fb_videomode *db,
                               unsigned int dbsize,
                               const struct fb_videomode *default_mode,
@@ -620,7 +664,8 @@ static inline int fb_find_mode(struct fb_var_screeninfo *var,
 }
 #else
 extern int __init fb_find_mode(struct fb_var_screeninfo *var,
-                              struct fb_info *info, const char *mode_option,
+                              struct fb_info *info,
+                              const char *mode_option,
                               const struct fb_videomode *db,
                               unsigned int dbsize,
                               const struct fb_videomode *default_mode,
index 2b77773..d247474 100644 (file)
@@ -799,15 +799,8 @@ typedef struct ide_dma_ops_s {
        int (*ide_dma_good_drive)(ide_drive_t *drive);
        int (*ide_dma_count)(ide_drive_t *drive);
        int (*ide_dma_verbose)(ide_drive_t *drive);
-       int (*ide_dma_retune)(ide_drive_t *drive);
        int (*ide_dma_lostirq)(ide_drive_t *drive);
        int (*ide_dma_timeout)(ide_drive_t *drive);
-       /* dma queued operations */
-       int (*ide_dma_queued_on)(ide_drive_t *drive);
-       int (*ide_dma_queued_off)(ide_drive_t *drive);
-       ide_startstop_t (*ide_dma_queued_read)(ide_drive_t *drive);
-       ide_startstop_t (*ide_dma_queued_write)(ide_drive_t *drive);
-       ide_startstop_t (*ide_dma_queued_start)(ide_drive_t *drive);
 } ide_dma_ops_t;
 
 /*
@@ -945,17 +938,9 @@ typedef struct hwif_s {
        int (*ide_dma_good_drive)(ide_drive_t *drive);
        int (*ide_dma_count)(ide_drive_t *drive);
        int (*ide_dma_verbose)(ide_drive_t *drive);
-       int (*ide_dma_retune)(ide_drive_t *drive);
        int (*ide_dma_lostirq)(ide_drive_t *drive);
        int (*ide_dma_timeout)(ide_drive_t *drive);
 
-       /* dma queued operations */
-       int (*ide_dma_queued_on)(ide_drive_t *drive);
-       int (*ide_dma_queued_off)(ide_drive_t *drive);
-       ide_startstop_t (*ide_dma_queued_read)(ide_drive_t *drive);
-       ide_startstop_t (*ide_dma_queued_write)(ide_drive_t *drive);
-       ide_startstop_t (*ide_dma_queued_start)(ide_drive_t *drive);
-
        void (*OUTB)(u8 addr, unsigned long port);
        void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
        void (*OUTW)(u16 addr, unsigned long port);
@@ -1214,13 +1199,6 @@ typedef struct ide_driver_s {
 
 extern int generic_ide_ioctl(struct block_device *, unsigned, unsigned long);
 
-typedef struct ide_devices_s {
-       char                    name[4];                /* hdX */
-       unsigned                attached        : 1;    /* native */
-       unsigned                alttached       : 1;    /* alternate */
-       struct ide_devices_s    *next;
-} ide_devices_t;
-
 /*
  * ide_hwifs[] is the master data structure used to keep track
  * of just about everything in ide.c.  Whenever possible, routines
@@ -1231,13 +1209,6 @@ typedef struct ide_devices_s {
  */
 #ifndef _IDE_C
 extern ide_hwif_t      ide_hwifs[];            /* master data repository */
-
-extern ide_devices_t   *idedisk;
-extern ide_devices_t   *idecd;
-extern ide_devices_t   *idefloppy;
-extern ide_devices_t   *idetape;
-extern ide_devices_t   *idescsi;
-
 #endif
 extern int noautodma;
 
@@ -1626,6 +1597,10 @@ extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_de
 #define BAD_DMA_DRIVE          0
 #define GOOD_DMA_DRIVE         1
 
+#ifdef CONFIG_BLK_DEV_IDEDMA
+int __ide_dma_bad_drive(ide_drive_t *);
+int __ide_dma_good_drive(ide_drive_t *);
+
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 extern int ide_build_sglist(ide_drive_t *, struct request *);
 extern int ide_raw_build_sglist(ide_drive_t *, struct request *);
@@ -1647,11 +1622,8 @@ extern int __ide_dma_write(ide_drive_t *);
 extern int __ide_dma_begin(ide_drive_t *);
 extern int __ide_dma_end(ide_drive_t *);
 extern int __ide_dma_test_irq(ide_drive_t *);
-extern int __ide_dma_bad_drive(ide_drive_t *);
-extern int __ide_dma_good_drive(ide_drive_t *);
 extern int __ide_dma_count(ide_drive_t *);
 extern int __ide_dma_verbose(ide_drive_t *);
-extern int __ide_dma_retune(ide_drive_t *);
 extern int __ide_dma_lostirq(ide_drive_t *);
 extern int __ide_dma_timeout(ide_drive_t *);
 
@@ -1661,22 +1633,14 @@ extern int __ide_dma_queued_off(ide_drive_t *drive);
 extern ide_startstop_t __ide_dma_queued_read(ide_drive_t *drive);
 extern ide_startstop_t __ide_dma_queued_write(ide_drive_t *drive);
 extern ide_startstop_t __ide_dma_queued_start(ide_drive_t *drive);
-#else
-static inline int __ide_dma_queued_on(ide_drive_t *drive)
-{
-       return 1;
-}
-
-static inline int __ide_dma_queued_off(ide_drive_t *drive)
-{
-       return 1;
-}
 #endif
 
 #else
 static inline void ide_release_dma(ide_hwif_t *drive) {;}
 #endif
 
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
 extern int ide_hwif_request_regions(ide_hwif_t *hwif);
 extern void ide_hwif_release_regions(ide_hwif_t* hwif);
 extern void ide_unregister (unsigned int index);
index 4419670..0f2382b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'.
  *
- * 
+ *
  * Portions are (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
  * NCM: Network and Communications Management, Inc.
  *
  *
  *     This software may be used and distributed according to the terms
  *     of the GNU Public License, incorporated herein by reference.
- * 
+ *
  * 2003/03/18 - Amir Noam <amir.noam at intel dot com>
  *     - Added support for getting slave's speed and duplex via ethtool.
  *       Needed for 802.3ad and other future modes.
- * 
+ *
  * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
  *             Shmulik Hen <shmulik.hen at intel dot com>
  *     - Enable support of modes that need to use the unique mac address of
@@ -42,7 +42,7 @@
 #include <linux/if_ether.h>
 
 /* userland - kernel ABI version (2003/05/08) */
-#define BOND_ABI_VERSION 1
+#define BOND_ABI_VERSION 2
 
 /*
  * We can remove these ioctl definitions in 2.5.  People should use the
 
 #define BOND_DEFAULT_MAX_BONDS  1   /* Default maximum number of devices to support */
 
-#define BOND_MULTICAST_DISABLED 0
-#define BOND_MULTICAST_ACTIVE   1
-#define BOND_MULTICAST_ALL      2
-
 typedef struct ifbond {
        __s32 bond_mode;
        __s32 num_slaves;
@@ -90,9 +86,9 @@ typedef struct ifbond {
 typedef struct ifslave
 {
        __s32 slave_id; /* Used as an IN param to the BOND_SLAVE_INFO_QUERY ioctl */
-       char slave_name[IFNAMSIZ];
-       char link;
-       char state;
+       __s8 slave_name[IFNAMSIZ];
+       __s8 link;
+       __s8 state;
        __u32  link_failure_count;
 } ifslave;
 
@@ -115,3 +111,4 @@ struct ad_info {
  *  tab-width: 8
  * End:
  */
+
index 6cb10ed..104df18 100644 (file)
@@ -200,6 +200,152 @@ static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
 {
        return __vlan_hwaccel_rx(skb, grp, vlan_tag, 1);
 }
+
+/**
+ * __vlan_put_tag - regular VLAN tag inserting
+ * @skb: skbuff to tag
+ * @tag: VLAN tag to insert
+ *
+ * Inserts the VLAN tag into @skb as part of the payload
+ * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
+ * 
+ * Following the skb_unshare() example, in case of error, the calling function
+ * doesn't have to worry about freeing the original skb.
+ */
+static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, unsigned short tag)
+{
+       struct vlan_ethhdr *veth;
+
+       if (skb_headroom(skb) < VLAN_HLEN) {
+               struct sk_buff *sk_tmp = skb;
+               skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
+               kfree_skb(sk_tmp);
+               if (!skb) {
+                       printk(KERN_ERR "vlan: failed to realloc headroom\n");
+                       return NULL;
+               }
+       } else {
+               skb = skb_unshare(skb, GFP_ATOMIC);
+               if (!skb) {
+                       printk(KERN_ERR "vlan: failed to unshare skbuff\n");
+                       return NULL;
+               }
+       }
+
+       veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
+
+       /* Move the mac addresses to the beginning of the new header. */
+       memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
+
+       /* first, the ethernet type */
+       veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
+
+       /* now, the tag */
+       veth->h_vlan_TCI = htons(tag);
+
+       skb->protocol = __constant_htons(ETH_P_8021Q);
+       skb->mac.raw -= VLAN_HLEN;
+       skb->nh.raw -= VLAN_HLEN;
+
+       return skb;
+}
+
+/**
+ * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
+ * @skb: skbuff to tag
+ * @tag: VLAN tag to insert
+ *
+ * Puts the VLAN tag in @skb->cb[] and lets the device do the rest
+ */
+static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, unsigned short tag)
+{
+       struct vlan_skb_tx_cookie *cookie;
+
+       cookie = VLAN_TX_SKB_CB(skb);
+       cookie->magic = VLAN_TX_COOKIE_MAGIC;
+       cookie->vlan_tag = tag;
+
+       return skb;
+}
+
+#define HAVE_VLAN_PUT_TAG
+
+/**
+ * vlan_put_tag - inserts VLAN tag according to device features
+ * @skb: skbuff to tag
+ * @tag: VLAN tag to insert
+ *
+ * Assumes skb->dev is the target that will xmit this frame.
+ * Returns a VLAN tagged skb.
+ */
+static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, unsigned short tag)
+{
+       if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
+               return __vlan_hwaccel_put_tag(skb, tag);
+       } else {
+               return __vlan_put_tag(skb, tag);
+       }
+}
+
+/**
+ * __vlan_get_tag - get the VLAN ID that is part of the payload
+ * @skb: skbuff to query
+ * @tag: buffer to store vlaue
+ * 
+ * Returns error if the skb is not of VLAN type
+ */
+static inline int __vlan_get_tag(struct sk_buff *skb, unsigned short *tag)
+{
+       struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
+
+       if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
+               return -EINVAL;
+       }
+
+       *tag = ntohs(veth->h_vlan_TCI);
+
+       return 0;
+}
+
+/**
+ * __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[]
+ * @skb: skbuff to query
+ * @tag: buffer to store vlaue
+ * 
+ * Returns error if @skb->cb[] is not set correctly
+ */
+static inline int __vlan_hwaccel_get_tag(struct sk_buff *skb, unsigned short *tag)
+{
+       struct vlan_skb_tx_cookie *cookie;
+
+       cookie = VLAN_TX_SKB_CB(skb);
+       if (cookie->magic == VLAN_TX_COOKIE_MAGIC) {
+               *tag = cookie->vlan_tag;
+               return 0;
+       } else {
+               *tag = 0;
+               return -EINVAL;
+       }
+}
+
+#define HAVE_VLAN_GET_TAG
+
+/**
+ * vlan_get_tag - get the VLAN ID from the skb
+ * @skb: skbuff to query
+ * @tag: buffer to store vlaue
+ * 
+ * Returns error if the skb is not VLAN tagged
+ */
+static inline int vlan_get_tag(struct sk_buff *skb, unsigned short *tag)
+{
+       if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
+               return __vlan_hwaccel_get_tag(skb, tag);
+       } else {
+               return __vlan_get_tag(skb, tag);
+       }
+}
+
 #endif /* __KERNEL__ */
 
 /* VLAN IOCTLs are found in sockios.h */
index 8689112..5b4e89b 100644 (file)
@@ -183,5 +183,17 @@ struct in6_flowlabel_req
 #define IPV6_IPSEC_POLICY      34
 #define IPV6_XFRM_POLICY       35
 
+/*
+ * Multicast:
+ * Following socket options are shared between IPv4 and IPv6.
+ *
+ * MCAST_JOIN_GROUP            42
+ * MCAST_BLOCK_SOURCE          43
+ * MCAST_UNBLOCK_SOURCE                44
+ * MCAST_LEAVE_GROUP           45
+ * MCAST_JOIN_SOURCE_GROUP     46
+ * MCAST_LEAVE_SOURCE_GROUP    47
+ * MCAST_MSFILTER              48
+ */
 
 #endif
index 18913df..1c5eb02 100644 (file)
@@ -21,6 +21,7 @@ struct ipv4_devconf
        int     medium_id;
        int     no_xfrm;
        int     no_policy;
+       int     force_igmp_version;
        void    *sysctl;
 };
 
index 59afa63..77ba731 100644 (file)
@@ -752,25 +752,28 @@ struct ff_effect {
 #define init_input_dev(dev)    do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
 
 #define SET_INPUT_KEYCODE(dev, scancode, val)                  \
-       do {                                                    \
+               ({      unsigned __old;                         \
                switch (dev->keycodesize) {                     \
                        case 1: {                               \
                                u8 *k = (u8 *)dev->keycode;     \
+                               __old = k[scancode];            \
                                k[scancode] = val;              \
                                break;                          \
                        }                                       \
                        case 2: {                               \
                                u16 *k = (u16 *)dev->keycode;   \
+                               __old = k[scancode];            \
                                k[scancode] = val;              \
                                break;                          \
                        }                                       \
-                       case 4: {                               \
+                       default: {                              \
                                u32 *k = (u32 *)dev->keycode;   \
+                               __old = k[scancode];            \
                                k[scancode] = val;              \
                                break;                          \
                        }                                       \
                }                                               \
-       } while (0)
+               __old; })
 
 struct input_dev {
 
index 5ad913d..363aef7 100644 (file)
@@ -99,6 +99,8 @@ extern int allocate_resource(struct resource *root, struct resource *new,
                             void (*alignf)(void *, struct resource *,
                                            unsigned long, unsigned long),
                             void *alignf_data);
+int adjust_resource(struct resource *res, unsigned long start,
+                   unsigned long size);
 
 /* Convenience shorthand with allocation */
 #define request_region(start,n,name)   __request_region(&ioport_resource, (start), (n), (name))
index ab97fc5..29911bf 100644 (file)
@@ -185,7 +185,6 @@ struct inet6_skb_parm
        int                     iif;
        __u16                   ra;
        __u16                   hop;
-       __u16                   auth;
        __u16                   dst0;
        __u16                   srcrt;
        __u16                   dst1;
@@ -211,7 +210,6 @@ struct ipv6_pinfo {
                                rxhlim:1,
                                hopopts:1,
                                dstopts:1,
-                                authhdr:1,
                                 rxflow:1;
                } bits;
                __u8            all;
index 9dd7c9e..e7a19b3 100644 (file)
@@ -92,6 +92,7 @@ asmlinkage int printk(const char * fmt, ...)
 unsigned long int_sqrt(unsigned long);
 
 extern int printk_ratelimit(void);
+extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst);
 
 static inline void console_silent(void)
 {
index 67cce17..c0d7ce1 100644 (file)
@@ -148,4 +148,21 @@ struct ccw_device_id {
 #define CCW_DEVICE_ID_MATCH_DEVICE_MODEL       0x08
 
 
+#define PNP_ID_LEN     8
+#define PNP_MAX_DEVICES        8
+
+struct pnp_device_id {
+       __u8 id[PNP_ID_LEN];
+       kernel_ulong_t driver_data;
+};
+
+struct pnp_card_device_id {
+       __u8 id[PNP_ID_LEN];
+       kernel_ulong_t driver_data;
+       struct {
+               __u8 id[PNP_ID_LEN];
+       } devs[PNP_MAX_DEVICES];
+};
+
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
index cfdeaaa..ebc9426 100644 (file)
@@ -375,6 +375,10 @@ struct net_device
        atomic_t                refcnt;
        /* delayed register/unregister */
        struct list_head        todo_list;
+       /* device name hash chain */
+       struct hlist_node       name_hlist;
+       /* device index hash chain */
+       struct hlist_node       index_hlist;
 
        /* register/unregister state machine */
        enum { NETREG_UNINITIALIZED=0,
@@ -470,8 +474,15 @@ struct net_device
        /* class/net/name entry */
        struct class_device     class_dev;
        struct net_device_stats* (*last_stats)(struct net_device *);
+       /* how much padding had been added by alloc_netdev() */
+       int padded;
 };
 
+static inline void *netdev_priv(struct net_device *dev)
+{
+       return (char *)dev + ((sizeof(struct net_device) + 31) & ~31);
+}
+
 #define SET_MODULE_OWNER(dev) do { } while (0)
 /* Set the sysfs physical device reference for the network logical device
  * if set prior to registration will cause a symlink during initialization.
@@ -496,6 +507,7 @@ extern rwlock_t                             dev_base_lock;          /* Device list lock */
 
 extern int                     netdev_boot_setup_add(char *name, struct ifmap *map);
 extern int                     netdev_boot_setup_check(struct net_device *dev);
+extern unsigned long           netdev_boot_base(const char *prefix, int unit);
 extern struct net_device    *dev_getbyhwaddr(unsigned short type, char *hwaddr);
 extern struct net_device *__dev_getfirstbyhwtype(unsigned short type);
 extern struct net_device *dev_getfirstbyhwtype(unsigned short type);
index ea15674..4c8b5d1 100644 (file)
@@ -50,5 +50,6 @@ static inline int ip_conntrack_confirm(struct sk_buff *skb)
 extern struct list_head *ip_conntrack_hash;
 extern struct list_head ip_conntrack_expect_list;
 DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
+DECLARE_RWLOCK_EXTERN(ip_conntrack_expect_tuple_lock);
 #endif /* _IP_CONNTRACK_CORE_H */
 
index 77e99e8..eff925b 100644 (file)
@@ -311,6 +311,8 @@ struct parport {
 
        int spintime;
        atomic_t ref_count;
+
+       struct list_head full_list;
 };
 
 #define DEFAULT_SPIN_TIME 500 /* us */
index cbc23e3..0a5260e 100644 (file)
 #define PCI_DEVICE_ID_ATI_RADEON_In    0x496e
 /* Radeon RV280 (9200) */
 #define PCI_DEVICE_ID_ATI_RADEON_Y_    0x5960
+#define PCI_DEVICE_ID_ATI_RADEON_Ya    0x5961
 #define PCI_DEVICE_ID_ATI_RADEON_Yd    0x5964
 /* Radeon R300 (9500) */
 #define PCI_DEVICE_ID_ATI_RADEON_AD    0x4144
 #define PCI_DEVICE_ID_HP_TACHLITE      0x1029
 #define PCI_DEVICE_ID_HP_J2585A                0x1030
 #define PCI_DEVICE_ID_HP_J2585B                0x1031
+#define PCI_DEVICE_ID_HP_J2973A                0x1040
+#define PCI_DEVICE_ID_HP_J2970A                0x1042
 #define PCI_DEVICE_ID_HP_DIVA          0x1048
 #define PCI_DEVICE_ID_HP_DIVA_TOSCA1   0x1049
 #define PCI_DEVICE_ID_HP_DIVA_TOSCA2   0x104A
index d97edad..8ae0e14 100644 (file)
@@ -290,6 +290,37 @@ struct tc_htb_xstats
        __u32 ctokens;
 };
 
+/* HFSC section */
+
+struct tc_hfsc_qopt
+{
+       __u16   defcls;         /* default class */
+};
+
+struct tc_service_curve
+{
+       __u32   m1;             /* slope of the first segment in bps */
+       __u32   d;              /* x-projection of the first segment in us */
+       __u32   m2;             /* slope of the second segment in bps */
+};
+
+struct tc_hfsc_stats
+{
+       __u64   work;           /* total work done */
+       __u64   rtwork;         /* work done by real-time criteria */
+       __u32   period;         /* current period */
+       __u32   level;          /* class level in hierarchy */
+};
+
+enum
+{
+       TCA_HFSC_UNSPEC,
+       TCA_HFSC_RSC,
+       TCA_HFSC_FSC,
+       TCA_HFSC_USC,
+       TCA_HFSC_MAX = TCA_HFSC_USC
+};
+
 /* CBQ section */
 
 #define TC_CBQ_MAXPRIO         8
index 34d8c84..d728e2f 100644 (file)
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/mod_devicetable.h>
 
 #define PNP_MAX_PORT           8
 #define PNP_MAX_MEM            4
 #define PNP_MAX_IRQ            2
 #define PNP_MAX_DMA            2
-#define PNP_MAX_DEVICES                8
-#define PNP_ID_LEN             8
 #define PNP_NAME_LEN           50
 
 struct pnp_protocol;
@@ -34,8 +33,8 @@ struct pnp_dev;
 #define pnp_port_end(dev,bar)     ((dev)->res.port_resource[(bar)].end)
 #define pnp_port_flags(dev,bar)   ((dev)->res.port_resource[(bar)].flags)
 #define pnp_port_valid(dev,bar) \
-       ((pnp_port_flags((dev),(bar)) & IORESOURCE_IO) && \
-       !(pnp_port_flags((dev),(bar)) & IORESOURCE_UNSET))
+       ((pnp_port_flags((dev),(bar)) & (IORESOURCE_IO | IORESOURCE_UNSET)) \
+               == IORESOURCE_IO)
 #define pnp_port_len(dev,bar) \
        ((pnp_port_start((dev),(bar)) == 0 &&   \
          pnp_port_end((dev),(bar)) ==          \
@@ -48,8 +47,8 @@ struct pnp_dev;
 #define pnp_mem_end(dev,bar)     ((dev)->res.mem_resource[(bar)].end)
 #define pnp_mem_flags(dev,bar)   ((dev)->res.mem_resource[(bar)].flags)
 #define pnp_mem_valid(dev,bar) \
-       ((pnp_mem_flags((dev),(bar)) & IORESOURCE_MEM) && \
-       !(pnp_mem_flags((dev),(bar)) & IORESOURCE_UNSET))
+       ((pnp_mem_flags((dev),(bar)) & (IORESOURCE_MEM | IORESOURCE_UNSET)) \
+               == IORESOURCE_MEM)
 #define pnp_mem_len(dev,bar) \
        ((pnp_mem_start((dev),(bar)) == 0 &&    \
          pnp_mem_end((dev),(bar)) ==           \
@@ -61,14 +60,14 @@ struct pnp_dev;
 #define pnp_irq(dev,bar)        ((dev)->res.irq_resource[(bar)].start)
 #define pnp_irq_flags(dev,bar)  ((dev)->res.irq_resource[(bar)].flags)
 #define pnp_irq_valid(dev,bar) \
-       ((pnp_irq_flags((dev),(bar)) & IORESOURCE_IRQ) && \
-       !(pnp_irq_flags((dev),(bar)) & IORESOURCE_UNSET))
+       ((pnp_irq_flags((dev),(bar)) & (IORESOURCE_IRQ | IORESOURCE_UNSET)) \
+               == IORESOURCE_IRQ)
 
 #define pnp_dma(dev,bar)        ((dev)->res.dma_resource[(bar)].start)
 #define pnp_dma_flags(dev,bar)  ((dev)->res.dma_resource[(bar)].flags)
 #define pnp_dma_valid(dev,bar) \
-       ((pnp_dma_flags((dev),(bar)) & IORESOURCE_DMA) && \
-       !(pnp_dma_flags((dev),(bar)) & IORESOURCE_UNSET))
+       ((pnp_dma_flags((dev),(bar)) & (IORESOURCE_DMA | IORESOURCE_UNSET)) \
+               == IORESOURCE_DMA)
 
 #define PNP_PORT_FLAG_16BITADDR        (1<<0)
 #define PNP_PORT_FLAG_FIXED    (1<<1)
@@ -287,19 +286,6 @@ struct pnp_id {
        struct pnp_id * next;
 };
 
-struct pnp_device_id {
-       char id[PNP_ID_LEN];
-       unsigned long driver_data;      /* data private to the driver */
-};
-
-struct pnp_card_device_id {
-       char id[PNP_ID_LEN];
-       unsigned long driver_data;      /* data private to the driver */
-       struct {
-               char id[PNP_ID_LEN];
-       } devs[PNP_MAX_DEVICES];        /* logical devices */
-};
-
 struct pnp_driver {
        char * name;
        const struct pnp_device_id *id_table;
index 91a309f..53132cd 100644 (file)
 #define PT_TRACE_EXIT  0x00000200
 
 #define PT_TRACE_MASK  0x000003f4
-#define PT_SINGLESTEP  0x80000000      /* single stepping (used on ARM) */
+
+/* single stepping state bits (used on ARM and PA-RISC) */
+#define PT_SINGLESTEP_BIT      31
+#define PT_SINGLESTEP          (1<<PT_SINGLESTEP_BIT)
+#define PT_BLOCKSTEP_BIT       30
+#define PT_BLOCKSTEP           (1<<PT_BLOCKSTEP_BIT)
 
 #include <linux/compiler.h>            /* For unlikely.  */
 #include <linux/sched.h>               /* For struct task_struct.  */
index 4965e14..885a4a0 100644 (file)
@@ -200,7 +200,7 @@ struct scc_kiss {
        unsigned char fulldup;          /* Full Duplex mode 0=CSMA 1=DUP 2=ALWAYS KEYED */
        unsigned char waittime;         /* Waittime before any transmit attempt */
        unsigned int  maxkeyup;         /* Maximum time to transmit (seconds) */
-       unsigned char mintime;          /* Minimal offtime after MAXKEYUP timeout (seconds) */
+       unsigned int  mintime;          /* Minimal offtime after MAXKEYUP timeout (seconds) */
        unsigned int  idletime;         /* Maximum idle time in ALWAYS KEYED mode (seconds) */
        unsigned int  maxdefer;         /* Timer for CSMA channel busy limit */
        unsigned char tx_inhibit;       /* Transmit is not allowed when set */  
index 9ddc3bd..a851af9 100644 (file)
@@ -61,14 +61,14 @@ typedef struct sctphdr {
        __u16 dest;
        __u32 vtag;
        __u32 checksum;
-} sctp_sctphdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_sctphdr_t;
 
 /* Section 3.2.  Chunk Field Descriptions. */
 typedef struct sctp_chunkhdr {
        __u8 type;
        __u8 flags;
        __u16 length;
-} sctp_chunkhdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_chunkhdr_t;
 
 
 /* Section 3.2.  Chunk Type Values.
@@ -152,7 +152,7 @@ enum { SCTP_CHUNK_FLAG_T = 0x01 };
 typedef struct sctp_paramhdr {
        __u16 type;
        __u16 length;
-} sctp_paramhdr_t __attribute((packed));
+} __attribute__((packed)) sctp_paramhdr_t;
 
 typedef enum {
 
@@ -202,12 +202,12 @@ typedef struct sctp_datahdr {
        __u16 ssn;
        __u32 ppid;
        __u8  payload[0];
-} sctp_datahdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_datahdr_t;
 
 typedef struct sctp_data_chunk {
         sctp_chunkhdr_t chunk_hdr;
         sctp_datahdr_t  data_hdr;
-} sctp_data_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_data_chunk_t;
 
 /* DATA Chuck Specific Flags */
 enum {
@@ -232,48 +232,48 @@ typedef struct sctp_inithdr {
        __u16 num_inbound_streams;
        __u32 initial_tsn;
        __u8  params[0];
-} sctp_inithdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_inithdr_t;
 
 typedef struct sctp_init_chunk {
        sctp_chunkhdr_t chunk_hdr;
        sctp_inithdr_t init_hdr;
-} sctp_init_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_init_chunk_t;
 
 
 /* Section 3.3.2.1. IPv4 Address Parameter (5) */
 typedef struct sctp_ipv4addr_param {
        sctp_paramhdr_t param_hdr;
        struct in_addr  addr;
-} sctp_ipv4addr_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_ipv4addr_param_t;
 
 /* Section 3.3.2.1. IPv6 Address Parameter (6) */
 typedef struct sctp_ipv6addr_param {
        sctp_paramhdr_t param_hdr;
        struct in6_addr addr;
-} sctp_ipv6addr_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_ipv6addr_param_t;
 
 /* Section 3.3.2.1 Cookie Preservative (9) */
 typedef struct sctp_cookie_preserve_param {
        sctp_paramhdr_t param_hdr;
        uint32_t        lifespan_increment;
-} sctp_cookie_preserve_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_cookie_preserve_param_t;
 
 /* Section 3.3.2.1 Host Name Address (11) */
 typedef struct sctp_hostname_param {
        sctp_paramhdr_t param_hdr;
        uint8_t hostname[0];
-} sctp_hostname_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_hostname_param_t;
 
 /* Section 3.3.2.1 Supported Address Types (12) */
 typedef struct sctp_supported_addrs_param {
        sctp_paramhdr_t param_hdr;
        uint16_t types[0];
-} sctp_supported_addrs_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_supported_addrs_param_t;
 
 /* Appendix A. ECN Capable (32768) */
 typedef struct sctp_ecn_capable_param {
        sctp_paramhdr_t param_hdr;
-} sctp_ecn_capable_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_ecn_capable_param_t;
 
 
 
@@ -287,13 +287,13 @@ typedef sctp_init_chunk_t sctp_initack_chunk_t;
 typedef struct sctp_cookie_param {
        sctp_paramhdr_t p;
        __u8 body[0];
-} sctp_cookie_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_cookie_param_t;
 
 /* Section 3.3.3.1 Unrecognized Parameters (8) */
 typedef struct sctp_unrecognized_param {
        sctp_paramhdr_t param_hdr;
        sctp_paramhdr_t unrecognized;
-} sctp_unrecognized_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_unrecognized_param_t;
 
 
 
@@ -308,7 +308,7 @@ typedef struct sctp_unrecognized_param {
 typedef struct sctp_gap_ack_block {
        __u16 start;
        __u16 end;
-} sctp_gap_ack_block_t __attribute__((packed));
+} __attribute__((packed)) sctp_gap_ack_block_t;
 
 typedef uint32_t sctp_dup_tsn_t;
 
@@ -323,12 +323,12 @@ typedef struct sctp_sackhdr {
        __u16 num_gap_ack_blocks;
        __u16 num_dup_tsns;
        sctp_sack_variable_t variable[0];
-} sctp_sackhdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_sackhdr_t;
 
 typedef struct sctp_sack_chunk {
        sctp_chunkhdr_t chunk_hdr;
        sctp_sackhdr_t sack_hdr;
-} sctp_sack_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_sack_chunk_t;
 
 
 /* RFC 2960.  Section 3.3.5 Heartbeat Request (HEARTBEAT) (4):
@@ -340,12 +340,12 @@ typedef struct sctp_sack_chunk {
 
 typedef struct sctp_heartbeathdr {
        sctp_paramhdr_t info;
-} sctp_heartbeathdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_heartbeathdr_t;
 
 typedef struct sctp_heartbeat_chunk {
        sctp_chunkhdr_t chunk_hdr;
        sctp_heartbeathdr_t hb_hdr;
-} sctp_heartbeat_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_heartbeat_chunk_t;
 
 
 /* For the abort and shutdown ACK we must carry the init tag in the
@@ -354,7 +354,7 @@ typedef struct sctp_heartbeat_chunk {
  */
 typedef struct sctp_abort_chunk {
         sctp_chunkhdr_t uh;
-} sctp_abort_chunkt_t __attribute__((packed));
+} __attribute__((packed)) sctp_abort_chunkt_t;
 
 
 /* For the graceful shutdown we must carry the tag (in common header)
@@ -362,14 +362,12 @@ typedef struct sctp_abort_chunk {
  */
 typedef struct sctp_shutdownhdr {
        __u32 cum_tsn_ack;
-} sctp_shutdownhdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_shutdownhdr_t;
 
 struct sctp_shutdown_chunk_t {
         sctp_chunkhdr_t    chunk_hdr;
         sctp_shutdownhdr_t shutdown_hdr;
-} __attribute__((packed));
-
-
+} __attribute__ ((packed));
 
 /* RFC 2960.  Section 3.3.10 Operation Error (ERROR) (9) */
 
@@ -377,12 +375,12 @@ typedef struct sctp_errhdr {
        __u16 cause;
        __u16 length;
        __u8  variable[0];
-} sctp_errhdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_errhdr_t;
 
 typedef struct sctp_operr_chunk {
         sctp_chunkhdr_t chunk_hdr;
        sctp_errhdr_t   err_hdr;
-} sctp_operr_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_operr_chunk_t;
 
 /* RFC 2960 3.3.10 - Operation Error
  *
@@ -460,7 +458,7 @@ typedef struct sctp_ecnehdr {
 typedef struct sctp_ecne_chunk {
        sctp_chunkhdr_t chunk_hdr;
        sctp_ecnehdr_t ence_hdr;
-} sctp_ecne_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_ecne_chunk_t;
 
 /* RFC 2960.  Appendix A.  Explicit Congestion Notification.
  *   Congestion Window Reduced (CWR) (13)
@@ -472,7 +470,7 @@ typedef struct sctp_cwrhdr {
 typedef struct sctp_cwr_chunk {
        sctp_chunkhdr_t chunk_hdr;
        sctp_cwrhdr_t cwr_hdr;
-} sctp_cwr_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_cwr_chunk_t;
 
 /*
  * ADDIP Section 3.1 New Chunk Types
@@ -513,16 +511,16 @@ typedef struct sctp_cwr_chunk {
 typedef struct sctp_addip_param {
        sctp_paramhdr_t param_hdr;
        __u32           crr_id; 
-}sctp_addip_param_t __attribute__((packed));
+} __attribute__((packed)) sctp_addip_param_t;
 
 typedef struct sctp_addiphdr {
        __u32   serial;
        __u8    params[0];
-} sctp_addiphdr_t __attribute__((packed));
+} __attribute__((packed)) sctp_addiphdr_t;
 
 typedef struct sctp_addip_chunk {
        sctp_chunkhdr_t chunk_hdr;
        sctp_addiphdr_t addip_hdr;
-} sctp_addip_chunk_t __attribute__((packed));
+} __attribute__((packed)) sctp_addip_chunk_t;
 
 #endif /* __LINUX_SCTP_H__ */
index f37b7a6..6ad4e5c 100644 (file)
@@ -52,6 +52,9 @@ extern int strnicmp(const char *, const char *, __kernel_size_t);
 #ifndef __HAVE_ARCH_STRCHR
 extern char * strchr(const char *,int);
 #endif
+#ifndef __HAVE_ARCH_STRNCHR
+extern char * strnchr(const char *, size_t, int);
+#endif
 #ifndef __HAVE_ARCH_STRRCHR
 extern char * strrchr(const char *,int);
 #endif
index e83030e..6bad34f 100644 (file)
@@ -312,6 +312,7 @@ enum
        NET_TCP_FRTO=92,
        NET_TCP_LOW_LATENCY=93,
        NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
+       NET_TCP_WESTWOOD=95,
 };
 
 enum {
@@ -361,6 +362,7 @@ enum
        NET_IPV4_CONF_MEDIUM_ID=14,
        NET_IPV4_CONF_NOXFRM=15,
        NET_IPV4_CONF_NOPOLICY=16,
+       NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
 };
 
 /* /proc/sys/net/ipv4/netfilter */
@@ -582,6 +584,8 @@ enum {
        NET_SCTP_PRESERVE_ENABLE         = 11,
        NET_SCTP_MAX_BURST               = 12,
        NET_SCTP_ADDIP_ENABLE            = 13,
+       NET_SCTP_RMEM                    = 14,
+       NET_SCTP_WMEM                    = 15,
 };
 
 /* /proc/sys/net/bridge */
index d25e5bd..1b35358 100644 (file)
@@ -374,6 +374,20 @@ struct tcp_opt {
        __u32                   frto_highmark; /* snd_nxt when RTO occurred */
 
        unsigned long last_synq_overflow; 
+
+/* TCP Westwood structure */
+        struct {
+                __u32    bw_sample;        /* bandwidth sample */
+                __u32    bw_ns_est;        /* first bandwidth estimation..not too smoothed 8) */
+                __u32    bw_est;           /* bandwidth estimate */
+                __u32    rtt_win_sx;       /* here starts a new evaluation... */
+                __u32    bk;
+                __u32    snd_una;          /* used for evaluating the number of acked bytes */
+                __u32    cumul_ack;
+                __u32    accounted;
+                __u32    rtt;
+                __u32    rtt_min;          /* minimum observed RTT */
+        } westwood;
 };
 
 /* WARNING: don't change the layout of the members in tcp_sock! */
index f65d245..61fd735 100644 (file)
@@ -5,6 +5,8 @@
 #include <linux/if_arp.h>
 #include <net/neighbour.h>
 
+#define HAVE_ARP_CREATE
+
 extern struct neigh_table arp_tbl;
 
 extern void    arp_init(void);
@@ -19,6 +21,12 @@ extern int   arp_bind_neighbour(struct dst_entry *dst);
 extern int     arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir);
 extern void    arp_ifdown(struct net_device *dev);
 
+extern struct sk_buff *arp_create(int type, int ptype, u32 dest_ip,
+                                 struct net_device *dev, u32 src_ip,
+                                 unsigned char *dest_hw, unsigned char *src_hw,
+                                 unsigned char *target_hw);
+extern void arp_xmit(struct sk_buff *skb);
+
 extern struct neigh_ops arp_broken_ops;
 
 #endif /* _ARP_H */
index 394eb72..47048b1 100644 (file)
@@ -44,7 +44,7 @@ struct atmarp_entry {
 };
 
 
-#define PRIV(dev) ((struct clip_priv *) ((struct net_device *) (dev)+1))
+#define PRIV(dev) ((struct clip_priv *) netdev_priv(dev))
 
 
 struct clip_priv {
index 794ff35..8654632 100644 (file)
@@ -64,7 +64,6 @@ extern struct rt6_info                *rt6_lookup(struct in6_addr *daddr,
 
 extern struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
                                         struct neighbour *neigh,
-                                        struct in6_addr *addr,
                                         int (*output)(struct sk_buff *));
 extern int ndisc_dst_gc(int *more);
 extern void fib6_force_start_gc(void);
index 4576794..9d92e24 100644 (file)
@@ -385,7 +385,6 @@ extern int                  ip6_dst_lookup(struct sock *sk,
  */
 
 extern int                     ip6_output(struct sk_buff *skb);
-extern int                     ip6_output2(struct sk_buff *skb);
 extern int                     ip6_forward(struct sk_buff *skb);
 extern int                     ip6_input(struct sk_buff *skb);
 extern int                     ip6_mc_input(struct sk_buff *skb);
index 779d34a..eb3ad15 100644 (file)
@@ -40,7 +40,7 @@
 
 #define CONTROL_BIT    0x80
 
-inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, 
+void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
                                int expedited, struct sk_buff *skb);
 void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, 
                        __u8 opcode, struct sk_buff *skb);
index 739a89d..61103a3 100644 (file)
@@ -74,19 +74,19 @@ typedef void (*TIMER_CALLBACK)(void *);
 void irda_start_timer(struct timer_list *ptimer, int timeout, void* data,
                      TIMER_CALLBACK callback);
 
-inline void irlap_start_slot_timer(struct irlap_cb *self, int timeout);
-inline void irlap_start_query_timer(struct irlap_cb *self, int timeout);
-inline void irlap_start_final_timer(struct irlap_cb *self, int timeout);
-inline void irlap_start_wd_timer(struct irlap_cb *self, int timeout);
-inline void irlap_start_backoff_timer(struct irlap_cb *self, int timeout);
+void irlap_start_slot_timer(struct irlap_cb *self, int timeout);
+void irlap_start_query_timer(struct irlap_cb *self, int timeout);
+void irlap_start_final_timer(struct irlap_cb *self, int timeout);
+void irlap_start_wd_timer(struct irlap_cb *self, int timeout);
+void irlap_start_backoff_timer(struct irlap_cb *self, int timeout);
 
 void irlap_start_mbusy_timer(struct irlap_cb *self, int timeout);
 void irlap_stop_mbusy_timer(struct irlap_cb *);
 
-inline void irlmp_start_watchdog_timer(struct lsap_cb *, int timeout);
-inline void irlmp_start_discovery_timer(struct irlmp_cb *, int timeout);
-inline void irlmp_start_idle_timer(struct lap_cb *, int timeout);
-inline void irlmp_stop_idle_timer(struct lap_cb *self); 
+void irlmp_start_watchdog_timer(struct lsap_cb *, int timeout);
+void irlmp_start_discovery_timer(struct irlmp_cb *, int timeout);
+void irlmp_start_idle_timer(struct lap_cb *, int timeout);
+void irlmp_stop_idle_timer(struct lap_cb *self);
 
 #endif
 
index df98160..95684d3 100644 (file)
@@ -45,11 +45,6 @@ struct nd_msg {
        __u8            opt[0];
 };
 
-struct rs_msg {
-       struct icmp6hdr icmph;
-       __u8            opt[0];
-};
-
 struct ra_msg {
         struct icmp6hdr                icmph;
        __u32                   reachable_time;
index af1050f..857f03a 100644 (file)
 #include <asm/atomic.h>
 #include <linux/skbuff.h>
 
-#include <linux/config.h>
-
 #include <linux/err.h>
 #include <linux/sysctl.h>
 
-#ifdef CONFIG_IPV6_NDISC_NEW
-#define NUD_IN_TIMER   (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
-#else
 #define NUD_IN_TIMER   (NUD_INCOMPLETE|NUD_DELAY|NUD_PROBE)
-#endif
 #define NUD_VALID      (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
 #define NUD_CONNECTED  (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
 
@@ -177,51 +171,6 @@ struct neigh_table
        struct pneigh_entry     *phash_buckets[PNEIGH_HASHMASK+1];
 };
 
-static __inline__ char * neigh_state(int state)
-{
-       switch (state) {
-       case NUD_NONE:          return "NONE";
-       case NUD_INCOMPLETE:    return "INCOMPLETE";
-       case NUD_REACHABLE:     return "REACHABLE";
-       case NUD_STALE:         return "STALE";
-       case NUD_DELAY:         return "DELAY";
-       case NUD_PROBE:         return "PROBE";
-       case NUD_FAILED:        return "FAILED";
-       case NUD_NOARP:         return "NOARP";
-       case NUD_PERMANENT:     return "PERMANENT";
-       default:                return "???";
-       }
-}
-
-/* flags for __neigh_update() */
-#define NEIGH_UPDATE_F_ADMIN                   0x00000001
-#define NEIGH_UPDATE_F_ISROUTER                        0x00000002
-#define NEIGH_UPDATE_F_OVERRIDE                        0x00000004
-#define NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER 0x00000008
-#define NEIGH_UPDATE_F_REUSEADDR               0x00000010
-#define NEIGH_UPDATE_F_REUSESUSPECTSTATE       0x00000020
-#define NEIGH_UPDATE_F_SETUP_ISROUTER          0x00000040
-#define NEIGH_UPDATE_F_SUSPECT_CONNECTED       0x00000080
-
-#define NEIGH_UPDATE_F_IP6NS           (NEIGH_UPDATE_F_SETUP_ISROUTER|\
-                                        NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
-                                        NEIGH_UPDATE_F_OVERRIDE)
-#define NEIGH_UPDATE_F_IP6NA           (NEIGH_UPDATE_F_SETUP_ISROUTER|\
-                                        NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
-                                        NEIGH_UPDATE_F_SUSPECT_CONNECTED|\
-                                        NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER)
-#define NEIGH_UPDATE_F_IP6RS           (NEIGH_UPDATE_F_SETUP_ISROUTER|\
-                                        NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
-                                        NEIGH_UPDATE_F_OVERRIDE|\
-                                        NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER)
-#define NEIGH_UPDATE_F_IP6RA           (NEIGH_UPDATE_F_SETUP_ISROUTER|\
-                                        NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
-                                        NEIGH_UPDATE_F_OVERRIDE|\
-                                        NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER|\
-                                        NEIGH_UPDATE_F_ISROUTER)
-#define NEIGH_UPDATE_F_IP6REDIRECT     (NEIGH_UPDATE_F_REUSESUSPECTSTATE|\
-                                        NEIGH_UPDATE_F_OVERRIDE)
-
 extern void                    neigh_table_init(struct neigh_table *tbl);
 extern int                     neigh_table_clear(struct neigh_table *tbl);
 extern struct neighbour *      neigh_lookup(struct neigh_table *tbl,
@@ -232,7 +181,6 @@ extern struct neighbour *   neigh_create(struct neigh_table *tbl,
                                             struct net_device *dev);
 extern void                    neigh_destroy(struct neighbour *neigh);
 extern int                     __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
-extern int                     __neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags);
 extern int                     neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, int override, int arp);
 extern void                    neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 extern int                     neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
@@ -258,7 +206,6 @@ extern int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb);
 extern int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
 extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
 extern void neigh_app_ns(struct neighbour *n);
-extern void neigh_app_notify(struct neighbour *n);
 
 extern int                     neigh_sysctl_register(struct net_device *dev, 
                                                      struct neigh_parms *p,
@@ -273,35 +220,18 @@ extern void                       neigh_sysctl_unregister(struct neigh_parms *p);
 
 static inline void neigh_release(struct neighbour *neigh)
 {
-#ifdef CONFIG_IPV6_NDISC_DEBUG
-       printk(KERN_DEBUG "%s(neigh=%p): refcnt=%d\n",
-               __FUNCTION__, neigh, atomic_read(&neigh->refcnt)-1);
-#endif
        if (atomic_dec_and_test(&neigh->refcnt))
                neigh_destroy(neigh);
 }
 
 static inline struct neighbour * neigh_clone(struct neighbour *neigh)
 {
-#ifdef CONFIG_IPV6_NDISC_DEBUG
-       printk(KERN_DEBUG "%s(neigh=%p): refcnt=%d\n",
-               __FUNCTION__, neigh, neigh ? atomic_read(&neigh->refcnt)+1 : 0);
-#endif
        if (neigh)
                atomic_inc(&neigh->refcnt);
        return neigh;
 }
 
-#ifdef CONFIG_IPV6_NDISC_DEBUG
-#define neigh_hold(n)  ({      \
-       struct neighbour *_n = (n);             \
-       printk(KERN_DEBUG "%s(neigh=%p): refcnt=%d\n", \
-               __FUNCTION__, _n, atomic_read(&_n->refcnt)+1);  \
-       atomic_inc(&_n->refcnt);        \
-})
-#else
 #define neigh_hold(n)  atomic_inc(&(n)->refcnt)
-#endif
 
 static inline void neigh_confirm(struct neighbour *neigh)
 {
@@ -321,24 +251,10 @@ static inline int neigh_is_valid(struct neighbour *neigh)
 
 static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
-       int ret = 0;
-
-#ifdef CONFIG_IPV6_NDISC_DEBUG
-       printk(KERN_DEBUG
-               "%s(neigh=%p, skb=%p): %s, refcnt=%d\n",
-               __FUNCTION__, neigh, skb, neigh_state(neigh->nud_state), atomic_read(&neigh->refcnt));
-#endif
-       write_lock_bh(&neigh->lock);
        neigh->used = jiffies;
        if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
-               ret = __neigh_event_send(neigh, skb);
-       write_unlock_bh(&neigh->lock);
-       if (ret < 0) {
-               if (skb)
-                       kfree_skb(skb);
-               ret = 1;
-       }
-       return ret;
+               return __neigh_event_send(neigh, skb);
+       return 0;
 }
 
 static inline struct neighbour *
@@ -365,23 +281,6 @@ __neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
        return neigh_create(tbl, pkey, dev);
 }
 
-static inline struct pneigh_entry *pneigh_clone(struct pneigh_entry *pneigh)
-{
-       return pneigh;
-}
-
-static inline void pneigh_refcnt_init(struct pneigh_entry *pneigh) {}
-
-static inline int pneigh_refcnt_dec_and_test(struct pneigh_entry *pneigh)
-{
-       return 1;
-}
-
-static inline int pneigh_alloc_flag(void)
-{
-       return GFP_KERNEL;
-}
-
 #endif
 #endif
 
index 2705238..35f600b 100644 (file)
@@ -203,6 +203,7 @@ typedef long                psched_tdiff_t;
 
 #define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
 #define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ))
+#define PSCHED_JIFFIE2US(delay) ((delay)*(1000000/HZ))
 
 #define PSCHED_EXPORTLIST EXPORT_SYMBOL(psched_tod_diff);
 
@@ -251,6 +252,7 @@ extern PSCHED_WATCHER psched_time_mark;
 #endif
 
 #define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE)
+#define PSCHED_JIFFIE2US(delay) ((delay)<<PSCHED_JSCALE)
 
 #elif PSCHED_CLOCK_SOURCE == PSCHED_CPU
 
@@ -261,6 +263,7 @@ extern int psched_clock_scale;
                             EXPORT_SYMBOL(psched_clock_scale);
 
 #define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz)
+#define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz)
 
 #ifdef CONFIG_X86_TSC
 
index f031313..6112e85 100644 (file)
@@ -323,7 +323,7 @@ typedef enum {
 #define SCTP_DEFAULT_COOKIE_LIFE_USEC  0  /* microseconds */
 
 #define SCTP_DEFAULT_MINWINDOW 1500    /* default minimum rwnd size */
-#define SCTP_DEFAULT_MAXWINDOW 32768   /* default rwnd size */
+#define SCTP_DEFAULT_MAXWINDOW 65535   /* default rwnd size */
 #define SCTP_DEFAULT_MAXSEGMENT 1500   /* MTU size, this is the limit
                                          * to which we will raise the P-MTU.
                                         */
index 92394f3..ee24aa0 100644 (file)
@@ -193,6 +193,10 @@ extern struct sctp_globals {
        
        /* Flag to indicate if addip is enabled. */
        int addip_enable;
+
+       /* socket receive and send buffer sizes. */ 
+       int rmem;
+       int wmem;
 } sctp_globals;
 
 #define sctp_rto_initial               (sctp_globals.rto_initial)
@@ -221,6 +225,8 @@ extern struct sctp_globals {
 #define sctp_local_addr_list           (sctp_globals.local_addr_list)
 #define sctp_local_addr_lock           (sctp_globals.local_addr_lock)
 #define sctp_addip_enable              (sctp_globals.addip_enable)
+#define sctp_rmem                      (sctp_globals.rmem)
+#define sctp_wmem                      (sctp_globals.wmem)
 
 /* SCTP Socket type: UDP or TCP style. */
 typedef enum {
@@ -369,7 +375,7 @@ typedef struct sctp_sender_hb_info {
        struct sctp_paramhdr param_hdr;
        union sctp_addr daddr;
        unsigned long sent_at;
-} sctp_sender_hb_info_t __attribute__((packed));
+} __attribute__((packed)) sctp_sender_hb_info_t;
 
 /*
  *  RFC 2960 1.3.2 Sequenced Delivery within Streams
index 4ef3b80..55c5ea8 100644 (file)
@@ -579,6 +579,7 @@ extern int sysctl_tcp_adv_win_scale;
 extern int sysctl_tcp_tw_reuse;
 extern int sysctl_tcp_frto;
 extern int sysctl_tcp_low_latency;
+extern int sysctl_tcp_westwood;
 
 extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
@@ -738,7 +739,7 @@ DECLARE_SNMP_STAT(struct tcp_mib, tcp_statistics);
 #define TCP_ADD_STATS_BH(field, val)   SNMP_ADD_STATS_BH(tcp_statistics, field, val)
 #define TCP_ADD_STATS_USER(field, val) SNMP_ADD_STATS_USER(tcp_statistics, field, val)
 
-extern inline void             tcp_put_port(struct sock *sk);
+extern void                    tcp_put_port(struct sock *sk);
 extern void                    tcp_inherit_port(struct sock *sk, struct sock *child);
 
 extern void                    tcp_v4_err(struct sk_buff *skb, u32);
@@ -2019,4 +2020,67 @@ struct tcp_iter_state {
 extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo);
 extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);
 
+/* TCP Westwood functions and constants */
+
+#define TCP_WESTWOOD_INIT_RTT  (20*HZ)           /* maybe too conservative?! */
+#define TCP_WESTWOOD_RTT_MIN   (HZ/20)           /* 50ms */
+
+static inline void tcp_westwood_update_rtt(struct tcp_opt *tp, __u32 rtt_seq)
+{
+        if (sysctl_tcp_westwood)
+                tp->westwood.rtt = rtt_seq;
+}
+
+void __tcp_westwood_fast_bw(struct sock *, struct sk_buff *);
+void __tcp_westwood_slow_bw(struct sock *, struct sk_buff *);
+
+static inline void tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
+{
+        if (sysctl_tcp_westwood)
+                __tcp_westwood_fast_bw(sk, skb);
+}
+
+static inline void tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
+{
+        if (sysctl_tcp_westwood)
+                __tcp_westwood_slow_bw(sk, skb);
+}
+
+static inline __u32 __tcp_westwood_bw_rttmin(const struct tcp_opt *tp)
+{
+        return max((tp->westwood.bw_est) * (tp->westwood.rtt_min) /
+                  (__u32) (tp->mss_cache),
+                  2U);
+}
+
+static inline __u32 tcp_westwood_bw_rttmin(const struct tcp_opt *tp)
+{
+       return sysctl_tcp_westwood ? __tcp_westwood_bw_rttmin(tp) : 0;
+}
+
+static inline int tcp_westwood_ssthresh(struct tcp_opt *tp)
+{
+       __u32 ssthresh = 0;
+
+       if (sysctl_tcp_westwood) {
+               ssthresh = __tcp_westwood_bw_rttmin(tp);
+               if (ssthresh)
+                       tp->snd_ssthresh = ssthresh;  
+       }
+
+       return (ssthresh != 0);
+}
+
+static inline int tcp_westwood_cwnd(struct tcp_opt *tp)
+{
+       __u32 cwnd = 0;
+
+       if (sysctl_tcp_westwood) {
+               cwnd = __tcp_westwood_bw_rttmin(tp);
+               if (cwnd)
+                       tp->snd_cwnd = cwnd;
+       }
+
+       return (cwnd != 0);
+}
 #endif /* _TCP_H */
index d5e7bf9..cf37658 100644 (file)
@@ -479,6 +479,8 @@ void snd_ac97_resume(ac97_t *ac97);
 
 /* quirk types */
 enum {
+       AC97_TUNE_DEFAULT = -1, /* use default from quirk list (not valid in list) */
+       AC97_TUNE_NONE = 0,     /* nothing extra to do */
        AC97_TUNE_HP_ONLY,      /* headphone (true line-out) control as master only */
        AC97_TUNE_SWAP_HP,      /* swap headphone and master controls */
        AC97_TUNE_SWAP_SURROUND, /* swap master and surround controls */
@@ -493,7 +495,7 @@ struct ac97_quirk {
        int type;               /* quirk type above */
 };
 
-int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk);
+int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, int override);
 int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate);
 
 int snd_ac97_pcm_assign(ac97_bus_t *ac97,
index 8f5c5d1..4a58003 100644 (file)
@@ -199,6 +199,7 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
 #define vx_pipe_t_magic                                0xa15a4112
 #define azf3328_t_magic                                0xa15a4200
 #define snd_card_harmony_t_magic               0xa15a4300
+#define bt87x_t_magic                          0xa15a4400
 
 #else
 
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
new file mode 100644 (file)
index 0000000..ad3c3be
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __SOUND_TEA575X_TUNER_H
+#define __SOUND_TEA575X_TUNER_H
+
+/*
+ *   ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
+ *
+ *     Copyright (c) 2004 Jaroslav Kysela <perex@suse.cz>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the 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/videodev.h>
+
+typedef struct snd_tea575x tea575x_t;
+
+struct snd_tea575x_ops {
+       void (*write)(tea575x_t *tea, unsigned int val);
+       unsigned int (*read)(tea575x_t *tea);
+};
+
+struct snd_tea575x {
+       snd_card_t *card;
+       struct video_device vd;         /* video device */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
+       struct file_operations fops;
+#endif
+       int dev_nr;                     /* requested device number + 1 */
+       int vd_registered;              /* video device is registered */
+       int tea5759;                    /* 5759 chip is present */
+       unsigned int freq_fixup;        /* crystal onboard */
+       unsigned int val;               /* hw value */
+       unsigned long freq;             /* frequency */
+       struct snd_tea575x_ops *ops;
+       void *private_data;
+};
+
+void snd_tea575x_init(tea575x_t *tea);
+void snd_tea575x_exit(tea575x_t *tea);
+
+#endif /* __SOUND_TEA575X_TUNER_H */
index 502e74e..139c090 100644 (file)
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.2"
-#define CONFIG_SND_DATE " (Tue Jan 27 10:28:52 2004 UTC)"
+#define CONFIG_SND_VERSION "1.0.2c"
+#define CONFIG_SND_DATE " (Thu Feb 05 15:41:49 2004 UTC)"
index 806b2d7..bb548b5 100644 (file)
@@ -509,7 +509,7 @@ int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
        return 0;
 }
 
-#if !defined(__ia64__) && !defined(__x86_64__)
+#if !defined(__ia64__) && !defined(__x86_64__) && !defined(__hppa__)
 
 /**
  *     ipc_parse_version       -       IPC call version
index 833c264..79c8fc9 100644 (file)
@@ -56,7 +56,7 @@ int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid);
 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
 
-#if defined(__ia64__) || defined(__x86_64__)
+#if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__)
   /* On IA-64, we always use the "64-bit version" of the IPC structures.  */ 
 # define ipc_parse_version(cmd)        IPC_64
 #else
index 8d08b13..cf51df6 100644 (file)
@@ -796,7 +796,6 @@ NORET_TYPE void do_exit(long code)
        /* Avoid "noreturn function does return".  */
        for (;;) ;
 }
-EXPORT_SYMBOL(do_exit);
 
 NORET_TYPE void complete_and_exit(struct completion *comp, long code)
 {
index c20e1da..d4d7ed5 100644 (file)
@@ -820,12 +820,6 @@ void tty_write_message(struct tty_struct *tty, char *msg)
        return;
 }
 
-/* minimum time in jiffies between messages */
-int printk_ratelimit_jiffies = 5*HZ;
-
-/* number of messages we send before ratelimiting */
-int printk_ratelimit_burst = 10;
-
 /*
  * printk rate limiting, lifted from the networking subsystem.
  *
@@ -833,7 +827,7 @@ int printk_ratelimit_burst = 10;
  * every printk_ratelimit_jiffies to make a denial-of-service
  * attack impossible.
  */
-int printk_ratelimit(void)
+int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
 {
        static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
        static unsigned long toks = 10*5*HZ;
@@ -845,12 +839,12 @@ int printk_ratelimit(void)
        spin_lock_irqsave(&ratelimit_lock, flags);
        toks += now - last_msg;
        last_msg = now;
-       if (toks > (printk_ratelimit_burst * printk_ratelimit_jiffies))
-               toks = printk_ratelimit_burst * printk_ratelimit_jiffies;
-       if (toks >= printk_ratelimit_jiffies) {
+       if (toks > (ratelimit_burst * ratelimit_jiffies))
+               toks = ratelimit_burst * ratelimit_jiffies;
+       if (toks >= ratelimit_jiffies) {
                int lost = missed;
                missed = 0;
-               toks -= printk_ratelimit_jiffies;
+               toks -= ratelimit_jiffies;
                spin_unlock_irqrestore(&ratelimit_lock, flags);
                if (lost)
                        printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
@@ -860,6 +854,19 @@ int printk_ratelimit(void)
        spin_unlock_irqrestore(&ratelimit_lock, flags);
        return 0;
 }
+EXPORT_SYMBOL(__printk_ratelimit);
+
+/* minimum time in jiffies between messages */
+int printk_ratelimit_jiffies = 5*HZ;
+
+/* number of messages we send before ratelimiting */
+int printk_ratelimit_burst = 10;
+
+int printk_ratelimit(void)
+{
+       return __printk_ratelimit(printk_ratelimit_jiffies,
+                               printk_ratelimit_burst);
+}
 EXPORT_SYMBOL(printk_ratelimit);
 
 #ifdef CONFIG_IA64_EARLY_PRINTK
index e2048de..558e5ed 100644 (file)
@@ -361,6 +361,49 @@ int insert_resource(struct resource *parent, struct resource *new)
 EXPORT_SYMBOL(insert_resource);
 
 /*
+ * Given an existing resource, change its start and size to match the
+ * arguments.  Returns -EBUSY if it can't fit.  Existing children of
+ * the resource are assumed to be immutable.
+ */
+int adjust_resource(struct resource *res, unsigned long start, unsigned long size)
+{
+       struct resource *tmp, *parent = res->parent;
+       unsigned long end = start + size - 1;
+       int result = -EBUSY;
+
+       write_lock(&resource_lock);
+
+       if ((start < parent->start) || (end > parent->end))
+               goto out;
+
+       for (tmp = res->child; tmp; tmp = tmp->sibling) {
+               if ((tmp->start < start) || (tmp->end > end))
+                       goto out;
+       }
+
+       if (res->sibling && (res->sibling->start <= end))
+               goto out;
+
+       tmp = parent->child;
+       if (tmp != res) {
+               while (tmp->sibling != res)
+                       tmp = tmp->sibling;
+               if (start <= tmp->end)
+                       goto out;
+       }
+
+       res->start = start;
+       res->end = end;
+       result = 0;
+
+ out:
+       write_unlock(&resource_lock);
+       return result;
+}
+
+EXPORT_SYMBOL(adjust_resource);
+
+/*
  * This is compatibility stuff for IO resources.
  *
  * Note how this, unlike the above, knows about
index fb09dff..5e93a93 100644 (file)
@@ -220,7 +220,7 @@ EXPORT_SYMBOL(bitmap_snprintf);
 int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
         unsigned long *maskp, int nmaskbits)
 {
-       int i, c, old_c, totaldigits, ndigits, nchunks, nbits;
+       int c, old_c, totaldigits, ndigits, nchunks, nbits;
        u32 chunk;
 
        bitmap_clear(maskp, nmaskbits);
@@ -270,9 +270,7 @@ int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
                        continue;
 
                bitmap_shift_right(maskp, maskp, CHUNKSZ, nmaskbits);
-               for (i = 0; i < CHUNKSZ; i++)
-                       if (chunk & (1 << i))
-                               set_bit(i, maskp);
+               *maskp |= chunk;
                nchunks++;
                nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ;
                if (nbits > nmaskbits)
index e660de0..d2f23f2 100644 (file)
@@ -273,6 +273,22 @@ char * strrchr(const char * s, int c)
 }
 #endif
 
+#ifndef __HAVE_ARCH_STRNCHR
+/**
+ * strnchr - Find a character in a length limited string
+ * @s: The string to be searched
+ * @count: The number of characters to be searched
+ * @c: The character to search for
+ */
+char *strnchr(const char *s, size_t count, int c)
+{
+       for (; count-- && *s != '\0'; ++s)
+               if (*s == (char) c)
+                       return (char *) s;
+       return NULL;
+}
+#endif
+
 #ifndef __HAVE_ARCH_STRLEN
 /**
  * strlen - Find the length of a string
index da4398a..b30a4a2 100644 (file)
@@ -234,6 +234,11 @@ static char * number(char * buf, char * end, unsigned long long num, int base, i
 * @fmt: The format string to use
 * @args: Arguments for the format string
 *
+* The return value is the number of characters which would be
+* generated for the given input, excluding the trailing null,
+* as per ISO C99.  If the return is greater than or equal to
+* @size, the resulting string is truncated.
+*
 * Call this function if you are already dealing with a va_list.
 * You probably want snprintf instead.
  */
@@ -482,6 +487,11 @@ EXPORT_SYMBOL(vsnprintf);
  * @size: The size of the buffer, including the trailing null space
  * @fmt: The format string to use
  * @...: Arguments for the format string
+ *
+ * The return value is the number of characters which would be
+ * generated for the given input, excluding the trailing null,
+ * as per ISO C99.  If the return is greater than or equal to
+ * @size, the resulting string is truncated.
  */
 int snprintf(char * buf, size_t size, const char *fmt, ...)
 {
@@ -608,7 +618,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
                                field_width = 1;
                        do {
                                *s++ = *str++;
-                       } while(field_width-- > 0 && *str);
+                       } while (--field_width > 0 && *str);
                        num++;
                }
                continue;
index b57186d..4c457c7 100644 (file)
@@ -129,10 +129,10 @@ static inline int sync_page(struct page *page)
  * filemap_fdatawrite - start writeback against all of a mapping's dirty pages
  * @mapping: address space structure to write
  *
- * This is a "data integrity" operation, as opposed to a regular memory
- * cleansing writeback.  The difference between these two operations is that
- * if a dirty page/buffer is encountered, it must be waited upon, and not just
- * skipped over.
+ * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as
+ * opposed to a regular memory * cleansing writeback.  The difference between
+ * these two operations is that if a dirty page/buffer is encountered, it must
+ * be waited upon, and not just skipped over.
  */
 static int __filemap_fdatawrite(struct address_space *mapping, int sync_mode)
 {
index 47131d2..b91d251 100644 (file)
@@ -445,6 +445,7 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
         */
 
        if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
+               int orig_headroom = skb_headroom(skb);
                unsigned short veth_TCI;
 
                /* This is not a VLAN frame...but we can fix that! */
@@ -454,33 +455,7 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                printk(VLAN_DBG "%s: proto to encap: 0x%hx (hbo)\n",
                        __FUNCTION__, htons(veth->h_vlan_proto));
 #endif
-
-               if (skb_headroom(skb) < VLAN_HLEN) {
-                       struct sk_buff *sk_tmp = skb;
-                       skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
-                       kfree_skb(sk_tmp);
-                       if (skb == NULL) {
-                               stats->tx_dropped++;
-                               return 0;
-                       }
-                       VLAN_DEV_INFO(dev)->cnt_inc_headroom_on_tx++;
-               } else {
-                       if (!(skb = skb_unshare(skb, GFP_ATOMIC))) {
-                               printk(KERN_ERR "vlan: failed to unshare skbuff\n");
-                               stats->tx_dropped++;
-                               return 0;
-                       }
-               }
-               veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
-
-               /* Move the mac addresses to the beginning of the new header. */
-               memmove(skb->data, skb->data + VLAN_HLEN, 12);
-
-               /* first, the ethernet type */
-               /* put_unaligned(__constant_htons(ETH_P_8021Q), &veth->h_vlan_proto); */
-               veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
-
-               /* Now, construct the second two bytes. This field looks something
+               /* Construct the second two bytes. This field looks something
                 * like:
                 * usr_priority: 3 bits  (high bits)
                 * CFI           1 bit
@@ -489,10 +464,16 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
                veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
 
-               veth->h_vlan_TCI = htons(veth_TCI);
-       }
+               skb = __vlan_put_tag(skb, veth_TCI);
+               if (!skb) {
+                       stats->tx_dropped++;
+                       return 0;
+               }
 
-       skb->dev = VLAN_DEV_INFO(dev)->real_dev;
+               if (orig_headroom < VLAN_HLEN) {
+                       VLAN_DEV_INFO(dev)->cnt_inc_headroom_on_tx++;
+               }
+       }
 
 #ifdef VLAN_DEBUG
        printk(VLAN_DBG "%s: about to send skb: %p to dev: %s\n",
@@ -506,10 +487,7 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        stats->tx_packets++; /* for statics only */
        stats->tx_bytes += skb->len;
 
-       skb->protocol = __constant_htons(ETH_P_8021Q);
-       skb->mac.raw -= VLAN_HLEN;
-       skb->nh.raw -= VLAN_HLEN;
-
+       skb->dev = VLAN_DEV_INFO(dev)->real_dev;
        dev_queue_xmit(skb);
 
        return 0;
@@ -518,17 +496,22 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_device_stats *stats = vlan_dev_get_stats(dev);
-       struct vlan_skb_tx_cookie *cookie;
+       unsigned short veth_TCI;
+
+       /* Construct the second two bytes. This field looks something
+        * like:
+        * usr_priority: 3 bits  (high bits)
+        * CFI           1 bit
+        * VLAN ID       12 bits (low bits)
+        */
+       veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
+       veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
+       skb = __vlan_hwaccel_put_tag(skb, veth_TCI);
 
        stats->tx_packets++;
        stats->tx_bytes += skb->len;
 
        skb->dev = VLAN_DEV_INFO(dev)->real_dev;
-       cookie = VLAN_TX_SKB_CB(skb);
-       cookie->magic = VLAN_TX_COOKIE_MAGIC;
-       cookie->vlan_tag = (VLAN_DEV_INFO(dev)->vlan_id |
-                           vlan_dev_get_egress_qos_mask(dev, skb));
-
        dev_queue_xmit(skb);
 
        return 0;
index 3dcc4c3..d20ba70 100644 (file)
@@ -145,7 +145,7 @@ config DECNET
 
          To find some tools to use with the kernel layer support, please
          look at Patrick Caulfield's web site:
-         <http://linux.dreamtime.org/decnet/>.
+         <http://linux-decnet.sourceforge.net/>.
 
          More detailed documentation is available in
          <file:Documentation/networking/decnet.txt>.
@@ -436,7 +436,7 @@ config X25
          (say Y to "LAPB Data Link Driver" below if you want that).
 
          You can read more about X.25 at <http://www.sangoma.com/x25.htm> and
-         <http://www.cisco.com/univercd/data/doc/software/11_0/rpcg/cx25.htm>.
+         <http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/cbook/cx25.htm>.
          Information about X.25 for Linux is contained in the files
          <file:Documentation/networking/x25.txt> and
          <file:Documentation/networking/x25-iface.txt>.
@@ -571,7 +571,7 @@ config NET_FASTROUTE
 
          At the moment, few devices support fast switching (tulip is one of
          them, a modified 8390 driver can be found at
-         <ftp://ftp.inr.ac.ru/ip-routing/fastroute/fastroute-8390.tar.gz>).
+         <ftp://ftp.tux.org/pub/net/ip-routing/fastroute/fastroute-8390.tar.gz>).
 
          If unsure, say N.
 
@@ -583,7 +583,7 @@ config NET_HW_FLOWCONTROL
          during periods of extreme congestion. At the moment only a couple
          of device drivers support it (really only one -- tulip, a modified
          8390 driver can be found at
-         <ftp://ftp.inr.ac.ru/ip-routing/fastroute/fastroute-8390.tar.gz>).
+         <ftp://ftp.tux.org/pub/net/ip-routing/fastroute/fastroute-8390.tar.gz>).
 
          Really, this option is applicable to any machine attached to a fast
          enough network, and even a 10 Mb NIC is able to kill a not very slow
@@ -614,7 +614,7 @@ config NET_SCHED
          This code is considered to be experimental.
 
          To administer these schedulers, you'll need the user-level utilities
-         from the package iproute2+tc at <ftp://ftp.inr.ac.ru/ip-routing/>.
+         from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>.
          That package also contains some documentation; for more, check out
          <http://snafu.freedom.org/linux2.2/iproute-notes.html>.
 
index 189676e..4db4f79 100644 (file)
@@ -1051,7 +1051,7 @@ static int atalk_create(struct socket *sock, int protocol)
        sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, 1, NULL);
        if (!sk)
                goto out;
-       at = at_sk(sk) = kmalloc(sizeof(*at), GFP_KERNEL);
+       at = sk->sk_protinfo = kmalloc(sizeof(*at), GFP_KERNEL);
        if (!at)
                goto outsk;
        memset(at, 0, sizeof(*at));
index 4bbc6fc..e6971cd 100644 (file)
@@ -563,32 +563,20 @@ static int clip_setentry(struct atm_vcc *vcc,u32 ip)
 }
 
 
-static int clip_init(struct net_device *dev)
+static void clip_setup(struct net_device *dev)
 {
-       DPRINTK("clip_init %s\n",dev->name);
        dev->hard_start_xmit = clip_start_xmit;
        /* sg_xmit ... */
-       dev->hard_header = NULL;
-       dev->rebuild_header = NULL;
-       dev->set_mac_address = NULL;
-       dev->hard_header_parse = NULL;
-       dev->hard_header_cache = NULL;
-       dev->header_cache_update = NULL;
-       dev->change_mtu = NULL;
-       dev->do_ioctl = NULL;
        dev->get_stats = clip_get_stats;
        dev->type = ARPHRD_ATM;
        dev->hard_header_len = RFC1483LLC_LEN;
        dev->mtu = RFC1626_MTU;
-       dev->addr_len = 0;
        dev->tx_queue_len = 100; /* "normal" queue (packets) */
            /* When using a "real" qdisc, the qdisc determines the queue */
            /* length. tx_queue_len is only used for the default case, */
            /* without any more elaborate queuing. 100 is a reasonable */
            /* compromise between decent burst-tolerance and protection */
            /* against memory hogs. */
-       dev->flags = 0;
-       return 0;
 }
 
 
@@ -608,18 +596,16 @@ static int clip_create(int number)
                        if (PRIV(dev)->number >= number)
                                number = PRIV(dev)->number+1;
        }
-       dev = kmalloc(sizeof(struct net_device)+sizeof(struct clip_priv),
-           GFP_KERNEL); 
-       if (!dev) return -ENOMEM;
-       memset(dev,0,sizeof(struct net_device)+sizeof(struct clip_priv));
+       dev = alloc_netdev(sizeof(struct clip_priv), "", clip_setup);
+       if (!dev)
+               return -ENOMEM;
        clip_priv = PRIV(dev);
        sprintf(dev->name,"atm%d",number);
-       dev->init = clip_init;
        spin_lock_init(&clip_priv->xoff_lock);
        clip_priv->number = number;
        error = register_netdev(dev);
        if (error) {
-               kfree(dev);
+               free_netdev(dev);
                return error;
        }
        clip_priv->next = clip_devs;
@@ -634,7 +620,7 @@ static int clip_device_event(struct notifier_block *this,unsigned long event,
 {
        /* ignore non-CLIP devices */
        if (((struct net_device *) dev)->type != ARPHRD_ATM ||
-           ((struct net_device *) dev)->init != clip_init)
+           ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit)
                return NOTIFY_DONE;
        switch (event) {
                case NETDEV_UP:
@@ -1021,6 +1007,9 @@ static int __init atm_clip_init(void)
        clip_tbl.kmem_cachep = kmem_cache_create(clip_tbl.id,
            clip_tbl.entry_size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
 
+       if (!clip_tbl.kmem_cachep)
+               return -ENOMEM;
+
        /* so neigh_ifdown() doesn't complain */
        clip_tbl.proxy_timer.data = 0;
        clip_tbl.proxy_timer.function = 0;
index 75d2c4a..671c355 100644 (file)
@@ -816,7 +816,7 @@ int ax25_create(struct socket *sock, int protocol)
        if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, 1, NULL)) == NULL)
                return -ENOMEM;
 
-       ax25 = ax25_sk(sk) = ax25_create_cb();
+       ax25 = sk->sk_protinfo = ax25_create_cb();
        if (!ax25) {
                sk_free(sk);
                return -ENOMEM;
@@ -901,7 +901,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
                memcpy(ax25->digipeat, oax25->digipeat, sizeof(ax25_digi));
        }
 
-       ax25_sk(sk) = ax25;
+       sk->sk_protinfo = ax25;
        ax25->sk    = sk;
 
        return sk;
index 9450f1d..47f6138 100644 (file)
@@ -172,7 +172,7 @@ int br_add_bridge(const char *name)
 
        ret = register_netdev(br->dev);
        if (ret)
-               kfree(br->dev);
+               free_netdev(br->dev);
        return ret;
 }
 
index 99fb6b4..c10acfc 100644 (file)
@@ -161,6 +161,47 @@ static struct timer_list samp_timer = TIMER_INITIALIZER(sample_queue, 0, 0);
 #endif
 
 /*
+ * The @dev_base list is protected by @dev_base_lock and the rtln
+ * semaphore.
+ *
+ * Pure readers hold dev_base_lock for reading.
+ *
+ * Writers must hold the rtnl semaphore while they loop through the
+ * dev_base list, and hold dev_base_lock for writing when they do the
+ * actual updates.  This allows pure readers to access the list even
+ * while a writer is preparing to update it.
+ *
+ * To put it another way, dev_base_lock is held for writing only to
+ * protect against pure readers; the rtnl semaphore provides the
+ * protection against other writers.
+ *
+ * See, for example usages, register_netdevice() and
+ * unregister_netdevice(), which must be called with the rtnl
+ * semaphore held.
+ */
+struct net_device *dev_base;
+struct net_device **dev_tail = &dev_base;
+rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
+
+EXPORT_SYMBOL(dev_base);
+EXPORT_SYMBOL(dev_base_lock);
+
+#define NETDEV_HASHBITS        8
+static struct hlist_head dev_name_head[1<<NETDEV_HASHBITS];
+static struct hlist_head dev_index_head[1<<NETDEV_HASHBITS];
+
+static inline struct hlist_head *dev_name_hash(const char *name)
+{
+       unsigned hash = full_name_hash(name, strnlen(name, IFNAMSIZ));
+       return &dev_name_head[hash & ((1<<NETDEV_HASHBITS)-1)];
+}
+
+static inline struct hlist_head *dev_index_hash(int ifindex)
+{
+       return &dev_index_head[ifindex & ((1<<NETDEV_HASHBITS)-1)];
+}
+
+/*
  *     Our notifier list
  */
 
@@ -371,6 +412,30 @@ int netdev_boot_setup_check(struct net_device *dev)
        return 0;
 }
 
+
+/**
+ *     netdev_boot_base        - get address from boot time settings
+ *     @prefix: prefix for network device
+ *     @unit: id for network device
+ *
+ *     Check boot time settings for the base address of device.
+ *     The found settings are set for the device to be used
+ *     later in the device probing.
+ *     Returns 0 if no settings found.
+ */
+unsigned long netdev_boot_base(const char *prefix, int unit)
+{
+       const struct netdev_boot_setup *s = dev_boot_setup;
+       char name[IFNAMSIZ];
+       int i;
+
+       sprintf(name, "%s%d", prefix, unit);
+       for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
+               if (!strcmp(name, s[i].name))
+                       return s[i].map.base_addr;
+       return 0;
+}
+
 /*
  * Saves at boot time configured settings for any netdevice.
  */
@@ -419,12 +484,15 @@ __setup("netdev=", netdev_boot_setup);
 
 struct net_device *__dev_get_by_name(const char *name)
 {
-       struct net_device *dev;
+       struct hlist_node *p;
 
-       for (dev = dev_base; dev; dev = dev->next)
+       hlist_for_each(p, dev_name_hash(name)) {
+               struct net_device *dev
+                       = hlist_entry(p, struct net_device, name_hlist);
                if (!strncmp(dev->name, name, IFNAMSIZ))
-                       break;
-       return dev;
+                       return dev;
+       }
+       return NULL;
 }
 
 /**
@@ -492,12 +560,15 @@ int __dev_get(const char *name)
 
 struct net_device *__dev_get_by_index(int ifindex)
 {
-       struct net_device *dev;
+       struct hlist_node *p;
 
-       for (dev = dev_base; dev; dev = dev->next)
+       hlist_for_each(p, dev_index_hash(ifindex)) {
+               struct net_device *dev
+                       = hlist_entry(p, struct net_device, index_hlist);
                if (dev->ifindex == ifindex)
-                       break;
-       return dev;
+                       return dev;
+       }
+       return NULL;
 }
 
 
@@ -649,30 +720,55 @@ int dev_valid_name(const char *name)
 
 int dev_alloc_name(struct net_device *dev, const char *name)
 {
-       int i;
-       char buf[32];
-       char *p;
+       int i = 0;
+       char buf[IFNAMSIZ];
+       const char *p;
+       const int max_netdevices = 8*PAGE_SIZE;
+       long *inuse;
+       struct net_device *d;
 
-       /*
-        * Verify the string as this thing may have come from
-        * the user.  There must be either one "%d" and no other "%"
-        * characters, or no "%" characters at all.
-        */
-       p = strchr(name, '%');
-       if (p && (p[1] != 'd' || strchr(p + 2, '%')))
-               return -EINVAL;
+       p = strnchr(name, IFNAMSIZ-1, '%');
+       if (p) {
+               /*
+                * Verify the string as this thing may have come from
+                * the user.  There must be either one "%d" and no other "%"
+                * characters.
+                */
+               if (p[1] != 'd' || strchr(p + 2, '%'))
+                       return -EINVAL;
 
-       /*
-        * If you need over 100 please also fix the algorithm...
-        */
-       for (i = 0; i < 100; i++) {
-               snprintf(buf, sizeof(buf), name, i);
-               if (!__dev_get_by_name(buf)) {
-                       strcpy(dev->name, buf);
-                       return i;
+               /* Use one page as a bit array of possible slots */
+               inuse = (long *) get_zeroed_page(GFP_ATOMIC);
+               if (!inuse)
+                       return -ENOMEM;
+
+               for (d = dev_base; d; d = d->next) {
+                       if (!sscanf(d->name, name, &i))
+                               continue;
+                       if (i < 0 || i >= max_netdevices)
+                               continue;
+
+                       /*  avoid cases where sscanf is not exact inverse of printf */
+                       snprintf(buf, sizeof(buf), name, i);
+                       if (!strncmp(buf, d->name, IFNAMSIZ))
+                               set_bit(i, inuse);
                }
+
+               i = find_first_zero_bit(inuse, max_netdevices);
+               free_page((unsigned long) inuse);
        }
-       return -ENFILE; /* Over 100 of the things .. bail out! */
+
+       snprintf(buf, sizeof(buf), name, i);
+       if (!__dev_get_by_name(buf)) {
+               strlcpy(dev->name, buf, IFNAMSIZ);
+               return i;
+       }
+
+       /* It is possible to run out of possible slots
+        * when the name is long and there isn't enough space left
+        * for the digits, or if all bits are used.
+        */
+       return -ENFILE;
 }
 
 
@@ -705,6 +801,9 @@ int dev_change_name(struct net_device *dev, char *newname)
        else
                strlcpy(dev->name, newname, IFNAMSIZ);
 
+       hlist_del(&dev->name_hlist);
+       hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
+
        class_device_rename(&dev->class_dev, dev->name);
        notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
        return 0;
@@ -1940,9 +2039,9 @@ void dev_seq_stop(struct seq_file *seq, void *v)
 
 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
 {
-       struct net_device_stats *stats = dev->get_stats ? dev->get_stats(dev) :
-                                                         NULL;
-       if (stats)
+       if (dev->get_stats) {
+               struct net_device_stats *stats = dev->get_stats(dev);
+
                seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
                                "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
                           dev->name, stats->rx_bytes, stats->rx_packets,
@@ -1960,7 +2059,7 @@ static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
                             stats->tx_window_errors +
                             stats->tx_heartbeat_errors,
                           stats->tx_compressed);
-       else
+       } else
                seq_printf(seq, "%6s: No statistics available.\n", dev->name);
 }
 
@@ -2693,7 +2792,8 @@ static inline void net_set_todo(struct net_device *dev)
 
 int register_netdevice(struct net_device *dev)
 {
-       struct net_device *d, **dp;
+       struct hlist_head *head;
+       struct hlist_node *p;
        int ret;
 
        BUG_ON(dev_boot_phase);
@@ -2734,13 +2834,17 @@ int register_netdevice(struct net_device *dev)
        if (dev->iflink == -1)
                dev->iflink = dev->ifindex;
 
-       /* Check for existence, and append to tail of chain */
-       ret = -EEXIST;
-       for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) {
-               if (d == dev || !strcmp(d->name, dev->name))
-                       goto out_err;
-       }
-       
+       /* Check for existence of name */
+       head = dev_name_hash(dev->name);
+       hlist_for_each(p, head) {
+               struct net_device *d
+                       = hlist_entry(p, struct net_device, name_hlist);
+               if (!strncmp(d->name, dev->name, IFNAMSIZ)) {
+                       ret = -EEXIST;
+                       goto out_err;
+               }
+       }
+
        /* Fix illegal SG+CSUM combinations. */
        if ((dev->features & NETIF_F_SG) &&
            !(dev->features & (NETIF_F_IP_CSUM |
@@ -2769,7 +2873,10 @@ int register_netdevice(struct net_device *dev)
        dev->next = NULL;
        dev_init_scheduler(dev);
        write_lock_bh(&dev_base_lock);
-       *dp = dev;
+       *dev_tail = dev;
+       dev_tail = &dev->next;
+       hlist_add_head(&dev->name_hlist, head);
+       hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
        dev_hold(dev);
        dev->reg_state = NETREG_REGISTERING;
        write_unlock_bh(&dev_base_lock);
@@ -2936,7 +3043,7 @@ void free_netdev(struct net_device *dev)
 {
        /*  Compatiablity with error handling in drivers */
        if (dev->reg_state == NETREG_UNINITIALIZED) {
-               kfree(dev);
+               kfree((char *)dev - dev->padded);
                return;
        }
 
@@ -2991,6 +3098,10 @@ int unregister_netdevice(struct net_device *dev)
        for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) {
                if (d == dev) {
                        write_lock_bh(&dev_base_lock);
+                       hlist_del(&dev->name_hlist);
+                       hlist_del(&dev->index_hlist);
+                       if (dev_tail == &dev->next)
+                               dev_tail = dp;
                        *dp = d->next;
                        write_unlock_bh(&dev_base_lock);
                        break;
@@ -3067,6 +3178,12 @@ static int __init net_dev_init(void)
        for (i = 0; i < 16; i++) 
                INIT_LIST_HEAD(&ptype_base[i]);
 
+       for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)
+               INIT_HLIST_HEAD(&dev_name_head[i]);
+
+       for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)
+               INIT_HLIST_HEAD(&dev_index_head[i]);
+
        /*
         *      Initialise the packet receive queues.
         */
index 4d5e12b..e711fdc 100644 (file)
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 
-#ifdef CONFIG_IPV6_NDISC_DEBUG
-#define NEIGH_DEBUG 3
-#else
 #define NEIGH_DEBUG 1
-#endif
 
 #define NEIGH_PRINTK(x...) printk(x)
 #define NEIGH_NOPRINTK(x...) do { ; } while(0)
 #define NEIGH_PRINTK0 NEIGH_PRINTK
 #define NEIGH_PRINTK1 NEIGH_NOPRINTK
 #define NEIGH_PRINTK2 NEIGH_NOPRINTK
-#define NEIGH_PRINTK3 NEIGH_NOPRINTK
 
 #if NEIGH_DEBUG >= 1
 #undef NEIGH_PRINTK1
 #undef NEIGH_PRINTK2
 #define NEIGH_PRINTK2 NEIGH_PRINTK
 #endif
-#if NEIGH_DEBUG >= 3
-#undef NEIGH_PRINTK3
-#define NEIGH_PRINTK3 NEIGH_PRINTK
-#endif
 
 static void neigh_timer_handler(unsigned long arg);
+#ifdef CONFIG_ARPD
+static void neigh_app_notify(struct neighbour *n);
+#endif
 static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
 void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 
@@ -395,11 +389,10 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
        if (!creat)
                goto out;
 
-       n = kmalloc(sizeof(*n) + key_len, pneigh_alloc_flag());
+       n = kmalloc(sizeof(*n) + key_len, GFP_KERNEL);
        if (!n)
                goto out;
 
-       pneigh_refcnt_init(n);
        memcpy(n->key, pkey, key_len);
        n->dev = dev;
 
@@ -433,9 +426,6 @@ int pneigh_delete(struct neigh_table *tbl, const void *pkey,
        for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;
             np = &n->next) {
                if (!memcmp(n->key, pkey, key_len) && n->dev == dev) {
-                       if (!pneigh_refcnt_dec_and_test(n)) {
-                               return 0;
-                       }
                        write_lock_bh(&tbl->lock);
                        *np = n->next;
                        write_unlock_bh(&tbl->lock);
@@ -546,7 +536,6 @@ static void neigh_connect(struct neighbour *neigh)
                hh->hh_output = neigh->ops->hh_output;
 }
 
-#ifndef CONFIG_IPV6_NDISC_NEW
 /*
    Transitions NUD_STALE <-> NUD_REACHABLE do not occur
    when fast path is built: we have no timers associated with
@@ -580,7 +569,6 @@ static void neigh_sync(struct neighbour *n)
                }
        }
 }
-#endif
 
 static void neigh_periodic_timer(unsigned long arg)
 {
@@ -631,13 +619,11 @@ static void neigh_periodic_timer(unsigned long arg)
                                continue;
                        }
 
-#ifndef CONFIG_IPV6_NDISC_NEW
                        if (n->nud_state & NUD_REACHABLE &&
                            now - n->confirmed > n->parms->reachable_time) {
                                n->nud_state = NUD_STALE;
                                neigh_suspect(n);
                        }
-#endif
                        write_unlock(&n->lock);
 
 next_elt:
@@ -662,94 +648,40 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
 
 static void neigh_timer_handler(unsigned long arg)
 {
-       unsigned long now, next;
+       unsigned long now = jiffies;
        struct neighbour *neigh = (struct neighbour *)arg;
        unsigned state;
+       int notify = 0;
 
-       int refcnt;
+       write_lock(&neigh->lock);
 
-       write_lock_bh(&neigh->lock);
-       now = jiffies;
-       next = now + HZ;
-       
        state = neigh->nud_state;
 
        if (!(state & NUD_IN_TIMER)) {
 #ifndef CONFIG_SMP
                printk(KERN_WARNING "neigh: timer & !nud_in_timer\n");
 #endif
-               write_unlock_bh(&neigh->lock);
-               refcnt = atomic_read(&neigh->refcnt) - 1;
-               neigh_release(neigh);
-               NEIGH_PRINTK3(KERN_DEBUG 
-                               "%s(): => state=%s, refcnt=%d\n",
-                               __FUNCTION__, neigh_state(state), refcnt);
-               return;
+               goto out;
        }
 
-#ifdef CONFIG_IPV6_NDISC_NEW
-       if (state & NUD_REACHABLE) {
-               if (now - neigh->confirmed < neigh->parms->reachable_time) {
-                       next = neigh->confirmed + neigh->parms->reachable_time;
-               } else if (now - neigh->used <= neigh->parms->delay_probe_time) {
-                       neigh->nud_state = NUD_DELAY;
-                       neigh_suspect(neigh);
-                       next = now + neigh->parms->delay_probe_time;
-               } else {
-                       neigh->nud_state = NUD_STALE;
-                       neigh_suspect(neigh);
-               }
-       } else if (state & NUD_DELAY) {
-               if (now - neigh->confirmed <= neigh->parms->delay_probe_time) {
-                       neigh->nud_state = NUD_REACHABLE;
-                       neigh_connect(neigh);
-                       next = neigh->confirmed + neigh->parms->reachable_time;
-               } else {
-                       neigh->nud_state = NUD_PROBE;
-                       atomic_set(&neigh->probes, 0);
-                       next = now + neigh->parms->retrans_time;
-               }
-       } else {
-               /* PROBE,INCOMPLETE */
-               next = now + neigh->parms->retrans_time;
-       }
-#else
        if ((state & NUD_VALID) &&
            now - neigh->confirmed < neigh->parms->reachable_time) {
-               state = neigh->nud_state = NUD_REACHABLE;
+               neigh->nud_state = NUD_REACHABLE;
                NEIGH_PRINTK2("neigh %p is still alive.\n", neigh);
                neigh_connect(neigh);
-               refcnt = atomic_read(&neigh->refcnt) - 1;
-               write_unlock_bh(&neigh->lock);
-               neigh_release(neigh);
-               NEIGH_PRINTK3(KERN_DEBUG 
-                               "%s(): => state=%s, refcnt=%d\n",
-                               __FUNCTION__, 
-                               neigh_state(state), refcnt);
-               return;
+               goto out;
        }
        if (state == NUD_DELAY) {
                NEIGH_PRINTK2("neigh %p is probed.\n", neigh);
                neigh->nud_state = NUD_PROBE;
                atomic_set(&neigh->probes, 0);
        }
-#endif
 
-       if (
-#ifdef CONFIG_IPV6_NDISC_NEW
-           (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
-#endif
-           atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
+       if (atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
                struct sk_buff *skb;
 
-#ifdef CONFIG_IPV6_NDISC_NEW
-               neigh->updated = now;
-#endif
-               state = neigh->nud_state = NUD_FAILED;
-
-#ifdef CONFIG_IPV6_NDISC_NEW
-               del_timer(&neigh->timer);       /* release neigh later */
-#endif
+               neigh->nud_state = NUD_FAILED;
+               notify = 1;
                neigh->tbl->stats.res_failed++;
                NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
 
@@ -760,113 +692,62 @@ static void neigh_timer_handler(unsigned long arg)
                 */
                while (neigh->nud_state == NUD_FAILED &&
                       (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
-                       write_unlock_bh(&neigh->lock);
+                       write_unlock(&neigh->lock);
                        neigh->ops->error_report(neigh, skb);
-                       write_lock_bh(&neigh->lock);
+                       write_lock(&neigh->lock);
                }
                skb_queue_purge(&neigh->arp_queue);
-#ifdef CONFIG_ARPD
-               if (neigh->parms->app_probes) {
-                       write_unlock_bh(&neigh->lock);
-                       neigh_app_notify(neigh);
-               } else
-#endif
-               refcnt = atomic_read(&neigh->refcnt) - 1;
-               write_unlock_bh(&neigh->lock);
-
-               neigh_release(neigh);
-
-               NEIGH_PRINTK3(KERN_DEBUG 
-                               "%s(): => state=%s, refcnt=%d\n",
-                               __FUNCTION__, 
-                               neigh_state(state), refcnt);
-
-               return;
+               goto out;
        }
 
-#ifdef CONFIG_IPV6_NDISC_NEW
-       if (neigh->nud_state & NUD_IN_TIMER) {
-               neigh_hold(neigh);
-               if (time_before(next, jiffies + HZ/2))
-                       next = jiffies + HZ/2;
-               mod_timer(&neigh->timer, next);
-               if (neigh->nud_state&(NUD_INCOMPLETE|NUD_PROBE)) {
-                       write_unlock_bh(&neigh->lock);
-                       neigh->ops->solicit(neigh, skb_peek(&neigh->arp_queue));
-                       atomic_inc(&neigh->probes);
-               } else {
-                       write_unlock_bh(&neigh->lock);
-               }
-       } else {
-               del_timer(&neigh->timer);
-               write_unlock_bh(&neigh->lock);
-       }
-       refcnt = atomic_read(&neigh->refcnt) - 1;
-       state = neigh->nud_state;
-       neigh_release(neigh);
-#else
        neigh->timer.expires = now + neigh->parms->retrans_time;
        add_timer(&neigh->timer);
-
-       refcnt = atomic_read(&neigh->refcnt);
-       state = neigh->nud_state;
-       write_unlock_bh(&neigh->lock);
+       write_unlock(&neigh->lock);
 
        neigh->ops->solicit(neigh, skb_peek(&neigh->arp_queue));
        atomic_inc(&neigh->probes);
-#endif
-       NEIGH_PRINTK3(KERN_DEBUG 
-                       "%s(): => state=%s, refcnt=%d\n",
-                       __FUNCTION__, 
-                       neigh_state(state), refcnt);
-
        return;
+
+out:
+       write_unlock(&neigh->lock);
+#ifdef CONFIG_ARPD
+       if (notify && neigh->parms->app_probes)
+               neigh_app_notify(neigh);
+#endif
+       neigh_release(neigh);
 }
 
 int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
-       int rc = 0;
-       unsigned long now = jiffies;
-       
-       NEIGH_PRINTK3(KERN_DEBUG 
-                       "%s(neigh=%p, skb=%p): %s\n",
-                       __FUNCTION__, 
-                       neigh, skb, neigh_state(neigh->nud_state));
+       int rc;
+
+       write_lock_bh(&neigh->lock);
 
+       rc = 0;
        if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))
-               goto out;
+               goto out_unlock_bh;
 
        if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {
                if (neigh->parms->mcast_probes + neigh->parms->app_probes) {
                        atomic_set(&neigh->probes, neigh->parms->ucast_probes);
                        neigh->nud_state     = NUD_INCOMPLETE;
                        neigh_hold(neigh);
-#ifdef CONFIG_IPV6_NDISC_NEW
-                       neigh->timer.expires = now;
-#else
-                       neigh->timer.expires = now +
+                       neigh->timer.expires = jiffies +
                                               neigh->parms->retrans_time;
-#endif
                        add_timer(&neigh->timer);
-#ifndef CONFIG_IPV6_NDISC_NEW
                        write_unlock_bh(&neigh->lock);
                        neigh->ops->solicit(neigh, skb);
                        atomic_inc(&neigh->probes);
                        write_lock_bh(&neigh->lock);
-#endif
                } else {
                        neigh->nud_state = NUD_FAILED;
-                       return -1;
+                       write_unlock_bh(&neigh->lock);
+
+                       if (skb)
+                               kfree_skb(skb);
+                       return 1;
                }
        }
-#ifdef CONFIG_IPV6_NDISC_NEW
-       else if (neigh->nud_state == NUD_STALE) {
-               neigh_hold(neigh);
-               neigh->nud_state = NUD_DELAY;
-               neigh->timer.expires = now + neigh->parms->delay_probe_time;
-               add_timer(&neigh->timer);
-       }
-#endif
 
        if (neigh->nud_state == NUD_INCOMPLETE) {
                if (skb) {
@@ -880,18 +761,16 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                        __skb_queue_tail(&neigh->arp_queue, skb);
                }
                rc = 1;
-       }
-#ifndef CONFIG_IPV6_NDISC_NEW
-       else if (neigh->nud_state == NUD_STALE) {
+       } else if (neigh->nud_state == NUD_STALE) {
                NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
                neigh_hold(neigh);
                neigh->nud_state = NUD_DELAY;
-               neigh->timer.expires = now + neigh->parms->delay_probe_time;
+               neigh->timer.expires = jiffies + neigh->parms->delay_probe_time;
                add_timer(&neigh->timer);
                rc = 0;
        }
-#endif
-out:
+out_unlock_bh:
+       write_unlock_bh(&neigh->lock);
        return rc;
 }
 
@@ -915,57 +794,32 @@ static __inline__ void neigh_update_hhs(struct neighbour *neigh)
 /* Generic update routine.
    -- lladdr is new lladdr or NULL, if it is not supplied.
    -- new    is new state.
-   -- flags  specifies details of update
+   -- override == 1 allows to override existing lladdr, if it is different.
+   -- arp == 0 means that the change is administrative.
 
    Caller MUST hold reference count on the entry.
-   __neigh_update() is called under write_lock_bh().
-
  */
 
-int __neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags)
+int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
+                int override, int arp)
 {
        u8 old;
        int err;
+#ifdef CONFIG_ARPD
        int notify = 0;
+#endif
        struct net_device *dev;
-#ifdef CONFIG_IPV6_NDISC_NEW
-       unsigned long now = jiffies;
-       int hold = 0;
-       int update_isrouter = 0;
-
-       NEIGH_PRINTK3(KERN_DEBUG
-                       "%s(neigh=%p, lladdr=%p, new=%u, flags=%08x): %s\n",
-                       __FUNCTION__,
-                       neigh, lladdr, new, flags, neigh_state(neigh->nud_state));
-       
-       if (!neigh) {
-               NEIGH_PRINTK1(KERN_WARNING "__neigh_update(): neigh==NULL\n");
-               return -EINVAL;
-       }
 
-       old = neigh->nud_state;
-#endif /* CONFIG_IPV6_NDISC_NEW */
+       write_lock_bh(&neigh->lock);
 
-#ifndef CONFIG_IPV6_NDISC_NEW
        dev    = neigh->dev;
        old    = neigh->nud_state;
        err    = -EPERM;
-#else /* CONFIG_IPV6_NDISC_NEW */
-       dev = neigh->dev;
-       if (!dev) {
-               NEIGH_PRINTK1(KERN_WARNING "__neigh_update(): neigh->dev==NULL\n");
-               return -EINVAL;
-       }
-#endif /* CONFIG_IPV6_NDISC_NEW */
 
-       err = -EPERM;
-       if (!(flags & NEIGH_UPDATE_F_ADMIN) && (old & (NUD_NOARP | NUD_PERMANENT)))
+       if (arp && (old & (NUD_NOARP | NUD_PERMANENT)))
                goto out;
 
        if (!(new & NUD_VALID)) {
-#ifdef CONFIG_IPV6_NDISC_NEW
-               /* NONE,INCOMPLETE,FAILED */
-#endif /* CONFIG_IPV6_NDISC_NEW */
                neigh_del_timer(neigh);
                if (old & NUD_CONNECTED)
                        neigh_suspect(neigh);
@@ -990,10 +844,8 @@ int __neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags)
                if (old & NUD_VALID) {
                        if (!memcmp(lladdr, neigh->ha, dev->addr_len))
                                lladdr = neigh->ha;
-#ifndef CONFIG_IPV6_NDISC_NEW
-                       else if (!(flags & NEIGH_UPDATE_F_OVERRIDE))
+                       else if (!override)
                                goto out;
-#endif /* not CONFIG_IPV6_NDISC_NEW */
                }
        } else {
                /* No address is supplied; if we know something,
@@ -1005,93 +857,28 @@ int __neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags)
                lladdr = neigh->ha;
        }
 
-#ifndef CONFIG_IPV6_NDISC_NEW
        neigh_sync(neigh);
        old = neigh->nud_state;
        if (new & NUD_CONNECTED)
                neigh->confirmed = jiffies;
        neigh->updated = jiffies;
 
-#endif /* not CONFIG_IPV6_NDISC_NEW */
        /* If entry was valid and address is not changed,
           do not change entry state, if new one is STALE.
         */
        err = 0;
-#ifndef CONFIG_IPV6_NDISC_NEW
        if ((old & NUD_VALID) && lladdr == neigh->ha &&
            (new == old || (new == NUD_STALE && (old & NUD_CONNECTED))))
                goto out;
-#else /* CONFIG_IPV6_NDISC_NEW */
-       if (old & NUD_VALID) {
-               if (lladdr != neigh->ha &&
-                   !(flags & NEIGH_UPDATE_F_OVERRIDE)) {
-                       if ((flags & NEIGH_UPDATE_F_SUSPECT_CONNECTED) &&
-                           (old & NUD_CONNECTED)) {
-                               new = NUD_STALE;
-                               lladdr = neigh->ha;
-                       } else {
-                               goto out;
-                       }
-               } else {
-                       if ((flags & NEIGH_UPDATE_F_REUSEADDR) &&
-                           new == old)
-                               lladdr = neigh->ha;
-                       else if (lladdr == neigh->ha && new == NUD_STALE) {
-                               if ((flags & NEIGH_UPDATE_F_REUSESUSPECTSTATE) ||
-                                   (old & NUD_CONNECTED))
-                                       new = old;
-                       }
-                       update_isrouter = flags & NEIGH_UPDATE_F_OVERRIDE_VALID_ISROUTER;
-               }
-       } else {
-               /* INCOMPLETE */
-               update_isrouter = flags&NEIGH_UPDATE_F_SETUP_ISROUTER;
-       }
-#endif /* CONFIG_IPV6_NDISC_NEW */
 
-#ifndef CONFIG_IPV6_NDISC_NEW
        neigh_del_timer(neigh);
        neigh->nud_state = new;
-#else /* CONFIG_IPV6_NDISC_NEW */
-       if (new != old) {
-               if (new & NUD_IN_TIMER) {
-                       unsigned long next = now;
-                       switch(new) {
-                       case NUD_REACHABLE:
-                               next += neigh->parms->reachable_time;
-                               break;
-                       default:;
-                               /*XXX*/
-                       }
-                       if (old & NUD_IN_TIMER) {
-                               mod_timer(&neigh->timer, next);
-                       } else {
-                               neigh_hold(neigh);
-                               neigh->timer.expires = next;
-                               add_timer(&neigh->timer);
-                       }
-               } else {
-                       neigh_del_timer(neigh);
-               }
-               neigh->nud_state = new;
-       }
-       if ((new != old || lladdr != neigh->ha) &&
-           new & NUD_CONNECTED)
-               neigh->confirmed = now;
-#endif /* CONFIG_IPV6_NDISC_NEW */
        if (lladdr != neigh->ha) {
-#ifdef CONFIG_IPV6_NDISC_NEW
-               neigh->updated = now;
-#endif /* CONFIG_IPV6_NDISC_NEW */
                memcpy(&neigh->ha, lladdr, dev->addr_len);
                neigh_update_hhs(neigh);
                if (!(new & NUD_CONNECTED))
-#ifndef CONFIG_IPV6_NDISC_NEW
                        neigh->confirmed = jiffies -
                                      (neigh->parms->base_reachable_time << 1);
-#else /* CONFIG_IPV6_NDISC_NEW */
-                       neigh->confirmed = now - (neigh->parms->base_reachable_time<<1);
-#endif /* CONFIG_IPV6_NDISC_NEW */
 #ifdef CONFIG_ARPD
                notify = 1;
 #endif
@@ -1106,13 +893,6 @@ int __neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags)
                struct sk_buff *skb;
 
                /* Again: avoid dead loop if something went wrong */
-#ifdef CONFIG_IPV6_NDISC_NEW
-               neigh_hold(neigh);      /* don't release neigh while processing */
-               hold = 1;
-
-               if (new&NUD_VALID)
-                       notify = 1;
-#endif /* CONFIG_IPV6_NDISC_NEW */
 
                while (neigh->nud_state & NUD_VALID &&
                       (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
@@ -1127,68 +907,20 @@ int __neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags)
                skb_queue_purge(&neigh->arp_queue);
        }
 out:
-#ifdef CONFIG_IPV6_NDISC_NEW
-       if (update_isrouter) {
-               neigh->flags = (flags & NEIGH_UPDATE_F_ISROUTER) ?
-                               (neigh->flags | NTF_ROUTER) :
-                               (neigh->flags & ~NTF_ROUTER);
-       }
-
-       if (hold)
-               neigh_release(neigh);
-#endif /* CONFIG_IPV6_NDISC_NEW */
-
-       NEIGH_PRINTK3(KERN_DEBUG
-                       "%s() => %s\n",
-                       __FUNCTION__,
-                       neigh_state(neigh->nud_state));
-
-       return err ? err : notify;
-}
-
-int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
-                int override, int arp)
-{
-       int update;
-
-       NEIGH_PRINTK3(KERN_DEBUG
-                       "%s(neigh=%p, lladdr=%p, new=%u, override=%d, arp=%d): %s\n",
-                       __FUNCTION__, 
-                       neigh, lladdr, new, override, arp,
-                       neigh_state(neigh->nud_state));
-
-       neigh_hold(neigh);
-       write_lock_bh(&neigh->lock);
-       update = __neigh_update(neigh, lladdr, new, 
-#ifdef CONFIG_IPV6_NDISC_NEW
-                               NEIGH_UPDATE_F_REUSEADDR |
-#endif /* CONFIG_IPV6_NDISC_NEW */
-                               (override ? NEIGH_UPDATE_F_OVERRIDE : 0) |
-                               (arp ? 0 : NEIGH_UPDATE_F_ADMIN));
+       write_unlock_bh(&neigh->lock);
 #ifdef CONFIG_ARPD
-       if (update > 0 && neigh->parms->app_probes) {
-               write_unlock_bh(&neigh->lock);
+       if (notify && neigh->parms->app_probes)
                neigh_app_notify(neigh);
-       } else
 #endif
-       write_unlock_bh(&neigh->lock);
-       neigh_release(neigh);   /*XXX: may invalidate neigh... */
-       return update >= 0 ? 0 : update;
+       return err;
 }
 
 struct neighbour *neigh_event_ns(struct neigh_table *tbl,
                                 u8 *lladdr, void *saddr,
                                 struct net_device *dev)
 {
-       struct neighbour *neigh;
-
-       NEIGH_PRINTK3(KERN_DEBUG
-                       "%s(tbl=%p, lladdr=%p, saddr=%p, dev=%p)\n",
-                       __FUNCTION__, 
-                       tbl, lladdr, saddr, dev);
-
-       neigh = __neigh_lookup(tbl, saddr, dev,
-                              lladdr || !dev->addr_len);
+       struct neighbour *neigh = __neigh_lookup(tbl, saddr, dev,
+                                                lladdr || !dev->addr_len);
        if (neigh)
                neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
        return neigh;
@@ -1722,7 +1454,7 @@ void neigh_app_ns(struct neighbour *n)
        netlink_broadcast(rtnl, skb, 0, RTMGRP_NEIGH, GFP_ATOMIC);
 }
 
-void neigh_app_notify(struct neighbour *n)
+static void neigh_app_notify(struct neighbour *n)
 {
        struct nlmsghdr *nlh;
        int size = NLMSG_SPACE(sizeof(struct ndmsg) + 256);
@@ -2004,7 +1736,6 @@ EXPORT_SYMBOL(neigh_rand_reach_time);
 EXPORT_SYMBOL(neigh_resolve_output);
 EXPORT_SYMBOL(neigh_table_clear);
 EXPORT_SYMBOL(neigh_table_init);
-EXPORT_SYMBOL(__neigh_update);
 EXPORT_SYMBOL(neigh_update);
 EXPORT_SYMBOL(neigh_update_hhs);
 EXPORT_SYMBOL(pneigh_enqueue);
@@ -2012,7 +1743,6 @@ EXPORT_SYMBOL(pneigh_lookup);
 
 #ifdef CONFIG_ARPD
 EXPORT_SYMBOL(neigh_app_ns);
-EXPORT_SYMBOL(neigh_app_notify);
 #endif
 #ifdef CONFIG_SYSCTL
 EXPORT_SYMBOL(neigh_sysctl_register);
index 5281a1e..5720ca0 100644 (file)
@@ -372,7 +372,7 @@ static void netdev_release(struct class_device *cd)
 
        BUG_ON(dev->reg_state != NETREG_RELEASED);
 
-       kfree(dev);
+       kfree((char *)dev - dev->padded);
 }
 
 static struct class net_class = {
index 995f2b5..8058d9c 100644 (file)
@@ -41,37 +41,11 @@ int net_msg_cost = 5*HZ;
 int net_msg_burst = 10;
 
 /* 
- * This enforces a rate limit: not more than one kernel message
- * every 5secs to make a denial-of-service attack impossible.
- *
- * All warning printk()s should be guarded by this function. 
+ * All net warning printk()s should be guarded by this function.
  */ 
 int net_ratelimit(void)
 {
-       static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
-       static unsigned long toks = 10*5*HZ;
-       static unsigned long last_msg; 
-       static int missed;
-       unsigned long flags;
-       unsigned long now = jiffies;
-
-       spin_lock_irqsave(&ratelimit_lock, flags);
-       toks += now - last_msg;
-       last_msg = now;
-       if (toks > net_msg_burst)
-               toks = net_msg_burst;
-       if (toks >= net_msg_cost) {
-               int lost = missed;
-               missed = 0;
-               toks -= net_msg_cost;
-               spin_unlock_irqrestore(&ratelimit_lock, flags);
-               if (lost)
-                       printk(KERN_WARNING "NET: %d messages suppressed.\n", lost);
-               return 1;
-       }
-       missed++;
-       spin_unlock_irqrestore(&ratelimit_lock, flags);
-       return 0;
+       return __printk_ratelimit(net_msg_cost, net_msg_burst);
 }
 
 EXPORT_SYMBOL(net_random);
index 74f1f2d..74d6aac 100644 (file)
@@ -22,8 +22,9 @@ config DECNET_ROUTER
          network link driver", "Routing messages" and "Network packet
          filtering".  The first two are required to allow configuration via
          rtnetlink (you will need Alexey Kuznetsov's iproute2 package
-         from <ftp://ftp.inr.ac.ru/>). The "Network packet filtering" option
-         will be required for the forthcoming routing daemon to work.
+         from <ftp://ftp.tux.org/pub/net/ip-routing/>). The "Network packet
+         filtering" option will be required for the forthcoming routing daemon
+         to work.
 
          See <file:Documentation/networking/decnet.txt> for more information.
 
index 03c5c49..e0d5284 100644 (file)
@@ -163,7 +163,7 @@ static struct hlist_head *dn_find_list(struct sock *sk)
        struct dn_scp *scp = DN_SK(sk);
 
        if (scp->addr.sdn_flags & SDF_WILD)
-               return hlist_empty(&dn_wild_sk) ? NULL : &dn_wild_sk;
+               return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL;
 
        return &dn_sk_hash[scp->addrloc & DN_SK_HASH_MASK];
 }
@@ -456,7 +456,7 @@ struct sock *dn_alloc_sock(struct socket *sock, int gfp)
        if  (!sk)
                goto out;
 
-       DN_SK(sk) = scp = (struct dn_scp *)(sk + 1);
+       sk->sk_protinfo = scp = (struct dn_scp *)(sk + 1);
 
        if (sock)
                sock->ops = &dn_proto_ops;
index 67bef89..ab64b85 100644 (file)
@@ -327,7 +327,7 @@ static int dn_phase3_output(struct sk_buff *skb)
        }
 
        data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
-       ((unsigned short *)data) = dn_htons(skb->len - 2);
+       *((unsigned short *)data) = dn_htons(skb->len - 2);
        sp = (struct dn_short_packet *)(data + 2);
 
        sp->msgflg   = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
index 53a4e0f..d9628db 100644 (file)
@@ -1720,7 +1720,8 @@ static void *dn_rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
 static void dn_rt_cache_seq_stop(struct seq_file *seq, void *v)
 {
-       rcu_read_unlock();
+       if (v)
+               rcu_read_unlock();
 }
 
 static int dn_rt_cache_seq_show(struct seq_file *seq, void *v)
index 2b15431..fa876ce 100644 (file)
@@ -318,12 +318,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 #ifdef CONFIG_ECONET_NATIVE
                dev_hold(dev);
                
-               skb = sock_alloc_send_skb(sk, len+dev->hard_header_len+15, 
+               skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev), 
                                          msg->msg_flags & MSG_DONTWAIT, &err);
                if (skb==NULL)
                        goto out_unlock;
                
-               skb_reserve(skb, (dev->hard_header_len+15)&~15);
+               skb_reserve(skb, LL_RESERVED_SPACE(dev));
                skb->nh.raw = skb->data;
                
                eb = (struct ec_cb *)&skb->cb;
@@ -568,7 +568,7 @@ static int econet_create(struct socket *sock, int protocol)
        sock_init_data(sock,sk);
        sk_set_owner(sk, THIS_MODULE);
 
-       eo = ec_sk(sk) = kmalloc(sizeof(*eo), GFP_KERNEL);
+       eo = sk->sk_protinfo = kmalloc(sizeof(*eo), GFP_KERNEL);
        if (!eo)
                goto out_free;
        memset(eo, 0, sizeof(*eo));
index 6ee8011..0791bd0 100644 (file)
@@ -71,7 +71,7 @@ config IP_MULTIPLE_TABLES
          documentation at <http://www.compendium.com.ar/policy-routing.txt>
          and <ftp://post.tepkom.ru/pub/vol2/Linux/docs/advanced-routing.tex>.
          You will need supporting software from
-         <ftp://ftp.inr.ac.ru/ip-routing/>.
+         <ftp://ftp.tux.org/pub/net/ip-routing/>.
 
          If unsure, say N.
 
index 5c03f63..0de93f9 100644 (file)
  *                                     now it is in net/core/neighbour.c.
  *             Krzysztof Halasa:       Added Frame Relay ARP support.
  *             Arnaldo C. Melo :       convert /proc/net/arp to seq_file
+ *             Shmulik Hen:            Split arp_send to arp_create and
+ *                                     arp_xmit so intermediate drivers like
+ *                                     bonding can change the skb before
+ *                                     sending (e.g. insert 8021q tag).
  */
 
 #include <linux/module.h>
@@ -487,34 +491,26 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
  */
 
 /*
- *     Create and send an arp packet. If (dest_hw == NULL), we create a broadcast
+ *     Create an arp packet. If (dest_hw == NULL), we create a broadcast
  *     message.
  */
-
-void arp_send(int type, int ptype, u32 dest_ip, 
-             struct net_device *dev, u32 src_ip, 
-             unsigned char *dest_hw, unsigned char *src_hw,
-             unsigned char *target_hw)
+struct sk_buff *arp_create(int type, int ptype, u32 dest_ip,
+                          struct net_device *dev, u32 src_ip,
+                          unsigned char *dest_hw, unsigned char *src_hw,
+                          unsigned char *target_hw)
 {
        struct sk_buff *skb;
        struct arphdr *arp;
        unsigned char *arp_ptr;
 
        /*
-        *      No arp on this interface.
-        */
-       
-       if (dev->flags&IFF_NOARP)
-               return;
-
-       /*
         *      Allocate a buffer
         */
        
        skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4)
                                + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
        if (skb == NULL)
-               return;
+               return NULL;
 
        skb_reserve(skb, LL_RESERVED_SPACE(dev));
        skb->nh.raw = skb->data;
@@ -594,12 +590,46 @@ void arp_send(int type, int ptype, u32 dest_ip,
        arp_ptr+=dev->addr_len;
        memcpy(arp_ptr, &dest_ip, 4);
 
-       /* Send it off, maybe filter it using firewalling first.  */
-       NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, dev, dev_queue_xmit);
-       return;
+       return skb;
 
 out:
        kfree_skb(skb);
+       return NULL;
+}
+
+/*
+ *     Send an arp packet.
+ */
+void arp_xmit(struct sk_buff *skb)
+{
+       /* Send it off, maybe filter it using firewalling first.  */
+       NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit);
+}
+
+/*
+ *     Create and send an arp packet.
+ */
+void arp_send(int type, int ptype, u32 dest_ip, 
+             struct net_device *dev, u32 src_ip, 
+             unsigned char *dest_hw, unsigned char *src_hw,
+             unsigned char *target_hw)
+{
+       struct sk_buff *skb;
+
+       /*
+        *      No arp on this interface.
+        */
+       
+       if (dev->flags&IFF_NOARP)
+               return;
+
+       skb = arp_create(type, ptype, dest_ip, dev, src_ip,
+                        dest_hw, src_hw, target_hw);
+       if (skb == NULL) {
+               return;
+       }
+
+       arp_xmit(skb);
 }
 
 static void parp_redo(struct sk_buff *skb)
@@ -1437,6 +1467,8 @@ static int __init arp_proc_init(void)
 EXPORT_SYMBOL(arp_broken_ops);
 EXPORT_SYMBOL(arp_find);
 EXPORT_SYMBOL(arp_rcv);
+EXPORT_SYMBOL(arp_create);
+EXPORT_SYMBOL(arp_xmit);
 EXPORT_SYMBOL(arp_send);
 EXPORT_SYMBOL(arp_tbl);
 
index 4bdfd73..4f3415a 100644 (file)
@@ -1132,7 +1132,7 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int *name, int nlen,
 
 static struct devinet_sysctl_table {
        struct ctl_table_header *sysctl_header;
-       ctl_table               devinet_vars[17];
+       ctl_table               devinet_vars[18];
        ctl_table               devinet_dev[2];
        ctl_table               devinet_conf_dir[2];
        ctl_table               devinet_proto_dir[2];
@@ -1269,6 +1269,15 @@ static struct devinet_sysctl_table {
                        .proc_handler   = &ipv4_doint_and_flush,
                        .strategy       = &ipv4_doint_and_flush_strategy,
                },
+               {
+                       .ctl_name       = NET_IPV4_CONF_FORCE_IGMP_VERSION,
+                       .procname       = "force_igmp_version",
+                       .data           = &ipv4_devconf.force_igmp_version,
+                       .maxlen         = sizeof(int),
+                       .mode           = 0644,
+                       .proc_handler   = &ipv4_doint_and_flush,
+                       .strategy       = &ipv4_doint_and_flush_strategy,
+               },
        },
        .devinet_dev = {
                {
index b1f9f7d..f8d8fb5 100644 (file)
  * contradict to specs provided this delay is small enough.
  */
 
-#define IGMP_V1_SEEN(in_dev) ((in_dev)->mr_v1_seen && \
-               time_before(jiffies, (in_dev)->mr_v1_seen))
-#define IGMP_V2_SEEN(in_dev) ((in_dev)->mr_v2_seen && \
-               time_before(jiffies, (in_dev)->mr_v2_seen))
+#define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \
+               (in_dev)->cnf.force_igmp_version == 1 || \
+               ((in_dev)->mr_v1_seen && \
+               time_before(jiffies, (in_dev)->mr_v1_seen)))
+#define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \
+               (in_dev)->cnf.force_igmp_version == 2 || \
+               ((in_dev)->mr_v2_seen && \
+               time_before(jiffies, (in_dev)->mr_v2_seen)))
 
 static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
 static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr);
@@ -1063,7 +1067,7 @@ static void igmp_group_dropped(struct ip_mc_list *im)
        reporter = im->reporter;
        igmp_stop_timer(im);
 
-       if (in_dev->dev->flags & IFF_UP) {
+       if (!in_dev->dead) {
                if (IGMP_V1_SEEN(in_dev))
                        goto done;
                if (IGMP_V2_SEEN(in_dev)) {
@@ -1094,6 +1098,8 @@ static void igmp_group_added(struct ip_mc_list *im)
        if (im->multiaddr == IGMP_ALL_HOSTS)
                return;
 
+       if (in_dev->dead)
+               return;
        if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) {
                spin_lock_bh(&im->lock);
                igmp_start_timer(im, IGMP_Initial_Report_Delay);
@@ -1167,7 +1173,7 @@ void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
        igmpv3_del_delrec(in_dev, im->multiaddr);
 #endif
        igmp_group_added(im);
-       if (in_dev->dev->flags & IFF_UP)
+       if (!in_dev->dead)
                ip_rt_multicast_event(in_dev);
 out:
        return;
@@ -1191,7 +1197,7 @@ void ip_mc_dec_group(struct in_device *in_dev, u32 addr)
                                write_unlock_bh(&in_dev->lock);
                                igmp_group_dropped(i);
 
-                               if (in_dev->dev->flags & IFF_UP)
+                               if (!in_dev->dead)
                                        ip_rt_multicast_event(in_dev);
 
                                ip_ma_put(i);
@@ -1267,6 +1273,9 @@ void ip_mc_destroy_dev(struct in_device *in_dev)
 
        ASSERT_RTNL();
 
+       /* Deactivate timers */
+       ip_mc_down(in_dev);
+
        write_lock_bh(&in_dev->lock);
        while ((i = in_dev->mc_list) != NULL) {
                in_dev->mc_list = i->next;
index 13b39ae..395e84d 100644 (file)
@@ -20,8 +20,7 @@ config        IP_VS
          be used to choose which server the connection is directed to,
          thus load balancing can be achieved among the servers.  For more
          information and its administration program, please visit the
-         following URL:
-               http://www.linuxvirtualserver.org/
+         following URL: <http://www.linuxvirtualserver.org/>.
 
          If you want to compile it in kernel, say Y. To compile it as a
          module, choose M here. If unsure, say N.
index 1b18710..f38a2dc 100644 (file)
@@ -2,8 +2,12 @@
    but required by, the NAT layer; it can also be used by an iptables
    extension. */
 
-/* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
- * Public Licence. 
+/* (C) 1999-2001 Paul `Rusty' Russell  
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * 23 Apr 2001: Harald Welte <laforge@gnumonks.org>
  *     - new API and handling of conntrack/nat helpers
index 53d168a..ce5e625 100644 (file)
@@ -1,4 +1,13 @@
 /* FTP extension for IP connection tracking. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell  
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/netfilter.h>
index 4a4ddda..0df558a 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
index 409c078..4711484 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
index ec5727d..a2d1039 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
index f560174..a63c32d 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
index 4c357ef..53db0e4 100644 (file)
@@ -4,8 +4,13 @@
    These are not required by the compatibility layer.
 */
 
-/* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
-   Public Licence. */
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
 
 #include <linux/config.h>
 #include <linux/types.h>
@@ -154,6 +159,7 @@ list_conntracks(char *buffer, char **start, off_t offset, int length)
        }
 
        /* Now iterate through expecteds. */
+       READ_LOCK(&ip_conntrack_expect_tuple_lock);
        list_for_each(e, &ip_conntrack_expect_list) {
                unsigned int last_len;
                struct ip_conntrack_expect *expect
@@ -164,10 +170,12 @@ list_conntracks(char *buffer, char **start, off_t offset, int length)
                len += print_expect(buffer + len, expect);
                if (len > length) {
                        len = last_len;
-                       goto finished;
+                       goto finished_expects;
                }
        }
 
+ finished_expects:
+       READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
  finished:
        READ_UNLOCK(&ip_conntrack_lock);
 
index 39f5e47..324632c 100644 (file)
@@ -1,5 +1,9 @@
-/*
- * Licensed under GNU GPL version 2 Copyright Magnus Boden <mb@ozaba.mine.nu>
+/* (C) 2001-2002 Magnus Boden <mb@ozaba.mine.nu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
  * Version: 0.0.7
  *
  * Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org>
index ed9ceca..a45090d 100644 (file)
@@ -1,5 +1,14 @@
 /* Compatibility framework for ipchains and ipfwadm support; designed
    to look as much like the 2.2 infrastructure as possible. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 struct notifier_block;
 
 #include <linux/netfilter_ipv4.h>
index 7747f99..d942b1a 100644 (file)
@@ -4,6 +4,15 @@
    ports 61000:65095 (in 2.0 and 2.2 they get EADDRINUSE).  Just DON'T
    DO IT.
  */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/skbuff.h>
 #include <linux/in.h>
 #include <linux/ip.h>
index de44547..6a24a5c 100644 (file)
@@ -7,6 +7,15 @@
    FIXME: Timing is overly simplistic.  If anyone complains, make it
    use conntrack.
 */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/config.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
index 0471440..3685dad 100644 (file)
@@ -1,7 +1,13 @@
 /* NAT for netfilter; shared with compatibility layer. */
 
-/* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
-   Public Licence. */
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/timer.h>
index 5a6198b..68dc04f 100644 (file)
@@ -1,4 +1,13 @@
 /* FTP extension for TCP NAT alteration. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/ip.h>
index aa90a03..a49c722 100644 (file)
@@ -1,8 +1,11 @@
-/* ip_nat_mangle.c - generic support functions for NAT helpers 
+/* ip_nat_helper.c - generic support functions for NAT helpers 
  *
- * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2000-2002 Harald Welte <laforge@netfilter.org>
+ * (C) 2003-2004 Netfilter Core Team <coreteam@netfilter.org>
  *
- * distributed under the terms of GNU GPL
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  *     14 Jan 2002 Harald Welte <laforge@gnumonks.org>:
  *             - add support for SACK adjustment 
index 0f1a867..f7d31f8 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/netfilter.h>
index f22c2b7..731a12d 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/netfilter.h>
index a477410..2938465 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/netfilter.h>
index e918e46..2d42a00 100644 (file)
@@ -2,6 +2,14 @@
  * don't understand.  It's returned by ip_ct_find_proto().
  */
 
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/netfilter.h>
index f88c208..145b2c5 100644 (file)
@@ -1,3 +1,11 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 /* Everything about the rules for NAT. */
 #include <linux/types.h>
 #include <linux/ip.h>
index bb45edc..4d68064 100644 (file)
@@ -4,9 +4,15 @@
    These are not required by the compatibility layer.
 */
 
-/* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
- * Public Licence.
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
  *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
  * 23 Apr 2001: Harald Welte <laforge@gnumonks.org>
  *     - new API and handling of conntrack/nat helpers
  *     - now capable of multiple expectations for one master
index 5260b59..61ed62b 100644 (file)
@@ -1,5 +1,9 @@
-/*
- * Licensed under GNU GPL version 2 Copyright Magnus Boden <mb@ozaba.mine.nu>
+/* (C) 2001-2002 Magnus Boden <mb@ozaba.mine.nu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
  * Version: 0.0.7
  *
  * Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org>
index d20aa3a..906b89d 100644 (file)
@@ -2,7 +2,11 @@
  * This is a module which is used for queueing IPv4 packets and
  * communicating with userspace via netlink.
  *
- * (C) 2000-2002 James Morris, this code is GPL.
+ * (C) 2000-2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * 2000-03-27: Simplified code (thanks to Andi Kleen for clues).
  * 2000-05-20: Fixed notifier problems (following Miguel Freitas' report).
index 96ba0b6..a7103cc 100644 (file)
@@ -2,7 +2,11 @@
  * Packet matching code.
  *
  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
- * Copyright (C) 2009-2002 Netfilter core team <coreteam@netfilter.org>
+ * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
  *     - increase module usage count as soon as we have rules inside
index 4959b18..e7b3004 100644 (file)
@@ -3,6 +3,13 @@
  * of an skb for qdisc classification.
  */
 
+/* (C) 2001-2002 Patrick McHardy <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -71,10 +78,7 @@ static struct ipt_target ipt_classify_reg = {
 
 static int __init init(void)
 {
-       if (ipt_register_target(&ipt_classify_reg))
-               return -EINVAL;
-
-       return 0;
+       return ipt_register_target(&ipt_classify_reg);
 }
 
 static void __exit fini(void)
index 75c44cb..3ea4509 100644 (file)
@@ -1,8 +1,11 @@
 /* iptables module for setting the IPv4 DSCP field, Version 1.8
  *
- * (C) 2002 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2002 by Harald Welte <laforge@netfilter.org>
  * based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com>
- * This software is distributed under GNU GPL v2, 1991
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation.
  * 
  * See RFC2474 for a description of the DSCP field within the IP Header.
  *
@@ -91,10 +94,7 @@ static struct ipt_target ipt_dscp_reg = {
 
 static int __init init(void)
 {
-       if (ipt_register_target(&ipt_dscp_reg))
-               return -EINVAL;
-
-       return 0;
+       return ipt_register_target(&ipt_dscp_reg);
 }
 
 static void __exit fini(void)
index bdd0c6c..341e845 100644 (file)
@@ -1,9 +1,11 @@
 /* iptables module for the IPv4 and TCP ECN bits, Version 1.5
  *
- * (C) 2002 by Harald Welte <laforge@gnumonks.org>
- * 
- * This software is distributed under GNU GPL v2, 1991
+ * (C) 2002 by Harald Welte <laforge@netfilter.org>
  * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation.
+ *
  * ipt_ECN.c,v 1.5 2002/08/18 19:36:51 laforge Exp
 */
 
@@ -155,10 +157,7 @@ static struct ipt_target ipt_ecn_reg = {
 
 static int __init init(void)
 {
-       if (ipt_register_target(&ipt_ecn_reg))
-               return -EINVAL;
-
-       return 0;
+       return ipt_register_target(&ipt_ecn_reg);
 }
 
 static void __exit fini(void)
index d062bf0..0240056 100644 (file)
@@ -1,6 +1,15 @@
 /*
  * This is a module which is used for logging packets.
  */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>
@@ -404,10 +413,7 @@ static struct ipt_target ipt_log_reg = {
 
 static int __init init(void)
 {
-       if (ipt_register_target(&ipt_log_reg))
-               return -EINVAL;
-
-       return 0;
+       return ipt_register_target(&ipt_log_reg);
 }
 
 static void __exit fini(void)
index ee4be24..06bcb8d 100644 (file)
@@ -1,4 +1,12 @@
 /* This is a module which is used for setting the NFMARK field of an skb. */
+
+/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -59,10 +67,7 @@ static struct ipt_target ipt_mark_reg = {
 
 static int __init init(void)
 {
-       if (ipt_register_target(&ipt_mark_reg))
-               return -EINVAL;
-
-       return 0;
+       return ipt_register_target(&ipt_mark_reg);
 }
 
 static void __exit fini(void)
index 92f98ad..6082f12 100644 (file)
@@ -1,5 +1,14 @@
 /* Masquerade.  Simple mapping which alters range to a local IP address
    (depending on route). */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/ip.h>
index ba6a9f9..561efb1 100644 (file)
@@ -1,9 +1,14 @@
 /* NETMAP - static NAT mapping of IP network addresses (1:1).
-   The mapping can be applied to source (POSTROUTING),
-   destination (PREROUTING), or both (with separate rules).
-
-   Author: Svenning Soerensen <svenning@post5.tele.dk>
-*/
+ * The mapping can be applied to source (POSTROUTING),
+ * destination (PREROUTING), or both (with separate rules).
+ */
+
+/* (C) 2000-2001 Svenning Soerensen <svenning@post5.tele.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
 
 #include <linux/config.h>
 #include <linux/ip.h>
index bf9346b..15232f5 100644 (file)
@@ -1,4 +1,12 @@
 /* Redirect.  Simple mapping which alters dst to a local IP address. */
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/types.h>
 #include <linux/ip.h>
 #include <linux/timer.h>
index fd8b19e..8445b5e 100644 (file)
@@ -3,6 +3,15 @@
  * Added support for customized reject packets (Jozsef Kadlecsik).
  * Added support for ICMP type-3-code-13 (Maciej Soltysiak). [RFC 1812]
  */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -449,9 +458,7 @@ static struct ipt_target ipt_reject_reg = {
 
 static int __init init(void)
 {
-       if (ipt_register_target(&ipt_reject_reg))
-               return -EINVAL;
-       return 0;
+       return ipt_register_target(&ipt_reject_reg);
 }
 
 static void __exit fini(void)
index 4313eee..ca8d403 100644 (file)
@@ -1,7 +1,12 @@
 /* Same.  Just like SNAT, only try to make the connections
  *       between client A and server B always have the same source ip.
  *
- * (C) 2000 Rusty Russell.  GPL.
+ * (C) 2000 Paul `Rusty' Russell
+ * (C) 2001 Martin Josefsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * 010320 Martin Josefsson <gandalf@wlug.westbo.se>
  *     * copied ipt_BALANCE.c to ipt_SAME.c and changed a few things.
index 8f840a3..369f84b 100644 (file)
@@ -1,8 +1,13 @@
 /*
  * This is a module which is used for setting the MSS option in TCP packets.
  *
- * Copyright (c) 2000 Marc Boucher
+ * Copyright (C) 2000 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
index dacd5c0..85c70d2 100644 (file)
@@ -1,4 +1,13 @@
 /* This is a module which is used for setting the TOS field of a packet. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -84,10 +93,7 @@ static struct ipt_target ipt_tos_reg = {
 
 static int __init init(void)
 {
-       if (ipt_register_target(&ipt_tos_reg))
-               return -EINVAL;
-
-       return 0;
+       return ipt_register_target(&ipt_tos_reg);
 }
 
 static void __exit fini(void)
index 1398b85..f263e7a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * netfilter module for userspace packet logging daemons
  *
- * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2000-2002 by Harald Welte <laforge@netfilter.org>
  *
  * 2000/09/22 ulog-cprange feature added
  * 2001/01/04 in-kernel queue as proposed by Sebastian Zander 
  * 2002/08/29 fix shifted/unshifted nlgroup bug -HW
  * 2002/10/30 fix uninitialized mac_len field - <Anders K. Pedersen>
  *
- * Released under the terms of the GPL
+ * (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * This module accepts two parameters: 
  * 
index f691738..1f0d765 100644 (file)
@@ -1,4 +1,11 @@
 /* Kernel module to match AH parameters. */
+/* (C) 1999-2000 Yon Uriarte <yon@astaro.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
index 6d11d22..2e7e4bd 100644 (file)
@@ -1,7 +1,13 @@
 /* Kernel module to match connection tracking information.
  * Superset of Rusty's minimalistic state match.
- * GPL (C) 2001  Marc Boucher (marc@mbsi.ca).
+ *
+ * (C) 2001  Marc Boucher (marc@mbsi.ca).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4/ip_conntrack.h>
index cd32f29..5df52a6 100644 (file)
@@ -2,9 +2,11 @@
  *
  * ipt_dscp.c,v 1.3 2002/08/05 19:00:21 laforge Exp
  *
- * (C) 2002 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2002 by Harald Welte <laforge@netfilter.org>
  *
- * This software is distributed under the terms  GNU GPL
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
index 674f981..0e1efd7 100644 (file)
@@ -4,7 +4,9 @@
  *
  * (C) 2002 by Harald Welte <laforge@gnumonks.org>
  *
- * This software is distributed under the terms GNU GPL v2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
index 60c61ec..c3b8893 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match ESP parameters. */
+
+/* (C) 1999-2000 Yon Uriarte <yon@astaro.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
index 68101b7..bed83c7 100644 (file)
@@ -1,12 +1,15 @@
+/* iptables module to match on related connections */
 /*
- * iptables module to match on related connections
- *   (c) 2001 Martin Josefsson <gandalf@wlug.westbo.se>
+ * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se>
  *
- * Released under the terms of GNU GPLv2.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  *   19 Mar 2002 Harald Welte <laforge@gnumonks.org>:
  *              - Port to newnat infrastructure
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter.h>
index e666695..b835b7b 100644 (file)
@@ -1,9 +1,11 @@
 /*
  * iptables module to match IP address ranges
- *   (c) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
  *
- * Released under the terms of GNU GPLv2.
+ * (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
  *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
 #include <linux/module.h>
 #include <linux/skbuff.h>
index 7f3d058..4eabcfb 100644 (file)
@@ -1,4 +1,11 @@
 /* Kernel module to match packet length. */
+/* (C) 1999-2001 James Morris <jmorros@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
index deac142..46460e4 100644 (file)
@@ -1,12 +1,18 @@
 /* Kernel module to control the rate
  *
- * Jérôme de Vivie   <devivie@info.enserb.u-bordeaux.fr>
- * Hervé Eychenne   <eychenne@info.enserb.u-bordeaux.fr>
- *
  * 2 September 1999: Changed from the target RATE to the match
  *                   `limit', removed logging.  Did I mention that
  *                   Alexey is a fucking genius?
  *                   Rusty Russell (rusty@rustcorp.com.au).  */
+
+/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
+ * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
index 96a1bd4..77109e0 100644 (file)
@@ -1,4 +1,13 @@
 /* Kernel module to match MAC address parameters. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
index c8a064b..8955728 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match NFMARK values. */
+
+/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
index e4bc609..64e7999 100644 (file)
@@ -1,5 +1,14 @@
 /* Kernel module to match one of a list of TCP/UDP ports: ports are in
    the same place so we can treat them as equal. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/udp.h>
index 279263f..a152989 100644 (file)
@@ -1,8 +1,13 @@
 /* Kernel module to match various things tied to sockets associated with
-   locally generated outgoing packets.
+   locally generated outgoing packets. */
 
-   Copyright (C) 2000 Marc Boucher
+/* (C) 2000 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/file.h>
index 8f5dadc..1a53924 100644 (file)
@@ -1,5 +1,13 @@
 /* Kernel module to match the bridge port in and
  * out device for IP packets coming into contact with a bridge. */
+
+/* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4/ipt_physdev.h>
index 0477000..8ddb1dc 100644 (file)
@@ -1,3 +1,10 @@
+/* (C) 1999-2001 Michal Ludvig <michal@logix.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
@@ -7,6 +14,8 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 
 MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>");
+MODULE_DESCRIPTION("IP tables match to match on linklayer packet type");
 
 static int match(const struct sk_buff *skb,
       const struct net_device *in,
index 1ddb613..c70e791 100644 (file)
@@ -1,6 +1,13 @@
-/* Kernel module to match connection tracking information.
- * GPL (C) 1999  Rusty Russell (rusty@rustcorp.com.au).
+/* Kernel module to match connection tracking information. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4/ip_conntrack.h>
index f874b9f..c7cb62a 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match TCP MSS values. */
+
+/* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <net/tcp.h>
index 59d0939..086a1bb 100644 (file)
@@ -1,4 +1,13 @@
 /* Kernel module to match TOS values. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
index 15534e7..219aa9d 100644 (file)
@@ -2,9 +2,11 @@
  *
  * ipt_ttl.c,v 1.5 2000/11/13 11:16:08 laforge Exp
  *
- * (C) 2000,2001 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2000,2001 by Harald Welte <laforge@netfilter.org>
  *
- * This software is distributed under the terms  GNU GPL
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
@@ -13,7 +15,7 @@
 #include <linux/netfilter_ipv4/ipt_ttl.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("IP tables TTL matching module");
 MODULE_LICENSE("GPL");
 
index 86001fc..8fb2ed9 100644 (file)
@@ -2,7 +2,14 @@
  * This is the 1999 rewrite of IP Firewalling, aiming for kernel 2.3.x.
  *
  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
  */
+
 #include <linux/module.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
index 3f666ec..1c3d96b 100644 (file)
@@ -2,6 +2,11 @@
  * This is the 1999 rewrite of IP Firewalling, aiming for kernel 2.3.x.
  *
  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  *
  * Extended to all five netfilter hooks by Brad Chapman & Harald Welte
  */
index f1ac4b2..782ac7c 100644 (file)
@@ -584,6 +584,14 @@ ctl_table ipv4_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
                .strategy       = &sysctl_jiffies
        },
+       {
+               .ctl_name       = NET_TCP_WESTWOOD, 
+               .procname       = "tcp_westwood",
+               .data           = &sysctl_tcp_westwood,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
        { .ctl_name = 0 }
 };
 
index 8d60264..dd0b4c0 100644 (file)
@@ -1536,19 +1536,14 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                struct sk_buff *skb;
                u32 offset;
 
-               /* Are we at urgent data? Stop if we have read anything. */
-               if (copied && tp->urg_data && tp->urg_seq == *seq)
-                       break;
-
-               /* We need to check signals first, to get correct SIGURG
-                * handling. FIXME: Need to check this doesn't impact 1003.1g
-                * and move it down to the bottom of the loop
-                */
-               if (signal_pending(current)) {
+               /* Are we at urgent data? Stop if we have read anything or have SIGURG pending. */
+               if (tp->urg_data && tp->urg_seq == *seq) {
                        if (copied)
                                break;
-                       copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
-                       break;
+                       if (signal_pending(current)) {
+                               copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
+                               break;
+                       }
                }
 
                /* Next get a buffer. */
@@ -1587,6 +1582,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                            sk->sk_state == TCP_CLOSE ||
                            (sk->sk_shutdown & RCV_SHUTDOWN) ||
                            !timeo ||
+                           signal_pending(current) ||
                            (flags & MSG_PEEK))
                                break;
                } else {
@@ -1616,6 +1612,11 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                copied = -EAGAIN;
                                break;
                        }
+
+                       if (signal_pending(current)) {
+                               copied = sock_intr_errno(timeo);
+                               break;
+                       }
                }
 
                cleanup_rbuf(sk, copied);
index 5f446e0..c5e4bcb 100644 (file)
@@ -61,6 +61,7 @@
  *             Panu Kuhlberg:          Experimental audit of TCP (re)transmission
  *                                     engine. Lots of bugs are found.
  *             Pasi Sarolahti:         F-RTO for dealing with spurious RTOs
+ *             Angelo Dell'Aera:       TCP Westwood+ support
  */
 
 #include <linux/config.h>
@@ -89,6 +90,7 @@ int sysctl_tcp_stdurg;
 int sysctl_tcp_rfc1337;
 int sysctl_tcp_max_orphans = NR_FILE;
 int sysctl_tcp_frto;
+int sysctl_tcp_westwood;
 
 #define FLAG_DATA              0x01 /* Incoming frame contained data.          */
 #define FLAG_WIN_UPDATE                0x02 /* Incoming ACK was a window update.       */
@@ -474,6 +476,8 @@ static void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt)
                tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
                tp->rtt_seq = tp->snd_nxt;
        }
+
+       tcp_westwood_update_rtt(tp, tp->srtt >> 3);
 }
 
 /* Calculate rto without backoff.  This is the second half of Van Jacobson's
@@ -981,7 +985,8 @@ void tcp_enter_frto(struct sock *sk)
             tp->snd_una == tp->high_seq ||
             (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) {
                tp->prior_ssthresh = tcp_current_ssthresh(tp);
-               tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
+               if (!tcp_westwood_ssthresh(tp))
+                       tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
        }
 
        /* Have to clear retransmission markers here to keep the bookkeeping
@@ -1390,11 +1395,24 @@ static __inline__ void tcp_moderate_cwnd(struct tcp_opt *tp)
 static void tcp_cwnd_down(struct tcp_opt *tp)
 {
        int decr = tp->snd_cwnd_cnt + 1;
+       __u32 limit;
+
+       /*
+        * TCP Westwood
+        * Here limit is evaluated as BWestimation*RTTmin (for obtaining it
+        * in packets we use mss_cache). If sysctl_tcp_westwood is off
+        * tcp_westwood_bw_rttmin() returns 0. In such case snd_ssthresh is
+        * still used as usual. It prevents other strange cases in which
+        * BWE*RTTmin could assume value 0. It should not happen but...
+        */
+
+       if (!(limit = tcp_westwood_bw_rttmin(tp)))
+               limit = tp->snd_ssthresh/2;
 
        tp->snd_cwnd_cnt = decr&1;
        decr >>= 1;
 
-       if (decr && tp->snd_cwnd > tp->snd_ssthresh/2)
+       if (decr && tp->snd_cwnd > limit)
                tp->snd_cwnd -= decr;
 
        tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1);
@@ -1539,7 +1557,10 @@ static int tcp_try_undo_loss(struct sock *sk, struct tcp_opt *tp)
 
 static __inline__ void tcp_complete_cwr(struct tcp_opt *tp)
 {
-       tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
+       if (tcp_westwood_cwnd(tp)) 
+               tp->snd_ssthresh = tp->snd_cwnd;
+       else
+               tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
        tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
@@ -2030,6 +2051,240 @@ static void tcp_process_frto(struct sock *sk, u32 prior_snd_una)
         */
        tp->frto_counter = (tp->frto_counter + 1) % 3;
 }
+/*
+ * TCP Westwood
+ * Functions needed for estimating bandwidth.
+ */
+
+/*
+ * This function initializes fields used in TCP Westwood.
+ * We can't get no information about RTT at this time so
+ * we are forced to set it to 0.
+ */
+static void init_westwood(struct sock *sk)
+{
+        struct tcp_opt *tp = tcp_sk(sk);
+
+        tp->westwood.bw_sample = 0;
+        tp->westwood.bw_ns_est = 0;
+        tp->westwood.bw_est = 0;
+        tp->westwood.accounted = 0;
+        tp->westwood.cumul_ack = 0;
+        tp->westwood.rtt_win_sx = tcp_time_stamp;
+        tp->westwood.rtt = TCP_WESTWOOD_INIT_RTT;
+        tp->westwood.rtt_min = TCP_WESTWOOD_INIT_RTT;
+        tp->westwood.snd_una = tp->snd_una;
+}
+
+/*
+ * @westwood_do_filter
+ * Low-pass filter. Implemented using constant coeffients.
+ */
+static inline __u32 westwood_do_filter(__u32 a, __u32 b)
+{
+       return (((7 * a) + b) >> 3);
+}
+
+static void westwood_filter(struct sock *sk, __u32 delta)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+       __u32 sample = tp->westwood.bk / delta;
+
+       tp->westwood.bw_ns_est =
+               westwood_do_filter(tp->westwood.bw_ns_est, sample);
+       tp->westwood.bw_est =
+               westwood_do_filter(tp->westwood.bw_est,
+                                  tp->westwood.bw_ns_est);
+       tp->westwood.bw_sample = sample;
+}
+
+/* @westwood_update_rttmin
+ * It is used to update RTTmin. In this case we MUST NOT use
+ * WESTWOOD_RTT_MIN minimum bound since we could be on a LAN!
+ */
+static inline __u32 westwood_update_rttmin(struct sock *sk)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+       __u32 rttmin = tp->westwood.rtt_min;
+
+       if (tp->westwood.rtt == 0)
+               return(rttmin);
+
+       if (tp->westwood.rtt < tp->westwood.rtt_min || !rttmin)
+               rttmin = tp->westwood.rtt;
+
+       return(rttmin);
+}
+
+/*
+ * @westwood_acked
+ * Evaluate increases for dk. It requires no lock since when it is
+ * called lock should already be held. Be careful about it!
+ */
+static inline __u32 westwood_acked(struct sock *sk)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+
+       return ((tp->snd_una) - (tp->westwood.snd_una));
+}
+
+/*
+ * @westwood_new_window
+ * It evaluates if we are receiving data inside the same RTT window as
+ * when we started.
+ * Return value:
+ * It returns 0 if we are still evaluating samples in the same RTT
+ * window, 1 if the sample has to be considered in the next window.
+ */
+static int westwood_new_window(struct sock *sk)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+       __u32 left_bound;
+       __u32 rtt;
+       int ret = 0;
+
+       left_bound = tp->westwood.rtt_win_sx;
+       rtt = max(tp->westwood.rtt, (u32) TCP_WESTWOOD_RTT_MIN);
+
+       /*
+        * A RTT-window has passed. Be careful since if RTT is less than
+        * 50ms we don't filter but we continue 'building the sample'.
+        * This minimum limit was choosen since an estimation on small
+        * time intervals is better to avoid...
+        * Obvioulsy on a LAN we reasonably will always have
+        * right_bound = left_bound + WESTWOOD_RTT_MIN
+         */
+
+       if ((left_bound + rtt) < tcp_time_stamp)
+               ret = 1;
+
+       return ret;
+}
+
+/*
+ * @westwood_update_window
+ * It updates RTT evaluation window if it is the right moment to do
+ * it. If so it calls filter for evaluating bandwidth. Be careful
+ * about __westwood_update_window() since it is called without
+ * any form of lock. It should be used only for internal purposes.
+ * Call westwood_update_window() instead.
+ */
+static void __westwood_update_window(struct sock *sk, __u32 now)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+       __u32 delta = now - tp->westwood.rtt_win_sx;
+
+        if (!delta)
+                return;
+
+       if (tp->westwood.rtt)
+                westwood_filter(sk, delta);
+
+        tp->westwood.bk = 0;
+        tp->westwood.rtt_win_sx = tcp_time_stamp;
+}
+
+
+static void westwood_update_window(struct sock *sk, __u32 now)
+{
+       if (westwood_new_window(sk)) 
+               __westwood_update_window(sk, now);
+}
+
+/*
+ * @__westwood_fast_bw
+ * It is called when we are in fast path. In particular it is called when
+ * header prediction is successfull. In such case infact update is
+ * straight forward and doesn't need any particular care.
+ */
+void __tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+
+       westwood_update_window(sk, tcp_time_stamp);
+
+       tp->westwood.bk += westwood_acked(sk);
+       tp->westwood.snd_una = tp->snd_una;
+       tp->westwood.rtt_min = westwood_update_rttmin(sk);
+}
+
+
+/*
+ * @tcp_westwood_dupack_update
+ * It updates accounted and cumul_ack when receiving a dupack.
+ */
+
+static void westwood_dupack_update(struct sock *sk)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+
+       tp->westwood.accounted += tp->mss_cache;
+       tp->westwood.cumul_ack = tp->mss_cache;
+}
+
+static inline int westwood_may_change_cumul(struct tcp_opt *tp)
+{
+       return ((tp->westwood.cumul_ack) > tp->mss_cache);
+}
+
+static inline void westwood_partial_update(struct tcp_opt *tp)
+{
+       tp->westwood.accounted -= tp->westwood.cumul_ack;
+       tp->westwood.cumul_ack = tp->mss_cache;
+}
+
+static inline void westwood_complete_update(struct tcp_opt *tp)
+{
+       tp->westwood.cumul_ack -= tp->westwood.accounted;
+       tp->westwood.accounted = 0;
+}
+
+/*
+ * @westwood_acked_count
+ * This function evaluates cumul_ack for evaluating dk in case of
+ * delayed or partial acks.
+ */
+static __u32 westwood_acked_count(struct sock *sk)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+
+       tp->westwood.cumul_ack = westwood_acked(sk);
+
+        /* If cumul_ack is 0 this is a dupack since it's not moving
+         * tp->snd_una.
+         */
+        if (!(tp->westwood.cumul_ack))
+                westwood_dupack_update(sk);
+
+        if (westwood_may_change_cumul(tp)) {
+               /* Partial or delayed ack */
+               if ((tp->westwood.accounted) >= (tp->westwood.cumul_ack))
+                       westwood_partial_update(tp);
+               else
+                       westwood_complete_update(tp);
+       }
+
+       tp->westwood.snd_una = tp->snd_una;
+
+       return tp->westwood.cumul_ack;
+}
+
+
+/*
+ * @__westwood_slow_bw
+ * It is called when something is going wrong..even if there could
+ * be no problems! Infact a simple delayed packet may trigger a
+ * dupack. But we need to be careful in such case.
+ */
+void __tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
+{
+       struct tcp_opt *tp = tcp_sk(sk);
+
+       westwood_update_window(sk, tcp_time_stamp);
+
+       tp->westwood.bk += westwood_acked_count(sk);
+       tp->westwood.rtt_min = westwood_update_rttmin(sk);
+}
 
 /* This routine deals with incoming acks, but not outgoing ones. */
 static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
@@ -2057,6 +2312,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
                 */
                tcp_update_wl(tp, ack, ack_seq);
                tp->snd_una = ack;
+               tcp_westwood_fast_bw(sk, skb);
                flag |= FLAG_WIN_UPDATE;
 
                NET_INC_STATS_BH(TCPHPAcks);
@@ -2073,6 +2329,8 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
 
                if (TCP_ECN_rcv_ecn_echo(tp, skb->h.th))
                        flag |= FLAG_ECE;
+
+               tcp_westwood_slow_bw(sk,skb);
        }
 
        /* We passed data and got it acked, remove any soft error
@@ -3866,6 +4124,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                        if(tp->af_specific->conn_request(sk, skb) < 0)
                                return 1;
 
+                       init_westwood(sk);
+
                        /* Now we have several options: In theory there is 
                         * nothing else in the frame. KA9Q has an option to 
                         * send data with the syn, BSD accepts data with the
@@ -3887,6 +4147,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                goto discard;
 
        case TCP_SYN_SENT:
+               init_westwood(sk);
+
                queued = tcp_rcv_synsent_state_process(sk, skb, th, len);
                if (queued >= 0)
                        return queued;
index 7ea3ed7..77c24ac 100644 (file)
@@ -313,7 +313,7 @@ static void __tcp_put_port(struct sock *sk)
        spin_unlock(&head->lock);
 }
 
-inline void tcp_put_port(struct sock *sk)
+void tcp_put_port(struct sock *sk)
 {
        local_bh_disable();
        __tcp_put_port(sk);
index 83255ed..f5b5688 100644 (file)
@@ -19,10 +19,6 @@ config IPV6_PRIVACY
 
          See <file:Documentation/networking/ip-sysctl.txt> for details.
 
-config IPV6_NDISC_NEW
-       bool
-       default y
-
 config INET6_AH
        tristate "IPv6: AH transformation"
        depends on IPV6
index 5274126..89fc158 100644 (file)
@@ -2541,10 +2541,6 @@ restart:
                        unsigned long regen_advance;
 #endif
 
-#ifdef CONFIG_IPV6_PRIVACY
-                       regen_advance = ifp->idev->cnf.regen_max_retry * ifp->idev->cnf.dad_transmits * ifp->idev->nd_parms->retrans_time / HZ;
-#endif
-
                        if (ifp->flags & IFA_F_PERMANENT)
                                continue;
 
@@ -2587,33 +2583,28 @@ restart:
                                }
 #ifdef CONFIG_IPV6_PRIVACY
                        } else if ((ifp->flags&IFA_F_TEMPORARY) &&
-                                  !(ifp->flags&IFA_F_TENTATIVE) &&
-                                  age >= ifp->prefered_lft - regen_advance) {
-                               struct inet6_ifaddr *ifpub = ifp->ifpub;
-                               if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
-                                       next = ifp->tstamp + ifp->prefered_lft * HZ;
-                               if (!ifp->regen_count && ifpub) {
-                                       ifp->regen_count++;
-                                       in6_ifa_hold(ifp);
-                                       in6_ifa_hold(ifpub);
-                                       spin_unlock(&ifp->lock);
-                                       write_unlock(&addrconf_hash_lock);
-                                       ipv6_create_tempaddr(ifpub, ifp);
-                                       in6_ifa_put(ifpub);
-                                       in6_ifa_put(ifp);
-                                       goto restart;
-                               } else {
-                                       spin_unlock(&ifp->lock);
-                               }
+                                  !(ifp->flags&IFA_F_TENTATIVE)) {
+                               if (age >= ifp->prefered_lft - regen_advance) {
+                                       struct inet6_ifaddr *ifpub = ifp->ifpub;
+                                       if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
+                                               next = ifp->tstamp + ifp->prefered_lft * HZ;
+                                       if (!ifp->regen_count && ifpub) {
+                                               ifp->regen_count++;
+                                               in6_ifa_hold(ifp);
+                                               in6_ifa_hold(ifpub);
+                                               spin_unlock(&ifp->lock);
+                                               write_unlock(&addrconf_hash_lock);
+                                               ipv6_create_tempaddr(ifpub, ifp);
+                                               in6_ifa_put(ifpub);
+                                               in6_ifa_put(ifp);
+                                               goto restart;
+                                       }
+                               } else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
+                                       next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
+                               spin_unlock(&ifp->lock);
 #endif
                        } else {
                                /* ifp->prefered_lft <= ifp->valid_lft */
-#ifdef CONFIG_IPV6_PRIVACY
-                               if (ifp->flags&IFA_F_TEMPORARY) {
-                                       if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
-                                               next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
-                               } else
-#endif
                                if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
                                        next = ifp->tstamp + ifp->prefered_lft * HZ;
                                spin_unlock(&ifp->lock);
@@ -2669,7 +2660,6 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                        return -EINVAL;
                pfx = RTA_DATA(rta[IFA_LOCAL-1]);
        }
-
        if (pfx == NULL)
                return -EINVAL;
 
@@ -3504,20 +3494,10 @@ void __init addrconf_init(void)
        register_netdevice_notifier(&ipv6_dev_notf);
 
 #ifdef CONFIG_IPV6_PRIVACY
-       struct crypto_tfm *tfm = crypto_alloc_tfm("md5", 0);
-       if (likely(tfm != NULL)) {
-               spin_lock(&md5_tfm_lock);
-               if (likely(md5_tfm == NULL)) {
-                       md5_tfm = tfm;
-                       spin_unlock(&md5_tfm_lock);
-               } else {
-                       spin_unlock(&md5_tfm_lock);
-                       crypto_free_tfm(tfm);
-               }
-       } else {
+       md5_tfm = crypto_alloc_tfm("md5", 0);
+       if (unlikely(md5_tfm == NULL))
                printk(KERN_WARNING
                        "failed to load transform for md5\n");
-       }
 #endif
 
        addrconf_verify(0);
@@ -3536,9 +3516,6 @@ void addrconf_cleanup(void)
        struct inet6_dev *idev;
        struct inet6_ifaddr *ifa;
        int i;
-#ifdef CONFIG_IPV6_PRIVACY
-       struct crypto_tfm *tfm;
-#endif
 
        unregister_netdevice_notifier(&ipv6_dev_notf);
 
@@ -3584,12 +3561,10 @@ void addrconf_cleanup(void)
        rtnl_unlock();
 
 #ifdef CONFIG_IPV6_PRIVACY
-       spin_lock(&md5_tfm_lock);
-       tfm = md5_tfm;
-       md5_tfm = NULL;
-       spin_unlock(&md5_tfm_lock);
-       if (likely(tfm))
-               crypto_free_tfm(tfm);
+       if (likely(md5_tfm != NULL)) {
+               crypto_free_tfm(md5_tfm);
+               md5_tfm = NULL;
+       }
 #endif
 
 #ifdef CONFIG_PROC_FS
index 54e85a0..2a3e8c9 100644 (file)
@@ -464,7 +464,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
                if (np->sndflow)
                        sin->sin6_flowinfo = np->flow_label;
        } else {
-               if (ipv6_addr_type(&np->rcv_saddr) == IPV6_ADDR_ANY)
+               if (ipv6_addr_any(&np->rcv_saddr))
                        ipv6_addr_copy(&sin->sin6_addr, &np->saddr);
                else
                        ipv6_addr_copy(&sin->sin6_addr, &np->rcv_saddr);
index 291be6d..c966d06 100644 (file)
@@ -111,7 +111,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
-       if (ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST)
+       if (ipv6_addr_is_multicast(addr))
                return -EINVAL;
        if (ipv6_chk_addr(addr, NULL, 0))
                return -EINVAL;
index b50452a..8c39cf5 100644 (file)
@@ -242,10 +242,6 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
                struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
                put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
        }
-       if (np->rxopt.bits.authhdr && opt->auth) {
-               u8 *ptr = skb->nh.raw + opt->auth;
-               put_cmsg(msg, SOL_IPV6, IPV6_AUTHHDR, (ptr[1]+2)<<2, ptr);
-       }
        if (np->rxopt.bits.dstopts && opt->dst1) {
                u8 *ptr = skb->nh.raw + opt->dst1;
                put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
@@ -378,26 +374,6 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        opt->dst1opt = hdr;
                        break;
 
-               case IPV6_AUTHHDR:
-                        if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-
-                       hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
-                       len = ((hdr->hdrlen + 2) << 2);
-                       if (cmsg->cmsg_len < CMSG_LEN(len)) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-                       if (len & ~7) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-                       opt->opt_flen += len;
-                       opt->auth = hdr;
-                       break;
-
                case IPV6_RTHDR:
                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
                                err = -EINVAL;
index 4307574..93b2f8b 100644 (file)
@@ -218,7 +218,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
        struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
        struct in6_addr *addr;
        struct in6_addr daddr;
-       int addr_type;
        int n, i;
 
        struct ipv6_rt_hdr *hdr;
@@ -233,7 +232,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
 
        hdr = (struct ipv6_rt_hdr *) skb->h.raw;
 
-       if ((ipv6_addr_type(&skb->nh.ipv6h->daddr)&IPV6_ADDR_MULTICAST) ||
+       if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
            skb->pkt_type != PACKET_HOST) {
                kfree_skb(skb);
                return -1;
@@ -293,9 +292,7 @@ looped_back:
        addr = rthdr->addr;
        addr += i - 1;
 
-       addr_type = ipv6_addr_type(addr);
-
-       if (addr_type&IPV6_ADDR_MULTICAST) {
+       if (ipv6_addr_is_multicast(addr)) {
                kfree_skb(skb);
                return -1;
        }
@@ -521,17 +518,6 @@ static u8 *ipv6_build_exthdr(struct sk_buff *skb, u8 *prev_hdr, u8 type, struct
        return &h->nexthdr;
 }
 
-static u8 *ipv6_build_authhdr(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_opt_hdr *opt)
-{
-       struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_put(skb, (opt->hdrlen+2)<<2);
-
-       memcpy(h, opt, (opt->hdrlen+2)<<2);
-       h->nexthdr = *prev_hdr;
-       *prev_hdr = NEXTHDR_AUTH;
-       return &h->nexthdr;
-}
-
-
 u8 *ipv6_build_nfrag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt,
                          struct in6_addr *daddr, u32 jumbolen)
 {
@@ -570,8 +556,6 @@ u8 *ipv6_build_nfrag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptio
 
 u8 *ipv6_build_frag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt)
 {
-       if (opt->auth)
-               prev_hdr = ipv6_build_authhdr(skb, prev_hdr, opt->auth);
        if (opt->dst1opt)
                prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst1opt);
        return prev_hdr;
@@ -611,15 +595,6 @@ static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv
        *proto = type;
 }
 
-static void ipv6_push_authhdr(struct sk_buff *skb, u8 *proto, struct ipv6_opt_hdr *opt)
-{
-       struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, (opt->hdrlen+2)<<2);
-
-       memcpy(h, opt, (opt->hdrlen+2)<<2);
-       h->nexthdr = *proto;
-       *proto = NEXTHDR_AUTH;
-}
-
 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
                          u8 *proto,
                          struct in6_addr **daddr)
@@ -636,8 +611,6 @@ void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *pr
 {
        if (opt->dst1opt)
                ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
-       if (opt->auth)
-               ipv6_push_authhdr(skb, proto, opt->auth);
 }
 
 struct ipv6_txoptions *
@@ -655,8 +628,6 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
                        *((char**)&opt2->dst0opt) += dif;
                if (opt2->dst1opt)
                        *((char**)&opt2->dst1opt) += dif;
-               if (opt2->auth)
-                       *((char**)&opt2->auth) += dif;
                if (opt2->srcrt)
                        *((char**)&opt2->srcrt) += dif;
        }
index c9aa51f..52c0218 100644 (file)
@@ -230,11 +230,6 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
                retv = 0;
                break;
 
-       case IPV6_AUTHHDR:
-               np->rxopt.bits.authhdr = valbool;
-               retv = 0;
-               break;
-
        case IPV6_DSTOPTS:
                np->rxopt.bits.dstopts = valbool;
                retv = 0;
@@ -623,10 +618,6 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, char *optval,
                val = np->rxopt.bits.hopopts;
                break;
 
-       case IPV6_AUTHHDR:
-               val = np->rxopt.bits.authhdr;
-               break;
-
        case IPV6_DSTOPTS:
                val = np->rxopt.bits.dstopts;
                break;
index 8c8c2c9..a7a22da 100644 (file)
@@ -175,7 +175,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
        struct ipv6_pinfo *np = inet6_sk(sk);
        int err;
 
-       if (!(ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST))
+       if (!ipv6_addr_is_multicast(addr))
                return -EINVAL;
 
        mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
@@ -348,7 +348,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
        source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
        group = &((struct sockaddr_in6 *)&pgsr->gsr_group)->sin6_addr;
 
-       if (!(ipv6_addr_type(group) & IPV6_ADDR_MULTICAST))
+       if (!ipv6_addr_is_multicast(group))
                return -EINVAL;
 
        idev = ip6_mc_find_dev(group, pgsr->gsr_interface);
@@ -457,7 +457,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
 
        group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr;
 
-       if (!(ipv6_addr_type(group) & IPV6_ADDR_MULTICAST))
+       if (!ipv6_addr_is_multicast(group))
                return -EINVAL;
        if (gsf->gf_fmode != MCAST_INCLUDE &&
            gsf->gf_fmode != MCAST_EXCLUDE)
@@ -529,7 +529,7 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
 
        group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr;
 
-       if (!(ipv6_addr_type(group) & IPV6_ADDR_MULTICAST))
+       if (!ipv6_addr_is_multicast(group))
                return -EINVAL;
 
        idev = ip6_mc_find_dev(group, gsf->gf_interface);
index 5950a12..e988ccd 100644 (file)
@@ -277,25 +277,21 @@ static int ndisc_constructor(struct neighbour *neigh)
        struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
        struct net_device *dev = neigh->dev;
        struct inet6_dev *in6_dev = in6_dev_get(dev);
-       int addr_type;
+       int is_multicast = ipv6_addr_is_multicast(addr);
 
        if (in6_dev == NULL)
                return -EINVAL;
 
-       addr_type = ipv6_addr_type(addr);
        if (in6_dev->nd_parms)
                neigh->parms = in6_dev->nd_parms;
 
-       if (addr_type&IPV6_ADDR_MULTICAST)
-               neigh->type = RTN_MULTICAST;
-       else
-               neigh->type = RTN_UNICAST;
+       neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
        if (dev->hard_header == NULL) {
                neigh->nud_state = NUD_NOARP;
                neigh->ops = &ndisc_direct_ops;
                neigh->output = neigh->ops->queue_xmit;
        } else {
-               if (addr_type&IPV6_ADDR_MULTICAST) {
+               if (is_multicast) {
                        neigh->nud_state = NUD_NOARP;
                        ndisc_mc_map(addr, neigh->ha, dev, 1);
                } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
@@ -347,7 +343,6 @@ static void pndisc_destructor(struct pneigh_entry *n)
 
 
 
-#if 0
 static int
 ndisc_build_ll_hdr(struct sk_buff *skb, struct net_device *dev,
                   struct in6_addr *daddr, struct neighbour *neigh, int len)
@@ -355,14 +350,8 @@ ndisc_build_ll_hdr(struct sk_buff *skb, struct net_device *dev,
        unsigned char ha[MAX_ADDR_LEN];
        unsigned char *h_dest = NULL;
 
-       if (!dev) {
-               printk(KERN_DEBUG "%s:device=%p, neigh=%p\n",
-                       __FUNCTION__, dev, neigh);
-               BUG();
-       }
-
        if (dev->hard_header) {
-               if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
+               if (ipv6_addr_is_multicast(daddr)) {
                        ndisc_mc_map(daddr, ha, dev, 1);
                        h_dest = ha;
                } else if (neigh) {
@@ -391,14 +380,12 @@ ndisc_build_ll_hdr(struct sk_buff *skb, struct net_device *dev,
 
        return 1;
 }
-#endif
 
 
 /*
  *     Send a Neighbour Advertisement
  */
 
-#if 0
 static int ndisc_output(struct sk_buff *skb)
 {
        if (skb) {
@@ -412,7 +399,6 @@ static int ndisc_output(struct sk_buff *skb)
        }
        return -EINVAL;
 }
-#endif
 
 static inline void ndisc_flow_init(struct flowi *fl, u8 type,
                            struct in6_addr *saddr, struct in6_addr *daddr)
@@ -425,21 +411,6 @@ static inline void ndisc_flow_init(struct flowi *fl, u8 type,
        fl->fl_icmp_code        = 0;
 }
 
-static void inline ndisc_update(struct neighbour *neigh,
-                               u8 *lladdr, u32 flags)
-{
-       int notify;
-       write_lock_bh(&neigh->lock);
-       notify = __neigh_update(neigh, lladdr, NUD_STALE, flags);
-#ifdef CONFIG_ARPD
-       if (notify > 0 && neigh->parms->app_probes) {
-               write_unlock_bh(&neigh->lock);
-               neigh_app_notify(neigh);
-       } else
-#endif
-       write_unlock_bh(&neigh->lock);
-}
-
 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
                   struct in6_addr *daddr, struct in6_addr *solicited_addr,
                   int router, int solicited, int override, int inc_opt) 
@@ -471,7 +442,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 
        ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
 
-       dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+       dst = ndisc_dst_alloc(dev, neigh, ndisc_output);
        if (!dst)
                return;
 
@@ -488,8 +459,9 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
                        inc_opt = 0;
        }
 
-       skb = sock_alloc_send_skb(sk, MAX_HEADER + len +
-                       dev->hard_header_len + dst->header_len + 64 + 15, 1, &err);
+       skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
+                                 1, &err);
+
        if (skb == NULL) {
                ND_PRINTK1("send_na: alloc skb failed\n");
                dst_release(dst);
@@ -499,7 +471,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
        skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
        ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
 
-       skb->h.raw = (unsigned char*) msg = (struct nd_msg *) skb_put(skb, len);
+       msg = (struct nd_msg *)skb_put(skb, len);
+       skb->h.raw = (unsigned char*)msg;
 
         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
         msg->icmph.icmp6_code = 0;
@@ -557,7 +530,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 
        ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
 
-       dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+       dst = ndisc_dst_alloc(dev, neigh, ndisc_output);
        if (!dst)
                return;
 
@@ -568,12 +541,12 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
        }
 
        len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
-       send_llinfo = dev->addr_len && ipv6_addr_type(saddr) != IPV6_ADDR_ANY;
+       send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
        if (send_llinfo)
                len += NDISC_OPT_SPACE(dev->addr_len);
 
-       skb = sock_alloc_send_skb(sk, MAX_HEADER + len +
-                        dev->hard_header_len + dst->header_len + 64 + 15, 1, &err);
+       skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
+                                 1, &err);
        if (skb == NULL) {
                ND_PRINTK1("send_ns: alloc skb failed\n");
                dst_release(dst);
@@ -583,7 +556,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
        skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
        ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
 
-       skb->h.raw = (unsigned char*) msg = (struct nd_msg *)skb_put(skb, len);
+       msg = (struct nd_msg *)skb_put(skb, len);
+       skb->h.raw = (unsigned char*)msg;
        msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
        msg->icmph.icmp6_code = 0;
        msg->icmph.icmp6_cksum = 0;
@@ -629,7 +603,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
 
        ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
 
-       dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
+       dst = ndisc_dst_alloc(dev, NULL, ndisc_output);
        if (!dst)
                return;
 
@@ -643,8 +617,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
        if (dev->addr_len)
                len += NDISC_OPT_SPACE(dev->addr_len);
 
-        skb = sock_alloc_send_skb(sk, MAX_HEADER + len + 
-                       dev->hard_header_len + dst->header_len + 64 + 15, 1, &err);
+        skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
+                                 1, &err);
        if (skb == NULL) {
                ND_PRINTK1("send_ns: alloc skb failed\n");
                dst_release(dst);
@@ -654,7 +628,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
        skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
        ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
 
-        skb->h.raw = (unsigned char*) hdr = (struct icmp6hdr *) skb_put(skb, len);
+        hdr = (struct icmp6hdr *)skb_put(skb, len);
+        skb->h.raw = (unsigned char*)hdr;
         hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
         hdr->icmp6_code = 0;
         hdr->icmp6_cksum = 0;
@@ -732,10 +707,12 @@ static void ndisc_recv_ns(struct sk_buff *skb)
        struct ndisc_options ndopts;
        struct net_device *dev = skb->dev;
        struct inet6_ifaddr *ifp;
+       struct inet6_dev *idev = NULL;
        struct neighbour *neigh;
-       int addr_type = ipv6_addr_type(saddr);
+       int dad = ipv6_addr_any(saddr);
+       int inc;
 
-       if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
+       if (ipv6_addr_is_multicast(&msg->target)) {
                if (net_ratelimit())
                        printk(KERN_WARNING "ICMP NS: target address is multicast\n");
                return;
@@ -745,7 +722,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
         * RFC2461 7.1.1:
         * DAD has to be destined for solicited node multicast address.
         */
-       if (addr_type == IPV6_ADDR_ANY &&
+       if (dad &&
            !(daddr->s6_addr32[0] == htonl(0xff020000) &&
              daddr->s6_addr32[1] == htonl(0x00000000) &&
              daddr->s6_addr32[2] == htonl(0x00000001) &&
@@ -775,13 +752,15 @@ static void ndisc_recv_ns(struct sk_buff *skb)
                 *      there MUST NOT be source link-layer address option 
                 *      in the message.
                 */
-               if (addr_type == IPV6_ADDR_ANY) {
+               if (dad) {
                        if (net_ratelimit())
                                printk(KERN_WARNING "ICMP6 NS: bad DAD packet (link-layer address option)\n");
                        return;
                }
        }
 
+       inc = ipv6_addr_is_multicast(daddr);
+
        if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
                if (ifp->flags & IFA_F_TENTATIVE) {
                        /* Address is tentative. If the source
@@ -789,177 +768,89 @@ static void ndisc_recv_ns(struct sk_buff *skb)
                           does DAD, otherwise we ignore solicitations
                           until DAD timer expires.
                         */
-                       if (addr_type == IPV6_ADDR_ANY) {
-                               if (dev->type == ARPHRD_IEEE802_TR) { 
-                                       unsigned char *sadr = skb->mac.raw ;
-                                       if (((sadr[8] &0x7f) != (dev->dev_addr[0] & 0x7f)) ||
-                                       (sadr[9] != dev->dev_addr[1]) ||
-                                       (sadr[10] != dev->dev_addr[2]) ||
-                                       (sadr[11] != dev->dev_addr[3]) ||
-                                       (sadr[12] != dev->dev_addr[4]) ||
-                                       (sadr[13] != dev->dev_addr[5])) 
-                                       {
-                                               addrconf_dad_failure(ifp) ; 
-                                       }
-                               } else {
-                                       addrconf_dad_failure(ifp);
+                       if (!dad)
+                               goto out;
+                       if (dev->type == ARPHRD_IEEE802_TR) {
+                               unsigned char *sadr = skb->mac.raw;
+                               if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 &&
+                                   sadr[9] == dev->dev_addr[1] &&
+                                   sadr[10] == dev->dev_addr[2] &&
+                                   sadr[11] == dev->dev_addr[3] &&
+                                   sadr[12] == dev->dev_addr[4] &&
+                                   sadr[13] == dev->dev_addr[5]) {
+                                       /* looped-back to us */
+                                       goto out;
                                }
-                       } else
-                               in6_ifa_put(ifp);
-                       return;
-               }
-       
-               if (addr_type == IPV6_ADDR_ANY) {
-                       struct in6_addr maddr;
-
-                       ipv6_addr_all_nodes(&maddr);
-                       ndisc_send_na(dev, NULL, &maddr, &ifp->addr, 
-                                     ifp->idev->cnf.forwarding, 0, 
-                                     1, 1);
-                       in6_ifa_put(ifp);
+                       }
+                       addrconf_dad_failure(ifp); 
                        return;
                }
 
-               if (addr_type & IPV6_ADDR_UNICAST) {
-                       int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
-
-                       if (inc)
-                               nd_tbl.stats.rcv_probes_mcast++;
-                       else
-                               nd_tbl.stats.rcv_probes_ucast++;
-
-                       /* 
-                        *      update / create cache entry
-                        *      for the source address
-                        */
-
-#ifdef CONFIG_IPV6_NDISC_NEW
-                       neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, !inc || lladdr || !skb->dev->addr_len);
-                       if (neigh) {
-                               ndisc_update(neigh, lladdr, NEIGH_UPDATE_F_IP6NS);
-                               ndisc_send_na(dev, neigh, saddr, &ifp->addr,
-                                             ifp->idev->cnf.forwarding, 1, inc, inc);
-                               neigh_release(neigh);
-                       }
-#else
-                       neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
-
-                       if (neigh || !dev->hard_header) {
-                               ndisc_send_na(dev, neigh, saddr, &ifp->addr, 
-                                             ifp->idev->cnf.forwarding, 1, 
-                                             1, 1);
-                               if (neigh)
-                                       neigh_release(neigh);
-                       }
-#endif
-               }
-               in6_ifa_put(ifp);
-       } else if (ipv6_chk_acast_addr(dev, &msg->target)) {
-               struct inet6_dev *idev = in6_dev_get(dev);
-       
-               /* anycast */
-       
+               idev = ifp->idev;
+       } else {
+               idev = in6_dev_get(dev);
                if (!idev) {
                        /* XXX: count this drop? */
                        return;
                }
-       
-               if (addr_type == IPV6_ADDR_ANY) {
-                       struct in6_addr maddr;
-       
-                       ipv6_addr_all_nodes(&maddr);
-                       ndisc_send_na(dev, NULL, &maddr, &msg->target,
-                                     idev->cnf.forwarding, 0, 0, 1);
-                       in6_dev_put(idev);
-                       return;
-               }
-
-               if (addr_type & IPV6_ADDR_UNICAST) {
-                       int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
-                       if (inc)  
-                               nd_tbl.stats.rcv_probes_mcast++;
-                       else
-                               nd_tbl.stats.rcv_probes_ucast++;
-       
-                       /*
-                        *   update / create cache entry
-                        *   for the source address
-                        */
 
-#ifdef CONFIG_IPV6_NDISC_NEW
-                       neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, !inc || lladdr || !skb->dev->addr_len);
-                       if (neigh) {
-                               ndisc_update(neigh, lladdr,
-                                            NEIGH_UPDATE_F_IP6NS);
-                               ndisc_send_na(dev, neigh, saddr, &msg->target,
-                                             idev->cnf.forwarding, 1, 0, inc);
-                               neigh_release(neigh);
-                       }
-#else
-                       neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, skb->dev);
-
-                       if (neigh || !dev->hard_header) {
-                               ndisc_send_na(dev, neigh, saddr,
-                                             &msg->target, 
-                                             idev->cnf.forwarding, 1, 0, inc);
-                               if (neigh)
-                                       neigh_release(neigh);
-                       }
-#endif
-               }
-               in6_dev_put(idev);
-       } else {
-               struct inet6_dev *in6_dev = in6_dev_get(dev);
-
-               if (in6_dev && in6_dev->cnf.forwarding &&
-                   (addr_type & IPV6_ADDR_UNICAST ||
-                    addr_type == IPV6_ADDR_ANY) &&
-                   pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
-                       int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
-
-                       if (skb->stamp.tv_sec == 0 ||
-                           skb->pkt_type == PACKET_HOST ||
-                           inc == 0 ||
-                           in6_dev->nd_parms->proxy_delay == 0) {
-                               if (inc)
-                                       nd_tbl.stats.rcv_probes_mcast++;
-                               else
-                                       nd_tbl.stats.rcv_probes_ucast++;
-                                       
-                               if (addr_type & IPV6_ADDR_UNICAST) {
-#ifdef CONFIG_IPV6_NDISC_NEW
-                                       neigh = __neigh_lookup(&nd_tbl, saddr, dev,
-                                                              !inc || lladdr || !dev->addr_len);
-#else
-                                       neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
-#endif
-                                       if (neigh) {
-#ifdef CONFIG_IPV6_NDISC_NEW
-                                               ndisc_update(neigh, lladdr, 
-                                                            NEIGH_UPDATE_F_IP6NS);
-#endif
-                                               ndisc_send_na(dev, neigh, saddr, &msg->target,
-                                                             0, 1, 0, 1);
-                                               neigh_release(neigh);
-                                       }
-                               } else {
-                                       /* proxy should also protect against DAD */
-                                       struct in6_addr maddr;
-                                       ipv6_addr_all_nodes(&maddr);
-                                       ndisc_send_na(dev, NULL, &maddr, &msg->target, 
-                                                     0, 0, 0, 1);
-                               }
-                       } else {
+               if (ipv6_chk_acast_addr(dev, &msg->target) ||
+                   (idev->cnf.forwarding && 
+                    pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
+                       if (skb->stamp.tv_sec != 0 &&
+                           skb->pkt_type != PACKET_HOST &&
+                           inc != 0 &&
+                           idev->nd_parms->proxy_delay != 0) {
+                               /*
+                                * for anycast or proxy,
+                                * sender should delay its response 
+                                * by a random time between 0 and 
+                                * MAX_ANYCAST_DELAY_TIME seconds.
+                                * (RFC2461) -- yoshfuji
+                                */
                                struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
                                if (n)
-                                       pneigh_enqueue(&nd_tbl, in6_dev->nd_parms, n);
-                               in6_dev_put(in6_dev);
-                               return;
+                                       pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
+                               goto out;
                        }
-               }
-               if (in6_dev)
-                       in6_dev_put(in6_dev);
+               } else
+                       goto out;
+       }
+
+       if (dad) {
+               struct in6_addr maddr;
+
+               ipv6_addr_all_nodes(&maddr);
+               ndisc_send_na(dev, NULL, &maddr, &msg->target,
+                             idev->cnf.forwarding, 0, (ifp != NULL), 1);
+               goto out;
+       }
+
+       if (inc)
+               nd_tbl.stats.rcv_probes_mcast++;
+       else
+               nd_tbl.stats.rcv_probes_ucast++;
+
+       /* 
+        *      update / create cache entry
+        *      for the source address
+        */
+       neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
+
+       if (neigh || !dev->hard_header) {
+               ndisc_send_na(dev, neigh, saddr, &msg->target,
+                             idev->cnf.forwarding, 
+                             1, (ifp != NULL && inc), inc);
+               if (neigh)
+                       neigh_release(neigh);
        }
+
+out:
+       if (ifp)
+               in6_ifa_put(ifp);
+       else
+               in6_dev_put(idev);
+
        return;
 }
 
@@ -982,13 +873,13 @@ static void ndisc_recv_na(struct sk_buff *skb)
                return;
        }
 
-       if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
+       if (ipv6_addr_is_multicast(&msg->target)) {
                if (net_ratelimit())
                        printk(KERN_WARNING "NDISC NA: target address is multicast\n");
                return;
        }
 
-       if ((ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST) &&
+       if (ipv6_addr_is_multicast(daddr) &&
            msg->icmph.icmp6_solicited) {
                ND_PRINTK0("NDISC: solicited NA is multicasted\n");
                return;
@@ -1026,36 +917,6 @@ static void ndisc_recv_na(struct sk_buff *skb)
        neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
 
        if (neigh) {
-#ifdef CONFIG_IPV6_NDISC_NEW
-               int notify = 0;
-               int was_router = 0;
-
-               write_lock_bh(&neigh->lock);
-               if (!(neigh->nud_state & ~NUD_FAILED))
-                       goto ignore;
-
-               was_router = neigh->flags & NTF_ROUTER;
-
-               notify = __neigh_update(neigh, lladdr,
-                                       msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
-                                       (NEIGH_UPDATE_F_IP6NA|
-                                        (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0) |
-                                        (msg->icmph.icmp6_router   ? NEIGH_UPDATE_F_ISROUTER : 0)));
-
-               if (was_router && !(neigh->flags & NTF_ROUTER)) {
-                       /*
-                        *      Change: router to host
-                        */
-                       struct rt6_info *rt;
-                       rt = rt6_get_dflt_router(saddr, dev);
-                       if (rt) {
-                               /* It is safe only because 
-                                * we're in BH */
-                               dst_release(&rt->u.dst);
-                               ip6_del_rt(rt, NULL, NULL);
-                       }
-               }
-#else
                if (neigh->flags & NTF_ROUTER) {
                        if (msg->icmph.icmp6_router == 0) {
                                /*
@@ -1074,80 +935,10 @@ static void ndisc_recv_na(struct sk_buff *skb)
                neigh_update(neigh, lladdr,
                             msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
                             msg->icmph.icmp6_override, 1);
-#endif
-#ifdef CONFIG_IPV6_NDISC_NEW
-ignore:
-#ifdef CONFIG_ARPD
-               if (notify > 0 && neigh->parms->app_probes) {
-                       write_unlock_bh(&neigh->lock);
-                       neigh_app_notify(neigh);
-               } else
-#endif
-               write_unlock_bh(&neigh->lock);
-#endif
                neigh_release(neigh);
        }
 }
 
-static void ndisc_recv_rs(struct sk_buff *skb)
-{
-       struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
-       unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
-       struct neighbour *neigh;
-       struct inet6_dev *idev;
-       struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-       struct ndisc_options ndopts;
-       u8 *lladdr = NULL;
-       int lladdrlen = 0;
-
-       if (skb->len < sizeof(*rs_msg))
-               return;
-
-       idev = in6_dev_get(skb->dev);
-       if (!idev) {
-               if (net_ratelimit())
-                       ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
-               return;
-       }
-
-       /* Don't accept RS if we're not in router mode */
-       if (!idev->cnf.forwarding || idev->cnf.accept_ra)
-               goto out;
-
-       /*
-        * Don't update NCE if src = ::;
-        * this implies that the source node has no ip address assigned yet.
-        */
-       if (ipv6_addr_any(saddr))
-               goto out;
-
-       /* Parse ND options */
-       if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
-               if (net_ratelimit())
-                       ND_PRINTK2("ICMP6 NS: invalid ND option, ignored\n");
-               goto out;
-       }
-
-       if (ndopts.nd_opts_src_lladdr) {
-               lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1);
-               lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
-               if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
-                       goto out;
-       }
-
-       neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
-       if (neigh) {
-#ifdef CONFIG_IPV6_NDISC_NEW
-               ndisc_update(neigh, lladdr, NEIGH_UPDATE_F_IP6RS);
-#else
-               neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
-#endif
-               neigh_release(neigh);
-       }
-out:
-       in6_dev_put(idev);
-}
-
 static void ndisc_router_discovery(struct sk_buff *skb)
 {
         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
@@ -1306,11 +1097,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
                                goto out;
                        }
                }
-#ifdef CONFIG_IPV6_NDISC_NEW
-               ndisc_update(neigh, lladdr, NEIGH_UPDATE_F_IP6RA);
-#else
                neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
-#endif
        }
 
        if (ndopts.nd_opts_pi) {
@@ -1386,7 +1173,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
        target = (struct in6_addr *) (icmph + 1);
        dest = target + 1;
 
-       if (ipv6_addr_type(dest) & IPV6_ADDR_MULTICAST) {
+       if (ipv6_addr_is_multicast(dest)) {
                if (net_ratelimit())
                        printk(KERN_WARNING "ICMP redirect for multicast addr\n");
                return;
@@ -1439,18 +1226,11 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
 
        neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
        if (neigh) {
-#ifdef CONFIG_IPV6_NDISC_NEW
-               rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
-#else
-               if (neigh->nud_state&NUD_VALID) {
-                       if (!rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, NULL, on_link))
-                               neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
-               } else {
-                       write_lock_bh(&neigh->lock);
+               neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
+               if (neigh->nud_state&NUD_VALID)
+                       rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
+               else
                        __neigh_event_send(neigh, NULL);
-                       write_unlock_bh(&neigh->lock);
-               }
-#endif
                neigh_release(neigh);
        }
        in6_dev_put(in6_dev);
@@ -1525,10 +1305,11 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        rd_len &= ~0x7;
        len += rd_len;
 
-       buff = sock_alloc_send_skb(sk, MAX_HEADER + len +
-                       dev->hard_header_len  + dst->header_len + 64 + 15, 1, &err);
+       buff = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
+                                  1, &err);
        if (buff == NULL) {
                ND_PRINTK1("ndisc_send_redirect: alloc_skb failed\n");
+               dst_release(dst);
                return;
        }
 
@@ -1538,7 +1319,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
                   IPPROTO_ICMPV6, len);
 
-       buff->h.raw = (unsigned char*) icmph = (struct icmp6hdr *) skb_put(buff, len);
+       icmph = (struct icmp6hdr *)skb_put(buff, len);
+       buff->h.raw = (unsigned char*)icmph;
 
        memset(icmph, 0, sizeof(struct icmp6hdr));
        icmph->icmp6_type = NDISC_REDIRECT;
@@ -1628,10 +1410,6 @@ int ndisc_rcv(struct sk_buff *skb)
                ndisc_recv_na(skb);
                break;
 
-       case NDISC_ROUTER_SOLICITATION:
-               ndisc_recv_rs(skb);
-               break;
-
        case NDISC_ROUTER_ADVERTISEMENT:
                ndisc_router_discovery(skb);
                break;
index 95181d5..792299f 100644 (file)
@@ -22,7 +22,7 @@ config IP6_NF_QUEUE
          IPv64 Project - Work based in IPv64 draft by Arturo Azcorra.
          Universidad Carlos III de Madrid
          Universidad Politecnica de Alcala de Henares
-         email: fanton@it.uc3m.es
+         email: <fanton@it.uc3m.es>.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
index 5d3d102..75f9ac7 100644 (file)
@@ -8,6 +8,10 @@
  *     Universidad Politecnica de Alcala de Henares - Alcala de H. (Madrid) - Spain
  *     email: fanton@it.uc3m.es
  *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
  * 2001-11-06: First try. Working with ip_queue.c for IPv4 and trying
  *             to adapt it to IPv6
  *             HEAVILY based in ipqueue.c by James Morris. It's just
index c39eaf0..24b0565 100644 (file)
@@ -4,6 +4,10 @@
  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
  * Copyright (C) 2000-2002 Netfilter core team <coreteam@netfilter.org>
  *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
  * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
  *     - increase module usage count as soon as we have rules inside
  *       a table
index 43c4c62..f0ed516 100644 (file)
@@ -1,6 +1,15 @@
 /*
  * This is a module which is used for logging packets.
  */
+
+/* (C) 2001 Jan Rekorajski <baggins@pld.org.pl>
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
index 3640374..ce287d2 100644 (file)
@@ -1,4 +1,12 @@
 /* This is a module which is used for setting the NFMARK field of an skb. */
+
+/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
index 978cf43..f5b9efd 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match AH parameters. */
+
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index 1032865..2d38503 100644 (file)
@@ -1,4 +1,13 @@
 /* Kernel module to match Hop-by-Hop and Destination parameters. */
+
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index b9e970a..ecdd48b 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match ESP parameters. */
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index 63cc4b7..42fda42 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match EUI64 address parameters. */
+
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index af92bce..d6eabaa 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match FRAG parameters. */
+
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index aed55d7..6849122 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match Hop-by-Hop and Destination parameters. */
+
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index c9f7939..e538f14 100644 (file)
@@ -1,9 +1,11 @@
-/*
- * Hop Limit matching module
- * Maciej Soltysiak <solt@dns.toxicfilms.tv>
+/* Hop Limit matching module */
+
+/* (C) 2001-2002 Maciej Soltysiak <solt@dns.toxicfilms.tv>
  * Based on HW's ttl module
  *
- * This software is distributed under the terms  GNU GPL
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
 
 #include <linux/module.h>
index 2dfff69..ae5d1c6 100644 (file)
@@ -1,9 +1,16 @@
 /* ipv6header match - matches IPv6 packets based
-on whether they contain certain headers */
+   on whether they contain certain headers */
 
 /* Original idea: Brad Chapman 
  * Rewritten by: Andras Kis-Szabo <kisza@sch.bme.hu> */
 
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index 4bb876f..5a86722 100644 (file)
@@ -1,5 +1,13 @@
 /* Length Match - IPv6 Port */
 
+/* (C) 1999-2001 James Morris <jmorros@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv6/ip6t_length.h>
index e94319f..4780c3a 100644 (file)
@@ -1,12 +1,18 @@
 /* Kernel module to control the rate
  *
- * Jérôme de Vivie   <devivie@info.enserb.u-bordeaux.fr>
- * Hervé Eychenne   <eychenne@info.enserb.u-bordeaux.fr>
- *
  * 2 September 1999: Changed from the target RATE to the match
  *                   `limit', removed logging.  Did I mention that
  *                   Alexey is a fucking genius?
  *                   Rusty Russell (rusty@rustcorp.com.au).  */
+
+/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
+ * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
index 5a348d4..4d184e4 100644 (file)
@@ -1,4 +1,13 @@
 /* Kernel module to match MAC address parameters. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
index 5094ab7..dc8484e 100644 (file)
@@ -1,4 +1,13 @@
 /* Kernel module to match NFMARK values. */
+
+/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
index 3373312..7250415 100644 (file)
@@ -1,5 +1,14 @@
 /* Kernel module to match one of a list of TCP/UDP ports: ports are in
    the same place so we can treat them as equal. */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/udp.h>
index cf23001..02e5ee4 100644 (file)
@@ -1,8 +1,13 @@
 /* Kernel module to match various things tied to sockets associated with
-   locally generated outgoing packets.
+   locally generated outgoing packets. */
 
-   Copyright (C) 2000,2001 Marc Boucher
+/* (C) 2000-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/file.h>
index fe49dae..f444ed9 100644 (file)
@@ -1,4 +1,12 @@
 /* Kernel module to match ROUTING parameters. */
+
+/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
index 66ac2b6..46daa79 100644 (file)
@@ -2,7 +2,13 @@
  * This is the 1999 rewrite of IP Firewalling, aiming for kernel 2.3.x.
  *
  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
  */
+
 #include <linux/module.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
 
index 3ebf2fc..0d15d5b 100644 (file)
@@ -2,6 +2,13 @@
  * IPv6 packet mangling table, a port of the IPv4 mangle table to IPv6
  *
  * Copyright (C) 2000-2001 by Harald Welte <laforge@gnumonks.org>
+ * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Extended to all five netfilter hooks by Brad Chapman & Harald Welte
  */
 #include <linux/module.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
index 78b599a..7d928fb 100644 (file)
@@ -81,7 +81,7 @@ struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
                             struct in6_addr *loc_addr, struct in6_addr *rmt_addr)
 {
        struct hlist_node *node;
-       int addr_type = ipv6_addr_type(loc_addr);
+       int is_multicast = ipv6_addr_is_multicast(loc_addr);
 
        sk_for_each_from(sk, node)
                if (inet_sk(sk)->num == num) {
@@ -94,7 +94,7 @@ struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
                        if (!ipv6_addr_any(&np->rcv_saddr)) {
                                if (!ipv6_addr_cmp(&np->rcv_saddr, loc_addr))
                                        goto found;
-                               if ((addr_type & IPV6_ADDR_MULTICAST) &&
+                               if (is_multicast &&
                                    inet6_mc_check(sk, loc_addr, rmt_addr))
                                        goto found;
                                continue;
index 224c400..c243a48 100644 (file)
@@ -563,7 +563,6 @@ static struct dst_entry *ndisc_dst_gc_list;
 
 struct dst_entry *ndisc_dst_alloc(struct net_device *dev, 
                                  struct neighbour *neigh,
-                                 struct in6_addr *addr,
                                  int (*output)(struct sk_buff *))
 {
        struct rt6_info *rt = ip6_dst_alloc();
@@ -575,13 +574,11 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
                dev_hold(dev);
        if (neigh)
                neigh_hold(neigh);
-       else
-               neigh = ndisc_get_neigh(dev, addr);
 
        rt->rt6i_dev      = dev;
        rt->rt6i_nexthop  = neigh;
        rt->rt6i_expires  = 0;
-       rt->rt6i_flags    = RTF_LOCAL;
+       rt->rt6i_flags    = RTF_LOCAL | RTF_NDISC;
        rt->rt6i_metric   = 0;
        atomic_set(&rt->u.dst.__refcnt, 1);
        rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
@@ -835,7 +832,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
                }
        }
 
-       rt->rt6i_flags = rtmsg->rtmsg_flags;
+       rt->rt6i_flags = rtmsg->rtmsg_flags & ~RTF_NDISC;
 
 install_route:
        if (rta && rta[RTA_METRICS-1]) {
index 5d77779..155740e 100644 (file)
@@ -658,7 +658,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
        /* 
         *      Multicast receive code 
         */
-       if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
+       if (ipv6_addr_is_multicast(daddr)) {
                udpv6_mcast_deliver(uh, saddr, daddr, skb);
                return 0;
        }
index ed0f252..2e231e0 100644 (file)
@@ -1351,7 +1351,7 @@ static int ipx_create(struct socket *sock, int protocol)
                rc = -ENOMEM;
                if (!sk)
                        goto out;
-               ipx = ipx_sk(sk) = kmalloc(sizeof(*ipx), GFP_KERNEL);
+               ipx = sk->sk_protinfo = kmalloc(sizeof(*ipx), GFP_KERNEL);
                if (!ipx)
                        goto outsk;
                memset(ipx, 0, sizeof(*ipx));
index 4acddaa..3b4f9c4 100644 (file)
@@ -1089,7 +1089,7 @@ static int irda_create(struct socket *sock, int protocol)
                return -ENOMEM;
 
        /* Allocate IrDA socket */
-       self = irda_sk(sk) = kmalloc(sizeof(struct irda_sock), GFP_ATOMIC);
+       self = sk->sk_protinfo = kmalloc(sizeof(struct irda_sock), GFP_ATOMIC);
        if (self == NULL) {
                sk_free(sk);
                return -ENOMEM;
@@ -1208,7 +1208,7 @@ static int irda_release(struct socket *sock)
        /* Destroy IrDA socket */
        irda_destroy_socket(irda_sk(sk));
        /* Prevent sock_def_destruct() to create havoc */
-       irda_sk(sk) = NULL;
+       sk->sk_protinfo = NULL;
 
        sock_orphan(sk);
        sock->sk   = NULL;
index 49a49d3..9f82962 100644 (file)
@@ -148,7 +148,7 @@ static int pfkey_create(struct socket *sock, int protocol)
        sk_set_owner(sk, THIS_MODULE);
 
        err = -ENOMEM;
-       pfk = pfkey_sk(sk) = kmalloc(sizeof(*pfk), GFP_KERNEL);
+       pfk = sk->sk_protinfo = kmalloc(sizeof(*pfk), GFP_KERNEL);
        if (!pfk) {
                sk_free(sk);
                goto out;
index 7b4edca..0753644 100644 (file)
@@ -826,7 +826,7 @@ int llc_sk_init(struct sock* sk)
                        * tx_win of remote LLC) */
        skb_queue_head_init(&llc->pdu_unack_q);
        sk->sk_backlog_rcv = llc_backlog_rcv;
-       llc_sk(sk) = llc;
+       sk->sk_protinfo = llc;
 out:
        return rc;
 }
index b0e410d..38c27b9 100644 (file)
@@ -230,7 +230,7 @@ static int netlink_create(struct socket *sock, int protocol)
        sock_init_data(sock,sk);
        sk_set_owner(sk, THIS_MODULE);
 
-       nlk = nlk_sk(sk) = kmalloc(sizeof(*nlk), GFP_KERNEL);
+       nlk = sk->sk_protinfo = kmalloc(sizeof(*nlk), GFP_KERNEL);
        if (!nlk) {
                sk_free(sk);
                return -ENOMEM;
index f94b3f7..eb12999 100644 (file)
@@ -72,7 +72,7 @@ static struct sock *nr_alloc_sock(void)
        if (!sk)
                goto out;
 
-       nr = nr_sk(sk) = kmalloc(sizeof(*nr), GFP_ATOMIC);
+       nr = sk->sk_protinfo = kmalloc(sizeof(*nr), GFP_ATOMIC);
        if (!nr)
                goto frees;
 
index 3b01f54..7b4a14a 100644 (file)
@@ -961,7 +961,7 @@ static int packet_create(struct socket *sock, int protocol)
        sock_init_data(sock,sk);
        sk_set_owner(sk, THIS_MODULE);
 
-       po = pkt_sk(sk) = kmalloc(sizeof(*po), GFP_KERNEL);
+       po = sk->sk_protinfo = kmalloc(sizeof(*po), GFP_KERNEL);
        if (!po)
                goto out_free;
        memset(po, 0, sizeof(*po));
index f5ec0c8..89a7ef0 100644 (file)
@@ -133,7 +133,7 @@ static struct sock *rose_alloc_sock(void)
        if (!sk)
                goto out;
 
-       rose = rose_sk(sk) = kmalloc(sizeof(*rose), GFP_ATOMIC);
+       rose = sk->sk_protinfo = kmalloc(sizeof(*rose), GFP_ATOMIC);
        if (!rose)
                goto frees;
 
index f2eeaad..076f576 100644 (file)
@@ -30,7 +30,7 @@ config NET_SCH_HTB
        ---help---
          Say Y here if you want to use the Hierarchical Token Buckets (HTB)
          packet scheduling algorithm for some of your network devices. See
-         URL http://luxik.cdi.cz/~devik/qos/htb/ for complete manual and
+         <http://luxik.cdi.cz/~devik/qos/htb/> for complete manual and
          in-depth articles.
 
          HTB is very similar to the CBQ regarding its goals however is has 
@@ -39,6 +39,16 @@ config NET_SCH_HTB
          To compile this code as a module, choose M here: the
          module will be called sch_htb.
 
+config NET_SCH_HFSC
+       tristate "HFSC packet scheduler"
+       depends on NET_SCHED
+       ---help---
+         Say Y here if you want to use the Hierarchical Fair Service Curve
+         (HFSC) packet scheduling algorithm for some of your network devices.
+
+         To compile this code as a module, choose M here: the
+         module will be called sch_hfsc.
+
 config NET_SCH_CSZ
        tristate "CSZ packet scheduler"
        depends on NET_SCHED
@@ -55,7 +65,6 @@ config NET_SCH_CSZ
          module will be called sch_csz.
 
 #tristate '  H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ
-#tristate '  H-FSC packet scheduler' CONFIG_NET_SCH_HFCS
 config NET_SCH_ATM
        tristate "ATM pseudo-scheduler"
        depends on NET_SCHED && ATM
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
new file mode 100644 (file)
index 0000000..d6e22a4
--- /dev/null
@@ -0,0 +1,1864 @@
+/*
+ * Copyright (c) 2003 Patrick McHardy, <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 2003-10-17 - Ported from altq
+ */
+/*
+ * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation is hereby granted (including for commercial or
+ * for-profit use), provided that both the copyright notice and this
+ * permission notice appear in all copies of the software, derivative
+ * works, or modified versions, and any portions thereof.
+ *
+ * THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF
+ * WHICH MAY HAVE SERIOUS CONSEQUENCES.  CARNEGIE MELLON PROVIDES THIS
+ * SOFTWARE IN ITS ``AS IS'' CONDITION, 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 CARNEGIE MELLON UNIVERSITY 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.
+ *
+ * Carnegie Mellon encourages (but does not require) users of this
+ * software to return any improvements or extensions that they make,
+ * and to grant Carnegie Mellon the rights to redistribute these
+ * changes without encumbrance.
+ */
+/*
+ * H-FSC is described in Proceedings of SIGCOMM'97,
+ * "A Hierarchical Fair Service Curve Algorithm for Link-Sharing,
+ * Real-Time and Priority Service"
+ * by Ion Stoica, Hui Zhang, and T. S. Eugene Ng.
+ *
+ * Oleg Cherevko <olwi@aq.ml.com.ua> added the upperlimit for link-sharing.
+ * when a class has an upperlimit, the fit-time is computed from the
+ * upperlimit service curve.  the link-sharing scheduler does not schedule
+ * a class whose fit-time exceeds the current time.
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/jiffies.h>
+#include <linux/compiler.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/pkt_sched.h>
+#include <net/pkt_sched.h>
+#include <net/pkt_cls.h>
+#include <asm/system.h>
+#include <asm/div64.h>
+
+#define HFSC_DEBUG 1
+
+/*
+ * kernel internal service curve representation:
+ *   coordinates are given by 64 bit unsigned integers.
+ *   x-axis: unit is clock count.
+ *   y-axis: unit is byte.
+ *
+ *   The service curve parameters are converted to the internal
+ *   representation. The slope values are scaled to avoid overflow.
+ *   the inverse slope values as well as the y-projection of the 1st
+ *   segment are kept in order to to avoid 64-bit divide operations
+ *   that are expensive on 32-bit architectures.
+ */
+
+struct internal_sc
+{
+       u64     sm1;    /* scaled slope of the 1st segment */
+       u64     ism1;   /* scaled inverse-slope of the 1st segment */
+       u64     dx;     /* the x-projection of the 1st segment */
+       u64     dy;     /* the y-projection of the 1st segment */
+       u64     sm2;    /* scaled slope of the 2nd segment */
+       u64     ism2;   /* scaled inverse-slope of the 2nd segment */
+};
+
+/* runtime service curve */
+struct runtime_sc
+{
+       u64     x;      /* current starting position on x-axis */
+       u64     y;      /* current starting position on y-axis */
+       u64     sm1;    /* scaled slope of the 1st segment */
+       u64     ism1;   /* scaled inverse-slope of the 1st segment */
+       u64     dx;     /* the x-projection of the 1st segment */
+       u64     dy;     /* the y-projection of the 1st segment */
+       u64     sm2;    /* scaled slope of the 2nd segment */
+       u64     ism2;   /* scaled inverse-slope of the 2nd segment */
+};
+
+enum hfsc_class_flags
+{
+       HFSC_RSC = 0x1,
+       HFSC_FSC = 0x2,
+       HFSC_USC = 0x4
+};
+
+struct hfsc_class
+{
+       u32     classid;        /* class id */
+       unsigned int    refcnt;         /* usage count */
+
+       struct tc_stats stats;          /* generic statistics */
+       unsigned int    level;          /* class level in hierarchy */
+       struct tcf_proto *filter_list;  /* filter list */
+       unsigned int    filter_cnt;     /* filter count */
+
+       struct hfsc_sched *sched;       /* scheduler data */
+       struct hfsc_class *cl_parent;   /* parent class */
+       struct list_head siblings;      /* sibling classes */
+       struct list_head children;      /* child classes */
+       struct Qdisc    *qdisc;         /* leaf qdisc */
+
+       struct list_head actlist;       /* active children list */
+       struct list_head alist;         /* active children list member */
+       struct list_head ellist;        /* eligible list member */
+       struct list_head hlist;         /* hash list member */
+       struct list_head dlist;         /* drop list member */
+
+       u64     cl_total;       /* total work in bytes */
+       u64     cl_cumul;       /* cumulative work in bytes done by
+                                          real-time criteria */
+
+       u64     cl_d;           /* deadline*/
+       u64     cl_e;           /* eligible time */
+       u64     cl_vt;          /* virtual time */
+       u64     cl_f;           /* time when this class will fit for
+                                          link-sharing, max(myf, cfmin) */
+       u64     cl_myf;         /* my fit-time (calculated from this
+                                          class's own upperlimit curve) */
+       u64     cl_myfadj;      /* my fit-time adjustment (to cancel
+                                          history dependence) */
+       u64     cl_cfmin;       /* earliest children's fit-time (used
+                                          with cl_myf to obtain cl_f) */
+       u64     cl_cvtmin;      /* minimal virtual time among the
+                                          children fit for link-sharing
+                                          (monotonic within a period) */
+       u64     cl_vtadj;       /* intra-period cumulative vt
+                                          adjustment */
+       u64     cl_vtoff;       /* inter-period cumulative vt offset */
+       u64     cl_cvtmax;      /* max child's vt in the last period */
+
+       struct internal_sc cl_rsc;      /* internal real-time service curve */
+       struct internal_sc cl_fsc;      /* internal fair service curve */
+       struct internal_sc cl_usc;      /* internal upperlimit service curve */
+       struct runtime_sc cl_deadline;  /* deadline curve */
+       struct runtime_sc cl_eligible;  /* eligible curve */
+       struct runtime_sc cl_virtual;   /* virtual curve */
+       struct runtime_sc cl_ulimit;    /* upperlimit curve */
+
+       unsigned long   cl_flags;       /* which curves are valid */
+       unsigned long   cl_vtperiod;    /* vt period sequence number */
+       unsigned long   cl_parentperiod;/* parent's vt period sequence number*/
+       unsigned long   cl_nactive;     /* number of active children */
+};
+
+#define HFSC_HSIZE     16
+
+struct hfsc_sched
+{
+       u16     defcls;                 /* default class id */
+
+       struct hfsc_class root;                 /* root class */
+       struct hfsc_class *last_xmit;           /* class that transmitted last
+                                                  packet (for requeueing) */
+       struct list_head clhash[HFSC_HSIZE];    /* class hash */
+       struct list_head eligible;              /* eligible list */
+       struct list_head droplist;              /* active leaf class list (for
+                                                  dropping) */
+       struct timer_list wd_timer;             /* watchdog timer */
+};
+
+/*
+ * macros
+ */
+#if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
+#include <linux/time.h>
+#undef PSCHED_GET_TIME
+#define PSCHED_GET_TIME(stamp)                                         \
+do {                                                                   \
+       struct timeval tv;                                              \
+       do_gettimeofday(&tv);                                           \
+       (stamp) = 1000000ULL * tv.tv_sec + tv.tv_usec;                  \
+} while (0)
+#endif
+
+#if HFSC_DEBUG
+#define ASSERT(cond)                                                   \
+do {                                                                   \
+       if (unlikely(!(cond)))                                          \
+               printk("assertion %s failed at %s:%i (%s)\n",           \
+                      #cond, __FILE__, __LINE__, __FUNCTION__);        \
+} while (0)
+#else
+#define ASSERT(cond)
+#endif /* HFSC_DEBUG */
+
+#define        HT_INFINITY     0xffffffffffffffffULL   /* infinite time value */
+
+
+/*
+ * eligible list holds backlogged classes being sorted by their eligible times.
+ * there is one eligible list per hfsc instance.
+ */
+
+static void
+ellist_insert(struct hfsc_class *cl)
+{
+       struct list_head *head = &cl->sched->eligible;
+       struct hfsc_class *p;
+
+       /* check the last entry first */
+       if (list_empty(head) ||
+           ((p = list_entry(head->prev, struct hfsc_class, ellist)) &&
+            p->cl_e <= cl->cl_e)) {
+               list_add_tail(&cl->ellist, head);
+               return;
+       }
+
+       list_for_each_entry(p, head, ellist) {
+               if (cl->cl_e < p->cl_e) {
+                       /* insert cl before p */
+                       list_add_tail(&cl->ellist, &p->ellist);
+                       return;
+               }
+       }
+       ASSERT(0); /* should not reach here */
+}
+
+static inline void
+ellist_remove(struct hfsc_class *cl)
+{
+       list_del(&cl->ellist);
+}
+
+static void
+ellist_update(struct hfsc_class *cl)
+{
+       struct list_head *head = &cl->sched->eligible;
+       struct hfsc_class *p, *last;
+
+       /*
+        * the eligible time of a class increases monotonically.
+        * if the next entry has a larger eligible time, nothing to do.
+        */
+       if (cl->ellist.next == head ||
+           ((p = list_entry(cl->ellist.next, struct hfsc_class, ellist)) &&
+            cl->cl_e <= p->cl_e))
+               return;
+
+       /* check the last entry */
+       last = list_entry(head->prev, struct hfsc_class, ellist);
+       if (last->cl_e <= cl->cl_e) {
+               list_move_tail(&cl->ellist, head);
+               return;
+       }
+
+       /*
+        * the new position must be between the next entry
+        * and the last entry
+        */
+       list_for_each_entry_continue(p, head, ellist) {
+               if (cl->cl_e < p->cl_e) {
+                       list_move_tail(&cl->ellist, &p->ellist);
+                       return;
+               }
+       }
+       ASSERT(0); /* should not reach here */
+}
+
+/* find the class with the minimum deadline among the eligible classes */
+static inline struct hfsc_class *
+ellist_get_mindl(struct list_head *head, u64 cur_time)
+{
+       struct hfsc_class *p, *cl = NULL;
+
+       list_for_each_entry(p, head, ellist) {
+               if (p->cl_e > cur_time)
+                       break;
+               if (cl == NULL || p->cl_d < cl->cl_d)
+                       cl = p;
+       }
+       return cl;
+}
+
+/* find the class with minimum eligible time among the eligible classes */
+static inline struct hfsc_class *
+ellist_get_minel(struct list_head *head)
+{
+       if (list_empty(head))
+               return NULL;
+       return list_entry(head->next, struct hfsc_class, ellist);
+}
+
+/*
+ * active children list holds backlogged child classes being sorted
+ * by their virtual time. each intermediate class has one active
+ * children list.
+ */
+static void
+actlist_insert(struct hfsc_class *cl)
+{
+       struct list_head *head = &cl->cl_parent->actlist;
+       struct hfsc_class *p;
+
+       /* check the last entry first */
+       if (list_empty(head) ||
+           ((p = list_entry(head->prev, struct hfsc_class, alist)) &&
+            p->cl_vt <= cl->cl_vt)) {
+               list_add_tail(&cl->alist, head);
+               return;
+       }
+
+       list_for_each_entry(p, head, alist) {
+               if (cl->cl_vt < p->cl_vt) {
+                       /* insert cl before p */
+                       list_add_tail(&cl->alist, &p->alist);
+                       return;
+               }
+       }
+       ASSERT(0); /* should not reach here */
+}
+
+static inline void
+actlist_remove(struct hfsc_class *cl)
+{
+       list_del(&cl->alist);
+}
+
+static void
+actlist_update(struct hfsc_class *cl)
+{
+       struct list_head *head = &cl->cl_parent->actlist;
+       struct hfsc_class *p, *last;
+
+       /*
+        * the virtual time of a class increases monotonically.
+        * if the next entry has a larger virtual time, nothing to do.
+        */
+       if (cl->alist.next == head ||
+           ((p = list_entry(cl->alist.next, struct hfsc_class, alist)) &&
+            cl->cl_vt <= p->cl_vt))
+               return;
+
+       /* check the last entry */
+       last = list_entry(head->prev, struct hfsc_class, alist);
+       if (last->cl_vt <= cl->cl_vt) {
+               list_move_tail(&cl->alist, head);
+               return;
+       }
+
+       /*
+        * the new position must be between the next entry
+        * and the last entry
+        */
+       list_for_each_entry_continue(p, head, alist) {
+               if (cl->cl_vt < p->cl_vt) {
+                       list_move_tail(&cl->alist, &p->alist);
+                       return;
+               }
+       }
+       ASSERT(0); /* should not reach here */
+}
+
+static inline struct hfsc_class *
+actlist_firstfit(struct hfsc_class *cl, u64 cur_time)
+{
+       struct hfsc_class *p;
+
+       list_for_each_entry(p, &cl->actlist, alist) {
+               if (p->cl_f <= cur_time) {
+                       return p;
+               }
+       }
+       return NULL;
+}
+
+/*
+ * get the leaf class with the minimum vt in the hierarchy
+ */
+static struct hfsc_class *
+actlist_get_minvt(struct hfsc_class *cl, u64 cur_time)
+{
+       /* if root-class's cfmin is bigger than cur_time nothing to do */
+       if (cl->cl_cfmin > cur_time)
+               return NULL;
+
+       while (cl->level > 0) {
+               cl = actlist_firstfit(cl, cur_time);
+               if (cl == NULL)
+                       return NULL;
+               /*
+                * update parent's cl_cvtmin.
+                */
+               if (cl->cl_parent->cl_cvtmin < cl->cl_vt)
+                       cl->cl_parent->cl_cvtmin = cl->cl_vt;
+       }
+       return cl;
+}
+
+/*
+ * service curve support functions
+ *
+ *  external service curve parameters
+ *     m: bps
+ *     d: us
+ *  internal service curve parameters
+ *     sm: (bytes/psched_us) << SM_SHIFT
+ *     ism: (psched_us/byte) << ISM_SHIFT
+ *     dx: psched_us
+ *
+ * Time source resolution
+ *  PSCHED_JIFFIES: for 48<=HZ<=1534 resolution is between 0.63us and 1.27us.
+ *  PSCHED_CPU: resolution is between 0.5us and 1us.
+ *  PSCHED_GETTIMEOFDAY: resolution is exactly 1us.
+ *
+ * sm and ism are scaled in order to keep effective digits.
+ * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective
+ * digits in decimal using the following table.
+ *
+ * Note: We can afford the additional accuracy (altq hfsc keeps at most
+ * 3 effective digits) thanks to the fact that linux clock is bounded
+ * much more tightly.
+ *
+ *  bits/sec      100Kbps     1Mbps     10Mbps     100Mbps    1Gbps
+ *  ------------+-------------------------------------------------------
+ *  bytes/0.5us   6.25e-3    62.5e-3    625e-3     6250e-e    62500e-3
+ *  bytes/us      12.5e-3    125e-3     1250e-3    12500e-3   125000e-3
+ *  bytes/1.27us  15.875e-3  158.75e-3  1587.5e-3  15875e-3   158750e-3
+ *
+ *  0.5us/byte    160        16         1.6        0.16       0.016
+ *  us/byte       80         8          0.8        0.08       0.008
+ *  1.27us/byte   63         6.3        0.63       0.063      0.0063
+ */
+#define        SM_SHIFT        20
+#define        ISM_SHIFT       18
+
+#define        SM_MASK         ((1ULL << SM_SHIFT) - 1)
+#define        ISM_MASK        ((1ULL << ISM_SHIFT) - 1)
+
+static inline u64
+seg_x2y(u64 x, u64 sm)
+{
+       u64 y;
+
+       /*
+        * compute
+        *      y = x * sm >> SM_SHIFT
+        * but divide it for the upper and lower bits to avoid overflow
+        */
+       y = (x >> SM_SHIFT) * sm + (((x & SM_MASK) * sm) >> SM_SHIFT);
+       return y;
+}
+
+static inline u64
+seg_y2x(u64 y, u64 ism)
+{
+       u64 x;
+
+       if (y == 0)
+               x = 0;
+       else if (ism == HT_INFINITY)
+               x = HT_INFINITY;
+       else {
+               x = (y >> ISM_SHIFT) * ism
+                   + (((y & ISM_MASK) * ism) >> ISM_SHIFT);
+       }
+       return x;
+}
+
+/* Convert m (bps) into sm (bytes/psched us) */
+static u64
+m2sm(u32 m)
+{
+       u64 sm;
+
+       sm = ((u64)m << SM_SHIFT);
+       sm += PSCHED_JIFFIE2US(HZ) - 1;
+       do_div(sm, PSCHED_JIFFIE2US(HZ));
+       return sm;
+}
+
+/* convert m (bps) into ism (psched us/byte) */
+static u64
+m2ism(u32 m)
+{
+       u64 ism;
+
+       if (m == 0)
+               ism = HT_INFINITY;
+       else {
+               ism = ((u64)PSCHED_JIFFIE2US(HZ) << ISM_SHIFT);
+               ism += m - 1;
+               do_div(ism, m);
+       }
+       return ism;
+}
+
+/* convert d (us) into dx (psched us) */
+static u64
+d2dx(u32 d)
+{
+       u64 dx;
+
+       dx = ((u64)d * PSCHED_JIFFIE2US(HZ));
+       dx += 1000000 - 1;
+       do_div(dx, 1000000);
+       return dx;
+}
+
+/* convert sm (bytes/psched us) into m (bps) */
+static u32
+sm2m(u64 sm)
+{
+       u64 m;
+
+       m = (sm * PSCHED_JIFFIE2US(HZ)) >> SM_SHIFT;
+       return (u32)m;
+}
+
+/* convert dx (psched us) into d (us) */
+static u32
+dx2d(u64 dx)
+{
+       u64 d;
+
+       d = dx * 1000000;
+       do_div(d, PSCHED_JIFFIE2US(HZ));
+       return (u32)d;
+}
+
+static void
+sc2isc(struct tc_service_curve *sc, struct internal_sc *isc)
+{
+       isc->sm1  = m2sm(sc->m1);
+       isc->ism1 = m2ism(sc->m1);
+       isc->dx   = d2dx(sc->d);
+       isc->dy   = seg_x2y(isc->dx, isc->sm1);
+       isc->sm2  = m2sm(sc->m2);
+       isc->ism2 = m2ism(sc->m2);
+}
+
+/*
+ * initialize the runtime service curve with the given internal
+ * service curve starting at (x, y).
+ */
+static void
+rtsc_init(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x,
+                                                            u64 y)
+{
+       rtsc->x    = x;
+       rtsc->y    = y;
+       rtsc->sm1  = isc->sm1;
+       rtsc->ism1 = isc->ism1;
+       rtsc->dx   = isc->dx;
+       rtsc->dy   = isc->dy;
+       rtsc->sm2  = isc->sm2;
+       rtsc->ism2 = isc->ism2;
+}
+
+/*
+ * calculate the y-projection of the runtime service curve by the
+ * given x-projection value
+ */
+static u64
+rtsc_y2x(struct runtime_sc *rtsc, u64 y)
+{
+       u64 x;
+
+       if (y < rtsc->y)
+               x = rtsc->x;
+       else if (y <= rtsc->y + rtsc->dy) {
+               /* x belongs to the 1st segment */
+               if (rtsc->dy == 0)
+                       x = rtsc->x + rtsc->dx;
+               else
+                       x = rtsc->x + seg_y2x(y - rtsc->y, rtsc->ism1);
+       } else {
+               /* x belongs to the 2nd segment */
+               x = rtsc->x + rtsc->dx
+                   + seg_y2x(y - rtsc->y - rtsc->dy, rtsc->ism2);
+       }
+       return x;
+}
+
+static u64
+rtsc_x2y(struct runtime_sc *rtsc, u64 x)
+{
+       u64 y;
+
+       if (x <= rtsc->x)
+               y = rtsc->y;
+       else if (x <= rtsc->x + rtsc->dx)
+               /* y belongs to the 1st segment */
+               y = rtsc->y + seg_x2y(x - rtsc->x, rtsc->sm1);
+       else
+               /* y belongs to the 2nd segment */
+               y = rtsc->y + rtsc->dy
+                   + seg_x2y(x - rtsc->x - rtsc->dx, rtsc->sm2);
+       return y;
+}
+
+/*
+ * update the runtime service curve by taking the minimum of the current
+ * runtime service curve and the service curve starting at (x, y).
+ */
+static void
+rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x,
+                                                           u64 y)
+{
+       u64 y1, y2, dx, dy;
+       u32 dsm;
+
+       if (isc->sm1 <= isc->sm2) {
+               /* service curve is convex */
+               y1 = rtsc_x2y(rtsc, x);
+               if (y1 < y)
+                       /* the current rtsc is smaller */
+                       return;
+               rtsc->x = x;
+               rtsc->y = y;
+               return;
+       }
+
+       /*
+        * service curve is concave
+        * compute the two y values of the current rtsc
+        *      y1: at x
+        *      y2: at (x + dx)
+        */
+       y1 = rtsc_x2y(rtsc, x);
+       if (y1 <= y) {
+               /* rtsc is below isc, no change to rtsc */
+               return;
+       }
+
+       y2 = rtsc_x2y(rtsc, x + isc->dx);
+       if (y2 >= y + isc->dy) {
+               /* rtsc is above isc, replace rtsc by isc */
+               rtsc->x = x;
+               rtsc->y = y;
+               rtsc->dx = isc->dx;
+               rtsc->dy = isc->dy;
+               return;
+       }
+
+       /*
+        * the two curves intersect
+        * compute the offsets (dx, dy) using the reverse
+        * function of seg_x2y()
+        *      seg_x2y(dx, sm1) == seg_x2y(dx, sm2) + (y1 - y)
+        */
+       dx = (y1 - y) << SM_SHIFT;
+       dsm = isc->sm1 - isc->sm2;
+       do_div(dx, dsm);
+       /*
+        * check if (x, y1) belongs to the 1st segment of rtsc.
+        * if so, add the offset.
+        */
+       if (rtsc->x + rtsc->dx > x)
+               dx += rtsc->x + rtsc->dx - x;
+       dy = seg_x2y(dx, isc->sm1);
+
+       rtsc->x = x;
+       rtsc->y = y;
+       rtsc->dx = dx;
+       rtsc->dy = dy;
+       return;
+}
+
+static void
+init_ed(struct hfsc_class *cl, unsigned int next_len)
+{
+       u64 cur_time;
+
+       PSCHED_GET_TIME(cur_time);
+
+       /* update the deadline curve */
+       rtsc_min(&cl->cl_deadline, &cl->cl_rsc, cur_time, cl->cl_cumul);
+
+       /*
+        * update the eligible curve.
+        * for concave, it is equal to the deadline curve.
+        * for convex, it is a linear curve with slope m2.
+        */
+       cl->cl_eligible = cl->cl_deadline;
+       if (cl->cl_rsc.sm1 <= cl->cl_rsc.sm2) {
+               cl->cl_eligible.dx = 0;
+               cl->cl_eligible.dy = 0;
+       }
+
+       /* compute e and d */
+       cl->cl_e = rtsc_y2x(&cl->cl_eligible, cl->cl_cumul);
+       cl->cl_d = rtsc_y2x(&cl->cl_deadline, cl->cl_cumul + next_len);
+
+       ellist_insert(cl);
+}
+
+static void
+update_ed(struct hfsc_class *cl, unsigned int next_len)
+{
+       cl->cl_e = rtsc_y2x(&cl->cl_eligible, cl->cl_cumul);
+       cl->cl_d = rtsc_y2x(&cl->cl_deadline, cl->cl_cumul + next_len);
+
+       ellist_update(cl);
+}
+
+static inline void
+update_d(struct hfsc_class *cl, unsigned int next_len)
+{
+       cl->cl_d = rtsc_y2x(&cl->cl_deadline, cl->cl_cumul + next_len);
+}
+
+static void
+update_cfmin(struct hfsc_class *cl)
+{
+       struct hfsc_class *p;
+       u64 cfmin;
+
+       if (list_empty(&cl->actlist)) {
+               cl->cl_cfmin = 0;
+               return;
+       }
+       cfmin = HT_INFINITY;
+       list_for_each_entry(p, &cl->actlist, alist) {
+               if (p->cl_f == 0) {
+                       cl->cl_cfmin = 0;
+                       return;
+               }
+               if (p->cl_f < cfmin)
+                       cfmin = p->cl_f;
+       }
+       cl->cl_cfmin = cfmin;
+}
+
+static void
+init_vf(struct hfsc_class *cl, unsigned int len)
+{
+       struct hfsc_class *max_cl, *p;
+       u64 vt, f, cur_time;
+       int go_active;
+
+       cur_time = 0;
+       go_active = 1;
+       for (; cl->cl_parent != NULL; cl = cl->cl_parent) {
+               if (go_active && cl->cl_nactive++ == 0)
+                       go_active = 1;
+               else
+                       go_active = 0;
+
+               if (go_active) {
+                       if (!list_empty(&cl->cl_parent->actlist)) {
+                               max_cl = list_entry(cl->cl_parent->actlist.prev,
+                                                   struct hfsc_class, alist);
+                               /*
+                                * set vt to the average of the min and max
+                                * classes.  if the parent's period didn't
+                                * change, don't decrease vt of the class.
+                                */
+                               vt = max_cl->cl_vt;
+                               if (cl->cl_parent->cl_cvtmin != 0)
+                                       vt = (cl->cl_parent->cl_cvtmin + vt)/2;
+
+                               if (cl->cl_parent->cl_vtperiod !=
+                                   cl->cl_parentperiod || vt > cl->cl_vt)
+                                       cl->cl_vt = vt;
+                       } else {
+                               /*
+                                * first child for a new parent backlog period.
+                                * add parent's cvtmax to vtoff of children
+                                * to make a new vt (vtoff + vt) larger than
+                                * the vt in the last period for all children.
+                                */
+                               vt = cl->cl_parent->cl_cvtmax;
+                               list_for_each_entry(p, &cl->cl_parent->children,
+                                                                      siblings)
+                                       p->cl_vtoff += vt;
+                               cl->cl_vt = 0;
+                               cl->cl_parent->cl_cvtmax = 0;
+                               cl->cl_parent->cl_cvtmin = 0;
+                       }
+
+                       /* update the virtual curve */
+                       vt = cl->cl_vt + cl->cl_vtoff;
+                       rtsc_min(&cl->cl_virtual, &cl->cl_fsc, vt,
+                                                     cl->cl_total);
+                       if (cl->cl_virtual.x == vt) {
+                               cl->cl_virtual.x -= cl->cl_vtoff;
+                               cl->cl_vtoff = 0;
+                       }
+                       cl->cl_vtadj = 0;
+
+                       cl->cl_vtperiod++;  /* increment vt period */
+                       cl->cl_parentperiod = cl->cl_parent->cl_vtperiod;
+                       if (cl->cl_parent->cl_nactive == 0)
+                               cl->cl_parentperiod++;
+                       cl->cl_f = 0;
+
+                       actlist_insert(cl);
+
+                       if (cl->cl_flags & HFSC_USC) {
+                               /* class has upper limit curve */
+                               if (cur_time == 0)
+                                       PSCHED_GET_TIME(cur_time);
+
+                               /* update the ulimit curve */
+                               rtsc_min(&cl->cl_ulimit, &cl->cl_usc, cur_time,
+                                        cl->cl_total);
+                               /* compute myf */
+                               cl->cl_myf = rtsc_y2x(&cl->cl_ulimit,
+                                                     cl->cl_total);
+                               cl->cl_myfadj = 0;
+                       }
+               }
+
+               f = max(cl->cl_myf, cl->cl_cfmin);
+               if (f != cl->cl_f) {
+                       cl->cl_f = f;
+                       update_cfmin(cl->cl_parent);
+               }
+       }
+}
+
+static void
+update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time)
+{
+       u64 f; /* , myf_bound, delta; */
+       int go_passive = 0;
+
+       if (cl->qdisc->q.qlen == 0 && cl->cl_flags & HFSC_FSC)
+               go_passive = 1;
+
+       for (; cl->cl_parent != NULL; cl = cl->cl_parent) {
+               cl->cl_total += len;
+
+               if (!(cl->cl_flags & HFSC_FSC) || cl->cl_nactive == 0)
+                       continue;
+
+               if (go_passive && --cl->cl_nactive == 0)
+                       go_passive = 1;
+               else
+                       go_passive = 0;
+
+               if (go_passive) {
+                       /* no more active child, going passive */
+
+                       /* update cvtmax of the parent class */
+                       if (cl->cl_vt > cl->cl_parent->cl_cvtmax)
+                               cl->cl_parent->cl_cvtmax = cl->cl_vt;
+
+                       /* remove this class from the vt list */
+                       actlist_remove(cl);
+
+                       update_cfmin(cl->cl_parent);
+
+                       continue;
+               }
+
+               /*
+                * update vt and f
+                */
+               cl->cl_vt = rtsc_y2x(&cl->cl_virtual, cl->cl_total)
+                           - cl->cl_vtoff + cl->cl_vtadj;
+
+               /*
+                * if vt of the class is smaller than cvtmin,
+                * the class was skipped in the past due to non-fit.
+                * if so, we need to adjust vtadj.
+                */
+               if (cl->cl_vt < cl->cl_parent->cl_cvtmin) {
+                       cl->cl_vtadj += cl->cl_parent->cl_cvtmin - cl->cl_vt;
+                       cl->cl_vt = cl->cl_parent->cl_cvtmin;
+               }
+
+               /* update the vt list */
+               actlist_update(cl);
+
+               if (cl->cl_flags & HFSC_USC) {
+                       cl->cl_myf = cl->cl_myfadj + rtsc_y2x(&cl->cl_ulimit,
+                                                             cl->cl_total);
+#if 0
+                       /*
+                        * This code causes classes to stay way under their
+                        * limit when multiple classes are used at gigabit
+                        * speed. needs investigation. -kaber
+                        */
+                       /*
+                        * if myf lags behind by more than one clock tick
+                        * from the current time, adjust myfadj to prevent
+                        * a rate-limited class from going greedy.
+                        * in a steady state under rate-limiting, myf
+                        * fluctuates within one clock tick.
+                        */
+                       myf_bound = cur_time - PSCHED_JIFFIE2US(1);
+                       if (cl->cl_myf < myf_bound) {
+                               delta = cur_time - cl->cl_myf;
+                               cl->cl_myfadj += delta;
+                               cl->cl_myf += delta;
+                       }
+#endif
+               }
+
+               f = max(cl->cl_myf, cl->cl_cfmin);
+               if (f != cl->cl_f) {
+                       cl->cl_f = f;
+                       update_cfmin(cl->cl_parent);
+               }
+       }
+}
+
+static void
+set_active(struct hfsc_class *cl, unsigned int len)
+{
+       if (cl->cl_flags & HFSC_RSC)
+               init_ed(cl, len);
+       if (cl->cl_flags & HFSC_FSC)
+               init_vf(cl, len);
+
+       list_add_tail(&cl->dlist, &cl->sched->droplist);
+}
+
+static void
+set_passive(struct hfsc_class *cl)
+{
+       if (cl->cl_flags & HFSC_RSC)
+               ellist_remove(cl);
+
+       list_del(&cl->dlist);
+
+       /*
+        * actlist is now handled in update_vf() so that update_vf(cl, 0, 0)
+        * needs to be called explicitly to remove a class from actlist
+        */
+}
+
+/*
+ * hack to get length of first packet in queue.
+ */
+static unsigned int
+qdisc_peek_len(struct Qdisc *sch)
+{
+       struct sk_buff *skb;
+       unsigned int len;
+
+       skb = sch->dequeue(sch);
+       if (skb == NULL) {
+               if (net_ratelimit())
+                       printk("qdisc_peek_len: non work-conserving qdisc ?\n");
+               return 0;
+       }
+       len = skb->len;
+       if (unlikely(sch->ops->requeue(skb, sch) != NET_XMIT_SUCCESS)) {
+               if (net_ratelimit())
+                       printk("qdisc_peek_len: failed to requeue\n");
+               return 0;
+       }
+       return len;
+}
+
+static void
+hfsc_purge_queue(struct Qdisc *sch, struct hfsc_class *cl)
+{
+       unsigned int len = cl->qdisc->q.qlen;
+
+       qdisc_reset(cl->qdisc);
+       if (len > 0) {
+               update_vf(cl, 0, 0);
+               set_passive(cl);
+               sch->q.qlen -= len;
+       }
+}
+
+static void
+hfsc_adjust_levels(struct hfsc_class *cl)
+{
+       struct hfsc_class *p;
+       unsigned int level;
+
+       do {
+               level = 0;
+               list_for_each_entry(p, &cl->children, siblings) {
+                       if (p->level > level)
+                               level = p->level;
+               }
+               cl->level = level + 1;
+       } while ((cl = cl->cl_parent) != NULL);
+}
+
+static inline unsigned int
+hfsc_hash(u32 h)
+{
+       h ^= h >> 8;
+       h ^= h >> 4;
+
+       return h & (HFSC_HSIZE - 1);
+}
+
+static inline struct hfsc_class *
+hfsc_find_class(u32 classid, struct Qdisc *sch)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl;
+
+       list_for_each_entry(cl, &q->clhash[hfsc_hash(classid)], hlist) {
+               if (cl->classid == classid)
+                       return cl;
+       }
+       return NULL;
+}
+
+static void
+hfsc_change_rsc(struct hfsc_class *cl, struct tc_service_curve *rsc,
+                u64 cur_time)
+{
+       sc2isc(rsc, &cl->cl_rsc);
+       rtsc_init(&cl->cl_deadline, &cl->cl_rsc, cur_time, cl->cl_cumul);
+       cl->cl_eligible = cl->cl_deadline;
+       if (cl->cl_rsc.sm1 <= cl->cl_rsc.sm2) {
+               cl->cl_eligible.dx = 0;
+               cl->cl_eligible.dy = 0;
+       }
+       cl->cl_flags |= HFSC_RSC;
+}
+
+static void
+hfsc_change_fsc(struct hfsc_class *cl, struct tc_service_curve *fsc)
+{
+       sc2isc(fsc, &cl->cl_fsc);
+       rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total);
+       cl->cl_flags |= HFSC_FSC;
+}
+
+static void
+hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc,
+                u64 cur_time)
+{
+       sc2isc(usc, &cl->cl_usc);
+       rtsc_init(&cl->cl_ulimit, &cl->cl_usc, cur_time, cl->cl_total);
+       cl->cl_flags |= HFSC_USC;
+}
+
+static int
+hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+                  struct rtattr **tca, unsigned long *arg)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl = (struct hfsc_class *)*arg;
+       struct hfsc_class *parent = NULL;
+       struct rtattr *opt = tca[TCA_OPTIONS-1];
+       struct rtattr *tb[TCA_HFSC_MAX];
+       struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL;
+       u64 cur_time;
+
+       if (opt == NULL ||
+           rtattr_parse(tb, TCA_HFSC_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)))
+               return -EINVAL;
+
+       if (tb[TCA_HFSC_RSC-1]) {
+               if (RTA_PAYLOAD(tb[TCA_HFSC_RSC-1]) < sizeof(*rsc))
+                       return -EINVAL;
+               rsc = RTA_DATA(tb[TCA_HFSC_RSC-1]);
+               if (rsc->m1 == 0 && rsc->m2 == 0)
+                       rsc = NULL;
+       }
+
+       if (tb[TCA_HFSC_FSC-1]) {
+               if (RTA_PAYLOAD(tb[TCA_HFSC_FSC-1]) < sizeof(*fsc))
+                       return -EINVAL;
+               fsc = RTA_DATA(tb[TCA_HFSC_FSC-1]);
+               if (fsc->m1 == 0 && fsc->m2 == 0)
+                       fsc = NULL;
+       }
+
+       if (tb[TCA_HFSC_USC-1]) {
+               if (RTA_PAYLOAD(tb[TCA_HFSC_USC-1]) < sizeof(*usc))
+                       return -EINVAL;
+               usc = RTA_DATA(tb[TCA_HFSC_USC-1]);
+               if (usc->m1 == 0 && usc->m2 == 0)
+                       usc = NULL;
+       }
+
+       if (cl != NULL) {
+               if (parentid) {
+                       if (cl->cl_parent && cl->cl_parent->classid != parentid)
+                               return -EINVAL;
+                       if (cl->cl_parent == NULL && parentid != TC_H_ROOT)
+                               return -EINVAL;
+               }
+               PSCHED_GET_TIME(cur_time);
+
+               sch_tree_lock(sch);
+               if (rsc != NULL)
+                       hfsc_change_rsc(cl, rsc, cur_time);
+               if (fsc != NULL)
+                       hfsc_change_fsc(cl, fsc);
+               if (usc != NULL)
+                       hfsc_change_usc(cl, usc, cur_time);
+
+               if (cl->qdisc->q.qlen != 0) {
+                       if (cl->cl_flags & HFSC_RSC)
+                               update_ed(cl, qdisc_peek_len(cl->qdisc));
+                       if (cl->cl_flags & HFSC_FSC)
+                               update_vf(cl, 0, cur_time);
+               }
+               sch_tree_unlock(sch);
+
+#ifdef CONFIG_NET_ESTIMATOR
+               if (tca[TCA_RATE-1]) {
+                       qdisc_kill_estimator(&cl->stats);
+                       qdisc_new_estimator(&cl->stats, tca[TCA_RATE-1]);
+               }
+#endif
+               return 0;
+       }
+
+       if (parentid == TC_H_ROOT)
+               return -EEXIST;
+
+       parent = &q->root;
+       if (parentid) {
+               parent = hfsc_find_class(parentid, sch);
+               if (parent == NULL)
+                       return -ENOENT;
+       }
+
+       if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0)
+               return -EINVAL;
+       if (hfsc_find_class(classid, sch))
+               return -EEXIST;
+
+       if (rsc == NULL && fsc == NULL)
+               return -EINVAL;
+
+       cl = kmalloc(sizeof(struct hfsc_class), GFP_KERNEL);
+       if (cl == NULL)
+               return -ENOBUFS;
+       memset(cl, 0, sizeof(struct hfsc_class));
+
+       if (rsc != NULL)
+               hfsc_change_rsc(cl, rsc, 0);
+       if (fsc != NULL)
+               hfsc_change_fsc(cl, fsc);
+       if (usc != NULL)
+               hfsc_change_usc(cl, usc, 0);
+
+       cl->refcnt    = 1;
+       cl->classid   = classid;
+       cl->sched     = q;
+       cl->cl_parent = parent;
+       cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+       if (cl->qdisc == NULL)
+               cl->qdisc = &noop_qdisc;
+       cl->stats.lock = &sch->dev->queue_lock;
+       INIT_LIST_HEAD(&cl->children);
+       INIT_LIST_HEAD(&cl->actlist);
+
+       sch_tree_lock(sch);
+       list_add_tail(&cl->hlist, &q->clhash[hfsc_hash(classid)]);
+       list_add_tail(&cl->siblings, &parent->children);
+       if (parent->level == 0)
+               hfsc_purge_queue(sch, parent);
+       hfsc_adjust_levels(parent);
+       sch_tree_unlock(sch);
+
+#ifdef CONFIG_NET_ESTIMATOR
+       if (tca[TCA_RATE-1])
+               qdisc_new_estimator(&cl->stats, tca[TCA_RATE-1]);
+#endif
+       *arg = (unsigned long)cl;
+       return 0;
+}
+
+static void
+hfsc_destroy_filters(struct tcf_proto **fl)
+{
+       struct tcf_proto *tp;
+
+       while ((tp = *fl) != NULL) {
+               *fl = tp->next;
+               tcf_destroy(tp);
+       }
+}
+
+static void
+hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+
+       hfsc_destroy_filters(&cl->filter_list);
+       qdisc_destroy(cl->qdisc);
+#ifdef CONFIG_NET_ESTIMATOR
+       qdisc_kill_estimator(&cl->stats);
+#endif
+       if (cl != &q->root)
+               kfree(cl);
+}
+
+static int
+hfsc_delete_class(struct Qdisc *sch, unsigned long arg)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl = (struct hfsc_class *)arg;
+
+       if (cl->level > 0 || cl->filter_cnt > 0 || cl == &q->root)
+               return -EBUSY;
+
+       sch_tree_lock(sch);
+
+       list_del(&cl->hlist);
+       list_del(&cl->siblings);
+       hfsc_adjust_levels(cl->cl_parent);
+       hfsc_purge_queue(sch, cl);
+       if (q->last_xmit == cl)
+               q->last_xmit = NULL;
+
+       if (--cl->refcnt == 0)
+               hfsc_destroy_class(sch, cl);
+
+       sch_tree_unlock(sch);
+       return 0;
+}
+
+static struct hfsc_class *
+hfsc_classify(struct sk_buff *skb, struct Qdisc *sch)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl;
+       struct tcf_result res;
+       struct tcf_proto *tcf;
+       int result;
+
+       if (TC_H_MAJ(skb->priority ^ sch->handle) == 0 &&
+           (cl = hfsc_find_class(skb->priority, sch)) != NULL)
+               if (cl->level == 0)
+                       return cl;
+
+       tcf = q->root.filter_list;
+       while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
+#ifdef CONFIG_NET_CLS_POLICE
+               if (result == TC_POLICE_SHOT)
+                       return NULL;
+#endif
+               if ((cl = (struct hfsc_class *)res.class) == NULL) {
+                       if ((cl = hfsc_find_class(res.classid, sch)) == NULL)
+                               break; /* filter selected invalid classid */
+               }
+
+               if (cl->level == 0)
+                       return cl; /* hit leaf class */
+
+               /* apply inner filter chain */
+               tcf = cl->filter_list;
+       }
+
+       /* classification failed, try default class */
+       cl = hfsc_find_class(TC_H_MAKE(TC_H_MAJ(sch->handle), q->defcls), sch);
+       if (cl == NULL || cl->level > 0)
+               return NULL;
+
+       return cl;
+}
+
+static int
+hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
+                 struct Qdisc **old)
+{
+       struct hfsc_class *cl = (struct hfsc_class *)arg;
+
+       if (cl == NULL)
+               return -ENOENT;
+       if (cl->level > 0)
+               return -EINVAL;
+       if (new == NULL) {
+               new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+               if (new == NULL)
+                       new = &noop_qdisc;
+       }
+
+       sch_tree_lock(sch);
+       hfsc_purge_queue(sch, cl);
+       *old = xchg(&cl->qdisc, new);
+       sch_tree_unlock(sch);
+       return 0;
+}
+
+static struct Qdisc *
+hfsc_class_leaf(struct Qdisc *sch, unsigned long arg)
+{
+       struct hfsc_class *cl = (struct hfsc_class *)arg;
+
+       if (cl != NULL && cl->level == 0)
+               return cl->qdisc;
+
+       return NULL;
+}
+
+static unsigned long
+hfsc_get_class(struct Qdisc *sch, u32 classid)
+{
+       struct hfsc_class *cl = hfsc_find_class(classid, sch);
+
+       if (cl != NULL)
+               cl->refcnt++;
+
+       return (unsigned long)cl;
+}
+
+static void
+hfsc_put_class(struct Qdisc *sch, unsigned long arg)
+{
+       struct hfsc_class *cl = (struct hfsc_class *)arg;
+
+       if (--cl->refcnt == 0)
+               hfsc_destroy_class(sch, cl);
+}
+
+static unsigned long
+hfsc_bind_tcf(struct Qdisc *sch, unsigned long parent, u32 classid)
+{
+       struct hfsc_class *p = (struct hfsc_class *)parent;
+       struct hfsc_class *cl = hfsc_find_class(classid, sch);
+
+       if (cl != NULL) {
+               if (p != NULL && p->level <= cl->level)
+                       return 0;
+               cl->filter_cnt++;
+       }
+
+       return (unsigned long)cl;
+}
+
+static void
+hfsc_unbind_tcf(struct Qdisc *sch, unsigned long arg)
+{
+       struct hfsc_class *cl = (struct hfsc_class *)arg;
+
+       cl->filter_cnt--;
+}
+
+static struct tcf_proto **
+hfsc_tcf_chain(struct Qdisc *sch, unsigned long arg)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl = (struct hfsc_class *)arg;
+
+       if (cl == NULL)
+               cl = &q->root;
+
+       return &cl->filter_list;
+}
+
+static int
+hfsc_dump_sc(struct sk_buff *skb, int attr, struct internal_sc *sc)
+{
+       struct tc_service_curve tsc;
+
+       tsc.m1 = sm2m(sc->sm1);
+       tsc.d  = dx2d(sc->dx);
+       tsc.m2 = sm2m(sc->sm2);
+       RTA_PUT(skb, attr, sizeof(tsc), &tsc);
+
+       return skb->len;
+
+ rtattr_failure:
+       return -1;
+}
+
+static inline int
+hfsc_dump_curves(struct sk_buff *skb, struct hfsc_class *cl)
+{
+       if ((cl->cl_flags & HFSC_RSC) &&
+           (hfsc_dump_sc(skb, TCA_HFSC_RSC, &cl->cl_rsc) < 0))
+               goto rtattr_failure;
+
+       if ((cl->cl_flags & HFSC_FSC) &&
+           (hfsc_dump_sc(skb, TCA_HFSC_FSC, &cl->cl_fsc) < 0))
+               goto rtattr_failure;
+
+       if ((cl->cl_flags & HFSC_USC) &&
+           (hfsc_dump_sc(skb, TCA_HFSC_USC, &cl->cl_usc) < 0))
+               goto rtattr_failure;
+
+       return skb->len;
+
+ rtattr_failure:
+       return -1;
+}
+
+static inline int
+hfsc_dump_stats(struct sk_buff *skb, struct hfsc_class *cl)
+{
+       cl->stats.qlen = cl->qdisc->q.qlen;
+       if (qdisc_copy_stats(skb, &cl->stats) < 0)
+               goto rtattr_failure;
+
+       return skb->len;
+
+ rtattr_failure:
+       return -1;
+}
+
+static inline int
+hfsc_dump_xstats(struct sk_buff *skb, struct hfsc_class *cl)
+{
+       struct tc_hfsc_stats xstats;
+
+       xstats.level  = cl->level;
+       xstats.period = cl->cl_vtperiod;
+       xstats.work   = cl->cl_total;
+       xstats.rtwork = cl->cl_cumul;
+       RTA_PUT(skb, TCA_XSTATS, sizeof(xstats), &xstats);
+
+       return skb->len;
+
+ rtattr_failure:
+       return -1;
+}
+
+static int
+hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb,
+                struct tcmsg *tcm)
+{
+       struct hfsc_class *cl = (struct hfsc_class *)arg;
+       unsigned char *b = skb->tail;
+       struct rtattr *rta = (struct rtattr *)b;
+
+       tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT;
+       tcm->tcm_handle = cl->classid;
+       if (cl->level == 0)
+               tcm->tcm_info = cl->qdisc->handle;
+
+       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       if (hfsc_dump_curves(skb, cl) < 0)
+               goto rtattr_failure;
+       rta->rta_len = skb->tail - b;
+
+       if ((hfsc_dump_stats(skb, cl) < 0) ||
+           (hfsc_dump_xstats(skb, cl) < 0))
+               goto rtattr_failure;
+
+       return skb->len;
+
+ rtattr_failure:
+       skb_trim(skb, b - skb->data);
+       return -1;
+}
+
+static void
+hfsc_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl;
+       unsigned int i;
+
+       if (arg->stop)
+               return;
+
+       for (i = 0; i < HFSC_HSIZE; i++) {
+               list_for_each_entry(cl, &q->clhash[i], hlist) {
+                       if (arg->count < arg->skip) {
+                               arg->count++;
+                               continue;
+                       }
+                       if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
+                               arg->stop = 1;
+                               return;
+                       }
+                       arg->count++;
+               }
+       }
+}
+
+static void
+hfsc_watchdog(unsigned long arg)
+{
+       struct Qdisc *sch = (struct Qdisc *)arg;
+
+       sch->flags &= ~TCQ_F_THROTTLED;
+       netif_schedule(sch->dev);
+}
+
+static void
+hfsc_schedule_watchdog(struct Qdisc *sch, u64 cur_time)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl;
+       u64 next_time = 0;
+       long delay;
+
+       if ((cl = ellist_get_minel(&q->eligible)) != NULL)
+               next_time = cl->cl_e;
+       if (q->root.cl_cfmin != 0) {
+               if (next_time == 0 || next_time > q->root.cl_cfmin)
+                       next_time = q->root.cl_cfmin;
+       }
+       ASSERT(next_time != 0);
+       delay = next_time - cur_time;
+       delay = PSCHED_US2JIFFIE(delay);
+
+       sch->flags |= TCQ_F_THROTTLED;
+       mod_timer(&q->wd_timer, jiffies + delay);
+}
+
+static int
+hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct tc_hfsc_qopt *qopt;
+       unsigned int i;
+
+       if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt))
+               return -EINVAL;
+       qopt = RTA_DATA(opt);
+
+       memset(q, 0, sizeof(struct hfsc_sched));
+       sch->stats.lock = &sch->dev->queue_lock;
+
+       q->defcls = qopt->defcls;
+       for (i = 0; i < HFSC_HSIZE; i++)
+               INIT_LIST_HEAD(&q->clhash[i]);
+       INIT_LIST_HEAD(&q->eligible);
+       INIT_LIST_HEAD(&q->droplist);
+
+       q->root.refcnt  = 1;
+       q->root.classid = sch->handle;
+       q->root.sched   = q;
+       q->root.qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+       if (q->root.qdisc == NULL)
+               q->root.qdisc = &noop_qdisc;
+       q->root.stats.lock = &sch->dev->queue_lock;
+       INIT_LIST_HEAD(&q->root.children);
+       INIT_LIST_HEAD(&q->root.actlist);
+
+       list_add(&q->root.hlist, &q->clhash[hfsc_hash(q->root.classid)]);
+
+       init_timer(&q->wd_timer);
+       q->wd_timer.function = hfsc_watchdog;
+       q->wd_timer.data = (unsigned long)sch;
+
+       return 0;
+}
+
+static int
+hfsc_change_qdisc(struct Qdisc *sch, struct rtattr *opt)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct tc_hfsc_qopt *qopt;
+
+       if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt))
+               return -EINVAL;;
+       qopt = RTA_DATA(opt);
+
+       sch_tree_lock(sch);
+       q->defcls = qopt->defcls;
+       sch_tree_unlock(sch);
+
+       return 0;
+}
+
+static void
+hfsc_reset_class(struct hfsc_class *cl)
+{
+       cl->cl_total        = 0;
+       cl->cl_cumul        = 0;
+       cl->cl_d            = 0;
+       cl->cl_e            = 0;
+       cl->cl_vt           = 0;
+       cl->cl_vtadj        = 0;
+       cl->cl_vtoff        = 0;
+       cl->cl_cvtmin       = 0;
+       cl->cl_cvtmax       = 0;
+       cl->cl_vtperiod     = 0;
+       cl->cl_parentperiod = 0;
+       cl->cl_f            = 0;
+       cl->cl_myf          = 0;
+       cl->cl_myfadj       = 0;
+       cl->cl_cfmin        = 0;
+       cl->cl_nactive      = 0;
+       INIT_LIST_HEAD(&cl->actlist);
+       qdisc_reset(cl->qdisc);
+
+       if (cl->cl_flags & HFSC_RSC)
+               rtsc_init(&cl->cl_deadline, &cl->cl_rsc, 0, 0);
+       if (cl->cl_flags & HFSC_FSC)
+               rtsc_init(&cl->cl_virtual, &cl->cl_fsc, 0, 0);
+       if (cl->cl_flags & HFSC_USC)
+               rtsc_init(&cl->cl_ulimit, &cl->cl_usc, 0, 0);
+}
+
+static void
+hfsc_reset_qdisc(struct Qdisc *sch)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl;
+       unsigned int i;
+
+       for (i = 0; i < HFSC_HSIZE; i++) {
+               list_for_each_entry(cl, &q->clhash[i], hlist)
+                       hfsc_reset_class(cl);
+       }
+
+       INIT_LIST_HEAD(&q->eligible);
+       INIT_LIST_HEAD(&q->droplist);
+       q->last_xmit = NULL;
+       del_timer(&q->wd_timer);
+       sch->flags &= ~TCQ_F_THROTTLED;
+       sch->q.qlen = 0;
+}
+
+static void
+hfsc_destroy_qdisc(struct Qdisc *sch)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl, *next;
+       unsigned int i;
+
+       for (i = 0; i < HFSC_HSIZE; i++) {
+               list_for_each_entry_safe(cl, next, &q->clhash[i], hlist)
+                       hfsc_destroy_class(sch, cl);
+       }
+
+       del_timer(&q->wd_timer);
+}
+
+static int
+hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       unsigned char *b = skb->tail;
+       struct tc_hfsc_qopt qopt;
+
+       qopt.defcls = q->defcls;
+       RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
+
+       sch->stats.qlen = sch->q.qlen;
+       if (qdisc_copy_stats(skb, &sch->stats) < 0)
+               goto rtattr_failure;
+
+       return skb->len;
+
+ rtattr_failure:
+       skb_trim(skb, b - skb->data);
+       return -1;
+}
+
+static int
+hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+       struct hfsc_class *cl = hfsc_classify(skb, sch);
+       unsigned int len = skb->len;
+       int err;
+
+       if (cl == NULL) {
+               kfree_skb(skb);
+               sch->stats.drops++;
+               return NET_XMIT_DROP;
+       }
+
+       err = cl->qdisc->enqueue(skb, cl->qdisc);
+       if (unlikely(err != NET_XMIT_SUCCESS)) {
+               cl->stats.drops++;
+               sch->stats.drops++;
+               return err;
+       }
+
+       if (cl->qdisc->q.qlen == 1)
+               set_active(cl, len);
+
+       cl->stats.packets++;
+       cl->stats.bytes += len;
+       sch->stats.packets++;
+       sch->stats.bytes += len;
+       sch->q.qlen++;
+
+       return NET_XMIT_SUCCESS;
+}
+
+static struct sk_buff *
+hfsc_dequeue(struct Qdisc *sch)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl;
+       struct sk_buff *skb;
+       u64 cur_time;
+       unsigned int next_len;
+       int realtime = 0;
+
+       if (sch->q.qlen == 0)
+               return NULL;
+
+       PSCHED_GET_TIME(cur_time);
+
+       /*
+        * if there are eligible classes, use real-time criteria.
+        * find the class with the minimum deadline among
+        * the eligible classes.
+        */
+       if ((cl = ellist_get_mindl(&q->eligible, cur_time)) != NULL) {
+               realtime = 1;
+       } else {
+               /*
+                * use link-sharing criteria
+                * get the class with the minimum vt in the hierarchy
+                */
+               cl = actlist_get_minvt(&q->root, cur_time);
+               if (cl == NULL) {
+                       sch->stats.overlimits++;
+                       if (!netif_queue_stopped(sch->dev))
+                               hfsc_schedule_watchdog(sch, cur_time);
+                       return NULL;
+               }
+       }
+
+       skb = cl->qdisc->dequeue(cl->qdisc);
+       if (skb == NULL) {
+               if (net_ratelimit())
+                       printk("HFSC: Non-work-conserving qdisc ?\n");
+               return NULL;
+       }
+
+       update_vf(cl, skb->len, cur_time);
+       if (realtime)
+               cl->cl_cumul += skb->len;
+
+       if (cl->qdisc->q.qlen != 0) {
+               if (cl->cl_flags & HFSC_RSC) {
+                       /* update ed */
+                       next_len = qdisc_peek_len(cl->qdisc);
+                       if (realtime)
+                               update_ed(cl, next_len);
+                       else
+                               update_d(cl, next_len);
+               }
+       } else {
+               /* the class becomes passive */
+               set_passive(cl);
+       }
+
+       q->last_xmit = cl;
+       sch->flags &= ~TCQ_F_THROTTLED;
+       sch->q.qlen--;
+
+       return skb;
+}
+
+static int
+hfsc_requeue(struct sk_buff *skb, struct Qdisc *sch)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl = q->last_xmit;
+       unsigned int len = skb->len;
+       int ret;
+
+       if (cl == NULL) {
+               kfree_skb(skb);
+               sch->stats.drops++;
+               return NET_XMIT_DROP;
+       }
+
+       ret = cl->qdisc->ops->requeue(skb, cl->qdisc);
+       if (ret == NET_XMIT_SUCCESS) {
+               if (cl->qdisc->q.qlen == 1)
+                       set_active(cl, len);
+               sch->q.qlen++;
+       } else {
+               cl->stats.drops++;
+               sch->stats.drops++;
+       }
+       q->last_xmit = NULL;
+
+       return ret;
+}
+
+static unsigned int
+hfsc_drop(struct Qdisc *sch)
+{
+       struct hfsc_sched *q = (struct hfsc_sched *)sch->data;
+       struct hfsc_class *cl;
+       unsigned int len;
+
+       list_for_each_entry(cl, &q->droplist, dlist) {
+               if (cl->qdisc->ops->drop != NULL &&
+                   (len = cl->qdisc->ops->drop(cl->qdisc)) > 0) {
+                       if (cl->qdisc->q.qlen == 0) {
+                               update_vf(cl, 0, 0);
+                               set_passive(cl);
+                       } else {
+                               list_move_tail(&cl->dlist, &q->droplist);
+                       }
+                       cl->stats.drops++;
+                       sch->stats.drops++;
+                       sch->q.qlen--;
+                       return len;
+               }
+       }
+       return 0;
+}
+
+static struct Qdisc_class_ops hfsc_class_ops = {
+       .change         = hfsc_change_class,
+       .delete         = hfsc_delete_class,
+       .graft          = hfsc_graft_class,
+       .leaf           = hfsc_class_leaf,
+       .get            = hfsc_get_class,
+       .put            = hfsc_put_class,
+       .bind_tcf       = hfsc_bind_tcf,
+       .unbind_tcf     = hfsc_unbind_tcf,
+       .tcf_chain      = hfsc_tcf_chain,
+       .dump           = hfsc_dump_class,
+       .walk           = hfsc_walk
+};
+
+struct Qdisc_ops hfsc_qdisc_ops = {
+       .id             = "hfsc",
+       .init           = hfsc_init_qdisc,
+       .change         = hfsc_change_qdisc,
+       .reset          = hfsc_reset_qdisc,
+       .destroy        = hfsc_destroy_qdisc,
+       .dump           = hfsc_dump_qdisc,
+       .enqueue        = hfsc_enqueue,
+       .dequeue        = hfsc_dequeue,
+       .requeue        = hfsc_requeue,
+       .drop           = hfsc_drop,
+       .cl_ops         = &hfsc_class_ops,
+       .priv_size      = sizeof(struct hfsc_sched),
+       .owner          = THIS_MODULE
+};
+
+static int __init
+hfsc_init(void)
+{
+       return register_qdisc(&hfsc_qdisc_ops);
+}
+
+static void __exit
+hfsc_cleanup(void)
+{
+       unregister_qdisc(&hfsc_qdisc_ops);
+}
+
+MODULE_LICENSE("GPL");
+module_init(hfsc_init);
+module_exit(hfsc_cleanup);
index 865c0f0..1b683a1 100644 (file)
@@ -16,7 +16,7 @@ config IP_SCTP
        ---help---
          Stream Control Transmission Protocol
 
-         From RFC 2960 (http://www.ietf.org/rfc/rfc2960.txt)
+         From RFC 2960 <http://www.ietf.org/rfc/rfc2960.txt>.
 
          "SCTP is a reliable transport protocol operating on top of a
          connectionless packet network such as IP.  It offers the following
@@ -37,19 +37,6 @@ config IP_SCTP
 
          If in doubt, say N.
 
-config SCTP_ADLER32
-       bool "SCTP: Use old checksum (Adler-32)"
-       depends on IP_SCTP
-       help
-         RFC2960 currently specifies the Adler-32 checksum algorithm for SCTP.
-         This has been deprecated and replaced by an algorithm now referred
-         to as crc32c.
-
-         If you say Y, this will use the Adler-32 algorithm, this might be 
-         useful for interoperation with downlevel peers. 
-
-         If unsure, say N.  
-
 config SCTP_DBG_MSG
        bool "SCTP: Debug messages"
        depends on IP_SCTP
index e4127cb..70c828b 100644 (file)
@@ -9,13 +9,7 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
          transport.o chunk.o sm_make_chunk.o ulpevent.o \
          inqueue.o outqueue.o ulpqueue.o command.o \
          tsnmap.o bind_addr.o socket.o primitive.o \
-         output.o input.o debug.o ssnmap.o proc.o
-
-ifeq ($(CONFIG_SCTP_ADLER32), y)
-sctp-y += adler32.o
-else
-sctp-y += crc32c.o
-endif
+         output.o input.o debug.o ssnmap.o proc.o crc32c.o
 
 sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
 sctp-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/sctp/adler32.c b/net/sctp/adler32.c
deleted file mode 100644 (file)
index 63058b5..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/* SCTP kernel reference Implementation
- * Copyright (c) 1999-2000 Cisco, Inc.
- * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2003 International Business Machines, Corp.
- *
- * This file is part of the SCTP kernel reference Implementation
- *
- * This file has direct heritage from the SCTP user-level reference
- * implementation by R. Stewart, et al.  These functions implement the
- * Adler-32 algorithm as specified by RFC 2960.
- *
- * The SCTP reference implementation is free software;
- * you can redistribute 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.
- *
- * The SCTP reference implementation is distributed in the hope that 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.
- *
- * Please send any bug reports or fixes you make to the
- * email address(es):
- *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- *
- * Or submit a bug report through the following website:
- *    http://www.sf.net/projects/lksctp
- *
- * Written or modified by:
- *    Randall Stewart <rstewar1@email.mot.com>
- *    Ken Morneau     <kmorneau@cisco.com>
- *    Qiaobing Xie    <qxie1@email.mot.com>
- *    Sridhar Samudrala <sri@us.ibm.com>
- *
- * Any bugs reported given to us we will try to fix... any fixes shared will
- * be incorporated into the next SCTP release.
- */
-
-/* This is an entry point for external calls
- * Define this function in the header file. This is
- * direct from rfc1950, ...
- *
- * The following C code computes the Adler-32 checksum of a data buffer.
- * It is written for clarity, not for speed.  The sample code is in the
- * ANSI C programming language. Non C users may find it easier to read
- * with these hints:
- *
- *    &      Bitwise AND operator.
- *    >>     Bitwise right shift operator. When applied to an
- *           unsigned quantity, as here, right shift inserts zero bit(s)
- *           at the left.
- *    <<     Bitwise left shift operator. Left shift inserts zero
- *           bit(s) at the right.
- *    ++     "n++" increments the variable n.
- *    %      modulo operator: a % b is the remainder of a divided by b.
- *
- * Well, the above is a bit of a lie, I have optimized this a small
- * tad, but I have commented the original lines below
- */
-
-#include <linux/types.h>
-#include <net/sctp/sctp.h>
-
-#define BASE 65521 /* largest prime smaller than 65536 */
-
-
-/* Performance work as shown this pig to be the
- * worst CPU wise guy. I have done what I could think
- * of on my flight to Australia but I am sure some
- * clever assembly could speed this up, but of
- * course this would require the dreaded #ifdef's for
- * architecture. If you can speed this up more, pass
- * it back and we will incorporate it :-)
- */
-
-unsigned long update_adler32(unsigned long adler,
-                            unsigned char *buf, int len)
-{
-       __u32 s1 = adler & 0xffff;
-       __u32 s2 = (adler >> 16) & 0xffff;
-        int n;
-
-       for (n = 0; n < len; n++,buf++) {
-               /* s1 = (s1 + buf[n]) % BASE */
-               /* first we add */
-               s1 = (s1 + *buf);
-
-               /* Now if we need to, we do a mod by
-                * subtracting. It seems a bit faster
-                * since I really will only ever do
-                * one subtract at the MOST, since buf[n]
-                * is a max of 255.
-                */
-               if (s1 >= BASE)
-                       s1 -= BASE;
-
-               /* s2 = (s2 + s1) % BASE */
-               /* first we add */
-               s2 = (s2 + s1);
-
-               /* again, it is more efficient (it seems) to
-                * subtract since the most s2 will ever be
-                * is (BASE-1 + BASE-1) in the worse case.
-                * This would then be (2 * BASE) - 2, which
-                * will still only do one subtract. On Intel
-                * this is much better to do this way and
-                * avoid the divide. Have not -pg'd on
-                * sparc.
-                */
-               if (s2 >= BASE) {
-                       /*      s2 %= BASE;*/
-                       s2 -= BASE;
-               }
-       }
-
-       /* Return the adler32 of the bytes buf[0..len-1] */
-       return (s2 << 16) + s1;
-}
-
-__u32 sctp_start_cksum(__u8 *ptr, __u16 count)
-{
-       /*
-        * Update a running Adler-32 checksum with the bytes
-        * buf[0..len-1] and return the updated checksum. The Adler-32
-        * checksum should be initialized to 1.
-        */
-       __u32 adler = 1L;
-       __u32 zero = 0L;
-
-       /* Calculate the CRC up to the checksum field. */
-       adler = update_adler32(adler, ptr,
-                              sizeof(struct sctphdr) - sizeof(__u32));
-       /* Skip over the checksum field. */
-       adler = update_adler32(adler, (unsigned char *) &zero,
-                              sizeof(__u32));
-       ptr += sizeof(struct sctphdr);
-       count -= sizeof(struct sctphdr);
-
-       /* Calculate the rest of the Adler-32. */
-       adler = update_adler32(adler, ptr, count);
-
-        return adler;
-}
-
-__u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 adler)
-{
-       adler = update_adler32(adler, ptr, count);
-
-       return adler;
-}
-
-__u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 count, __u32 adler)
-{
-       /* Its not worth it to try harder.  Adler32 is obsolescent. */
-       adler = update_adler32(adler, from, count);
-       memcpy(to, from, count);
-
-       return adler;
-}
-
-__u32 sctp_end_cksum(__u32 adler)
-{
-       return adler;
-}
index 5c15d82..29fa694 100644 (file)
@@ -192,7 +192,7 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
        asoc->rwnd_over = 0;
 
        /* Use my own max window until I learn something better.  */
-       asoc->peer.rwnd = SCTP_DEFAULT_MAXWINDOW;
+       asoc->peer.rwnd = sctp_rmem;
 
        /* Set the sndbuf size for transmit.  */
        asoc->sndbuf_used = 0;
@@ -498,7 +498,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
         * so initialize ssthresh to the default value and it will be set
         * later when we process the INIT.
         */
-       peer->ssthresh = SCTP_DEFAULT_MAXWINDOW;
+       peer->ssthresh = sctp_rmem;
 
        peer->partial_bytes_acked = 0;
        peer->flight_size = 0;
index ab1cfb4..6391db3 100644 (file)
@@ -148,12 +148,8 @@ struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
                sp->autoclose * HZ;
 
        /* Set up the default send/receive buffer space.  */
-
-       /* FIXME - Should the min and max window size be configurable
-        * sysctl parameters as opposed to be constants?
-        */
-       sk->sk_rcvbuf = SCTP_DEFAULT_MAXWINDOW;
-       sk->sk_sndbuf = SCTP_DEFAULT_MAXWINDOW * 2;
+       sk->sk_rcvbuf = sctp_rmem;
+       sk->sk_sndbuf = sctp_wmem;
 
        /* Use SCTP specific send buffer space queues.  */
        sk->sk_write_space = sctp_write_space;
index 21f8623..2e79628 100644 (file)
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2004
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
@@ -445,7 +445,10 @@ struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
        memset(&fl, 0x0, sizeof(struct flowi));
        fl.fl4_dst  = daddr->v4.sin_addr.s_addr;
        fl.proto = IPPROTO_SCTP;
-
+       if (asoc) {
+               fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk);
+               fl.oif = asoc->base.sk->sk_bound_dev_if;
+       }
        if (saddr)
                fl.fl4_src = saddr->v4.sin_addr.s_addr;
 
@@ -1046,6 +1049,10 @@ __init int sctp_init(void)
        sctp_max_instreams              = SCTP_DEFAULT_INSTREAMS;
        sctp_max_outstreams             = SCTP_DEFAULT_OUTSTREAMS;
 
+       /* Initialize default send & receive buffer sizes. */
+       sctp_rmem                       = SCTP_DEFAULT_MAXWINDOW;
+       sctp_wmem                       = SCTP_DEFAULT_MAXWINDOW;
+
        /* Size and allocate the association hash table.
         * The methodology is similar to that of the tcp hash tables.
         */
index 15c5f3b..5732784 100644 (file)
@@ -170,6 +170,22 @@ static ctl_table sctp_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
+       {
+               .ctl_name       = NET_SCTP_RMEM,
+               .procname       = "rmem",
+               .data           = &sctp_rmem,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
+       {
+               .ctl_name       = NET_SCTP_WMEM,
+               .procname       = "wmem",
+               .data           = &sctp_wmem,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
        { .ctl_name = 0 }
 };
 
index a02b214..d9ec4af 100644 (file)
@@ -768,7 +768,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
                needed = ntohs(chunk->chunk_hdr->length);
                needed -= sizeof(sctp_data_chunk_t);
        } else 
-               needed = SCTP_DEFAULT_MAXWINDOW;
+               needed = sctp_rmem;
 
        freed = 0;
 
index 79ebf10..f40cf74 100644 (file)
@@ -71,7 +71,7 @@ static LIST_HEAD(all_tasks);
  * rpciod-related stuff
  */
 static DECLARE_WAIT_QUEUE_HEAD(rpciod_idle);
-static DECLARE_WAIT_QUEUE_HEAD(rpciod_killer);
+static DECLARE_COMPLETION(rpciod_killer);
 static DECLARE_MUTEX(rpciod_sema);
 static unsigned int            rpciod_users;
 static pid_t                   rpciod_pid;
@@ -950,7 +950,6 @@ rpciod_task_pending(void)
 static int
 rpciod(void *ptr)
 {
-       wait_queue_head_t *assassin = (wait_queue_head_t*) ptr;
        int             rounds = 0;
 
        lock_kernel();
@@ -992,11 +991,11 @@ rpciod(void *ptr)
                rpciod_killall();
        }
 
-       rpciod_pid = 0;
-       wake_up(assassin);
-
        dprintk("RPC: rpciod exiting\n");
        unlock_kernel();
+
+       rpciod_pid = 0;
+       complete_and_exit(&rpciod_killer, 0);
        return 0;
 }
 
@@ -1041,7 +1040,7 @@ rpciod_up(void)
        /*
         * Create the rpciod thread and wait for it to start.
         */
-       error = kernel_thread(rpciod, &rpciod_killer, 0);
+       error = kernel_thread(rpciod, NULL, 0);
        if (error < 0) {
                printk(KERN_WARNING "rpciod_up: create thread failed, error=%d\n", error);
                rpciod_users--;
@@ -1057,8 +1056,6 @@ out:
 void
 rpciod_down(void)
 {
-       unsigned long flags;
-
        down(&rpciod_sema);
        dprintk("rpciod_down pid %d sema %d\n", rpciod_pid, rpciod_users);
        if (rpciod_users) {
@@ -1073,27 +1070,8 @@ rpciod_down(void)
        }
 
        kill_proc(rpciod_pid, SIGKILL, 1);
-       /*
-        * Usually rpciod will exit very quickly, so we
-        * wait briefly before checking the process id.
-        */
-       clear_thread_flag(TIF_SIGPENDING);
-       yield();
-       /*
-        * Display a message if we're going to wait longer.
-        */
-       while (rpciod_pid) {
-               dprintk("rpciod_down: waiting for pid %d to exit\n", rpciod_pid);
-               if (signalled()) {
-                       dprintk("rpciod_down: caught signal\n");
-                       break;
-               }
-               interruptible_sleep_on(&rpciod_killer);
-       }
-       spin_lock_irqsave(&current->sighand->siglock, flags);
-       recalc_sigpending();
-       spin_unlock_irqrestore(&current->sighand->siglock, flags);
-out:
+       wait_for_completion(&rpciod_killer);
+ out:
        up(&rpciod_sema);
 }
 
index 82b66c6..c8d8dda 100644 (file)
@@ -1863,14 +1863,19 @@ static int unix_seq_show(struct seq_file *seq, void *v)
                        sock_i_ino(s));
 
                if (u->addr) {
-                       int i;
+                       int i, len;
                        seq_putc(seq, ' ');
-                       
-                       for (i = 0; i < u->addr->len-sizeof(short); i++)
-                               seq_putc(seq, u->addr->name->sun_path[i]);
 
-                       if (UNIX_ABSTRACT(s))
+                       i = 0;
+                       len = u->addr->len - sizeof(short);
+                       if (!UNIX_ABSTRACT(s))
+                               len--;
+                       else {
                                seq_putc(seq, '@');
+                               i++;
+                       }
+                       for ( ; i < len; i++)
+                               seq_putc(seq, u->addr->name->sun_path[i]);
                }
                unix_state_runlock(s);
                seq_putc(seq, '\n');
index 6e73ca0..f0d4451 100644 (file)
@@ -726,8 +726,6 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
 
                if (dev->name == NULL) {
                        err = -EINVAL;
-               } else if (dev_get(dev->name)) {
-                       err = -EEXIST;  /* name already exists */
                } else {
 
                        #ifdef WANDEBUG
index 7bc3194..9660884 100644 (file)
@@ -438,7 +438,7 @@ static struct sock *x25_alloc_socket(void)
        if (!sk)
                goto out;
 
-       x25 = x25_sk(sk) = kmalloc(sizeof(*x25), GFP_ATOMIC);
+       x25 = sk->sk_protinfo = kmalloc(sizeof(*x25), GFP_ATOMIC);
        if (!x25)
                goto frees;
 
index d4005d3..86a50d4 100644 (file)
@@ -775,7 +775,7 @@ restart:
 
                if (unlikely(nx<0)) {
                        err = nx;
-                       if (err == -EAGAIN && !flags) {
+                       if (err == -EAGAIN && flags) {
                                DECLARE_WAITQUEUE(wait, current);
 
                                add_wait_queue(&km_waitq, &wait);
index 1528ddd..fa8fd16 100644 (file)
@@ -176,6 +176,29 @@ static int do_ccw_entry(const char *filename,
        return 1;
 }
 
+/* looks like: "pnp:dD" */
+static int do_pnp_entry(const char *filename,
+                       struct pnp_device_id *id, char *alias)
+{
+       sprintf(alias, "pnp:d%s", id->id);
+       return 1;
+}
+
+/* looks like: "pnp:cCdD..." */
+static int do_pnp_card_entry(const char *filename,
+                       struct pnp_card_device_id *id, char *alias)
+{
+       int i;
+
+       sprintf(alias, "pnp:c%s", id->id);
+       for (i = 0; i < PNP_MAX_DEVICES; i++) {
+               if (! *id->devs[i].id)
+                       break;
+               sprintf(alias + strlen(alias), "d%s", id->devs[i].id);
+       }
+       return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -242,6 +265,12 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
        else if (sym_is(symname, "__mod_ccw_device_table"))
                do_table(symval, sym->st_size, sizeof(struct ccw_device_id),
                         do_ccw_entry, mod);
+       else if (sym_is(symname, "__mod_pnp_device_table"))
+               do_table(symval, sym->st_size, sizeof(struct pnp_device_id),
+                        do_pnp_entry, mod);
+       else if (sym_is(symname, "__mod_pnp_card_device_table"))
+               do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id),
+                        do_pnp_card_entry, mod);
 }
 
 /* Now add out buffered information to the generated C source */
index c7455c0..ab9f92a 100644 (file)
@@ -152,14 +152,26 @@ new_symbol(const char *name, struct module *module, unsigned int *crc)
        symbolhash[hash] = new;
 }
 
+#define DOTSYM_PFX "__dot_"
+
 struct symbol *
 find_symbol(const char *name)
 {
        struct symbol *s;
+       char dotname[64 + sizeof(DOTSYM_PFX)];
 
-       /* For our purposes, .foo matches foo.  PPC64 needs this. */
-       if (name[0] == '.')
+       /* .foo matches foo.  PPC64 needs this. */
+       if (name[0] == '.') {
                name++;
+               strcpy(dotname, DOTSYM_PFX);
+               strncat(dotname, name, sizeof(dotname) - sizeof(DOTSYM_PFX) - 1);
+               dotname[sizeof(dotname)-1] = 0;
+               /* Sparc32 wants .foo to match __dot_foo, try this first. */
+               for (s = symbolhash[tdb_hash(dotname) % SYMBOL_HASH_SIZE]; s; s=s->next) {
+                       if (strcmp(s->name, dotname) == 0)
+                               return s;
+               }
+       }
 
        for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
                if (strcmp(s->name, name) == 0)
index 6802f5c..76a26f5 100644 (file)
@@ -106,5 +106,6 @@ obj-$(CONFIG_SND_HARMONY) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
 obj-$(CONFIG_SND_VXPOCKET) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-hwdep.o
 obj-$(CONFIG_SND_VXP440) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-hwdep.o
 obj-$(CONFIG_SND_VX222) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-hwdep.o
+obj-$(CONFIG_SND_BT87X) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
 
 obj-m := $(sort $(obj-m))
index 4d4f80f..8e7efaf 100644 (file)
@@ -1177,6 +1177,7 @@ static void snd_mixer_oss_build(snd_mixer_oss_t *mixer)
                { SOUND_MIXER_TREBLE,   "Tone Control - Treble", 0 },
                { SOUND_MIXER_SYNTH,    "Synth",                0 },
                { SOUND_MIXER_SYNTH,    "FM",                   0 }, /* fallback */
+               { SOUND_MIXER_SYNTH,    "Music",                0 }, /* fallback */
                { SOUND_MIXER_PCM,      "PCM",                  0 },
                { SOUND_MIXER_SPEAKER,  "PC Speaker",           0 },
                { SOUND_MIXER_LINE,     "Line",                 0 },
@@ -1184,6 +1185,7 @@ static void snd_mixer_oss_build(snd_mixer_oss_t *mixer)
                { SOUND_MIXER_CD,       "CD",                   0 },
                { SOUND_MIXER_IMIX,     "Monitor Mix",          0 },
                { SOUND_MIXER_ALTPCM,   "PCM",                  1 },
+               { SOUND_MIXER_ALTPCM,   "Headphone",            0 }, /* fallback */
                { SOUND_MIXER_ALTPCM,   "Wave",                 0 }, /* fallback */
                { SOUND_MIXER_RECLEV,   "-- nothing --",        0 },
                { SOUND_MIXER_IGAIN,    "Capture",              0 },
@@ -1192,10 +1194,14 @@ static void snd_mixer_oss_build(snd_mixer_oss_t *mixer)
                { SOUND_MIXER_LINE2,    "Aux",                  1 },
                { SOUND_MIXER_LINE3,    "Aux",                  2 },
                { SOUND_MIXER_DIGITAL1, "Digital",              0 },
+               { SOUND_MIXER_DIGITAL1, "IEC958",               0 }, /* fallback */
+               { SOUND_MIXER_DIGITAL1, "IEC958 Optical",       0 }, /* fallback */
+               { SOUND_MIXER_DIGITAL1, "IEC958 Coaxial",       0 }, /* fallback */
                { SOUND_MIXER_DIGITAL2, "Digital",              1 },
                { SOUND_MIXER_DIGITAL3, "Digital",              2 },
                { SOUND_MIXER_PHONEIN,  "Phone",                0 },
-               { SOUND_MIXER_PHONEOUT, "Phone",                1 },
+               { SOUND_MIXER_PHONEOUT, "Master Mono",          0 },
+               { SOUND_MIXER_PHONEOUT, "Phone",                0 }, /* fallback */
                { SOUND_MIXER_VIDEO,    "Video",                0 },
                { SOUND_MIXER_RADIO,    "Radio",                0 },
                { SOUND_MIXER_MONITOR,  "Monitor",              0 }
index e385c93..81be9e5 100644 (file)
@@ -909,10 +909,11 @@ static long snd_rawmidi_kernel_read1(snd_rawmidi_substream_t *substream,
                if (kernel) {
                        memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1);
                } else {
+                       spin_unlock_irqrestore(&runtime->lock, flags);
                        if (copy_to_user(buf + result, runtime->buffer + runtime->appl_ptr, count1)) {
-                               spin_unlock_irqrestore(&runtime->lock, flags);
                                return result > 0 ? result : -EFAULT;
                        }
+                       spin_lock_irqsave(&runtime->lock, flags);
                }
                runtime->appl_ptr += count1;
                runtime->appl_ptr %= runtime->buffer_size;
@@ -1133,10 +1134,13 @@ static long snd_rawmidi_kernel_write1(snd_rawmidi_substream_t * substream, const
                if (kernel) {
                        memcpy(runtime->buffer + runtime->appl_ptr, buf, count1);
                } else {
+                       spin_unlock_irqrestore(&runtime->lock, flags);
                        if (copy_from_user(runtime->buffer + runtime->appl_ptr, buf, count1)) {
+                               spin_lock_irqsave(&runtime->lock, flags);
                                result = result > 0 ? result : -EFAULT;
                                goto __end;
                        }
+                       spin_lock_irqsave(&runtime->lock, flags);
                }
                runtime->appl_ptr += count1;
                runtime->appl_ptr %= runtime->buffer_size;
index c23a4f3..7790d08 100644 (file)
@@ -70,6 +70,8 @@ static struct list_head snd_minors_hash[SNDRV_CARDS];
 static DECLARE_MUTEX(sound_mutex);
 
 extern struct class_simple *sound_class;
+
+
 #ifdef CONFIG_KMOD
 
 /**
index 0fe1fe6..d16b96a 100644 (file)
@@ -4,7 +4,9 @@
 #
 
 snd-ak4xxx-adda-objs := ak4xxx-adda.o
+snd-tea575x-tuner-objs := tea575x-tuner.o
 
 # Module Dependency
 obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
 obj-$(CONFIG_SND_ICE1724) += snd-ak4xxx-adda.o
+obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
new file mode 100644 (file)
index 0000000..7b9f3ea
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ *   ALSA driver for TEA5757/5759 Philips AM/FM radio tuner chips
+ *
+ *     Copyright (c) 2004 Jaroslav Kysela <perex@suse.cz>
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the 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 <sound/driver.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <sound/core.h>
+#include <sound/tea575x-tuner.h>
+
+MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
+MODULE_LICENSE("GPL");
+
+/*
+ * definitions
+ */
+
+#define TEA575X_BIT_SEARCH     (1<<24)         /* 1 = search action, 0 = tuned */
+#define TEA575X_BIT_UPDOWN     (1<<23)         /* 0 = search down, 1 = search up */
+#define TEA575X_BIT_MONO       (1<<22)         /* 0 = stereo, 1 = mono */
+#define TEA575X_BIT_BAND_MASK  (3<<20)
+#define TEA575X_BIT_BAND_FM    (0<<20)
+#define TEA575X_BIT_BAND_MW    (1<<20)
+#define TEA575X_BIT_BAND_LW    (1<<21)
+#define TEA575X_BIT_BAND_SW    (1<<22)
+#define TEA575X_BIT_PORT_0     (1<<19)         /* user bit */
+#define TEA575X_BIT_PORT_1     (1<<18)         /* user bit */
+#define TEA575X_BIT_SEARCH_MASK        (3<<16)         /* search level */
+#define TEA575X_BIT_SEARCH_5_28             (0<<16)    /* FM >5uV, AM >28uV */
+#define TEA575X_BIT_SEARCH_10_40     (1<<16)   /* FM >10uV, AM > 40uV */
+#define TEA575X_BIT_SEARCH_30_63     (2<<16)   /* FM >30uV, AM > 63uV */
+#define TEA575X_BIT_SEARCH_150_1000  (3<<16)   /* FM > 150uV, AM > 1000uV */
+#define TEA575X_BIT_DUMMY      (1<<15)         /* buffer */
+#define TEA575X_BIT_FREQ_MASK  0x7fff
+
+/*
+ * lowlevel part
+ */
+
+static void snd_tea575x_set_freq(tea575x_t *tea)
+{
+       unsigned long freq;
+
+       freq = tea->freq / 16;          /* to kHz */
+       if (freq > 108000)
+               freq = 108000;
+       if (freq < 87000)
+               freq = 87000;
+       /* crystal fixup */
+       if (tea->tea5759)
+               freq -= tea->freq_fixup;
+       else
+               freq += tea->freq_fixup;
+       /* freq /= 12.5 */
+       freq *= 10;
+       freq /= 125;
+
+       tea->val &= ~TEA575X_BIT_FREQ_MASK;
+       tea->val |= freq & TEA575X_BIT_FREQ_MASK;
+       tea->ops->write(tea, tea->val);
+}
+
+/*
+ * Linux Video interface
+ */
+
+static int snd_tea575x_do_ioctl(struct inode *inode, struct file *file,
+                               unsigned int cmd, void *arg)
+{
+       struct video_device *dev = video_devdata(file);
+       tea575x_t *tea = video_get_drvdata(dev);
+       
+       switch(cmd) {
+               case VIDIOCGCAP:
+               {
+                       struct video_capability v;
+                       v.type = VID_TYPE_TUNER;
+                       v.channels = 1;
+                       v.audios = 1;
+                       /* No we don't do pictures */
+                       v.maxwidth = 0;
+                       v.maxheight = 0;
+                       v.minwidth = 0;
+                       v.minheight = 0;
+                       strcpy(v.name, tea->tea5759 ? "TEA5759" : "TEA5757");
+                       if (copy_to_user(arg,&v,sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCGTUNER:
+               {
+                       struct video_tuner v;
+                       if (copy_from_user(&v, arg,sizeof(v))!=0) 
+                               return -EFAULT;
+                       if (v.tuner)    /* Only 1 tuner */ 
+                               return -EINVAL;
+                       v.rangelow = (87*16000);
+                       v.rangehigh = (108*16000);
+                       v.flags = VIDEO_TUNER_LOW;
+                       v.mode = VIDEO_MODE_AUTO;
+                       strcpy(v.name, "FM");
+                       v.signal = 0xFFFF;
+                       if (copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCSTUNER:
+               {
+                       struct video_tuner v;
+                       if(copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if(v.tuner!=0)
+                               return -EINVAL;
+                       /* Only 1 tuner so no setting needed ! */
+                       return 0;
+               }
+               case VIDIOCGFREQ:
+                       if(copy_to_user(arg, &tea->freq, sizeof(tea->freq)))
+                               return -EFAULT;
+                       return 0;
+               case VIDIOCSFREQ:
+                       if(copy_from_user(&tea->freq, arg, sizeof(tea->freq)))
+                               return -EFAULT;
+                       snd_tea575x_set_freq(tea);
+                       return 0;
+               case VIDIOCGAUDIO:
+               {       
+                       struct video_audio v;
+                       memset(&v, 0, sizeof(v));
+                       strcpy(v.name, "Radio");
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;                       
+               }
+               case VIDIOCSAUDIO:
+               {
+                       struct video_audio v;
+                       if(copy_from_user(&v, arg, sizeof(v))) 
+                               return -EFAULT; 
+                       if(v.audio) 
+                               return -EINVAL;
+                       return 0;
+               }
+               default:
+                       return -ENOIOCTLCMD;
+       }
+}
+
+static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
+                            unsigned int cmd, unsigned long arg)
+{
+       return video_usercopy(inode, file, cmd, arg, snd_tea575x_do_ioctl);
+}
+
+/*
+ * initialize all the tea575x chips
+ */
+void snd_tea575x_init(tea575x_t *tea)
+{
+       unsigned int val;
+
+       val = tea->ops->read(tea);
+       if (val == 0x1ffffff || val == 0) {
+               snd_printk(KERN_ERR "Cannot find TEA575x chip\n");
+               return;
+       }
+
+       memset(&tea->vd, 0, sizeof(tea->vd));
+       tea->vd.owner = tea->card->module;
+       strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio");
+       tea->vd.type = VID_TYPE_TUNER;
+       tea->vd.hardware = VID_HARDWARE_RTRACK; /* FIXME: assign new number */
+       video_set_drvdata(&tea->vd, tea);
+       tea->vd.fops = &tea->fops;
+       tea->fops.owner = tea->card->module;
+       tea->fops.open = video_exclusive_open;
+       tea->fops.release = video_exclusive_release;
+       tea->fops.ioctl = snd_tea575x_ioctl;
+       if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) {
+               snd_printk(KERN_ERR "unable to register tea575x tuner\n");
+               return;
+       }
+       tea->vd_registered = 1;
+
+       tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
+       tea->freq = 90500 * 16;         /* 90.5Mhz default */
+
+       snd_tea575x_set_freq(tea);
+}
+
+void snd_tea575x_exit(tea575x_t *tea)
+{
+       if (tea->vd_registered) {
+               video_unregister_device(&tea->vd);
+               tea->vd_registered = 0;
+       }
+}
+
+static int __init alsa_tea575x_module_init(void)
+{
+       return 0;
+}
+        
+static void __exit alsa_tea575x_module_exit(void)
+{
+}
+        
+module_init(alsa_tea575x_module_init)
+module_exit(alsa_tea575x_module_exit)
+
+EXPORT_SYMBOL(snd_tea575x_init);
+EXPORT_SYMBOL(snd_tea575x_exit);
index 7fe9443..f294662 100644 (file)
@@ -143,7 +143,7 @@ static int __init snd_audiodrive_probe(int dev)
                }
        }
 
-       if (xmpu_irq >= 0) {
+       if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
                if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
                                               chip->mpu_port, 0,
                                               xmpu_irq,
index d9e1f5d..f9554a5 100644 (file)
@@ -151,6 +151,8 @@ static struct pnp_card_device_id snd_interwave_pnpids[] = {
        { .id = "CDC1111", .devs = { { .id = "CDC1112" } } },
        /* Panasonic PCA761AW Audio Card */
        { .id = "ADV55ff", .devs = { { .id = "ADV0010" } } },
+       /* InterWave STB without TEA6330T */
+       { .id = "ADV550a", .devs = { { .id = "ADV0010" } } },
 #else
        /* InterWave STB with TEA6330T */
        { .id = "ADV550a", .devs = { { .id = "ADV0010" }, { .id = "ADV0015" } } },
index f37ee7a..98515fe 100644 (file)
@@ -354,9 +354,9 @@ int ad1889_read_proc (char *page, char **start, off_t off,
        for (i = 0; i < AD_MAX_STATES; i++) {
                out += sprintf(out, "DMA status for %s:\n", 
                        (i == AD_WAV_STATE ? "WAV" : "ADC")); 
-               out += sprintf(out, "\t\t0x%p (IOVA: 0x%u)\n", 
+               out += sprintf(out, "\t\t0x%p (IOVA: 0x%llu)\n",
                        dev->state[i].dmabuf.rawbuf,
-                       dev->state[i].dmabuf.dma_handle);
+                       (unsigned long long)dev->state[i].dmabuf.dma_handle);
 
                out += sprintf(out, "\tread ptr: offset %u\n", 
                        (unsigned int)dev->state[i].dmabuf.rd_ptr);
index 052d480..933b460 100644 (file)
@@ -449,7 +449,7 @@ tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
                break;
        case SOUND_MIXER_MIC:
                if ((level&0xff)>0) {
-                       software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff); 
+                       software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
                        if (self->super.mixer[mixer] == 0) {
                                self->super.mixer[SOUND_MIXER_LINE] = 0;
                                shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
@@ -458,14 +458,14 @@ tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
                } else {
                        self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
                        software_input_volume = SW_INPUT_VOLUME_SCALE *
-                               (self->super.mixer[SOUND_MIXER_LINE]&0xff); 
+                               (self->super.mixer[SOUND_MIXER_LINE]&0xff);
                        shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
                        rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-               } 
+               }
                break;
        case SOUND_MIXER_LINE:
-               if (self->super.mixer[SOUND_MIXER_MIC] == 0) { 
-                       software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff); 
+               if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
+                       software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
                        rc=0;
                }
                break;
index 6e9d71d..4559dec 100644 (file)
@@ -61,7 +61,6 @@ static ssize_t pmac_ct_u16_read(const u_char *userPtr, size_t userCount,
 
 /*** Translations ************************************************************/
 
-extern int expand_bal; /* Balance factor for expanding (not volume!) */
 static int expand_data;        /* Data for expanding */
 
 static ssize_t pmac_ct_law(const u_char *userPtr, size_t userCount,
@@ -814,12 +813,12 @@ TRANS transAwacsNormalRead = {
 };
 
 TRANS transAwacsExpandRead = {
-       ct_s8:          pmac_ctx_s8_read,
-       ct_u8:          pmac_ctx_u8_read,
-       ct_s16be:       pmac_ctx_s16_read,
-       ct_u16be:       pmac_ctx_u16_read,
-       ct_s16le:       pmac_ctx_s16_read,
-       ct_u16le:       pmac_ctx_u16_read,
+       .ct_s8=         pmac_ctx_s8_read,
+       .ct_u8=         pmac_ctx_u8_read,
+       .ct_s16be=      pmac_ctx_s16_read,
+       .ct_u16be=      pmac_ctx_u16_read,
+       .ct_s16le=      pmac_ctx_s16_read,
+       .ct_u16le=      pmac_ctx_u16_read,
 };
 
 /* translation tables */
index 3ca1d60..22f0eff 100644 (file)
@@ -9,7 +9,7 @@
        called 'Vivace'. Both Harmony and Vicace are supported by this driver.
 
        Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@linuxcare.com>
-       Copyright 2000-2002 (c) Helge Deller <deller@gmx.de>
+       Copyright 2000-2003 (c) Helge Deller <deller@gmx.de>
        Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr>
        Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr>
 
@@ -157,19 +157,21 @@ struct harmony_hpa {
 };
 
 struct harmony_dev {
-       int irq;
        struct harmony_hpa *hpa;
+       struct parisc_device *dev;
        u32 current_gain;
+       u32 dac_rate;           /* 8000 ... 48000 (Hz) */
        u8 data_format;         /* HARMONY_DF_xx_BIT_xxx */
        u8 sample_rate;         /* HARMONY_SR_xx_KHZ */
        u8 stereo_select;       /* HARMONY_SS_MONO or HARMONY_SS_STEREO */
-       int format_initialized;
-       u32 dac_rate;           /* 8000 ... 48000 (Hz) */
-       int suspended_playing;
-       int suspended_recording;
+       int format_initialized  :1;
+       int suspended_playing   :1;
+       int suspended_recording :1;
        
-       int blocked_playing;
-       int blocked_recording;
+       int blocked_playing     :1;
+       int blocked_recording   :1;
+       int audio_open          :1;
+       int mixer_open          :1;
        
        wait_queue_head_t wq_play, wq_record;
        int first_filled_play;  /* first buffer containing data (next to play) */
@@ -178,11 +180,7 @@ struct harmony_dev {
        int first_filled_record;
        int nb_filled_record;
                
-       int audio_open, mixer_open;
        int dsp_unit, mixer_unit;
-
-       struct pci_dev *fake_pci_dev; /* The fake pci_dev needed for 
-                                       pci_* functions under ccio. */
 };
 
 
@@ -196,8 +194,8 @@ static struct harmony_dev harmony;
 struct harmony_buffer {
        unsigned char *addr;
        dma_addr_t dma_handle;
-       int dma_consistent;     /* Zero if pci_alloc_consistent() fails */
-       int len;
+       int dma_coherent;       /* Zero if dma_alloc_coherent() fails */
+       unsigned int len;
 };
 
 /*
@@ -208,23 +206,23 @@ static struct harmony_buffer played_buf, recorded_buf, silent, graveyard;
 
 
 #define CHECK_WBACK_INV_OFFSET(b,offset,len) \
-        do { if (!b.dma_consistent) \
+        do { if (!b.dma_coherent) \
                dma_cache_wback_inv((unsigned long)b.addr+offset,len); \
        } while (0) 
 
        
 static int __init harmony_alloc_buffer(struct harmony_buffer *b, 
-               int buffer_count)
+               unsigned int buffer_count)
 {
        b->len = buffer_count * HARMONY_BUF_SIZE;
-       b->addr = pci_alloc_consistent(harmony.fake_pci_dev, 
-                         b->len, &b->dma_handle);
+       b->addr = dma_alloc_coherent(&harmony.dev->dev, 
+                         b->len, &b->dma_handle, GFP_KERNEL|GFP_DMA);
        if (b->addr && b->dma_handle) {
-               b->dma_consistent = 1;
-               DPRINTK(KERN_INFO PFX "consistent memory: 0x%lx, played_buf: 0x%lx\n",
+               b->dma_coherent = 1;
+               DPRINTK(KERN_INFO PFX "coherent memory: 0x%lx, played_buf: 0x%lx\n",
                                (unsigned long)b->dma_handle, (unsigned long)b->addr);
        } else {
-               b->dma_consistent = 0;
+               b->dma_coherent = 0;
                /* kmalloc()ed memory will HPMC on ccio machines ! */
                b->addr = kmalloc(b->len, GFP_KERNEL);
                if (!b->addr) {
@@ -241,8 +239,8 @@ static void __exit harmony_free_buffer(struct harmony_buffer *b)
        if (!b->addr)
                return;
 
-       if (b->dma_consistent)
-               pci_free_consistent(harmony.fake_pci_dev,
+       if (b->dma_coherent)
+               dma_free_coherent(&harmony.dev->dev,
                                b->len, b->addr, b->dma_handle);
        else
                kfree(b->addr);
@@ -372,7 +370,7 @@ static int harmony_audio_open(struct inode *inode, struct file *file)
        if (harmony.audio_open) 
                return -EBUSY;
        
-       harmony.audio_open++;
+       harmony.audio_open = 1;
        harmony.suspended_playing = harmony.suspended_recording = 1;
        harmony.blocked_playing   = harmony.blocked_recording   = 0;
        harmony.first_filled_play = harmony.first_filled_record = 0;
@@ -402,7 +400,7 @@ static int harmony_audio_release(struct inode *inode, struct file *file)
        if (!harmony.audio_open) 
                return -EBUSY;
        
-       harmony.audio_open--;
+       harmony.audio_open = 0;
 
        return 0;
 }
@@ -835,15 +833,15 @@ static struct file_operations harmony_audio_fops = {
 static int harmony_audio_init(void)
 {
        /* Request that IRQ */
-       if (request_irq(harmony.irq, harmony_interrupt, 0 ,"harmony", &harmony)) {
-               printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.irq);
+       if (request_irq(harmony.dev->irq, harmony_interrupt, 0 ,"harmony", &harmony)) {
+               printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.dev->irq);
                return -EFAULT;
        }
 
        harmony.dsp_unit = register_sound_dsp(&harmony_audio_fops, -1);
        if (harmony.dsp_unit < 0) {
                printk(KERN_ERR PFX "Error registering dsp\n");
-               free_irq(harmony.irq, &harmony);
+               free_irq(harmony.dev->irq, &harmony);
                return -EFAULT;
        }
        
@@ -1131,7 +1129,7 @@ static int harmony_mixer_open(struct inode *inode, struct file *file)
 {
        if (harmony.mixer_open) 
                return -EBUSY;
-       harmony.mixer_open++;
+       harmony.mixer_open = 1;
        return 0;
 }
 
@@ -1139,7 +1137,7 @@ static int harmony_mixer_release(struct inode *inode, struct file *file)
 {
        if (!harmony.mixer_open) 
                return -EBUSY;
-       harmony.mixer_open--;
+       harmony.mixer_open = 0;
        return 0;
 }
 
@@ -1189,8 +1187,8 @@ static int __init harmony_mixer_init(void)
  * This is the callback that's called by the inventory hardware code 
  * if it finds a match to the registered driver. 
  */
-static int __init
-harmony_driver_callback(struct parisc_device *dev)
+static int __devinit
+harmony_driver_probe(struct parisc_device *dev)
 {
        u8      id;
        u8      rev;
@@ -1203,11 +1201,12 @@ harmony_driver_callback(struct parisc_device *dev)
                return -EBUSY;
        }
 
+       harmony.dev = dev;
+
        /* Set the HPA of harmony */
        harmony.hpa = (struct harmony_hpa *)dev->hpa;
 
-       harmony.irq = dev->irq;
-       if (!harmony.irq) {
+       if (!harmony.dev->irq) {
                printk(KERN_ERR PFX "no irq found\n");
                return -ENODEV;
        }
@@ -1223,7 +1222,7 @@ harmony_driver_callback(struct parisc_device *dev)
 
        printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", "
                        "h/w id %i, rev. %i at 0x%lx, IRQ %i\n",
-                       id, rev, dev->hpa, harmony.irq);
+                       id, rev, dev->hpa, harmony.dev->irq);
        
        /* Make sure the control bit isn't set, although I don't think it 
           ever is. */
@@ -1233,9 +1232,6 @@ harmony_driver_callback(struct parisc_device *dev)
                return -EBUSY;
        }
 
-       /* a fake pci_dev is needed for pci_* functions under ccio */
-       harmony.fake_pci_dev = ccio_get_fake(dev);
-       
        /* Initialize the memory buffers */
        if (harmony_alloc_buffer(&played_buf, MAX_BUFS) || 
            harmony_alloc_buffer(&recorded_buf, MAX_BUFS) ||
@@ -1276,7 +1272,7 @@ MODULE_DEVICE_TABLE(parisc, harmony_tbl);
 static struct parisc_driver harmony_driver = {
        .name           = "Lasi Harmony",
        .id_table       = harmony_tbl,
-       .probe          = harmony_driver_callback,
+       .probe          = harmony_driver_probe,
 };
 
 static int __init init_harmony(void)
@@ -1286,7 +1282,7 @@ static int __init init_harmony(void)
 
 static void __exit cleanup_harmony(void)
 {
-       free_irq(harmony.irq, &harmony);
+       free_irq(harmony.dev->irq, &harmony);
        unregister_sound_mixer(harmony.mixer_unit);
        unregister_sound_dsp(harmony.dsp_unit);
        harmony_free_buffer(&played_buf);
index 806ff1e..364cf83 100644 (file)
@@ -15,6 +15,13 @@ config SND_AZT3328
        help
          Say 'Y' or 'M' to include support for Aztech AZF3328 (PCI168) soundcards.
 
+config SND_BT87X
+        tristate "Bt87x Audio Capture"
+        depends on SND
+        help
+          Say 'Y' or 'M' to include support for recording audio from TV cards
+          based on Brooktree Bt878/Bt879 chips.
+
 config SND_CS46XX
        tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
        depends on SND
@@ -147,6 +154,13 @@ config SND_FM801
        help
          Say 'Y' or 'M' to include support for ForteMedia FM801 based soundcards.
 
+config CONFIG_SND_FM801_TEA575X
+       tristate "ForteMedia FM801 + TEA5757 tuner"
+       depends on SND_FM801 && CONFIG_VIDEO_DEV
+       help
+         Say 'Y' or 'M' to include support for ForteMedia FM801 based soundcards
+          with TEA5757 tuner connected to GPIO1-3 pins (Media Forte SF256-PCS-02).
+
 config SND_ICE1712
        tristate "ICEnsemble ICE1712 (Envy24)"
        depends on SND
index 81eed13..85c7047 100644 (file)
@@ -5,6 +5,7 @@
 
 snd-als4000-objs := als4000.o
 snd-azt3328-objs := azt3328.o
+snd-bt87x-objs := bt87x.o
 snd-cmipci-objs := cmipci.o
 snd-cs4281-objs := cs4281.o
 snd-ens1370-objs := ens1370.o
@@ -21,6 +22,8 @@ snd-via82xx-objs := via82xx.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
+obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o
+obj-$(CONFIG_SND_BT87X) += snd-bt87x.o
 obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o
 obj-$(CONFIG_SND_CS4281) += snd-cs4281.o
 obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o
@@ -34,6 +37,5 @@ obj-$(CONFIG_SND_RME32) += snd-rme32.o
 obj-$(CONFIG_SND_RME96) += snd-rme96.o
 obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
 obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
-obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o
 
 obj-$(CONFIG_SND) += ac97/ ali5451/ cs46xx/ emu10k1/ korg1212/ nm256/ rme9652/ trident/ ymfpci/ ice1712/ vx222/
index 489afb3..b217319 100644 (file)
@@ -2140,10 +2140,28 @@ static int tune_ad_sharing(ac97_t *ac97)
        return 0;
 }
 
+static int apply_quirk(ac97_t *ac97, int quirk)
+{
+       switch (quirk) {
+       case AC97_TUNE_NONE:
+               return 0;
+       case AC97_TUNE_HP_ONLY:
+               return swap_headphone(ac97, 1);
+       case AC97_TUNE_SWAP_HP:
+               return swap_headphone(ac97, 0);
+       case AC97_TUNE_SWAP_SURROUND:
+               return swap_surround(ac97);
+       case AC97_TUNE_AD_SHARING:
+               return tune_ad_sharing(ac97);
+       }
+       return -EINVAL;
+}
+
 /**
  * snd_ac97_tune_hardware - tune up the hardware
  * @ac97: the ac97 instance
  * @quirk: quirk list
+ * @override: explicit quirk value (overrides the list if not AC97_TUNE_DEFAULT)
  *
  * Do some workaround for each pci device, such as renaming of the
  * headphone (true line-out) control as "Master".
@@ -2152,28 +2170,29 @@ static int tune_ad_sharing(ac97_t *ac97)
  * Returns zero if successful, or a negative error code on failure.
  */
 
-int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk)
+int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, int override)
 {
+       int result;
+
        snd_assert(quirk, return -EINVAL);
 
+       if (override != AC97_TUNE_DEFAULT) {
+               result = apply_quirk(ac97, override);
+               if (result < 0)
+                       snd_printk(KERN_ERR "applying quirk type %d failed (%d)\n", override, result);
+               return result;
+       }
+
        for (; quirk->vendor; quirk++) {
                if (quirk->vendor != ac97->subsystem_vendor)
                        continue;
                if ((! quirk->mask && quirk->device == ac97->subsystem_device) ||
                    quirk->device == (quirk->mask & ac97->subsystem_device)) {
                        snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device);
-                       switch (quirk->type) {
-                       case AC97_TUNE_HP_ONLY:
-                               return swap_headphone(ac97, 1);
-                       case AC97_TUNE_SWAP_HP:
-                               return swap_headphone(ac97, 0);
-                       case AC97_TUNE_SWAP_SURROUND:
-                               return swap_surround(ac97);
-                       case AC97_TUNE_AD_SHARING:
-                               return tune_ad_sharing(ac97);
-                       }
-                       snd_printk(KERN_ERR "invalid quirk type %d for %s\n", quirk->type, quirk->name);
-                       return -EINVAL;
+                       result = apply_quirk(ac97, quirk->type);
+                       if (result < 0)
+                               snd_printk(KERN_ERR "applying quirk type %d for %s failed (%d)\n", quirk->type, quirk->name, result);
+                       return result;
                }
        }
        return 0;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
new file mode 100644 (file)
index 0000000..9acf55c
--- /dev/null
@@ -0,0 +1,891 @@
+/*
+ * bt87x.c - Brooktree Bt878/Bt879 driver for ALSA
+ *
+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
+ *
+ * based on btaudio.c by Gerd Knorr <kraxel@bytesex.org>
+ *
+ *
+ *  This driver is free software; you can redistribute it and/or modify
+ *  it under the terms of the 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 driver is distributed in the hope that 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 <sound/driver.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/control.h>
+#define SNDRV_GET_ID
+#include <sound/initval.h>
+
+MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
+MODULE_DESCRIPTION("Brooktree Bt87x audio driver");
+MODULE_LICENSE("GPL");
+MODULE_CLASSES("{sound}");
+MODULE_DEVICES("{{Brooktree,Bt878},"
+               "{Brooktree,Bt879}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;     /* Enable this card */
+static int digital_rate[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* digital input rate */
+
+MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(index, "Index value for Bt87x soundcard");
+MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
+MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+MODULE_PARM_DESC(id, "ID string for Bt87x soundcard");
+MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
+MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(enable, "Enable Bt87x soundcard");
+MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
+MODULE_PARM(digital_rate, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(digital_rate, "Digital input rate for Bt87x soundcard");
+MODULE_PARM_SYNTAX(digital_rate, SNDRV_ENABLED);
+
+
+#ifndef PCI_VENDOR_ID_BROOKTREE
+#define PCI_VENDOR_ID_BROOKTREE 0x109e
+#endif
+#ifndef PCI_DEVICE_ID_BROOKTREE_878
+#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
+#endif
+#ifndef PCI_DEVICE_ID_BROOKTREE_879
+#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
+#endif
+
+/* register offsets */
+#define REG_INT_STAT           0x100   /* interrupt status */
+#define REG_INT_MASK           0x104   /* interrupt mask */
+#define REG_GPIO_DMA_CTL       0x10c   /* audio control */
+#define REG_PACKET_LEN         0x110   /* audio packet lengths */
+#define REG_RISC_STRT_ADD      0x114   /* RISC program start address */
+#define REG_RISC_COUNT         0x120   /* RISC program counter */
+
+/* interrupt bits */
+#define INT_OFLOW      (1 <<  3)       /* audio A/D overflow */
+#define INT_RISCI      (1 << 11)       /* RISC instruction IRQ bit set */
+#define INT_FBUS       (1 << 12)       /* FIFO overrun due to bus access latency */
+#define INT_FTRGT      (1 << 13)       /* FIFO overrun due to target latency */
+#define INT_FDSR       (1 << 14)       /* FIFO data stream resynchronization */
+#define INT_PPERR      (1 << 15)       /* PCI parity error */
+#define INT_RIPERR     (1 << 16)       /* RISC instruction parity error */
+#define INT_PABORT     (1 << 17)       /* PCI master or target abort */
+#define INT_OCERR      (1 << 18)       /* invalid opcode */
+#define INT_SCERR      (1 << 19)       /* sync counter overflow */
+#define INT_RISC_EN    (1 << 27)       /* DMA controller running */
+#define INT_RISCS_SHIFT              28        /* RISC status bits */
+
+/* audio control bits */
+#define CTL_FIFO_ENABLE                (1 <<  0)       /* enable audio data FIFO */
+#define CTL_RISC_ENABLE                (1 <<  1)       /* enable audio DMA controller */
+#define CTL_PKTP_4             (0 <<  2)       /* packet mode FIFO trigger point - 4 DWORDs */
+#define CTL_PKTP_8             (1 <<  2)       /* 8 DWORDs */
+#define CTL_PKTP_16            (2 <<  2)       /* 16 DWORDs */
+#define CTL_ACAP_EN            (1 <<  4)       /* enable audio capture */
+#define CTL_DA_APP             (1 <<  5)       /* GPIO input */
+#define CTL_DA_IOM_AFE         (0 <<  6)       /* audio A/D input */
+#define CTL_DA_IOM_DA          (1 <<  6)       /* digital audio input */
+#define CTL_DA_SDR_SHIFT              8        /* DDF first stage decimation rate */
+#define CTL_DA_SDR_MASK                (0xf<< 8)
+#define CTL_DA_LMT             (1 << 12)       /* limit audio data values */
+#define CTL_DA_ES2             (1 << 13)       /* enable DDF stage 2 */
+#define CTL_DA_SBR             (1 << 14)       /* samples rounded to 8 bits */
+#define CTL_DA_DPM             (1 << 15)       /* data packet mode */
+#define CTL_DA_LRD_SHIFT             16        /* ALRCK delay */
+#define CTL_DA_MLB             (1 << 21)       /* MSB/LSB format */
+#define CTL_DA_LRI             (1 << 22)       /* left/right indication */
+#define CTL_DA_SCE             (1 << 23)       /* sample clock edge */
+#define CTL_A_SEL_STV          (0 << 24)       /* TV tuner audio input */
+#define CTL_A_SEL_SFM          (1 << 24)       /* FM audio input */
+#define CTL_A_SEL_SML          (2 << 24)       /* mic/line audio input */
+#define CTL_A_SEL_SMXC         (3 << 24)       /* MUX bypass */
+#define CTL_A_SEL_SHIFT                      24
+#define CTL_A_SEL_MASK         (3 << 24)
+#define CTL_A_PWRDN            (1 << 26)       /* analog audio power-down */
+#define CTL_A_G2X              (1 << 27)       /* audio gain boost */
+#define CTL_A_GAIN_SHIFT             28        /* audio input gain */
+#define CTL_A_GAIN_MASK                (0xf<<28)
+
+/* RISC instruction opcodes */
+#define RISC_WRITE     (0x1 << 28)     /* write FIFO data to memory at address */
+#define RISC_WRITEC    (0x5 << 28)     /* write FIFO data to memory at current address */
+#define RISC_SKIP      (0x2 << 28)     /* skip FIFO data */
+#define RISC_JUMP      (0x7 << 28)     /* jump to address */
+#define RISC_SYNC      (0x8 << 28)     /* synchronize with FIFO */
+
+/* RISC instruction bits */
+#define RISC_BYTES_ENABLE      (0xf << 12)     /* byte enable bits */
+#define RISC_RESYNC            (  1 << 15)     /* disable FDSR errors */
+#define RISC_SET_STATUS_SHIFT          16      /* set status bits */
+#define RISC_RESET_STATUS_SHIFT                20      /* clear status bits */
+#define RISC_IRQ               (  1 << 24)     /* interrupt */
+#define RISC_EOL               (  1 << 26)     /* end of line */
+#define RISC_SOL               (  1 << 27)     /* start of line */
+
+/* SYNC status bits values */
+#define RISC_SYNC_FM1  0x6
+#define RISC_SYNC_VRO  0xc
+
+#define ERROR_INTERRUPTS (INT_FBUS | INT_FTRGT | INT_PPERR | \
+                         INT_RIPERR | INT_PABORT | INT_OCERR)
+#define MY_INTERRUPTS (INT_RISCI | ERROR_INTERRUPTS)
+
+/* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */
+#define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8)
+
+#define chip_t bt87x_t
+typedef struct snd_bt87x bt87x_t;
+struct snd_bt87x {
+       snd_card_t *card;
+       struct pci_dev *pci;
+
+       void *mmio;
+       struct resource *res_mmio;
+       int irq;
+
+       int dig_rate;
+
+       spinlock_t reg_lock;
+       long opened;
+       snd_pcm_substream_t *substream;
+
+       u32 *risc;
+       dma_addr_t risc_dma;
+       unsigned int line_bytes;
+       unsigned int lines;
+
+       u32 reg_control;
+       int current_line;
+};
+
+enum { DEVICE_DIGITAL, DEVICE_ANALOG };
+
+static inline u32 snd_bt87x_readl(bt87x_t *chip, u32 reg)
+{
+       return readl(chip->mmio + reg);
+}
+
+static inline void snd_bt87x_writel(bt87x_t *chip, u32 reg, u32 value)
+{
+       writel(value, chip->mmio + reg);
+}
+
+static int snd_bt87x_create_risc(bt87x_t *chip, snd_pcm_substream_t *substream,
+                                unsigned int periods, unsigned int period_bytes)
+{
+       struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
+       unsigned int i, offset;
+       u32 *risc;
+
+       if (!chip->risc) {
+               chip->risc = (u32*)snd_malloc_pci_pages
+                       (chip->pci, PAGE_ALIGN(MAX_RISC_SIZE), &chip->risc_dma);
+               if (!chip->risc)
+                       return -ENOMEM;
+       }
+       risc = chip->risc;
+       offset = 0;
+       *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_FM1);
+       *risc++ = cpu_to_le32(0);
+       for (i = 0; i < periods; ++i) {
+               u32 rest;
+
+               rest = period_bytes;
+               do {
+                       u32 cmd, len;
+
+                       len = PAGE_SIZE - (offset % PAGE_SIZE);
+                       if (len > rest)
+                               len = rest;
+                       cmd = RISC_WRITE | len;
+                       if (rest == period_bytes) {
+                               u32 block = i * 16 / periods;
+                               cmd |= RISC_SOL;
+                               cmd |= block << RISC_SET_STATUS_SHIFT;
+                               cmd |= (~block & 0xf) << RISC_RESET_STATUS_SHIFT;
+                       }
+                       if (len == rest)
+                               cmd |= RISC_EOL | RISC_IRQ;
+                       *risc++ = cpu_to_le32(cmd);
+                       *risc++ = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, offset));
+                       offset += len;
+                       rest -= len;
+               } while (rest > 0);
+       }
+       *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_VRO);
+       *risc++ = cpu_to_le32(0);
+       *risc++ = cpu_to_le32(RISC_JUMP);
+       *risc++ = cpu_to_le32(chip->risc_dma);
+       chip->line_bytes = period_bytes;
+       chip->lines = periods;
+       return 0;
+}
+
+static void snd_bt87x_free_risc(bt87x_t *chip)
+{
+       if (chip->risc) {
+               snd_free_pci_pages(chip->pci, PAGE_ALIGN(MAX_RISC_SIZE),
+                                  chip->risc, chip->risc_dma);
+               chip->risc = NULL;
+       }
+}
+
+static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       bt87x_t *chip = snd_magic_cast(bt87x_t, dev_id, return IRQ_NONE);
+       unsigned int status;
+
+       status = snd_bt87x_readl(chip, REG_INT_STAT);
+       if (!(status & MY_INTERRUPTS))
+               return IRQ_NONE;
+       snd_bt87x_writel(chip, REG_INT_STAT, status & MY_INTERRUPTS);
+
+       if (status & ERROR_INTERRUPTS) {
+               if (status & (INT_FBUS | INT_FTRGT))
+                       snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status);
+               if (status & INT_OCERR)
+                       snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status);
+               if (status & (INT_PPERR | INT_RIPERR | INT_PABORT)) {
+                       u16 pci_status;
+                       pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
+                       pci_write_config_word(chip->pci, PCI_STATUS, pci_status &
+                                             (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
+                                              PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
+                                              PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
+                       snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
+                                  status, pci_status);
+               }
+       }
+       if (status & INT_RISCI) {
+               int current_block, irq_block;
+
+               /* assume that exactly one line has been recorded */
+               chip->current_line = (chip->current_line + 1) % chip->lines;
+               /* but check if some interrupts have been skipped */
+               current_block = chip->current_line * 16 / chip->lines;
+               irq_block = status >> INT_RISCS_SHIFT;
+               if (current_block != irq_block)
+                       chip->current_line = (irq_block * chip->lines + 15) / 16;
+
+               snd_pcm_period_elapsed(chip->substream);
+       }
+       return IRQ_HANDLED;
+}
+
+static snd_pcm_hardware_t snd_bt87x_digital_hw = {
+       .info = SNDRV_PCM_INFO_MMAP |
+               SNDRV_PCM_INFO_INTERLEAVED |
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_MMAP_VALID,
+       .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       .rates = 0, /* set at runtime */
+       .channels_min = 2,
+       .channels_max = 2,
+       .buffer_bytes_max = 255 * 4092,
+       .period_bytes_min = 32,
+       .period_bytes_max = 4092,
+       .periods_min = 2,
+       .periods_max = 255,
+};
+
+static snd_pcm_hardware_t snd_bt87x_analog_hw = {
+       .info = SNDRV_PCM_INFO_MMAP |
+               SNDRV_PCM_INFO_INTERLEAVED |
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_MMAP_VALID,
+       .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
+       .rates = SNDRV_PCM_RATE_KNOT,
+       .rate_min = 119467,
+       .rate_max = 448000,
+       .channels_min = 1,
+       .channels_max = 1,
+       .buffer_bytes_max = 255 * 4092,
+       .period_bytes_min = 32,
+       .period_bytes_max = 4092,
+       .periods_min = 2,
+       .periods_max = 255,
+};
+
+static int snd_bt87x_set_digital_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
+{
+       static struct {
+               int rate;
+               unsigned int bit;
+       } ratebits[] = {
+               {8000, SNDRV_PCM_RATE_8000},
+               {11025, SNDRV_PCM_RATE_11025},
+               {16000, SNDRV_PCM_RATE_16000},
+               {22050, SNDRV_PCM_RATE_22050},
+               {32000, SNDRV_PCM_RATE_32000},
+               {44100, SNDRV_PCM_RATE_44100},
+               {48000, SNDRV_PCM_RATE_48000}
+       };
+       int i;
+
+       chip->reg_control |= CTL_DA_IOM_DA;
+       runtime->hw = snd_bt87x_digital_hw;
+       runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
+       for (i = 0; i < ARRAY_SIZE(ratebits); ++i)
+               if (chip->dig_rate == ratebits[i].rate) {
+                       runtime->hw.rates = ratebits[i].bit;
+                       break;
+               }
+       runtime->hw.rate_min = chip->dig_rate;
+       runtime->hw.rate_max = chip->dig_rate;
+       return 0;
+}
+
+static int snd_bt87x_set_analog_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
+{
+       static unsigned int rates[] = {
+               119467, 128000, 137846, 149333, 162909, 179200,
+               199111, 224000, 256000, 298667, 358400, 448000
+       };
+       static snd_pcm_hw_constraint_list_t constraint_rates = {
+               .count = ARRAY_SIZE(rates),
+               .list = rates,
+               .mask = 0,
+       };
+
+       chip->reg_control &= ~CTL_DA_IOM_DA;
+       runtime->hw = snd_bt87x_analog_hw;
+       return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                         &constraint_rates);
+}
+
+static int snd_bt87x_pcm_open(snd_pcm_substream_t *substream)
+{
+       bt87x_t *chip = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
+       int err;
+
+       if (test_and_set_bit(0, &chip->opened))
+               return -EBUSY;
+
+       if (substream->pcm->device == DEVICE_DIGITAL)
+               err = snd_bt87x_set_digital_hw(chip, runtime);
+       else
+               err = snd_bt87x_set_analog_hw(chip, runtime);
+       if (err < 0)
+               goto _error;
+
+       err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+       if (err < 0)
+               goto _error;
+
+       chip->substream = substream;
+       return 0;
+
+_error:
+       clear_bit(0, &chip->opened);
+       smp_mb__after_clear_bit();
+       return err;
+}
+
+static int snd_bt87x_close(snd_pcm_substream_t *substream)
+{
+       bt87x_t *chip = snd_pcm_substream_chip(substream);
+
+       chip->substream = NULL;
+       clear_bit(0, &chip->opened);
+       smp_mb__after_clear_bit();
+       return 0;
+}
+
+static int snd_bt87x_hw_params(snd_pcm_substream_t *substream,
+                              snd_pcm_hw_params_t *hw_params)
+{
+       bt87x_t *chip = snd_pcm_substream_chip(substream);
+       int err;
+
+       err = snd_pcm_lib_malloc_pages(substream,
+                                      params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
+       return snd_bt87x_create_risc(chip, substream,
+                                    params_periods(hw_params),
+                                    params_period_bytes(hw_params));
+}
+
+static int snd_bt87x_hw_free(snd_pcm_substream_t *substream)
+{
+       bt87x_t *chip = snd_pcm_substream_chip(substream);
+
+       snd_bt87x_free_risc(chip);
+       snd_pcm_lib_free_pages(substream);
+       return 0;
+}
+
+static int snd_bt87x_prepare(snd_pcm_substream_t *substream)
+{
+       bt87x_t *chip = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
+       unsigned long flags;
+       int decimation;
+
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       chip->reg_control &= ~(CTL_DA_SDR_MASK | CTL_DA_SBR);
+       decimation = (1792000 + 5) / runtime->rate;
+       chip->reg_control |= decimation << CTL_DA_SDR_SHIFT;
+       if (runtime->format == SNDRV_PCM_FORMAT_S8)
+               chip->reg_control |= CTL_DA_SBR;
+       snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       return 0;
+}
+
+static int snd_bt87x_start(bt87x_t *chip)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       chip->current_line = 0;
+       chip->reg_control |= CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN;
+       snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->risc_dma);
+       snd_bt87x_writel(chip, REG_PACKET_LEN,
+                        chip->line_bytes | (chip->lines << 16));
+       snd_bt87x_writel(chip, REG_INT_MASK, MY_INTERRUPTS);
+       snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       return 0;
+}
+
+static int snd_bt87x_stop(bt87x_t *chip)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       chip->reg_control &= ~(CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN);
+       snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+       snd_bt87x_writel(chip, REG_INT_MASK, 0);
+       snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       return 0;
+}
+
+static int snd_bt87x_trigger(snd_pcm_substream_t *substream, int cmd)
+{
+       bt87x_t *chip = snd_pcm_substream_chip(substream);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               return snd_bt87x_start(chip);
+       case SNDRV_PCM_TRIGGER_STOP:
+               return snd_bt87x_stop(chip);
+       default:
+               return -EINVAL;
+       }
+}
+
+static snd_pcm_uframes_t snd_bt87x_pointer(snd_pcm_substream_t *substream)
+{
+       bt87x_t *chip = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
+
+       return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes);
+}
+
+static snd_pcm_ops_t snd_bt87x_pcm_ops = {
+       .open = snd_bt87x_pcm_open,
+       .close = snd_bt87x_close,
+       .ioctl = snd_pcm_lib_ioctl,
+       .hw_params = snd_bt87x_hw_params,
+       .hw_free = snd_bt87x_hw_free,
+       .prepare = snd_bt87x_prepare,
+       .trigger = snd_bt87x_trigger,
+       .pointer = snd_bt87x_pointer,
+       .page = snd_pcm_sgbuf_ops_page,
+};
+
+static int snd_bt87x_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+{
+       info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       info->count = 1;
+       info->value.integer.min = 0;
+       info->value.integer.max = 15;
+       return 0;
+}
+
+static int snd_bt87x_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+       bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+
+       value->value.integer.value[0] = (chip->reg_control & CTL_A_GAIN_MASK) >> CTL_A_GAIN_SHIFT;
+       return 0;
+}
+
+static int snd_bt87x_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+       bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+       unsigned long flags;
+       u32 old_control;
+       int changed;
+
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       old_control = chip->reg_control;
+       chip->reg_control = (chip->reg_control & ~CTL_A_GAIN_MASK)
+               | (value->value.integer.value[0] << CTL_A_GAIN_SHIFT);
+       snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+       changed = old_control != chip->reg_control;
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       return changed;
+}
+
+static snd_kcontrol_new_t snd_bt87x_capture_volume = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Capture Volume",
+       .info = snd_bt87x_capture_volume_info,
+       .get = snd_bt87x_capture_volume_get,
+       .put = snd_bt87x_capture_volume_put,
+};
+
+static int snd_bt87x_capture_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+{
+       info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+       info->count = 1;
+       info->value.integer.min = 0;
+       info->value.integer.max = 1;
+       return 0;
+}
+
+static int snd_bt87x_capture_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+       bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+
+       value->value.integer.value[0] = !! (chip->reg_control & CTL_A_G2X);
+       return 0;
+}
+
+static int snd_bt87x_capture_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+       bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+       unsigned long flags;
+       u32 old_control;
+       int changed;
+
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       old_control = chip->reg_control;
+       chip->reg_control = (chip->reg_control & ~CTL_A_G2X)
+               | (value->value.integer.value[0] ? CTL_A_G2X : 0);
+       snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+       changed = chip->reg_control != old_control;
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       return changed;
+}
+
+static snd_kcontrol_new_t snd_bt87x_capture_boost = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Capture Boost",
+       .info = snd_bt87x_capture_boost_info,
+       .get = snd_bt87x_capture_boost_get,
+       .put = snd_bt87x_capture_boost_put,
+};
+
+static int snd_bt87x_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+{
+       static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"};
+
+       info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+       info->count = 1;
+       info->value.enumerated.items = 3;
+       if (info->value.enumerated.item > 2)
+               info->value.enumerated.item = 2;
+       strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
+       return 0;
+}
+
+static int snd_bt87x_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+       bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+
+       value->value.enumerated.item[0] = (chip->reg_control & CTL_A_SEL_MASK) >> CTL_A_SEL_SHIFT;
+       return 0;
+}
+
+static int snd_bt87x_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+       bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+       unsigned long flags;
+       u32 old_control;
+       int changed;
+
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       old_control = chip->reg_control;
+       chip->reg_control = (chip->reg_control & ~CTL_A_SEL_MASK)
+               | (value->value.enumerated.item[0] << CTL_A_SEL_SHIFT);
+       snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+       changed = chip->reg_control != old_control;
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       return changed;
+}
+
+static snd_kcontrol_new_t snd_bt87x_capture_source = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Capture Source",
+       .info = snd_bt87x_capture_source_info,
+       .get = snd_bt87x_capture_source_get,
+       .put = snd_bt87x_capture_source_put,
+};
+
+static int snd_bt87x_free(bt87x_t *chip)
+{
+       if (chip->mmio) {
+               snd_bt87x_stop(chip);
+               if (chip->irq >= 0)
+                       synchronize_irq(chip->irq);
+
+               iounmap(chip->mmio);
+       }
+       if (chip->res_mmio) {
+               release_resource(chip->res_mmio);
+               kfree_nocheck(chip->res_mmio);
+       }
+       if (chip->irq >= 0)
+               free_irq(chip->irq, chip);
+       snd_magic_kfree(chip);
+       return 0;
+}
+
+static int snd_bt87x_dev_free(snd_device_t *device)
+{
+       bt87x_t *chip = snd_magic_cast(bt87x_t, device->device_data, return -ENXIO);
+       return snd_bt87x_free(chip);
+}
+
+static int __devinit snd_bt87x_pcm(bt87x_t *chip, int device, char *name)
+{
+       int err;
+       snd_pcm_t *pcm;
+
+       err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
+       if (err < 0)
+               return err;
+       pcm->private_data = chip;
+       strcpy(pcm->name, name);
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_bt87x_pcm_ops);
+       return snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm,
+                                                       128 * 1024,
+                                                       (255 * 4092 + 1023) & ~1023);
+}
+
+static int __devinit snd_bt87x_create(snd_card_t *card,
+                                     struct pci_dev *pci,
+                                     bt87x_t **rchip)
+{
+       bt87x_t *chip;
+       int err;
+       static snd_device_ops_t ops = {
+               .dev_free = snd_bt87x_dev_free
+       };
+
+       *rchip = NULL;
+
+       err = pci_enable_device(pci);
+       if (err < 0)
+               return err;
+
+       chip = snd_magic_kcalloc(bt87x_t, 0, GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+       chip->card = card;
+       chip->pci = pci;
+       chip->irq = -1;
+       spin_lock_init(&chip->reg_lock);
+
+       chip->res_mmio = request_mem_region(pci_resource_start(pci, 0),
+                                           pci_resource_len(pci, 0),
+                                           "Bt87x audio");
+       if (!chip->res_mmio) {
+               snd_bt87x_free(chip);
+               snd_printk(KERN_ERR "cannot allocate io memory\n");
+               return -EBUSY;
+       }
+       chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
+                                    pci_resource_len(pci, 0));
+       if (!chip->mmio) {
+               snd_bt87x_free(chip);
+               snd_printk(KERN_ERR "cannot remap io memory\n");
+               return -ENOMEM;
+       }
+
+       chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
+       snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+       snd_bt87x_writel(chip, REG_INT_MASK, 0);
+       snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
+
+       if (request_irq(pci->irq, snd_bt87x_interrupt, SA_INTERRUPT | SA_SHIRQ,
+                       "Bt87x audio", chip)) {
+               snd_bt87x_free(chip);
+               snd_printk(KERN_ERR "cannot grab irq\n");
+               return -EBUSY;
+       }
+       chip->irq = pci->irq;
+       pci_set_master(pci);
+       synchronize_irq(chip->irq);
+
+       err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+       if (err < 0) {
+               snd_bt87x_free(chip);
+               return err;
+       }
+       snd_card_set_dev(card, &pci->dev);
+       *rchip = chip;
+       return 0;
+}
+
+static int __devinit snd_bt87x_probe(struct pci_dev *pci,
+                                    const struct pci_device_id *pci_id)
+{
+       static int dev;
+       snd_card_t *card;
+       bt87x_t *chip;
+       int err;
+
+       if (dev >= SNDRV_CARDS)
+               return -ENODEV;
+       if (!enable[dev]) {
+               ++dev;
+               return -ENOENT;
+       }
+
+       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+       if (!card)
+               return -ENOMEM;
+
+       err = snd_bt87x_create(card, pci, &chip);
+       if (err < 0)
+               goto _error;
+
+       if (digital_rate[dev] > 0)
+               chip->dig_rate = digital_rate[dev];
+       else
+               chip->dig_rate = (int)pci_id->driver_data;
+
+       err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
+       if (err < 0)
+               goto _error;
+       err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
+       if (err < 0)
+               goto _error;
+
+       err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_volume, chip));
+       if (err < 0)
+               goto _error;
+       err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_boost, chip));
+       if (err < 0)
+               goto _error;
+       err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_source, chip));
+       if (err < 0)
+               goto _error;
+
+       strcpy(card->driver, "Bt87x");
+       sprintf(card->shortname, "Brooktree Bt%x", pci->device);
+       sprintf(card->longname, "%s at %#lx, irq %i",
+               card->shortname, pci_resource_start(pci, 0), chip->irq);
+       strcpy(card->mixername, "Bt87x");
+
+       err = snd_card_register(card);
+       if (err < 0)
+               goto _error;
+
+       pci_set_drvdata(pci, chip);
+       ++dev;
+       return 0;
+
+_error:
+       snd_card_free(card);
+       return err;
+}
+
+static void __devexit snd_bt87x_remove(struct pci_dev *pci)
+{
+       bt87x_t *chip = snd_magic_cast(bt87x_t, pci_get_drvdata(pci), return);
+       if (chip)
+               snd_card_free(chip->card);
+       pci_set_drvdata(pci, NULL);
+}
+
+#define BT_DEVICE(chip, subvend, subdev, rate) \
+       { .vendor = PCI_VENDOR_ID_BROOKTREE, \
+         .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
+         .subvendor = subvend, .subdevice = subdev, \
+         .driver_data = rate }
+
+/* driver_data is the default digital_rate value for that device */
+static struct pci_device_id snd_bt87x_ids[] = {
+       BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Osprey 200 */
+
+       /* default entries for 32kHz and generic Bt87x cards */
+       BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 32000),
+       BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 32000),
+       { }
+};
+MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
+
+static struct pci_driver driver = {
+       .name = "Bt87x",
+       .id_table = snd_bt87x_ids,
+       .probe = snd_bt87x_probe,
+       .remove = __devexit_p(snd_bt87x_remove),
+};
+
+static int __init alsa_card_bt87x_init(void)
+{
+       int err;
+
+       err = pci_module_init(&driver);
+       if (err < 0) {
+#ifdef MODULE
+               printk(KERN_ERR "Bt87x soundcard not found or device busy\n");
+#endif
+               return err;
+       }
+       return 0;
+}
+
+static void __exit alsa_card_bt87x_exit(void)
+{
+       pci_unregister_driver(&driver);
+}
+
+module_init(alsa_card_bt87x_init)
+module_exit(alsa_card_bt87x_exit)
+
+#ifndef MODULE
+
+/* format is: snd-bt87x=enable,index,id */
+
+static int __init alsa_card_bt87x_setup(char *str)
+{
+       static unsigned __initdata nr_dev = 0;
+
+       if (nr_dev >= SNDRV_CARDS)
+               return 0;
+       (void)(get_option(&str,&enable[nr_dev]) == 2 &&
+              get_option(&str,&index[nr_dev]) == 2 &&
+              get_id(&str,&id[nr_dev]) == 2);
+       nr_dev++;
+       return 1;
+}
+
+__setup("snd-bt87x=", alsa_card_bt87x_setup);
+
+#endif /* ifndef MODULE */
index 39d4cd6..3100d00 100644 (file)
@@ -1391,7 +1391,7 @@ int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
                temp |= DMA_RQ_C1_SOURCE_MOD16;
                break; 
        default:
-               snd_printdd ("period size (%d) not supported by HW\n");
+               snd_printdd ("period size (%d) not supported by HW\n", period_size);
                return -EINVAL;
        }
 
@@ -1429,7 +1429,7 @@ int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
                temp |= DMA_RQ_C1_DEST_MOD16;
                break; 
        default:
-               snd_printdd ("period size (%d) not supported by HW\n");
+               snd_printdd ("period size (%d) not supported by HW\n", period_size);
                return -EINVAL;
        }
 
index 6858a54..af94e82 100644 (file)
@@ -1330,7 +1330,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
 #define A_ADD_VOLUME_IN(var,vol,input) \
 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
 
-       /* AC'97 Playback Volume - used only for mic */
+       /* AC'97 Playback Volume - used only for mic (renamed later) */
        A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
        A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
        snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
@@ -1347,12 +1347,16 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
        /* Audigy CD Playback Volume */
        A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
        A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
-       snd_emu10k1_init_stereo_control(&controls[nctl++], "Audigy CD Playback Volume", gpr, 0);
+       snd_emu10k1_init_stereo_control(&controls[nctl++],
+                                       emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
+                                       gpr, 0);
        gpr += 2;
        /* Audigy CD Capture Volume */
        A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
        A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
-       snd_emu10k1_init_stereo_control(&controls[nctl++], "Audigy CD Capture Volume", gpr, 0);
+       snd_emu10k1_init_stereo_control(&controls[nctl++],
+                                       emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
+                                       gpr, 0);
        gpr += 2;
 
        /* Optical SPDIF Playback Volume */
@@ -1369,12 +1373,16 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
        /* Line2 Playback Volume */
        A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
        A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
-       snd_emu10k1_init_stereo_control(&controls[nctl++], "Line2 Playback Volume", gpr, 0);
+       snd_emu10k1_init_stereo_control(&controls[nctl++],
+                                       emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
+                                       gpr, 0);
        gpr += 2;
        /* Line2 Capture Volume */
        A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
        A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
-       snd_emu10k1_init_stereo_control(&controls[nctl++], "Line2 Capture Volume", gpr, 0);
+       snd_emu10k1_init_stereo_control(&controls[nctl++],
+                                       emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
+                                       gpr, 0);
        gpr += 2;
         
        /* Philips ADC Playback Volume */
@@ -1391,12 +1399,16 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
        /* Aux2 Playback Volume */
        A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
        A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
-       snd_emu10k1_init_stereo_control(&controls[nctl++], "Aux2 Playback Volume", gpr, 0);
+       snd_emu10k1_init_stereo_control(&controls[nctl++],
+                                       emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
+                                       gpr, 0);
        gpr += 2;
        /* Aux2 Capture Volume */
        A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
        A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
-       snd_emu10k1_init_stereo_control(&controls[nctl++], "Aux2 Capture Volume", gpr, 0);
+       snd_emu10k1_init_stereo_control(&controls[nctl++],
+                                       emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
+                                       gpr, 0);
        gpr += 2;
        
        /* Stereo Mix Front Playback Volume */
index b92687f..4dbe65a 100644 (file)
 
 #include <asm/io.h>
 
+#if defined(CONFIG_SND_FM801_TEA575X) && (defined(CONFIG_VIDEO_DEV) || defined(CONFIG_VIDEO_DEV_MODULE))
+#include <sound/tea575x-tuner.h>
+#define TEA575X_RADIO 1
+#endif
+
 #define chip_t fm801_t
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -47,6 +52,14 @@ MODULE_DEVICES("{{ForteMedia,FM801},"
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;     /* Enable this card */
+/*
+ *  Enable TEA575x tuner
+ *    1 = MediaForte 256-PCS
+ *    2 = MediaForte 256-PCPR
+ *    3 = MediaForte 64-PCR
+ *  High 16-bits are video (radio) device number + 1
+ */
+static int tea575x_tuner[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 };
 
 MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
@@ -57,6 +70,9 @@ MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
 MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
 MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
+MODULE_PARM(tea575x_tuner, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(tea575x_tuner, "Enable TEA575x tuner.");
+MODULE_PARM_SYNTAX(tea575x_tuner, SNDRV_ENABLE_DESC);
 
 /*
  *  Direct registers
@@ -116,6 +132,23 @@ MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
 #define FM801_IRQ_CAPTURE      (1<<9)
 #define FM801_IRQ_VOLUME       (1<<14)
 #define FM801_IRQ_MPU          (1<<15)
+
+/* GPIO control register */
+#define FM801_GPIO_GP0         (1<<0)  /* read/write */
+#define FM801_GPIO_GP1         (1<<1)
+#define FM801_GPIO_GP2         (1<<2)
+#define FM801_GPIO_GP3         (1<<3)
+#define FM801_GPIO_GP(x)       (1<<(0+(x)))
+#define FM801_GPIO_GD0         (1<<8)  /* directions: 1 = input, 0 = output*/
+#define FM801_GPIO_GD1         (1<<9)
+#define FM801_GPIO_GD2         (1<<10)
+#define FM801_GPIO_GD3         (1<<11)
+#define FM801_GPIO_GD(x)       (1<<(8+(x)))
+#define FM801_GPIO_GS0         (1<<12) /* function select: */
+#define FM801_GPIO_GS1         (1<<13) /*    1 = GPIO */
+#define FM801_GPIO_GS2         (1<<14) /*    0 = other (S/PDIF, VOL) */
+#define FM801_GPIO_GS3         (1<<15)
+#define FM801_GPIO_GS(x)       (1<<(12+(x)))
        
 /*
 
@@ -162,6 +195,10 @@ struct _snd_fm801 {
 
        spinlock_t reg_lock;
        snd_info_entry_t *proc_entry;
+
+#ifdef TEA575X_RADIO
+       tea575x_t tea;
+#endif
 };
 
 static struct pci_device_id snd_fm801_ids[] = {
@@ -674,6 +711,295 @@ static int __devinit snd_fm801_pcm(fm801_t *chip, int device, snd_pcm_t ** rpcm)
 }
 
 /*
+ *  TEA5757 radio
+ */
+
+#ifdef TEA575X_RADIO
+
+/* 256PCS GPIO numbers */
+#define TEA_256PCS_DATA                        1
+#define TEA_256PCS_WRITE_ENABLE                2       /* inverted */
+#define TEA_256PCS_BUS_CLOCK           3
+
+static void snd_fm801_tea575x_256pcs_write(tea575x_t *tea, unsigned int val)
+{
+       fm801_t *chip = tea->private_data;
+       unsigned short reg;
+       int i = 25;
+
+       spin_lock_irq(&chip->reg_lock);
+       reg = inw(FM801_REG(chip, GPIO_CTRL));
+       /* use GPIO lines and set write enable bit */
+       reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
+              FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
+              FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK);
+       /* all of lines are in the write direction */
+       /* clear data and clock lines */
+       reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) |
+                FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
+                FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_256PCS_DATA) |
+                FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE));
+       outw(reg, FM801_REG(chip, GPIO_CTRL));
+       udelay(1);
+
+       while (i--) {
+               if (val & (1 << i))
+                       reg |= FM801_GPIO_GP(TEA_256PCS_DATA);
+               else
+                       reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+       }
+
+       /* and reset the write enable bit */
+       reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) |
+              FM801_GPIO_GP(TEA_256PCS_DATA);
+       outw(reg, FM801_REG(chip, GPIO_CTRL));
+       spin_unlock_irq(&chip->reg_lock);
+}
+
+static unsigned int snd_fm801_tea575x_256pcs_read(tea575x_t *tea)
+{
+       fm801_t *chip = tea->private_data;
+       unsigned short reg;
+       unsigned int val = 0;
+       int i;
+       
+       spin_lock_irq(&chip->reg_lock);
+       reg = inw(FM801_REG(chip, GPIO_CTRL));
+       /* use GPIO lines, set data direction to input */
+       reg |= FM801_GPIO_GS(TEA_256PCS_DATA) |
+              FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) |
+              FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) |
+              FM801_GPIO_GD(TEA_256PCS_DATA) |
+              FM801_GPIO_GP(TEA_256PCS_DATA) |
+              FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE);
+       /* all of lines are in the write direction, except data */
+       /* clear data, write enable and clock lines */
+       reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) |
+                FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK));
+
+       for (i = 0; i < 24; i++) {
+               reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               val <<= 1;
+               if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA))
+                       val |= 1;
+       }
+
+       spin_unlock_irq(&chip->reg_lock);
+
+       return val;
+}
+
+/* 256PCPR GPIO numbers */
+#define TEA_256PCPR_BUS_CLOCK          0
+#define TEA_256PCPR_DATA               1
+#define TEA_256PCPR_WRITE_ENABLE       2       /* inverted */
+
+static void snd_fm801_tea575x_256pcpr_write(tea575x_t *tea, unsigned int val)
+{
+       fm801_t *chip = tea->private_data;
+       unsigned short reg;
+       int i = 25;
+
+       spin_lock_irq(&chip->reg_lock);
+       reg = inw(FM801_REG(chip, GPIO_CTRL));
+       /* use GPIO lines and set write enable bit */
+       reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
+              FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
+              FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK);
+       /* all of lines are in the write direction */
+       /* clear data and clock lines */
+       reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) |
+                FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
+                FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_256PCPR_DATA) |
+                FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE));
+       outw(reg, FM801_REG(chip, GPIO_CTRL));
+       udelay(1);
+
+       while (i--) {
+               if (val & (1 << i))
+                       reg |= FM801_GPIO_GP(TEA_256PCPR_DATA);
+               else
+                       reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+       }
+
+       /* and reset the write enable bit */
+       reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) |
+              FM801_GPIO_GP(TEA_256PCPR_DATA);
+       outw(reg, FM801_REG(chip, GPIO_CTRL));
+       spin_unlock_irq(&chip->reg_lock);
+}
+
+static unsigned int snd_fm801_tea575x_256pcpr_read(tea575x_t *tea)
+{
+       fm801_t *chip = tea->private_data;
+       unsigned short reg;
+       unsigned int val = 0;
+       int i;
+       
+       spin_lock_irq(&chip->reg_lock);
+       reg = inw(FM801_REG(chip, GPIO_CTRL));
+       /* use GPIO lines, set data direction to input */
+       reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) |
+              FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) |
+              FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) |
+              FM801_GPIO_GD(TEA_256PCPR_DATA) |
+              FM801_GPIO_GP(TEA_256PCPR_DATA) |
+              FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE);
+       /* all of lines are in the write direction, except data */
+       /* clear data, write enable and clock lines */
+       reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) |
+                FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK));
+
+       for (i = 0; i < 24; i++) {
+               reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               val <<= 1;
+               if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA))
+                       val |= 1;
+       }
+
+       spin_unlock_irq(&chip->reg_lock);
+
+       return val;
+}
+
+/* 64PCR GPIO numbers */
+#define TEA_64PCR_BUS_CLOCK            0
+#define TEA_64PCR_WRITE_ENABLE         1       /* inverted */
+#define TEA_64PCR_DATA                 2
+
+static void snd_fm801_tea575x_64pcr_write(tea575x_t *tea, unsigned int val)
+{
+       fm801_t *chip = tea->private_data;
+       unsigned short reg;
+       int i = 25;
+
+       spin_lock_irq(&chip->reg_lock);
+       reg = inw(FM801_REG(chip, GPIO_CTRL));
+       /* use GPIO lines and set write enable bit */
+       reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
+              FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
+              FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK);
+       /* all of lines are in the write direction */
+       /* clear data and clock lines */
+       reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) |
+                FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
+                FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_64PCR_DATA) |
+                FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE));
+       outw(reg, FM801_REG(chip, GPIO_CTRL));
+       udelay(1);
+
+       while (i--) {
+               if (val & (1 << i))
+                       reg |= FM801_GPIO_GP(TEA_64PCR_DATA);
+               else
+                       reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+       }
+
+       /* and reset the write enable bit */
+       reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) |
+              FM801_GPIO_GP(TEA_64PCR_DATA);
+       outw(reg, FM801_REG(chip, GPIO_CTRL));
+       spin_unlock_irq(&chip->reg_lock);
+}
+
+static unsigned int snd_fm801_tea575x_64pcr_read(tea575x_t *tea)
+{
+       fm801_t *chip = tea->private_data;
+       unsigned short reg;
+       unsigned int val = 0;
+       int i;
+       
+       spin_lock_irq(&chip->reg_lock);
+       reg = inw(FM801_REG(chip, GPIO_CTRL));
+       /* use GPIO lines, set data direction to input */
+       reg |= FM801_GPIO_GS(TEA_64PCR_DATA) |
+              FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) |
+              FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) |
+              FM801_GPIO_GD(TEA_64PCR_DATA) |
+              FM801_GPIO_GP(TEA_64PCR_DATA) |
+              FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE);
+       /* all of lines are in the write direction, except data */
+       /* clear data, write enable and clock lines */
+       reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) |
+                FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) |
+                FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK));
+
+       for (i = 0; i < 24; i++) {
+               reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK);
+               outw(reg, FM801_REG(chip, GPIO_CTRL));
+               udelay(1);
+               val <<= 1;
+               if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA))
+                       val |= 1;
+       }
+
+       spin_unlock_irq(&chip->reg_lock);
+
+       return val;
+}
+
+static struct snd_tea575x_ops snd_fm801_tea_ops[3] = {
+       {
+               /* 1 = MediaForte 256-PCS */
+               .write = snd_fm801_tea575x_256pcs_write,
+               .read = snd_fm801_tea575x_256pcs_read,
+       },
+       {
+               /* 2 = MediaForte 256-PCPR */
+               .write = snd_fm801_tea575x_256pcpr_write,
+               .read = snd_fm801_tea575x_256pcpr_read,
+       },
+       {
+               /* 3 = MediaForte 64-PCR */
+               .write = snd_fm801_tea575x_64pcr_write,
+               .read = snd_fm801_tea575x_64pcr_read,
+       }
+};
+#endif
+
+/*
  *  Mixer routines
  */
 
@@ -913,6 +1239,9 @@ static int snd_fm801_free(fm801_t *chip)
        outw(cmdw, FM801_REG(chip, IRQ_MASK));
 
       __end_hw:
+#ifdef TEA575X_RADIO
+       snd_tea575x_exit(&chip->tea);
+#endif
        if (chip->res_port) {
                release_resource(chip->res_port);
                kfree_nocheck(chip->res_port);
@@ -931,8 +1260,9 @@ static int snd_fm801_dev_free(snd_device_t *device)
 }
 
 static int __devinit snd_fm801_create(snd_card_t * card,
-                                  struct pci_dev * pci,
-                                  fm801_t ** rchip)
+                                     struct pci_dev * pci,
+                                     int tea575x_tuner,
+                                     fm801_t ** rchip)
 {
        fm801_t *chip;
        unsigned char rev, id;
@@ -1056,6 +1386,17 @@ static int __devinit snd_fm801_create(snd_card_t * card,
 
        snd_card_set_dev(card, &pci->dev);
 
+#ifdef TEA575X_RADIO
+       if (tea575x_tuner > 0 && (tea575x_tuner & 0xffff) < 4) {
+               chip->tea.dev_nr = tea575x_tuner >> 16;
+               chip->tea.card = card;
+               chip->tea.freq_fixup = 10700;
+               chip->tea.private_data = chip;
+               chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0xffff) - 1];
+               snd_tea575x_init(&chip->tea);
+       }
+#endif
+
        *rchip = chip;
        return 0;
 }
@@ -1079,7 +1420,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
        card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
        if (card == NULL)
                return -ENOMEM;
-       if ((err = snd_fm801_create(card, pci, &chip)) < 0) {
+       if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) {
                snd_card_free(card);
                return err;
        }
@@ -1160,7 +1501,7 @@ module_exit(alsa_card_fm801_exit)
 
 #ifndef MODULE
 
-/* format is: snd-fm801=enable,index,id */
+/* format is: snd-fm801=enable,index,id,tea575x_tuner */
 
 static int __init alsa_card_fm801_setup(char *str)
 {
@@ -1170,7 +1511,8 @@ static int __init alsa_card_fm801_setup(char *str)
                return 0;
        (void)(get_option(&str,&enable[nr_dev]) == 2 &&
               get_option(&str,&index[nr_dev]) == 2 &&
-              get_id(&str,&id[nr_dev]) == 2);
+              get_id(&str,&id[nr_dev]) == 2 &&
+              get_option(&str,&tea575x_tuner[nr_dev]));
        nr_dev++;
        return 1;
 }
index 463070b..c718142 100644 (file)
@@ -33,8 +33,8 @@
 extern struct snd_ice1712_card_info  snd_vt1724_aureon_cards[];
 
 /* GPIO bits */
-#define AUREON_CS8415_CS       (1 << 23)
-#define AUREON_CS8415_CDTO     (1 << 22)
+#define AUREON_CS8415_CS       (1 << 22)
+#define AUREON_CS8415_CDTO     (1 << 21)
 #define AUREON_WM_RESET                (1 << 20)
 #define AUREON_WM_CLK          (1 << 19)
 #define AUREON_WM_DATA         (1 << 18)
index fb172aa..c0580f5 100644 (file)
@@ -2,6 +2,7 @@
  *   ALSA driver for ICEnsemble ICE1712 (Envy24)
  *
  *   Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
+ *                          Digigram VX442
  *
  *     Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
  *
@@ -83,12 +84,19 @@ static unsigned char ap_cs8427_codec_select(ice1712_t *ice)
 {
        unsigned char tmp;
        tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-       if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010LT) {
+       switch (ice->eeprom.subvendor) {
+       case ICE1712_SUBDEVICE_DELTA1010LT:
                tmp &= ~ICE1712_DELTA_1010LT_CS;
                tmp |= ICE1712_DELTA_1010LT_CCLK | ICE1712_DELTA_1010LT_CS_CS8427;
-       } else { /* Audiophile */
+               break;
+       case ICE1712_SUBDEVICE_AUDIOPHILE:
                tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
                tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
+               break;
+       case ICE1712_SUBDEVICE_VX442:
+               tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
+               tmp &= ~ICE1712_VX442_CS_DIGITAL;
+               break;
        }
        snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
        udelay(5);
@@ -98,11 +106,17 @@ static unsigned char ap_cs8427_codec_select(ice1712_t *ice)
 /* deassert chip select */
 static void ap_cs8427_codec_deassert(ice1712_t *ice, unsigned char tmp)
 {
-       if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010LT) {
+       switch (ice->eeprom.subvendor) {
+       case ICE1712_SUBDEVICE_DELTA1010LT:
                tmp &= ~ICE1712_DELTA_1010LT_CS;
                tmp |= ICE1712_DELTA_1010LT_CS_NONE;
-       } else { /* Audiophile */
+               break;
+       case ICE1712_SUBDEVICE_AUDIOPHILE:
                tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
+               break;
+       case ICE1712_SUBDEVICE_VX442:
+               tmp |= ICE1712_VX442_CS_DIGITAL;
+               break;
        }
        snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
 }
@@ -257,6 +271,20 @@ static void delta1010lt_ak4524_lock(akm4xxx_t *ak, int chip)
 }
 
 /*
+ * AK4528 on VX442 to choose the chip mask
+ */
+static void vx442_ak4524_lock(akm4xxx_t *ak, int chip)
+{
+        struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
+        ice1712_t *ice = ak->private_data[0];
+
+       snd_ice1712_save_gpio_status(ice);
+       priv->cs_mask =
+       priv->cs_addr = chip == 0 ? ICE1712_VX442_CODEC_CHIP_A :
+                                   ICE1712_VX442_CODEC_CHIP_B;
+}
+
+/*
  * change the DFS bit according rate for Delta1010
  */
 static void delta_1010_set_rate_val(ice1712_t *ice, unsigned int rate)
@@ -308,6 +336,23 @@ static void delta_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
        snd_akm4xxx_reset(ak, 0);
 }
 
+/*
+ * change the rate of AK4524 on VX442
+ */
+static void vx442_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
+{
+       unsigned char val;
+
+       val = (rate > 48000) ? 0x65 : 0x60;
+       if (snd_akm4xxx_get(ak, 0, 0x02) != val ||
+           snd_akm4xxx_get(ak, 1, 0x02) != val) {
+               snd_akm4xxx_reset(ak, 1);
+               snd_akm4xxx_write(ak, 0, 0x02, val);
+               snd_akm4xxx_write(ak, 1, 0x02, val);
+               snd_akm4xxx_reset(ak, 0);
+       }
+}
+
 
 /*
  * SPDIF ops for Delta 1010, Dio, 66
@@ -435,6 +480,28 @@ static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
        .mask_flags = 0,
 };
 
+static akm4xxx_t akm_vx442 __devinitdata = {
+       .type = SND_AK4524,
+       .num_adcs = 4,
+       .num_dacs = 4,
+       .ops = {
+               .lock = vx442_ak4524_lock,
+               .set_rate_val = vx442_ak4524_set_rate_val
+       }
+};
+
+static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
+       .caddr = 2,
+       .cif = 0,
+       .data_mask = ICE1712_VX442_DOUT,
+       .clk_mask = ICE1712_VX442_CCLK,
+       .cs_mask = 0,
+       .cs_addr = 0, /* set later */
+       .cs_none = 0,
+       .add_flags = 0,
+       .mask_flags = 0,
+};
+
 static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
 {
        int err;
@@ -456,6 +523,9 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
        case ICE1712_SUBDEVICE_DELTA1010LT:
                ice->num_total_dacs = 8;
                break;
+       case ICE1712_SUBDEVICE_VX442:
+               ice->num_total_dacs = 4;
+               break;
        }
 
        /* initialize spdif */
@@ -463,6 +533,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
        case ICE1712_SUBDEVICE_AUDIOPHILE:
        case ICE1712_SUBDEVICE_DELTA410:
        case ICE1712_SUBDEVICE_DELTA1010LT:
+       case ICE1712_SUBDEVICE_VX442:
                if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
                        snd_printk("unable to create I2C bus\n");
                        return err;
@@ -517,6 +588,9 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
        case ICE1712_SUBDEVICE_DELTA44:
                err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
                break;
+       case ICE1712_SUBDEVICE_VX442:
+               err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
+               break;
        default:
                snd_BUG();
                return -EINVAL;
@@ -597,11 +671,13 @@ static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
        case ICE1712_SUBDEVICE_DELTA410:
        case ICE1712_SUBDEVICE_DELTA44:
        case ICE1712_SUBDEVICE_DELTA66:
+       case ICE1712_SUBDEVICE_VX442:
                err = snd_ice1712_akm4xxx_build_controls(ice);
                if (err < 0)
                        return err;
                break;
        }
+
        return 0;
 }
 
@@ -653,5 +729,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
                snd_ice1712_delta_init,
                snd_ice1712_delta_add_controls,
        },
+       {
+               ICE1712_SUBDEVICE_VX442,
+               "Digigram VX442",
+               snd_ice1712_delta_init,
+               snd_ice1712_delta_add_controls,
+               1, /* NO MPU */
+       },
        { } /* terminator */
 };
index dc8a3a6..8bf1ecf 100644 (file)
@@ -5,6 +5,7 @@
  *   ALSA driver for ICEnsemble ICE1712 (Envy24)
  *
  *   Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
+ *                          Digigram VX442
  *
  *     Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
  *
@@ -30,7 +31,8 @@
                "{MidiMan M Audio,Delta DiO 2496},"\
                "{MidiMan M Audio,Delta 66},"\
                "{MidiMan M Audio,Delta 44},"\
-               "{MidiMan M Audio,Audiophile 24/96},"
+               "{MidiMan M Audio,Audiophile 24/96},"\
+               "{Digigram,VX442},"
 
 #define ICE1712_SUBDEVICE_DELTA1010    0x121430d6
 #define ICE1712_SUBDEVICE_DELTADIO2496 0x121431d6
@@ -39,6 +41,7 @@
 #define ICE1712_SUBDEVICE_AUDIOPHILE   0x121434d6
 #define ICE1712_SUBDEVICE_DELTA410     0x121438d6
 #define ICE1712_SUBDEVICE_DELTA1010LT  0x12143bd6
+#define ICE1712_SUBDEVICE_VX442                0x12143cd6
 
 /* entry point */
 extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
@@ -134,4 +137,12 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
 #define ICE1712_DELTA_1010LT_CS_NONE   0x50    /* nothing */
 #define ICE1712_DELTA_1010LT_WORDCLOCK 0x80    /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
 
+/* Digigram VX442 definitions */
+#define ICE1712_VX442_CCLK             0x02    /* SPI clock */
+#define ICE1712_VX442_DIN              0x04    /* data input */
+#define ICE1712_VX442_DOUT             0x08    /* data output */
+#define ICE1712_VX442_CS_DIGITAL       0x10    /* chip select, low = CS8427 */
+#define ICE1712_VX442_CODEC_CHIP_A     0x20    /* select chip A */
+#define ICE1712_VX442_CODEC_CHIP_B     0x40    /* select chip B */
+
 #endif /* __SOUND_DELTA_H */
index f72415e..3103b84 100644 (file)
@@ -295,8 +295,8 @@ static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
 static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
 {
        ice1712_t *ice = snd_pcm_substream_chip(substream);
-       unsigned int what;
-       unsigned int old;
+       unsigned char what;
+       unsigned char old;
        struct list_head *pos;
        snd_pcm_substream_t *s;
 
@@ -316,12 +316,12 @@ static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
                                what |= VT1724_RDMA1_PAUSE;
                }
                spin_lock(&ice->reg_lock);
-               old = inl(ICEMT1724(ice, DMA_PAUSE));
+               old = inb(ICEMT1724(ice, DMA_PAUSE));
                if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
                        old |= what;
                else
                        old &= ~what;
-               outl(old, ICEMT1724(ice, DMA_PAUSE));
+               outb(old, ICEMT1724(ice, DMA_PAUSE));
                spin_unlock(&ice->reg_lock);
                break;
 
@@ -346,12 +346,12 @@ static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
                        }
                }
                spin_lock(&ice->reg_lock);
-               old = inl(ICEMT1724(ice, DMA_CONTROL));
+               old = inb(ICEMT1724(ice, DMA_CONTROL));
                if (cmd == SNDRV_PCM_TRIGGER_START)
                        old |= what;
                else
                        old &= ~what;
-               outl(old, ICEMT1724(ice, DMA_CONTROL));
+               outb(old, ICEMT1724(ice, DMA_CONTROL));
                spin_unlock(&ice->reg_lock);
                break;
 
index 4eb1e28..a86481b 100644 (file)
@@ -72,6 +72,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;    /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;     /* Enable this card */
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int ac97_quirk[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = AC97_TUNE_DEFAULT};
 #ifdef SUPPORT_JOYSTICK
 static int joystick[SNDRV_CARDS];
 #endif
@@ -91,6 +92,9 @@ MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
 MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
 MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:0");
+MODULE_PARM(ac97_quirk, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
+MODULE_PARM_SYNTAX(ac97_quirk, SNDRV_ENABLED ",allows:{{-1,3}},dialog:list,default:-1");
 #ifdef SUPPORT_JOYSTICK
 MODULE_PARM(joystick, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(joystick, "Enable joystick for Intel i8x0 soundcard.");
@@ -1107,6 +1111,9 @@ static int snd_intel8x0_playback_open(snd_pcm_substream_t * substream)
        int err;
 
        err = snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMOUT]);
+       if (err < 0)
+               return err;
+
        if (chip->multi6) {
                runtime->hw.channels_max = 6;
                snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels6);
@@ -1689,6 +1696,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
                .type = AC97_TUNE_HP_ONLY
        },
        {
+               .vendor = 0x10f1,
+               .device = 0x2885,
+               .name = "AMD64 Mobo",   /* ALC650 */
+               .type = AC97_TUNE_HP_ONLY
+       },
+       {
                .vendor = 0x110a,
                .device = 0x0056,
                .name = "Fujitsu-Siemens Scenic",       /* AD1981? */
@@ -1701,6 +1714,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
                .type = AC97_TUNE_HP_ONLY
        },
        {
+               .vendor = 0x1462,
+               .device = 0x5470,
+               .name = "MSI P4 ATX 645 Ultra",
+               .type = AC97_TUNE_HP_ONLY
+       },
+       {
                .vendor = 0x1734,
                .device = 0x0088,
                .name = "Fujitsu-Siemens D1522",        /* AD1981 */
@@ -1750,7 +1769,7 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
        { } /* terminator */
 };
 
-static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
+static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock, int ac97_quirk)
 {
        ac97_bus_t bus, *pbus;
        ac97_t ac97, *x97;
@@ -1840,7 +1859,7 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
                chip->ac97[i] = x97;
        }
        /* tune up the primary codec */
-       snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks);
+       snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, ac97_quirk);
        /* enable separate SDINs for ICH4 */
        if (chip->device_type == DEVICE_INTEL_ICH4)
                pbus->isdin = 1;
@@ -2264,10 +2283,8 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
 
        t = stop_time.tv_sec - start_time.tv_sec;
        t *= 1000000;
-       if (stop_time.tv_usec < start_time.tv_usec)
-               t -= start_time.tv_usec - stop_time.tv_usec;
-       else
-               t += stop_time.tv_usec - start_time.tv_usec;
+       t += stop_time.tv_usec - start_time.tv_usec;
+       printk(KERN_INFO "%s: measured %lu usecs\n", __FUNCTION__, t);
        if (t == 0) {
                snd_printk(KERN_ERR "?? calculation error..\n");
                return;
@@ -2598,7 +2615,7 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
                return err;
        }
 
-       if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev])) < 0) {
+       if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) {
                snd_card_free(card);
                return err;
        }
@@ -2783,7 +2800,7 @@ module_exit(alsa_card_intel8x0_exit)
 
 #ifndef MODULE
 
-/* format is: snd-intel8x0=enable,index,id,ac97_clock,mpu_port,joystick */
+/* format is: snd-intel8x0=enable,index,id,ac97_clock,ac97_quirk,mpu_port,joystick */
 
 static int __init alsa_card_intel8x0_setup(char *str)
 {
@@ -2794,7 +2811,8 @@ static int __init alsa_card_intel8x0_setup(char *str)
        (void)(get_option(&str,&enable[nr_dev]) == 2 &&
               get_option(&str,&index[nr_dev]) == 2 &&
               get_id(&str,&id[nr_dev]) == 2 &&
-              get_option(&str,&ac97_clock[nr_dev]) == 2
+              get_option(&str,&ac97_clock[nr_dev]) == 2 &&
+              get_option(&str,&ac97_quirk[nr_dev]) == 2
 #ifdef SUPPORT_MIDI
               && get_option(&str,&mpu_port[nr_dev]) == 2
 #endif
index dfcfa92..656c8d0 100644 (file)
@@ -82,6 +82,7 @@ static long mpu_port[SNDRV_CARDS];
 static int joystick[SNDRV_CARDS];
 #endif
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int ac97_quirk[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = AC97_TUNE_DEFAULT};
 static int dxs_support[SNDRV_CARDS];
 
 MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
@@ -104,6 +105,9 @@ MODULE_PARM_SYNTAX(joystick, SNDRV_ENABLE_DESC "," SNDRV_BOOLEAN_FALSE_DESC);
 MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
 MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:48000");
+MODULE_PARM(ac97_quirk, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
+MODULE_PARM_SYNTAX(ac97_quirk, SNDRV_ENABLED ",allows:{{-1,3}},dialog:list,default:-1");
 MODULE_PARM(dxs_support, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA)");
 MODULE_PARM_SYNTAX(dxs_support, SNDRV_ENABLED ",allows:{{0,4}},dialog:list");
@@ -523,14 +527,16 @@ static int snd_via82xx_codec_ready(via82xx_t *chip, int secondary)
 static int snd_via82xx_codec_valid(via82xx_t *chip, int secondary)
 {
        unsigned int timeout = 1000;    /* 1ms */
-       unsigned int val;
+       unsigned int val, val1;
        unsigned int stat = !secondary ? VIA_REG_AC97_PRIMARY_VALID :
                                         VIA_REG_AC97_SECONDARY_VALID;
        
        while (timeout-- > 0) {
-               udelay(1);
-               if ((val = snd_via82xx_codec_xread(chip)) & stat)
+               val = snd_via82xx_codec_xread(chip);
+               val1 = val & (VIA_REG_AC97_BUSY | stat);
+               if (val1 == stat)
                        return val & 0xffff;
+               udelay(1);
        }
        return -EIO;
 }
@@ -580,8 +586,7 @@ static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
                        return 0xffff;
                }
                snd_via82xx_codec_xwrite(chip, xval);
-               if (snd_via82xx_codec_ready(chip, ac97->num) < 0)
-                       continue;
+               udelay (20);
                if (snd_via82xx_codec_valid(chip, ac97->num) >= 0) {
                        udelay(25);
                        val = snd_via82xx_codec_xread(chip);
@@ -1558,7 +1563,7 @@ static struct ac97_quirk ac97_quirks[] = {
        { } /* terminator */
 };
 
-static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
+static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, int ac97_quirk)
 {
        ac97_bus_t bus;
        ac97_t ac97;
@@ -1581,7 +1586,7 @@ static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
        if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
                return err;
 
-       snd_ac97_tune_hardware(chip->ac97, ac97_quirks);
+       snd_ac97_tune_hardware(chip->ac97, ac97_quirks, ac97_quirk);
 
        if (chip->chip_type != TYPE_VIA686) {
                /* use slot 10/11 */
@@ -1641,14 +1646,6 @@ static int snd_via686_init_misc(via82xx_t *chip, int dev)
                } else {
                        mpu_port[dev] = pci_resource_start(chip->pci, 2);
                }
-               if (mpu_port[dev] >= 0x200 &&
-                   (chip->mpu_res = request_region(pci_resource_start(chip->pci, 2), 2,
-                                                   "VIA82xx MPU401")) != NULL) {
-                       legacy |= VIA_FUNC_ENABLE_MIDI;
-               } else {
-                       mpu_port[dev] = 0;
-                       legacy &= ~VIA_FUNC_ENABLE_MIDI;
-               }
        } else {
                switch (mpu_port[dev]) {        /* force MIDI */
                case 0x300:
@@ -1987,7 +1984,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
                { .vendor = 0x1019, .device = 0x0996, .action = VIA_DXS_48K },
                { .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_ENABLE }, /* ASUS A7V8X */
                { .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
-               { .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_ENABLE }, /* ASUS A7V600 */
+               { .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ 
                { .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
                { .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
                { .vendor = 0x1297, .device = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */
@@ -1995,6 +1992,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
                { .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
                { .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
                { .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
+               { .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
                { .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
                { .vendor = 0x1631, .device = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
                { .vendor = 0x1695, .device = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
@@ -2093,7 +2091,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
                
        if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
                goto __error;
-       if ((err = snd_via82xx_mixer_new(chip)) < 0)
+       if ((err = snd_via82xx_mixer_new(chip, ac97_quirk[dev])) < 0)
                goto __error;
 
        if (chip_type == TYPE_VIA686) {
@@ -2175,7 +2173,8 @@ module_exit(alsa_card_via82xx_exit)
 #ifndef MODULE
 
 /* format is: snd-via82xx=enable,index,id,
-                         mpu_port,joystick,ac97_clock,dxs_support */
+                         mpu_port,joystick,
+                         ac97_quirk,ac97_clock,dxs_support */
 
 static int __init alsa_card_via82xx_setup(char *str)
 {
@@ -2190,6 +2189,7 @@ static int __init alsa_card_via82xx_setup(char *str)
 #ifdef SUPPORT_JOYSTICK
               get_option(&str,&joystick[nr_dev]) == 2 &&
 #endif
+              get_option(&str,&ac97_quirk[nr_dev]) == 2 &&
               get_option(&str,&ac97_clock[nr_dev]) == 2 &&
               get_option(&str,&dxs_support[nr_dev]) == 2);
        nr_dev++;
index 8324e2e..6f73d05 100644 (file)
@@ -406,7 +406,8 @@ static int vx2_load_dsp(vx_core_t *vx, const snd_hwdep_dsp_image_t *dsp)
        int err;
 
        if (*dsp->name)
-               snd_printdd("loading dsp [%d] %s, size = %d\n", dsp->index, dsp->name, dsp->length);
+               snd_printdd("loading dsp [%d] %s, size = %Zd\n",
+                       dsp->index, dsp->name, dsp->length);
        switch (dsp->index) {
        case 0:
                /* xilinx image */