Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 5 Jan 2006 00:31:56 +0000 (16:31 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 5 Jan 2006 00:31:56 +0000 (16:31 -0800)
575 files changed:
Documentation/DocBook/usb.tmpl
Documentation/cpu-freq/governors.txt
Documentation/networking/ip-sysctl.txt
Documentation/scsi/ChangeLog.megaraid
Documentation/scsi/scsi_mid_low_api.txt
MAINTAINERS
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/pxa27x.c
arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.h
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/kernel/cpu/proc.c
arch/ia64/kernel/setup.c
arch/mips/kernel/linux32.c
arch/x86_64/kernel/setup.c
block/ll_rw_blk.c
block/scsi_ioctl.c
drivers/block/Kconfig
drivers/block/ub.c
drivers/bluetooth/bcm203x.c
drivers/bluetooth/bfusb.c
drivers/bluetooth/bpa10x.c
drivers/bluetooth/hci_usb.c
drivers/char/ip2/i2pack.h
drivers/char/random.c
drivers/char/watchdog/pcwd_usb.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/st5481_init.c
drivers/md/dm-table.c
drivers/media/dvb/b2c2/flexcop-usb.c
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-usb/a800.c
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/dibusb-mb.c
drivers/media/dvb/dvb-usb/dibusb-mc.c
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dtt200u.c
drivers/media/dvb/dvb-usb/nova-t-usb2.c
drivers/media/dvb/dvb-usb/umt-010.c
drivers/media/dvb/dvb-usb/vp702x.c
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/video/cpia_usb.c
drivers/media/video/em28xx/em28xx-video.c
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.h
drivers/message/fusion/mptspi.c
drivers/net/irda/irda-usb.c
drivers/net/irda/stir4200.c
drivers/net/ns83820.c
drivers/net/pppoe.c
drivers/net/pppox.c
drivers/net/sk98lin/skge.c
drivers/net/skge.c
drivers/net/tg3.c
drivers/net/wireless/ipw2200.c
drivers/scsi/53c700.c
drivers/scsi/53c700.h
drivers/scsi/53c7xx.c
drivers/scsi/Kconfig
drivers/scsi/NCR5380.c
drivers/scsi/aha152x.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/arm/Kconfig
drivers/scsi/arm/acornscsi.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/ch.c
drivers/scsi/constants.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_disc.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/megaraid.c
drivers/scsi/megaraid/Kconfig.megaraid
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_mbox.h
drivers/scsi/ncr53c8xx.c
drivers/scsi/ncr53c8xx.h
drivers/scsi/qla2xxx/Kconfig
drivers/scsi/qla2xxx/Makefile
drivers/scsi/qla2xxx/ql2400.c [new file with mode: 0644]
drivers/scsi/qla2xxx/ql2400_fw.c [new file with mode: 0644]
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/raid_class.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_spi.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/sr.c
drivers/scsi/sr_vendor.c
drivers/scsi/st.c
drivers/scsi/st.h
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sym53c8xx_2/sym_defs.h
drivers/scsi/sym53c8xx_2/sym_fw.c
drivers/scsi/sym53c8xx_2/sym_fw.h
drivers/scsi/sym53c8xx_2/sym_fw1.h
drivers/scsi/sym53c8xx_2/sym_fw2.h
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/sym53c8xx_2/sym_glue.h
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/scsi/sym53c8xx_2/sym_hipd.h
drivers/scsi/sym53c8xx_2/sym_malloc.c
drivers/scsi/sym53c8xx_2/sym_nvram.c
drivers/scsi/sym53c8xx_2/sym_nvram.h
drivers/scsi/sym53c8xx_comm.h [deleted file]
drivers/scsi/sym53c8xx_defs.h [deleted file]
drivers/usb/Makefile
drivers/usb/atm/Kconfig
drivers/usb/atm/Makefile
drivers/usb/atm/cxacru.c
drivers/usb/atm/speedtch.c
drivers/usb/atm/ueagle-atm.c [new file with mode: 0644]
drivers/usb/atm/usbatm.c
drivers/usb/atm/xusbatm.c
drivers/usb/class/audio.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.h
drivers/usb/class/usb-midi.c
drivers/usb/class/usblp.c
drivers/usb/core/Makefile
drivers/usb/core/buffer.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c [new file with mode: 0644]
drivers/usb/core/hcd.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/message.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/serial.c
drivers/usb/host/Makefile
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-q.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/isp116x.h
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/sl811_cs.c
drivers/usb/host/uhci-debug.c
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.h
drivers/usb/host/uhci-q.c
drivers/usb/image/mdc800.c
drivers/usb/image/microtek.c
drivers/usb/input/Kconfig
drivers/usb/input/Makefile
drivers/usb/input/acecad.c
drivers/usb/input/aiptek.c
drivers/usb/input/appletouch.c
drivers/usb/input/ati_remote.c
drivers/usb/input/ati_remote2.c [new file with mode: 0644]
drivers/usb/input/fixp-arith.h
drivers/usb/input/hid-core.c
drivers/usb/input/hid-input.c
drivers/usb/input/hiddev.c
drivers/usb/input/itmtouch.c
drivers/usb/input/kbtab.c
drivers/usb/input/keyspan_remote.c
drivers/usb/input/mtouchusb.c
drivers/usb/input/powermate.c
drivers/usb/input/touchkitusb.c
drivers/usb/input/usbkbd.c
drivers/usb/input/usbmouse.c
drivers/usb/input/wacom.c
drivers/usb/input/xpad.c
drivers/usb/input/yealink.c
drivers/usb/media/dabusb.c
drivers/usb/media/dsbr100.c
drivers/usb/media/ibmcam.c
drivers/usb/media/konicawc.c
drivers/usb/media/ov511.c
drivers/usb/media/pwc/pwc-ctrl.c
drivers/usb/media/pwc/pwc-if.c
drivers/usb/media/se401.c
drivers/usb/media/sn9c102_core.c
drivers/usb/media/stv680.c
drivers/usb/media/stv680.h
drivers/usb/media/usbvideo.c
drivers/usb/media/vicam.c
drivers/usb/media/w9968cf.c
drivers/usb/misc/auerswald.c
drivers/usb/misc/cytherm.c
drivers/usb/misc/emi26.c
drivers/usb/misc/emi62.c
drivers/usb/misc/idmouse.c
drivers/usb/misc/ldusb.c
drivers/usb/misc/legousbtower.c
drivers/usb/misc/phidgetkit.c
drivers/usb/misc/phidgetservo.c
drivers/usb/misc/rio500.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/usblcd.c
drivers/usb/misc/usbled.c
drivers/usb/misc/usbtest.c
drivers/usb/misc/uss720.c
drivers/usb/mon/mon_text.c
drivers/usb/net/asix.c
drivers/usb/net/catc.c
drivers/usb/net/cdc_ether.c
drivers/usb/net/cdc_subset.c
drivers/usb/net/gl620a.c
drivers/usb/net/kaweth.c
drivers/usb/net/net1080.c
drivers/usb/net/pegasus.c
drivers/usb/net/plusb.c
drivers/usb/net/rndis_host.c
drivers/usb/net/rtl8150.c
drivers/usb/net/zaurus.c
drivers/usb/net/zd1201.c
drivers/usb/serial/airprime.c
drivers/usb/serial/anydata.c
drivers/usb/serial/belkin_sa.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/cyberjack.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/empeg.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/generic.c
drivers/usb/serial/hp4x.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_edgeport.h
drivers/usb/serial/io_fw_boot2.h
drivers/usb/serial/io_ti.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipw.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/keyspan.h
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/omninet.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/safe_serial.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-serial.h
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/storage/Kconfig
drivers/usb/storage/Makefile
drivers/usb/storage/alauda.c [new file with mode: 0644]
drivers/usb/storage/alauda.h [new file with mode: 0644]
drivers/usb/storage/debug.c
drivers/usb/storage/initializers.h
drivers/usb/storage/libusual.c [new file with mode: 0644]
drivers/usb/storage/onetouch.c
drivers/usb/storage/protocol.h
drivers/usb/storage/sddr09.c
drivers/usb/storage/sddr09.h
drivers/usb/storage/transport.h
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h
drivers/usb/usb-skeleton.c
drivers/w1/dscore.c
fs/9p/trans_sock.c
fs/bio.c
fs/compat.c
fs/nfs/callback.c
fs/read_write.c
include/asm-alpha/bitops.h
include/asm-arm/arch-pxa/ohci.h [new file with mode: 0644]
include/asm-arm/bitops.h
include/asm-arm26/bitops.h
include/asm-cris/bitops.h
include/asm-frv/bitops.h
include/asm-generic/bitops.h
include/asm-h8300/bitops.h
include/asm-i386/bitops.h
include/asm-ia64/bitops.h
include/asm-m32r/bitops.h
include/asm-m68k/bitops.h
include/asm-m68knommu/bitops.h
include/asm-mips/bitops.h
include/asm-parisc/bitops.h
include/asm-powerpc/bitops.h
include/asm-s390/bitops.h
include/asm-sh/bitops.h
include/asm-sh64/bitops.h
include/asm-sparc/bitops.h
include/asm-sparc64/bitops.h
include/asm-v850/bitops.h
include/asm-x86_64/bitops.h
include/asm-xtensa/bitops.h
include/linux/bio.h
include/linux/bitops.h
include/linux/blkdev.h
include/linux/cpufreq.h
include/linux/dccp.h
include/linux/etherdevice.h
include/linux/if_pppox.h
include/linux/ip.h
include/linux/ipv6.h
include/linux/net.h
include/linux/pci_ids.h
include/linux/pfkeyv2.h
include/linux/pkt_sched.h
include/linux/random.h
include/linux/security.h
include/linux/skbuff.h
include/linux/socket.h
include/linux/sysctl.h
include/linux/tcp.h
include/linux/udp.h
include/linux/usb.h
include/linux/usb_usual.h [new file with mode: 0644]
include/linux/xfrm.h
include/net/af_unix.h
include/net/atmclip.h
include/net/dst.h
include/net/flow.h
include/net/genetlink.h
include/net/icmp.h
include/net/ieee80211_crypt.h
include/net/inet6_connection_sock.h [new file with mode: 0644]
include/net/inet6_hashtables.h
include/net/inet_common.h
include/net/inet_connection_sock.h
include/net/inet_ecn.h
include/net/inet_hashtables.h
include/net/inet_sock.h [new file with mode: 0644]
include/net/inet_timewait_sock.h
include/net/inetpeer.h
include/net/ip.h
include/net/ip_fib.h
include/net/ip_vs.h
include/net/ipv6.h
include/net/ndisc.h
include/net/neighbour.h
include/net/pkt_act.h
include/net/protocol.h
include/net/raw.h
include/net/request_sock.h
include/net/sctp/structs.h
include/net/sctp/user.h
include/net/sock.h
include/net/tcp.h
include/net/tcp_states.h
include/net/timewait_sock.h [new file with mode: 0644]
include/net/transp_v6.h
include/net/udp.h
include/net/xfrm.h
include/scsi/scsi_cmnd.h
include/scsi/scsi_dbg.h
include/scsi/scsi_device.h
include/scsi/scsi_transport_spi.h
init/main.c
net/appletalk/ddp.c
net/atm/pvc.c
net/atm/svc.c
net/ax25/af_ax25.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_sock.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bridge/br.c
net/bridge/br_device.c
net/bridge/br_if.c
net/bridge/br_input.c
net/bridge/br_netfilter.c
net/bridge/br_notify.c
net/bridge/br_private.h
net/bridge/br_stp_if.c
net/bridge/netfilter/Kconfig
net/bridge/netfilter/ebt_log.c
net/bridge/netfilter/ebt_ulog.c
net/core/datagram.c
net/core/dev.c
net/core/filter.c
net/core/flow.c
net/core/netpoll.c
net/core/pktgen.c
net/core/skbuff.c
net/core/sock.c
net/core/stream.c
net/dccp/Makefile
net/dccp/ackvec.c
net/dccp/ackvec.h
net/dccp/ccid.h
net/dccp/dccp.h
net/dccp/diag.c
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/ipv6.c [new file with mode: 0644]
net/dccp/ipv6.h [new file with mode: 0644]
net/dccp/minisocks.c
net/dccp/output.c
net/dccp/proto.c
net/decnet/af_decnet.c
net/decnet/dn_neigh.c
net/decnet/dn_nsp_in.c
net/econet/af_econet.c
net/ieee80211/ieee80211_rx.c
net/ipv4/Kconfig
net/ipv4/Makefile
net/ipv4/af_inet.c
net/ipv4/ah4.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/esp4.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipcomp.c
net/ipv4/ipconfig.c
net/ipv4/ipmr.c
net/ipv4/ipvs/ip_vs_app.c
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_dh.c
net/ipv4/ipvs/ip_vs_est.c
net/ipv4/ipvs/ip_vs_lblc.c
net/ipv4/ipvs/ip_vs_lblcr.c
net/ipv4/ipvs/ip_vs_proto_ah.c
net/ipv4/ipvs/ip_vs_proto_esp.c
net/ipv4/ipvs/ip_vs_proto_tcp.c
net/ipv4/ipvs/ip_vs_proto_udp.c
net/ipv4/ipvs/ip_vs_sh.c
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_conntrack_amanda.c
net/ipv4/netfilter/ip_conntrack_proto_gre.c
net/ipv4/netfilter/ip_conntrack_proto_udp.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_nat_snmp_basic.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_physdev.c
net/ipv4/proc.c
net/ipv4/syncookies.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_bic.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_cubic.c [new file with mode: 0644]
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv4/tcp_vegas.c
net/ipv4/udp.c
net/ipv6/Makefile
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/esp6.c
net/ipv6/exthdrs.c
net/ipv6/inet6_connection_sock.c [new file with mode: 0644]
net/ipv6/inet6_hashtables.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_output.c
net/ipv6/ipcomp6.c
net/ipv6/ipv6_sockglue.c
net/ipv6/mcast.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_ah.c
net/ipv6/netfilter/ip6t_esp.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/raw.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipx/af_ipx.c
net/irda/af_irda.c
net/key/af_key.c
net/llc/af_llc.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netrom/af_netrom.c
net/nonet.c
net/packet/af_packet.c
net/rose/af_rose.c
net/sched/sch_netem.c
net/sched/sch_teql.c
net/sctp/associola.c
net/sctp/input.c
net/sctp/ipv6.c
net/sctp/output.c
net/sctp/protocol.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/transport.c
net/socket.c
net/sunrpc/svcsock.c
net/unix/af_unix.c
net/unix/garbage.c
net/wanrouter/af_wanpipe.c
net/x25/af_x25.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/Kconfig
security/dummy.c
security/selinux/Makefile
security/selinux/hooks.c
security/selinux/include/av_perm_to_string.h
security/selinux/include/av_permissions.h
security/selinux/include/xfrm.h [new file with mode: 0644]
security/selinux/xfrm.c [new file with mode: 0644]
sound/usb/usbaudio.c
sound/usb/usx2y/usbusx2y.c

index 15ce0f2..320af25 100644 (file)
 !Edrivers/usb/core/urb.c
 !Edrivers/usb/core/message.c
 !Edrivers/usb/core/file.c
+!Edrivers/usb/core/driver.c
 !Edrivers/usb/core/usb.c
 !Edrivers/usb/core/hub.c
     </chapter>
index 933fae7..f4b8dc4 100644 (file)
@@ -27,6 +27,7 @@ Contents:
 2.2  Powersave
 2.3  Userspace
 2.4  Ondemand
+2.5  Conservative
 
 3.   The Governor Interface in the CPUfreq Core
 
@@ -110,9 +111,64 @@ directory.
 
 The CPUfreq govenor "ondemand" sets the CPU depending on the
 current usage. To do this the CPU must have the capability to
-switch the frequency very fast.
-
-
+switch the frequency very quickly.  There are a number of sysfs file
+accessible parameters:
+
+sampling_rate: measured in uS (10^-6 seconds), this is how often you
+want the kernel to look at the CPU usage and to make decisions on
+what to do about the frequency.  Typically this is set to values of
+around '10000' or more.
+
+show_sampling_rate_(min|max): the minimum and maximum sampling rates
+available that you may set 'sampling_rate' to.
+
+up_threshold: defines what the average CPU usaged between the samplings
+of 'sampling_rate' needs to be for the kernel to make a decision on
+whether it should increase the frequency.  For example when it is set
+to its default value of '80' it means that between the checking
+intervals the CPU needs to be on average more than 80% in use to then
+decide that the CPU frequency needs to be increased.  
+
+sampling_down_factor: this parameter controls the rate that the CPU
+makes a decision on when to decrease the frequency.  When set to its
+default value of '5' it means that at 1/5 the sampling_rate the kernel
+makes a decision to lower the frequency.  Five "lower rate" decisions
+have to be made in a row before the CPU frequency is actually lower.
+If set to '1' then the frequency decreases as quickly as it increases,
+if set to '2' it decreases at half the rate of the increase.
+
+ignore_nice_load: this parameter takes a value of '0' or '1', when set
+to '0' (its default) then all processes are counted towards towards the
+'cpu utilisation' value.   When set to '1' then processes that are
+run with a 'nice' value will not count (and thus be ignored) in the
+overal usage calculation.  This is useful if you are running a CPU
+intensive calculation on your laptop that you do not care how long it
+takes to complete as you can 'nice' it and prevent it from taking part
+in the deciding process of whether to increase your CPU frequency.
+
+
+2.5 Conservative
+----------------
+
+The CPUfreq governor "conservative", much like the "ondemand"
+governor, sets the CPU depending on the current usage.  It differs in
+behaviour in that it gracefully increases and decreases the CPU speed
+rather than jumping to max speed the moment there is any load on the
+CPU.  This behaviour more suitable in a battery powered environment.
+The governor is tweaked in the same manner as the "ondemand" governor
+through sysfs with the addition of:
+
+freq_step: this describes what percentage steps the cpu freq should be
+increased and decreased smoothly by.  By default the cpu frequency will
+increase in 5% chunks of your maximum cpu frequency.  You can change this
+value to anywhere between 0 and 100 where '0' will effectively lock your
+CPU at a speed regardless of its load whilst '100' will, in theory, make
+it behave identically to the "ondemand" governor.
+
+down_threshold: same as the 'up_threshold' found for the "ondemand"
+governor but for the opposite direction.  For example when set to its
+default value of '20' it means that if the CPU usage needs to be below
+20% between samples to have the frequency decreased.
 
 3. The Governor Interface in the CPUfreq Core
 =============================================
index ebc09a1..2b7cf19 100644 (file)
@@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER
        for the hash secret) for IP fragments.
        Default: 600
 
+ipfrag_max_dist - INTEGER
+       ipfrag_max_dist is a non-negative integer value which defines the 
+       maximum "disorder" which is allowed among fragments which share a 
+       common IP source address. Note that reordering of packets is 
+       not unusual, but if a large number of fragments arrive from a source 
+       IP address while a particular fragment queue remains incomplete, it 
+       probably indicates that one or more fragments belonging to that queue 
+       have been lost. When ipfrag_max_dist is positive, an additional check 
+       is done on fragments before they are added to a reassembly queue - if 
+       ipfrag_max_dist (or more) fragments have arrived from a particular IP 
+       address between additions to any IP fragment queue using that source 
+       address, it's presumed that one or more fragments in the queue are 
+       lost. The existing fragment queue will be dropped, and a new one 
+       started. An ipfrag_max_dist value of zero disables this check.
+
+       Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
+       result in unnecessarily dropping fragment queues when normal
+       reordering of packets occurs, which could lead to poor application 
+       performance. Using a very large value, e.g. 50000, increases the 
+       likelihood of incorrectly reassembling IP fragments that originate 
+       from different IP datagrams, which could result in data corruption.
+       Default: 64
+
 INET peer storage:
 
 inet_peer_threshold - INTEGER
index 5331d91..09f6300 100644 (file)
@@ -1,3 +1,38 @@
+Release Date   : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
+Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
+Older Version  : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
+
+1.     Sorted out PCI IDs to remove megaraid support overlaps.
+       Based on the patch from Daniel, sorted out PCI IDs along with
+       charactor node name change from 'megadev' to 'megadev_legacy' to avoid
+       conflict.
+       ---
+       Hopefully we'll be getting the build restriction zapped much sooner, 
+       but we should also be thinking about totally removing the hardware 
+       support overlap in the megaraid drivers.
+
+       This patch pencils in a date of Feb 06 for this, and performs some 
+       printk abuse in hope that existing legacy users might pick up on what's
+       going on.
+
+       Signed-off-by: Daniel Drake <dsd@gentoo.org>
+       ---
+
+2.     Fixed a issue: megaraid always fails to reset handler.
+       ---
+       I found that the megaraid driver always fails to reset the
+       adapter with the following message:
+               megaraid: resetting the host...
+               megaraid mbox: reset sequence completed successfully
+               megaraid: fast sync command timed out
+               megaraid: reservation reset failed
+       when the "Cluster mode" of the adapter BIOS is enabled.
+       So, whenever the reset occurs, the adapter goes to
+       offline and just become unavailable.
+
+       Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
+       ---
+
 Release Date   : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
 Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
 Older Version  : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
index 66565d4..c4af92b 100644 (file)
@@ -150,7 +150,8 @@ scsi devices of which only the first 2 respond:
 LLD                   mid level                    LLD
 ===-------------------=========--------------------===------
 scsi_host_alloc()  -->
-scsi_add_host()  --------+
+scsi_add_host()  ---->
+scsi_scan_host()  -------+
                          |
                     slave_alloc()
                     slave_configure() -->  scsi_adjust_queue_depth()
@@ -196,7 +197,7 @@ of the issues involved. See the section on reference counting below.
 
 
 The hotplug concept may be extended to SCSI devices. Currently, when an
-HBA is added, the scsi_add_host() function causes a scan for SCSI devices
+HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
 attached to the HBA's SCSI transport. On newer SCSI transports the HBA
 may become aware of a new SCSI device _after_ the scan has completed.
 An LLD can use this sequence to make the mid level aware of a SCSI device:
@@ -372,7 +373,7 @@ names all start with "scsi_".
 Summary:
    scsi_activate_tcq - turn on tag command queueing
    scsi_add_device - creates new scsi device (lu) instance
-   scsi_add_host - perform sysfs registration and SCSI bus scan.
+   scsi_add_host - perform sysfs registration and set up transport class
    scsi_adjust_queue_depth - change the queue depth on a SCSI device
    scsi_assign_lock - replace default host_lock with given lock
    scsi_bios_ptable - return copy of block device's partition table
@@ -386,6 +387,7 @@ Summary:
    scsi_remove_device - detach and remove a SCSI device
    scsi_remove_host - detach and remove all SCSI devices owned by host
    scsi_report_bus_reset - report scsi _bus_ reset observed
+   scsi_scan_host - scan SCSI bus
    scsi_track_queue_full - track successive QUEUE_FULL events 
    scsi_unblock_requests - allow further commands to be queued to given host
    scsi_unregister - [calls scsi_host_put()]
@@ -425,10 +427,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth)
  *      Might block: yes
  *
  *      Notes: This call is usually performed internally during a scsi
- *      bus scan when an HBA is added (i.e. scsi_add_host()). So it
+ *      bus scan when an HBA is added (i.e. scsi_scan_host()). So it
  *      should only be called if the HBA becomes aware of a new scsi
- *      device (lu) after scsi_add_host() has completed. If successful
- *      this call we lead to slave_alloc() and slave_configure() callbacks
+ *      device (lu) after scsi_scan_host() has completed. If successful
+ *      this call can lead to slave_alloc() and slave_configure() callbacks
  *      into the LLD.
  *
  *      Defined in: drivers/scsi/scsi_scan.c
@@ -439,7 +441,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
 
 
 /**
- * scsi_add_host - perform sysfs registration and SCSI bus scan.
+ * scsi_add_host - perform sysfs registration and set up transport class
  * @shost:   pointer to scsi host instance
  * @dev:     pointer to struct device of type scsi class
  *
@@ -448,7 +450,11 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
  *      Might block: no
  *
  *      Notes: Only required in "hotplug initialization model" after a
- *      successful call to scsi_host_alloc().
+ *      successful call to scsi_host_alloc().  This function does not
+ *     scan the bus; this can be done by calling scsi_scan_host() or
+ *     in some other transport-specific way.  The LLD must set up
+ *     the transport template before calling this function and may only
+ *     access the transport class data after this function has been called.
  *
  *      Defined in: drivers/scsi/hosts.c
  **/
@@ -559,7 +565,7 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
  *      area for the LLD's exclusive use.
  *      Both associated refcounting objects have their refcount set to 1.
  *      Full registration (in sysfs) and a bus scan are performed later when
- *      scsi_add_host() is called.
+ *      scsi_add_host() and scsi_scan_host() are called.
  *
  *      Defined in: drivers/scsi/hosts.c .
  **/
@@ -698,6 +704,19 @@ int scsi_remove_host(struct Scsi_Host *shost)
 void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
 
 
+/**
+ * scsi_scan_host - scan SCSI bus
+ * @shost: a pointer to a scsi host instance
+ *
+ *     Might block: yes
+ *
+ *     Notes: Should be called after scsi_add_host()
+ *
+ *     Defined in: drivers/scsi/scsi_scan.c
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+
+
 /**
  * scsi_track_queue_full - track successive QUEUE_FULL events on given
  *                      device to determine if and when there is a need
index 6af6830..3fd7687 100644 (file)
@@ -2640,6 +2640,12 @@ L:       linux-usb-users@lists.sourceforge.net
 L:     linux-usb-devel@lists.sourceforge.net
 S:     Maintained
 
+USB ISP116X DRIVER
+P:     Olav Kongas
+M:     ok@artecdesign.ee
+L:     linux-usb-devel@lists.sourceforge.net
+S:     Maintained
+
 USB KAWASAKI LSI DRIVER
 P:     Oliver Neukum
 M:     oliver@neukum.name
@@ -2651,7 +2657,7 @@ USB MASS STORAGE DRIVER
 P:     Matthew Dharm
 M:     mdharm-usb@one-eyed-alien.net
 L:     linux-usb-users@lists.sourceforge.net
-L:     linux-usb-devel@lists.sourceforge.net
+L:     usb-storage@lists.one-eyed-alien.net
 S:     Maintained
 W:     http://www.one-eyed-alien.net/~mdharm/linux-usb/
 
index 07892f4..277498a 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = {
        &mst_flash_device[1],
 };
 
+static int mainstone_ohci_init(struct device *dev)
+{
+       /* setup Port1 GPIO pin. */
+       pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);  /* USBHPWR1 */
+       pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
+
+       /* Set the Power Control Polarity Low and Power Sense
+          Polarity Low to active low. */
+       UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
+               ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+       return 0;
+}
+
+static struct pxaohci_platform_data mainstone_ohci_platform_data = {
+       .port_mode      = PMM_PERPORT_MODE,
+       .init           = mainstone_ohci_init,
+};
+
 static void __init mainstone_init(void)
 {
        int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
@@ -424,6 +444,7 @@ static void __init mainstone_init(void)
 
        pxa_set_mci_info(&mainstone_mci_platform_data);
        pxa_set_ficp_info(&mainstone_ficp_platform_data);
+       pxa_set_ohci_info(&mainstone_ohci_platform_data);
 }
 
 
index c722a9a..b41b1ef 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -194,6 +195,11 @@ static struct platform_device ohci_device = {
        .resource       = pxa27x_ohci_resources,
 };
 
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+       ohci_device.dev.platform_data = info;
+}
+
 static struct platform_device *devices[] __initdata = {
        &ohci_device,
 };
index 04a4053..2b62dee 100644 (file)
@@ -177,9 +177,10 @@ static unsigned int nforce2_fsb_read(int bootfsb)
  */
 static int nforce2_set_fsb(unsigned int fsb)
 {
-       u32 pll, temp = 0;
+       u32 temp = 0;
        unsigned int tfsb;
        int diff;
+       int pll = 0;
 
        if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
                printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
index 68a1fc8..0fbbd4c 100644 (file)
@@ -45,7 +45,7 @@
 
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 1.50.4"
+#define VERSION "version 1.60.0"
 #include "powernow-k8.h"
 
 /* serialize freq changes  */
@@ -216,10 +216,10 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
 
        do {
                wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
-                if (i++ > 100) {
-                        printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
-                        return 1;
-                }
+               if (i++ > 100) {
+                       printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+                       return 1;
+               }
        } while (query_current_values_with_pending_wait(data));
 
        if (savefid != data->currfid) {
@@ -336,7 +336,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
-       u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
+       u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid;
 
        if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
                printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@@ -359,9 +359,11 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
            : vcoreqfid - vcocurrfid;
 
        while (vcofiddiff > 2) {
+               (data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
+
                if (reqfid > data->currfid) {
                        if (data->currfid > LO_FID_TABLE_TOP) {
-                               if (write_new_fid(data, data->currfid + 2)) {
+                               if (write_new_fid(data, data->currfid + fid_interval)) {
                                        return 1;
                                }
                        } else {
@@ -371,7 +373,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
                                }
                        }
                } else {
-                       if (write_new_fid(data, data->currfid - 2))
+                       if (write_new_fid(data, data->currfid - fid_interval))
                                return 1;
                }
 
@@ -464,7 +466,7 @@ static int check_supported_cpu(unsigned int cpu)
        set_cpus_allowed(current, cpumask_of_cpu(cpu));
 
        if (smp_processor_id() != cpu) {
-               printk(KERN_ERR "limiting to cpu %u failed\n", cpu);
+               printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu);
                goto out;
        }
 
@@ -474,7 +476,7 @@ static int check_supported_cpu(unsigned int cpu)
        eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
        if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
            ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
-           ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) {
+           ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
                printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
                goto out;
        }
@@ -517,22 +519,24 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8
                        printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
                        return -ENODEV;
                }
-               if ((pst[j].fid > MAX_FID)
-                   || (pst[j].fid & 1)
-                   || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
+               if (pst[j].fid > MAX_FID) {
+                       printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
+                       return -ENODEV;
+               }
+               if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
                        /* Only first fid is allowed to be in "low" range */
-                       printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
+                       printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
                        return -EINVAL;
                }
                if (pst[j].fid < lastfid)
                        lastfid = pst[j].fid;
        }
        if (lastfid & 1) {
-               printk(KERN_ERR PFX "lastfid invalid\n");
+               printk(KERN_ERR BFX "lastfid invalid\n");
                return -EINVAL;
        }
        if (lastfid > LO_FID_TABLE_TOP)
-               printk(KERN_INFO PFX  "first fid not from lo freq table\n");
+               printk(KERN_INFO BFX  "first fid not from lo freq table\n");
 
        return 0;
 }
@@ -631,7 +635,7 @@ static int find_psb_table(struct powernow_k8_data *data)
 
                dprintk("table vers: 0x%x\n", psb->tableversion);
                if (psb->tableversion != PSB_VERSION_1_4) {
-                       printk(KERN_INFO BFX "PSB table is not v1.4\n");
+                       printk(KERN_ERR BFX "PSB table is not v1.4\n");
                        return -ENODEV;
                }
 
@@ -689,7 +693,7 @@ static int find_psb_table(struct powernow_k8_data *data)
         * BIOS and Kernel Developer's Guide, which is available on
         * www.amd.com
         */
-       printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
+       printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
        return -ENODEV;
 }
 
@@ -912,7 +916,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
        set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
        if (smp_processor_id() != pol->cpu) {
-               printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+               printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
                goto err_out;
        }
 
@@ -982,6 +986,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
        cpumask_t oldmask = CPU_MASK_ALL;
        int rc, i;
 
+       if (!cpu_online(pol->cpu))
+               return -ENODEV;
+
        if (!check_supported_cpu(pol->cpu))
                return -ENODEV;
 
@@ -1021,7 +1028,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
        set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
        if (smp_processor_id() != pol->cpu) {
-               printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+               printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
                goto err_out;
        }
 
@@ -1162,10 +1169,9 @@ static void __exit powernowk8_exit(void)
        cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com.");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_LICENSE("GPL");
 
 late_initcall(powernowk8_init);
 module_exit(powernowk8_exit);
-
index b1e85bb..d0de37d 100644 (file)
@@ -42,7 +42,7 @@ struct powernow_k8_data {
 #define CPUID_XFAM                     0x0ff00000      /* extended family */
 #define CPUID_XFAM_K8                  0
 #define CPUID_XMOD                     0x000f0000      /* extended model */
-#define CPUID_XMOD_REV_F               0x00040000
+#define CPUID_XMOD_REV_G               0x00060000
 #define CPUID_USE_XFAM_XMOD            0x00000f00
 #define CPUID_GET_MAX_CAPABILITIES     0x80000000
 #define CPUID_FREQ_VOLT_CAPABILITIES   0x80000007
@@ -86,13 +86,14 @@ struct powernow_k8_data {
  *   low fid table
  * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
  *   in the low fid table
- * - the parts can only step at 200 MHz intervals, so 1.9 GHz is never valid
+ * - the parts can only step at <= 200 MHz intervals, odd fid values are
+ *   supported in revision G and later revisions.
  * - lowest frequency must be >= interprocessor hypertransport link speed
  *   (only applies to MP systems obviously)
  */
 
 /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
-#define LO_FID_TABLE_TOP     6 /* fid values marking the boundary    */
+#define LO_FID_TABLE_TOP     7 /* fid values marking the boundary    */
 #define HI_FID_TABLE_BOTTOM  8 /* between the low and high tables    */
 
 #define LO_VCOFREQ_TABLE_TOP    1400   /* corresponding vco frequency values */
@@ -106,7 +107,7 @@ struct powernow_k8_data {
 #define MIN_FREQ 800   /* Min and max freqs, per spec */
 #define MAX_FREQ 5000
 
-#define INVALID_FID_MASK 0xffffffc1  /* not a valid fid if these bits are set */
+#define INVALID_FID_MASK 0xffffffc0  /* not a valid fid if these bits are set */
 #define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
 
 #define VID_OFF 0x3f
index 5b7d18a..b425cd3 100644 (file)
@@ -40,6 +40,7 @@ static struct pci_dev *speedstep_chipset_dev;
  */
 static unsigned int speedstep_processor = 0;
 
+static u32 pmbase;
 
 /*
  *   There are only two frequency states for each processor. Values
@@ -56,34 +57,47 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
 
 
 /**
- * speedstep_set_state - set the SpeedStep state
- * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ * speedstep_find_register - read the PMBASE address
  *
- *   Tries to change the SpeedStep state.
+ * Returns: -ENODEV if no register could be found
  */
-static void speedstep_set_state (unsigned int state)
+static int speedstep_find_register (void)
 {
-       u32 pmbase;
-       u8 pm2_blk;
-       u8 value;
-       unsigned long flags;
-
-       if (!speedstep_chipset_dev || (state > 0x1))
-               return;
+       if (!speedstep_chipset_dev)
+               return -ENODEV;
 
        /* get PMBASE */
        pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
        if (!(pmbase & 0x01)) {
                printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-               return;
+               return -ENODEV;
        }
 
        pmbase &= 0xFFFFFFFE;
        if (!pmbase) {
                printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-               return;
+               return -ENODEV;
        }
 
+       dprintk("pmbase is 0x%x\n", pmbase);
+       return 0;
+}
+
+/**
+ * speedstep_set_state - set the SpeedStep state
+ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ *
+ *   Tries to change the SpeedStep state.
+ */
+static void speedstep_set_state (unsigned int state)
+{
+       u8 pm2_blk;
+       u8 value;
+       unsigned long flags;
+
+       if (state > 0x1)
+               return;
+
        /* Disable IRQs */
        local_irq_save(flags);
 
@@ -315,10 +329,11 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
        cpus_allowed = current->cpus_allowed;
        set_cpus_allowed(current, policy->cpus);
 
-       /* detect low and high frequency */
+       /* detect low and high frequency and transition latency */
        result = speedstep_get_freqs(speedstep_processor,
                                     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
                                     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+                                    &policy->cpuinfo.transition_latency,
                                     &speedstep_set_state);
        set_cpus_allowed(current, cpus_allowed);
        if (result)
@@ -335,7 +350,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
 
        /* cpuinfo and default policy values */
        policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-       policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
        policy->cur = speed;
 
        result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
@@ -400,6 +414,9 @@ static int __init speedstep_init(void)
                return -EINVAL;
        }
 
+       if (speedstep_find_register())
+               return -ENODEV;
+
        return cpufreq_register_driver(&speedstep_driver);
 }
 
index d368b3f..7c47005 100644 (file)
@@ -320,11 +320,13 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor);
 unsigned int speedstep_get_freqs(unsigned int processor,
                                  unsigned int *low_speed,
                                  unsigned int *high_speed,
+                                 unsigned int *transition_latency,
                                  void (*set_state) (unsigned int state))
 {
        unsigned int prev_speed;
        unsigned int ret = 0;
        unsigned long flags;
+       struct timeval tv1, tv2;
 
        if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
                return -EINVAL;
@@ -337,7 +339,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
                return -EIO;
 
        dprintk("previous speed is %u\n", prev_speed);
-       
+
        local_irq_save(flags);
 
        /* switch to low state */
@@ -350,8 +352,17 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 
        dprintk("low speed is %u\n", *low_speed);
 
+       /* start latency measurement */
+       if (transition_latency)
+               do_gettimeofday(&tv1);
+
        /* switch to high state */
        set_state(SPEEDSTEP_HIGH);
+
+       /* end latency measurement */
+       if (transition_latency)
+               do_gettimeofday(&tv2);
+
        *high_speed = speedstep_get_processor_frequency(processor);
        if (!*high_speed) {
                ret = -EIO;
@@ -369,6 +380,25 @@ unsigned int speedstep_get_freqs(unsigned int processor,
        if (*high_speed != prev_speed)
                set_state(SPEEDSTEP_LOW);
 
+       if (transition_latency) {
+               *transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
+                       tv2.tv_usec - tv1.tv_usec;
+               dprintk("transition latency is %u uSec\n", *transition_latency);
+
+               /* convert uSec to nSec and add 20% for safety reasons */
+               *transition_latency *= 1200;
+
+               /* check if the latency measurement is too high or too low
+                * and set it to a safe value (500uSec) in that case
+                */
+               if (*transition_latency > 10000000 || *transition_latency < 50000) {
+                       printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
+                                       "range (%u nSec), falling back to a safe one of %u nSec.\n",
+                                       *transition_latency, 500000);
+                       *transition_latency = 500000;
+               }
+       }
+
  out:
        local_irq_restore(flags);
        return (ret);
index 261a2c9..6a727fd 100644 (file)
@@ -44,4 +44,5 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
 extern unsigned int speedstep_get_freqs(unsigned int processor,
          unsigned int *low_speed,
          unsigned int *high_speed,
+         unsigned int *transition_latency,
          void (*set_state) (unsigned int state));
index 2718fb6..28cc5d5 100644 (file)
@@ -269,6 +269,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
                result = speedstep_get_freqs(speedstep_processor,
                                &speedstep_freqs[SPEEDSTEP_LOW].frequency,
                                &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+                               NULL,
                                &speedstep_set_state);
 
                if (result) {
index e792131..6d91b27 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/string.h>
 #include <asm/semaphore.h>
 #include <linux/seq_file.h>
+#include <linux/cpufreq.h>
 
 /*
  *     Get CPU information for use by the procfs.
@@ -86,8 +87,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "stepping\t: unknown\n");
 
        if ( cpu_has(c, X86_FEATURE_TSC) ) {
+               unsigned int freq = cpufreq_quick_get(n);
+               if (!freq)
+                       freq = cpu_khz;
                seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-                       cpu_khz / 1000, (cpu_khz % 1000));
+                       freq / 1000, (freq % 1000));
        }
 
        /* Cache size */
index 5add0bc..088e5dd 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/initrd.h>
 #include <linux/platform.h>
 #include <linux/pm.h>
+#include <linux/cpufreq.h>
 
 #include <asm/ia32.h>
 #include <asm/machvec.h>
@@ -517,6 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v)
        char family[32], features[128], *cp, sep;
        struct cpuinfo_ia64 *c = v;
        unsigned long mask;
+       unsigned int proc_freq;
        int i;
 
        mask = c->features;
@@ -549,6 +551,10 @@ show_cpuinfo (struct seq_file *m, void *v)
                sprintf(cp, " 0x%lx", mask);
        }
 
+       proc_freq = cpufreq_quick_get(cpunum);
+       if (!proc_freq)
+               proc_freq = c->proc_freq / 1000;
+
        seq_printf(m,
                   "processor  : %d\n"
                   "vendor     : %s\n"
@@ -565,7 +571,7 @@ show_cpuinfo (struct seq_file *m, void *v)
                   "BogoMIPS   : %lu.%02lu\n",
                   cpunum, c->vendor, family, c->model, c->revision, c->archrev,
                   features, c->ppn, c->number,
-                  c->proc_freq / 1000000, c->proc_freq % 1000000,
+                  proc_freq / 1000, proc_freq % 1000,
                   c->itc_freq / 1000000, c->itc_freq % 1000000,
                   lpj*HZ/500000, (lpj*HZ/5000) % 100);
 #ifdef CONFIG_SMP
index 330cf84..60353f5 100644 (file)
@@ -420,7 +420,7 @@ asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
                goto out;
        pos = merge_64(a4, a5);
        ret = rw_verify_area(READ, file, &pos, count);
-       if (ret)
+       if (ret < 0)
                goto out;
        ret = -EINVAL;
        if (!file->f_op || !(read = file->f_op->read))
@@ -455,7 +455,7 @@ asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
                goto out;
        pos = merge_64(a4, a5);
        ret = rw_verify_area(WRITE, file, &pos, count);
-       if (ret)
+       if (ret < 0)
                goto out;
        ret = -EINVAL;
        if (!file->f_op || !(write = file->f_op->write))
index 750e01d..64c4534 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/edd.h>
 #include <linux/mmzone.h>
 #include <linux/kexec.h>
+#include <linux/cpufreq.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -1256,8 +1257,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "stepping\t: unknown\n");
        
        if (cpu_has(c,X86_FEATURE_TSC)) {
+               unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
+               if (!freq)
+                       freq = cpu_khz;
                seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-                            cpu_khz / 1000, (cpu_khz % 1000));
+                            freq / 1000, (freq % 1000));
        }
 
        /* Cache size */
index 99c9ca6..d4beb9a 100644 (file)
@@ -239,7 +239,7 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
        q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
        q->backing_dev_info.state = 0;
        q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
-       blk_queue_max_sectors(q, MAX_SECTORS);
+       blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
        blk_queue_hardsect_size(q, 512);
        blk_queue_dma_alignment(q, 511);
        blk_queue_congestion_threshold(q);
@@ -555,7 +555,12 @@ void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors)
                printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors);
        }
 
-       q->max_sectors = q->max_hw_sectors = max_sectors;
+       if (BLK_DEF_MAX_SECTORS > max_sectors)
+               q->max_hw_sectors = q->max_sectors = max_sectors;
+       else {
+               q->max_sectors = BLK_DEF_MAX_SECTORS;
+               q->max_hw_sectors = max_sectors;
+       }
 }
 
 EXPORT_SYMBOL(blk_queue_max_sectors);
@@ -657,8 +662,8 @@ EXPORT_SYMBOL(blk_queue_hardsect_size);
 void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
 {
        /* zero is "infinity" */
-       t->max_sectors = t->max_hw_sectors =
-               min_not_zero(t->max_sectors,b->max_sectors);
+       t->max_sectors = min_not_zero(t->max_sectors,b->max_sectors);
+       t->max_hw_sectors = min_not_zero(t->max_hw_sectors,b->max_hw_sectors);
 
        t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);
        t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
@@ -1293,9 +1298,15 @@ static inline int ll_new_hw_segment(request_queue_t *q,
 static int ll_back_merge_fn(request_queue_t *q, struct request *req, 
                            struct bio *bio)
 {
+       unsigned short max_sectors;
        int len;
 
-       if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
+       if (unlikely(blk_pc_request(req)))
+               max_sectors = q->max_hw_sectors;
+       else
+               max_sectors = q->max_sectors;
+
+       if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
                req->flags |= REQ_NOMERGE;
                if (req == q->last_merge)
                        q->last_merge = NULL;
@@ -1325,9 +1336,16 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req,
 static int ll_front_merge_fn(request_queue_t *q, struct request *req, 
                             struct bio *bio)
 {
+       unsigned short max_sectors;
        int len;
 
-       if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
+       if (unlikely(blk_pc_request(req)))
+               max_sectors = q->max_hw_sectors;
+       else
+               max_sectors = q->max_sectors;
+
+
+       if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
                req->flags |= REQ_NOMERGE;
                if (req == q->last_merge)
                        q->last_merge = NULL;
@@ -2144,7 +2162,7 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
        struct bio *bio;
        int reading;
 
-       if (len > (q->max_sectors << 9))
+       if (len > (q->max_hw_sectors << 9))
                return -EINVAL;
        if (!len || !ubuf)
                return -EINVAL;
@@ -2259,7 +2277,7 @@ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
 {
        struct bio *bio;
 
-       if (len > (q->max_sectors << 9))
+       if (len > (q->max_hw_sectors << 9))
                return -EINVAL;
        if (!len || !kbuf)
                return -EINVAL;
@@ -2306,6 +2324,8 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
        generic_unplug_device(q);
 }
 
+EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
+
 /**
  * blk_execute_rq - insert a request into queue for execution
  * @q:         queue to insert the request in
@@ -2444,7 +2464,7 @@ void disk_round_stats(struct gendisk *disk)
 /*
  * queue lock must be held
  */
-static void __blk_put_request(request_queue_t *q, struct request *req)
+void __blk_put_request(request_queue_t *q, struct request *req)
 {
        struct request_list *rl = req->rl;
 
@@ -2473,6 +2493,8 @@ static void __blk_put_request(request_queue_t *q, struct request *req)
        }
 }
 
+EXPORT_SYMBOL_GPL(__blk_put_request);
+
 void blk_put_request(struct request *req)
 {
        unsigned long flags;
index 6e7db2e..1d8852f 100644 (file)
@@ -233,7 +233,7 @@ static int sg_io(struct file *file, request_queue_t *q,
        if (verify_command(file, cmd))
                return -EPERM;
 
-       if (hdr->dxfer_len > (q->max_sectors << 9))
+       if (hdr->dxfer_len > (q->max_hw_sectors << 9))
                return -EIO;
 
        if (hdr->dxfer_len)
index 7b1cd93..c4b9d2a 100644 (file)
@@ -358,7 +358,8 @@ config BLK_DEV_UB
          This driver supports certain USB attached storage devices
          such as flash keys.
 
-         Warning: Enabling this cripples the usb-storage driver.
+         If you enable this driver, it is recommended to avoid conflicts
+         with usb-storage by enabling USB_LIBUSUAL.
 
          If unsure, say N.
 
index bfb23d5..10740a0 100644 (file)
@@ -9,7 +9,6 @@
  *
  * TODO (sorted by decreasing priority)
  *  -- Kill first_open (Al Viro fixed the block layer now)
- *  -- Do resets with usb_device_reset (needs a thread context, use khubd)
  *  -- set readonly flag for CDs, set removable flag for CF readers
  *  -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
  *  -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
@@ -29,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/timer.h>
  *                                                                   +--------+
  */
 
-/*
- * Definitions which have to be scattered once we understand the layout better.
- */
-
-/* Transport (despite PR in the name) */
-#define US_PR_BULK     0x50            /* bulk only */
-
-/* Protocol */
-#define US_SC_SCSI     0x06            /* Transparent */
-
 /*
  * This many LUNs per USB device.
  * Every one of them takes a host, see UB_MAX_HOSTS.
 /*
  */
 
-#define UB_MINORS_PER_MAJOR    8
+#define UB_PARTS_PER_LUN      8
 
 #define UB_MAX_CDB_SIZE      16                /* Corresponds to Bulk */
 
@@ -245,6 +235,13 @@ struct ub_scsi_cmd {
        void *back;
 };
 
+struct ub_request {
+       struct request *rq;
+       unsigned int current_try;
+       unsigned int nsg;               /* sgv[nsg] */
+       struct scatterlist sgv[UB_MAX_REQ_SG];
+};
+
 /*
  */
 struct ub_capacity {
@@ -340,6 +337,8 @@ struct ub_lun {
        int readonly;
        int first_open;                 /* Kludge. See ub_bd_open. */
 
+       struct ub_request urq;
+
        /* Use Ingo's mempool if or when we have more than one command. */
        /*
         * Currently we never need more than one command for the whole device.
@@ -360,6 +359,7 @@ struct ub_dev {
        atomic_t poison;                /* The USB device is disconnected */
        int openc;                      /* protected by ub_lock! */
                                        /* kref is too implicit for our taste */
+       int reset;                      /* Reset is running */
        unsigned int tagcnt;
        char name[12];
        struct usb_device *dev;
@@ -387,6 +387,9 @@ struct ub_dev {
        struct bulk_cs_wrap work_bcs;
        struct usb_ctrlrequest work_cr;
 
+       struct work_struct reset_work;
+       wait_queue_head_t reset_wait;
+
        int sg_stat[6];
        struct ub_scsi_trace tr;
 };
@@ -395,12 +398,14 @@ struct ub_dev {
  */
 static void ub_cleanup(struct ub_dev *sc);
 static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq);
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq);
+static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq);
+static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_end_rq(struct request *rq, int uptodate);
+static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_request *urq, struct ub_scsi_cmd *cmd);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
 static void ub_scsi_action(unsigned long _dev);
@@ -415,6 +420,8 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     int stalled_pipe);
 static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
+static void ub_reset_enter(struct ub_dev *sc);
+static void ub_reset_task(void *arg);
 static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
 static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_capacity *ret);
@@ -422,13 +429,18 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
 
 /*
  */
+#ifdef CONFIG_USB_LIBUSUAL
+
+#define ub_usb_ids  storage_usb_ids
+#else
+
 static struct usb_device_id ub_usb_ids[] = {
-       // { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) },  /* SDDR-31 */
        { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
        { }
 };
 
 MODULE_DEVICE_TABLE(usb, ub_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /*
  * Find me a way to identify "next free minor" for add_disk(),
@@ -521,6 +533,9 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
        cnt = 0;
        spin_lock_irqsave(&sc->lock, flags);
 
+       cnt += sprintf(page + cnt,
+           "poison %d reset %d\n",
+           atomic_read(&sc->poison), sc->reset);
        cnt += sprintf(page + cnt,
            "qlen %d qmax %d\n",
            sc->cmd_queue.qlen, sc->cmd_queue.qmax);
@@ -770,7 +785,8 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 {
        struct ub_dev *sc = lun->udev;
        struct ub_scsi_cmd *cmd;
-       int rc;
+       struct ub_request *urq;
+       int n_elem;
 
        if (atomic_read(&sc->poison) || lun->changed) {
                blkdev_dequeue_request(rq);
@@ -778,65 +794,70 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
                return 0;
        }
 
+       if (lun->urq.rq != NULL)
+               return -1;
        if ((cmd = ub_get_cmd(lun)) == NULL)
                return -1;
        memset(cmd, 0, sizeof(struct ub_scsi_cmd));
 
        blkdev_dequeue_request(rq);
+
+       urq = &lun->urq;
+       memset(urq, 0, sizeof(struct ub_request));
+       urq->rq = rq;
+
+       /*
+        * get scatterlist from block layer
+        */
+       n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
+       if (n_elem < 0) {
+               printk(KERN_INFO "%s: failed request map (%d)\n",
+                   lun->name, n_elem); /* P3 */
+               goto drop;
+       }
+       if (n_elem > UB_MAX_REQ_SG) {   /* Paranoia */
+               printk(KERN_WARNING "%s: request with %d segments\n",
+                   lun->name, n_elem);
+               goto drop;
+       }
+       urq->nsg = n_elem;
+       sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
+
        if (blk_pc_request(rq)) {
-               rc = ub_cmd_build_packet(sc, lun, cmd, rq);
+               ub_cmd_build_packet(sc, lun, cmd, urq);
        } else {
-               rc = ub_cmd_build_block(sc, lun, cmd, rq);
-       }
-       if (rc != 0) {
-               ub_put_cmd(lun, cmd);
-               ub_end_rq(rq, 0);
-               return 0;
+               ub_cmd_build_block(sc, lun, cmd, urq);
        }
        cmd->state = UB_CMDST_INIT;
        cmd->lun = lun;
        cmd->done = ub_rw_cmd_done;
-       cmd->back = rq;
+       cmd->back = urq;
 
        cmd->tag = sc->tagcnt++;
-       if (ub_submit_scsi(sc, cmd) != 0) {
-               ub_put_cmd(lun, cmd);
-               ub_end_rq(rq, 0);
-               return 0;
-       }
+       if (ub_submit_scsi(sc, cmd) != 0)
+               goto drop;
 
        return 0;
+
+drop:
+       ub_put_cmd(lun, cmd);
+       ub_end_rq(rq, 0);
+       return 0;
 }
 
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq)
+static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq)
 {
-       int ub_dir;
-       int n_elem;
+       struct request *rq = urq->rq;
        unsigned int block, nblks;
 
        if (rq_data_dir(rq) == WRITE)
-               ub_dir = UB_DIR_WRITE;
+               cmd->dir = UB_DIR_WRITE;
        else
-               ub_dir = UB_DIR_READ;
-       cmd->dir = ub_dir;
+               cmd->dir = UB_DIR_READ;
 
-       /*
-        * get scatterlist from block layer
-        */
-       n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
-       if (n_elem <= 0) {
-               printk(KERN_INFO "%s: failed request map (%d)\n",
-                   sc->name, n_elem); /* P3 */
-               return -1;              /* request with no s/g entries? */
-       }
-       if (n_elem > UB_MAX_REQ_SG) {   /* Paranoia */
-               printk(KERN_WARNING "%s: request with %d segments\n",
-                   sc->name, n_elem);
-               return -1;
-       }
-       cmd->nsg = n_elem;
-       sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
+       cmd->nsg = urq->nsg;
+       memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
 
        /*
         * build the command
@@ -847,7 +868,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
        block = rq->sector >> lun->capacity.bshift;
        nblks = rq->nr_sectors >> lun->capacity.bshift;
 
-       cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10;
+       cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10;
        /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
        cmd->cdb[2] = block >> 24;
        cmd->cdb[3] = block >> 16;
@@ -858,14 +879,12 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
        cmd->cdb_len = 10;
 
        cmd->len = rq->nr_sectors * 512;
-
-       return 0;
 }
 
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq)
+static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq)
 {
-       int n_elem;
+       struct request *rq = urq->rq;
 
        if (rq->data_len == 0) {
                cmd->dir = UB_DIR_NONE;
@@ -874,40 +893,26 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
                        cmd->dir = UB_DIR_WRITE;
                else
                        cmd->dir = UB_DIR_READ;
-
        }
 
-       /*
-        * get scatterlist from block layer
-        */
-       n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
-       if (n_elem < 0) {
-               printk(KERN_INFO "%s: failed request map (%d)\n",
-                   sc->name, n_elem); /* P3 */
-               return -1;
-       }
-       if (n_elem > UB_MAX_REQ_SG) {   /* Paranoia */
-               printk(KERN_WARNING "%s: request with %d segments\n",
-                   sc->name, n_elem);
-               return -1;
-       }
-       cmd->nsg = n_elem;
-       sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
+       cmd->nsg = urq->nsg;
+       memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
 
        memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
        cmd->cdb_len = rq->cmd_len;
 
        cmd->len = rq->data_len;
-
-       return 0;
 }
 
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
-       struct request *rq = cmd->back;
        struct ub_lun *lun = cmd->lun;
+       struct ub_request *urq = cmd->back;
+       struct request *rq;
        int uptodate;
 
+       rq = urq->rq;
+
        if (cmd->error == 0) {
                uptodate = 1;
 
@@ -928,9 +933,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                                rq->errors = SAM_STAT_CHECK_CONDITION;
                        else
                                rq->errors = DID_ERROR << 16;
+               } else {
+                       if (cmd->error == -EIO) {
+                               if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
+                                       return;
+                       }
                }
        }
 
+       urq->rq = NULL;
+
        ub_put_cmd(lun, cmd);
        ub_end_rq(rq, uptodate);
        blk_start_queue(lun->disk->queue);
@@ -938,13 +950,45 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
 static void ub_end_rq(struct request *rq, int uptodate)
 {
-       int rc;
-
-       rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
-       // assert(rc == 0);
+       end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
        end_that_request_last(rq);
 }
 
+static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_request *urq, struct ub_scsi_cmd *cmd)
+{
+
+       if (atomic_read(&sc->poison))
+               return -ENXIO;
+
+       ub_reset_enter(sc);
+
+       if (urq->current_try >= 3)
+               return -EIO;
+       urq->current_try++;
+       /* P3 */ printk("%s: dir %c len/act %d/%d "
+           "[sense %x %02x %02x] retry %d\n",
+           sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len,
+           cmd->key, cmd->asc, cmd->ascq, urq->current_try);
+
+       memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+       ub_cmd_build_block(sc, lun, cmd, urq);
+
+       cmd->state = UB_CMDST_INIT;
+       cmd->lun = lun;
+       cmd->done = ub_rw_cmd_done;
+       cmd->back = urq;
+
+       cmd->tag = sc->tagcnt++;
+
+#if 0 /* Wasteful */
+       return ub_submit_scsi(sc, cmd);
+#else
+       ub_cmdq_add(sc, cmd);
+       return 0;
+#endif
+}
+
 /*
  * Submit a regular SCSI operation (not an auto-sense).
  *
@@ -1075,7 +1119,7 @@ static void ub_scsi_dispatch(struct ub_dev *sc)
        struct ub_scsi_cmd *cmd;
        int rc;
 
-       while ((cmd = ub_cmdq_peek(sc)) != NULL) {
+       while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) {
                if (cmd->state == UB_CMDST_DONE) {
                        ub_cmdq_pop(sc);
                        (*cmd->done)(sc, cmd);
@@ -1098,11 +1142,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
        struct urb *urb = &sc->work_urb;
        struct bulk_cs_wrap *bcs;
+       int len;
        int rc;
 
        if (atomic_read(&sc->poison)) {
-               /* A little too simplistic, I feel... */
-               goto Bad_End;
+               ub_state_done(sc, cmd, -ENODEV);
+               return;
        }
 
        if (cmd->state == UB_CMDST_CLEAR) {
@@ -1110,7 +1155,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        /*
                         * STALL while clearning STALL.
                         * The control pipe clears itself - nothing to do.
-                        * XXX Might try to reset the device here and retry.
                         */
                        printk(KERN_NOTICE "%s: stall on control pipe\n",
                            sc->name);
@@ -1129,11 +1173,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
        } else if (cmd->state == UB_CMDST_CLR2STS) {
                if (urb->status == -EPIPE) {
-                       /*
-                        * STALL while clearning STALL.
-                        * The control pipe clears itself - nothing to do.
-                        * XXX Might try to reset the device here and retry.
-                        */
                        printk(KERN_NOTICE "%s: stall on control pipe\n",
                            sc->name);
                        goto Bad_End;
@@ -1151,11 +1190,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
        } else if (cmd->state == UB_CMDST_CLRRS) {
                if (urb->status == -EPIPE) {
-                       /*
-                        * STALL while clearning STALL.
-                        * The control pipe clears itself - nothing to do.
-                        * XXX Might try to reset the device here and retry.
-                        */
                        printk(KERN_NOTICE "%s: stall on control pipe\n",
                            sc->name);
                        goto Bad_End;
@@ -1172,7 +1206,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                ub_state_stat_counted(sc, cmd);
 
        } else if (cmd->state == UB_CMDST_CMD) {
-               if (urb->status == -EPIPE) {
+               switch (urb->status) {
+               case 0:
+                       break;
+               case -EOVERFLOW:
+                       goto Bad_End;
+               case -EPIPE:
                        rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
                        if (rc != 0) {
                                printk(KERN_NOTICE "%s: "
@@ -1182,17 +1221,20 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                                 * This is typically ENOMEM or some other such shit.
                                 * Retrying is pointless. Just do Bad End on it...
                                 */
-                               goto Bad_End;
+                               ub_state_done(sc, cmd, rc);
+                               return;
                        }
                        cmd->state = UB_CMDST_CLEAR;
                        ub_cmdtr_state(sc, cmd);
                        return;
-               }
-               if (urb->status != 0) {
+               case -ESHUTDOWN:        /* unplug */
+               case -EILSEQ:           /* unplug timeout on uhci */
+                       ub_state_done(sc, cmd, -ENODEV);
+                       return;
+               default:
                        goto Bad_End;
                }
                if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
-                       /* XXX Must do reset here to unconfuse the device */
                        goto Bad_End;
                }
 
@@ -1211,11 +1253,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                                printk(KERN_NOTICE "%s: "
                                    "unable to submit clear (%d)\n",
                                    sc->name, rc);
-                               /*
-                                * This is typically ENOMEM or some other such shit.
-                                * Retrying is pointless. Just do Bad End on it...
-                                */
-                               goto Bad_End;
+                               ub_state_done(sc, cmd, rc);
+                               return;
                        }
                        cmd->state = UB_CMDST_CLR2STS;
                        ub_cmdtr_state(sc, cmd);
@@ -1224,14 +1263,50 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                if (urb->status == -EOVERFLOW) {
                        /*
                         * A babble? Failure, but we must transfer CSW now.
-                        * XXX This is going to end in perpetual babble. Reset.
                         */
                        cmd->error = -EOVERFLOW;        /* A cheap trick... */
                        ub_state_stat(sc, cmd);
                        return;
                }
-               if (urb->status != 0)
-                       goto Bad_End;
+
+               if (cmd->dir == UB_DIR_WRITE) {
+                       /*
+                        * Do not continue writes in case of a failure.
+                        * Doing so would cause sectors to be mixed up,
+                        * which is worse than sectors lost.
+                        *
+                        * We must try to read the CSW, or many devices
+                        * get confused.
+                        */
+                       len = urb->actual_length;
+                       if (urb->status != 0 ||
+                           len != cmd->sgv[cmd->current_sg].length) {
+                               cmd->act_len += len;
+                               ub_cmdtr_act_len(sc, cmd);
+
+                               cmd->error = -EIO;
+                               ub_state_stat(sc, cmd);
+                               return;
+                       }
+
+               } else {
+                       /*
+                        * If an error occurs on read, we record it, and
+                        * continue to fetch data in order to avoid bubble.
+                        *
+                        * As a small shortcut, we stop if we detect that
+                        * a CSW mixed into data.
+                        */
+                       if (urb->status != 0)
+                               cmd->error = -EIO;
+
+                       len = urb->actual_length;
+                       if (urb->status != 0 ||
+                           len != cmd->sgv[cmd->current_sg].length) {
+                               if ((len & 0x1FF) == US_BULK_CS_WRAP_LEN)
+                                       goto Bad_End;
+                       }
+               }
 
                cmd->act_len += urb->actual_length;
                ub_cmdtr_act_len(sc, cmd);
@@ -1249,11 +1324,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                                printk(KERN_NOTICE "%s: "
                                    "unable to submit clear (%d)\n",
                                    sc->name, rc);
-                               /*
-                                * This is typically ENOMEM or some other such shit.
-                                * Retrying is pointless. Just do Bad End on it...
-                                */
-                               goto Bad_End;
+                               ub_state_done(sc, cmd, rc);
+                               return;
                        }
 
                        /*
@@ -1266,14 +1338,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        ub_cmdtr_state(sc, cmd);
                        return;
                }
-               if (urb->status == -EOVERFLOW) {
-                       /*
-                        * XXX We are screwed here. Retrying is pointless,
-                        * because the pipelined data will not get in until
-                        * we read with a big enough buffer. We must reset XXX.
-                        */
-                       goto Bad_End;
-               }
+
+               /* Catch everything, including -EOVERFLOW and other nasties. */
                if (urb->status != 0)
                        goto Bad_End;
 
@@ -1319,15 +1385,15 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        return;
                }
 
-               rc = le32_to_cpu(bcs->Residue);
-               if (rc != cmd->len - cmd->act_len) {
+               len = le32_to_cpu(bcs->Residue);
+               if (len != cmd->len - cmd->act_len) {
                        /*
                         * It is all right to transfer less, the caller has
                         * to check. But it's not all right if the device
                         * counts disagree with our counts.
                         */
                        /* P3 */ printk("%s: resid %d len %d act %d\n",
-                           sc->name, rc, cmd->len, cmd->act_len);
+                           sc->name, len, cmd->len, cmd->act_len);
                        goto Bad_End;
                }
 
@@ -1338,13 +1404,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                        ub_state_sense(sc, cmd);
                        return;
                case US_BULK_STAT_PHASE:
-                       /* XXX We must reset the transport here */
                        /* P3 */ printk("%s: status PHASE\n", sc->name);
                        goto Bad_End;
                default:
                        printk(KERN_INFO "%s: unknown CSW status 0x%x\n",
                            sc->name, bcs->Status);
-                       goto Bad_End;
+                       ub_state_done(sc, cmd, -EINVAL);
+                       return;
                }
 
                /* Not zeroing error to preserve a babble indicator */
@@ -1364,7 +1430,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                printk(KERN_WARNING "%s: "
                    "wrong command state %d\n",
                    sc->name, cmd->state);
-               goto Bad_End;
+               ub_state_done(sc, cmd, -EINVAL);
+               return;
        }
        return;
 
@@ -1611,6 +1678,93 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
        ub_scsi_urb_compl(sc, cmd);
 }
 
+/*
+ * Reset management
+ */
+
+static void ub_reset_enter(struct ub_dev *sc)
+{
+
+       if (sc->reset) {
+               /* This happens often on multi-LUN devices. */
+               return;
+       }
+       sc->reset = 1;
+
+#if 0 /* Not needed because the disconnect waits for us. */
+       unsigned long flags;
+       spin_lock_irqsave(&ub_lock, flags);
+       sc->openc++;
+       spin_unlock_irqrestore(&ub_lock, flags);
+#endif
+
+#if 0 /* We let them stop themselves. */
+       struct list_head *p;
+       struct ub_lun *lun;
+       list_for_each(p, &sc->luns) {
+               lun = list_entry(p, struct ub_lun, link);
+               blk_stop_queue(lun->disk->queue);
+       }
+#endif
+
+       schedule_work(&sc->reset_work);
+}
+
+static void ub_reset_task(void *arg)
+{
+       struct ub_dev *sc = arg;
+       unsigned long flags;
+       struct list_head *p;
+       struct ub_lun *lun;
+       int lkr, rc;
+
+       if (!sc->reset) {
+               printk(KERN_WARNING "%s: Running reset unrequested\n",
+                   sc->name);
+               return;
+       }
+
+       if (atomic_read(&sc->poison)) {
+               printk(KERN_NOTICE "%s: Not resetting disconnected device\n",
+                   sc->name); /* P3 This floods. Remove soon. XXX */
+       } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
+               printk(KERN_NOTICE "%s: Not resetting multi-interface device\n",
+                   sc->name); /* P3 This floods. Remove soon. XXX */
+       } else {
+               if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) {
+                       printk(KERN_NOTICE
+                           "%s: usb_lock_device_for_reset failed (%d)\n",
+                           sc->name, lkr);
+               } else {
+                       rc = usb_reset_device(sc->dev);
+                       if (rc < 0) {
+                               printk(KERN_NOTICE "%s: "
+                                   "usb_lock_device_for_reset failed (%d)\n",
+                                   sc->name, rc);
+                       }
+
+                       if (lkr)
+                               usb_unlock_device(sc->dev);
+               }
+       }
+
+       /*
+        * In theory, no commands can be running while reset is active,
+        * so nobody can ask for another reset, and so we do not need any
+        * queues of resets or anything. We do need a spinlock though,
+        * to interact with block layer.
+        */
+       spin_lock_irqsave(&sc->lock, flags);
+       sc->reset = 0;
+       tasklet_schedule(&sc->tasklet);
+       list_for_each(p, &sc->luns) {
+               lun = list_entry(p, struct ub_lun, link);
+               blk_start_queue(lun->disk->queue);
+       }
+       wake_up(&sc->reset_wait);
+       spin_unlock_irqrestore(&sc->lock, flags);
+}
+
 /*
  * This is called from a process context.
  */
@@ -2146,7 +2300,7 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
        if (ep_in == NULL || ep_out == NULL) {
                printk(KERN_NOTICE "%s: failed endpoint check\n",
                    sc->name);
-               return -EIO;
+               return -ENODEV;
        }
 
        /* Calculate and store the pipe values */
@@ -2172,6 +2326,9 @@ static int ub_probe(struct usb_interface *intf,
        int rc;
        int i;
 
+       if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
+               return -ENXIO;
+
        rc = -ENOMEM;
        if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
                goto err_core;
@@ -2181,6 +2338,8 @@ static int ub_probe(struct usb_interface *intf,
        usb_init_urb(&sc->work_urb);
        tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
        atomic_set(&sc->poison, 0);
+       INIT_WORK(&sc->reset_work, ub_reset_task, sc);
+       init_waitqueue_head(&sc->reset_wait);
 
        init_timer(&sc->work_timer);
        sc->work_timer.data = (unsigned long) sc;
@@ -2201,7 +2360,8 @@ static int ub_probe(struct usb_interface *intf,
 
        /* XXX Verify that we can handle the device (from descriptors) */
 
-       ub_get_pipes(sc, sc->dev, intf);
+       if (ub_get_pipes(sc, sc->dev, intf) != 0)
+               goto err_dev_desc;
 
        if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)
                goto err_diag;
@@ -2272,6 +2432,7 @@ static int ub_probe(struct usb_interface *intf,
 
        /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
 err_diag:
+err_dev_desc:
        usb_set_intfdata(intf, NULL);
        // usb_put_intf(sc->intf);
        usb_put_dev(sc->dev);
@@ -2309,14 +2470,14 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
        ub_revalidate(sc, lun);
 
        rc = -ENOMEM;
-       if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)
+       if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)
                goto err_diskalloc;
 
        lun->disk = disk;
        sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
        sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
        disk->major = UB_MAJOR;
-       disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
+       disk->first_minor = lun->id * UB_PARTS_PER_LUN;
        disk->fops = &ub_bd_fops;
        disk->private_data = lun;
        disk->driverfs_dev = &sc->intf->dev;
@@ -2379,6 +2540,11 @@ static void ub_disconnect(struct usb_interface *intf)
         */
        atomic_set(&sc->poison, 1);
 
+       /*
+        * Wait for reset to end, if any.
+        */
+       wait_event(sc->reset_wait, !sc->reset);
+
        /*
         * Blow away queued commands.
         *
@@ -2392,7 +2558,7 @@ static void ub_disconnect(struct usb_interface *intf)
        {
                struct ub_scsi_cmd *cmd;
                int cnt = 0;
-               while ((cmd = ub_cmdq_pop(sc)) != NULL) {
+               while ((cmd = ub_cmdq_peek(sc)) != NULL) {
                        cmd->error = -ENOTCONN;
                        cmd->state = UB_CMDST_DONE;
                        ub_cmdtr_state(sc, cmd);
@@ -2461,7 +2627,6 @@ static void ub_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver ub_driver = {
-       .owner =        THIS_MODULE,
        .name =         "ub",
        .probe =        ub_probe,
        .disconnect =   ub_disconnect,
@@ -2479,6 +2644,7 @@ static int __init ub_init(void)
        if ((rc = usb_register(&ub_driver)) != 0)
                goto err_register;
 
+       usb_usual_set_present(USB_US_TYPE_UB);
        return 0;
 
 err_register:
@@ -2494,6 +2660,7 @@ static void __exit ub_exit(void)
 
        devfs_remove(DEVFS_NAME);
        unregister_blkdev(UB_MAJOR, DRV_NAME);
+       usb_usual_clear_present(USB_US_TYPE_UB);
 }
 
 module_init(ub_init);
index 8e7fb35..3e7a067 100644 (file)
@@ -275,7 +275,6 @@ static void bcm203x_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver bcm203x_driver = {
-       .owner          = THIS_MODULE,
        .name           = "bcm203x",
        .probe          = bcm203x_probe,
        .disconnect     = bcm203x_disconnect,
index 067e278..8947c88 100644 (file)
@@ -768,7 +768,6 @@ static void bfusb_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver bfusb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "bfusb",
        .probe          = bfusb_probe,
        .disconnect     = bfusb_disconnect,
index 3947963..9446960 100644 (file)
@@ -619,7 +619,6 @@ static void bpa10x_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver bpa10x_driver = {
-       .owner          = THIS_MODULE,
        .name           = "bpa10x",
        .probe          = bpa10x_probe,
        .disconnect     = bpa10x_disconnect,
index 057cb2b..92382e8 100644 (file)
@@ -1044,7 +1044,6 @@ static void hci_usb_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver hci_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "hci_usb",
        .probe          = hci_usb_probe,
        .disconnect     = hci_usb_disconnect,
index e9b87a7..00342a6 100644 (file)
@@ -358,7 +358,7 @@ typedef struct _failStat
 #define MB_OUT_STRIPPED    0x40  // Board has read all output from fifo 
 #define MB_FATAL_ERROR     0x20  // Board has encountered a fatal error
 
-#pragma pack(4)                  // Reset padding to command-line default
+#pragma pack()                  // Reset padding to command-line default
 
 #endif      // I2PACK_H
 
index 7999da2..bdfdfd2 100644 (file)
@@ -1554,10 +1554,8 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
 
 EXPORT_SYMBOL(secure_tcp_sequence_number);
 
-
-
-/* Generate secure starting point for ephemeral TCP port search */
-u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
+/* Generate secure starting point for ephemeral IPV4 transport port search */
+u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
 {
        struct keydata *keyptr = get_keyptr();
        u32 hash[4];
@@ -1575,7 +1573,7 @@ u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
 }
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
+u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
 {
        struct keydata *keyptr = get_keyptr();
        u32 hash[12];
@@ -1586,7 +1584,7 @@ u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dp
 
        return twothirdsMD4Transform(daddr, hash);
 }
-EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
+EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
 #endif
 
 #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
index 092e9b1..1533f56 100644 (file)
@@ -151,7 +151,6 @@ static void usb_pcwd_disconnect     (struct usb_interface *interface);
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver usb_pcwd_driver = {
-       .owner =        THIS_MODULE,
        .name =         DRIVER_NAME,
        .probe =        usb_pcwd_probe,
        .disconnect =   usb_pcwd_disconnect,
index 815902c..a9163d0 100644 (file)
@@ -822,6 +822,30 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne
 }
 
 
+/** 
+ * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
+ * @cpu: CPU number
+ *
+ * This is the last known freq, without actually getting it from the driver.
+ * Return value will be same as what is shown in scaling_cur_freq in sysfs.
+ */
+unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+       unsigned int ret = 0;
+
+       if (policy) {
+               down(&policy->lock);
+               ret = policy->cur;
+               up(&policy->lock);
+               cpufreq_cpu_put(policy);
+       }
+
+       return (ret);
+}
+EXPORT_SYMBOL(cpufreq_quick_get);
+
+
 /** 
  * cpufreq_get - get the current CPU frequency (in kHz)
  * @cpu: CPU number
index 2ed5c43..39543a2 100644 (file)
@@ -93,7 +93,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
 {
        return  kstat_cpu(cpu).cpustat.idle +
                kstat_cpu(cpu).cpustat.iowait +
-               ( !dbs_tuners_ins.ignore_nice ? 
+               ( dbs_tuners_ins.ignore_nice ?
                  kstat_cpu(cpu).cpustat.nice :
                  0);
 }
@@ -127,7 +127,7 @@ show_one(sampling_rate, sampling_rate);
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(up_threshold, up_threshold);
 show_one(down_threshold, down_threshold);
-show_one(ignore_nice, ignore_nice);
+show_one(ignore_nice_load, ignore_nice);
 show_one(freq_step, freq_step);
 
 static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
@@ -207,7 +207,7 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
                const char *buf, size_t count)
 {
        unsigned int input;
@@ -272,7 +272,7 @@ define_one_rw(sampling_rate);
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
 define_one_rw(down_threshold);
-define_one_rw(ignore_nice);
+define_one_rw(ignore_nice_load);
 define_one_rw(freq_step);
 
 static struct attribute * dbs_attributes[] = {
@@ -282,7 +282,7 @@ static struct attribute * dbs_attributes[] = {
        &sampling_down_factor.attr,
        &up_threshold.attr,
        &down_threshold.attr,
-       &ignore_nice.attr,
+       &ignore_nice_load.attr,
        &freq_step.attr,
        NULL
 };
index 1774111..e69fd8d 100644 (file)
@@ -89,7 +89,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
 {
        return  kstat_cpu(cpu).cpustat.idle +
                kstat_cpu(cpu).cpustat.iowait +
-               ( !dbs_tuners_ins.ignore_nice ? 
+               ( dbs_tuners_ins.ignore_nice ?
                  kstat_cpu(cpu).cpustat.nice :
                  0);
 }
@@ -122,7 +122,7 @@ static ssize_t show_##file_name                                             \
 show_one(sampling_rate, sampling_rate);
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(up_threshold, up_threshold);
-show_one(ignore_nice, ignore_nice);
+show_one(ignore_nice_load, ignore_nice);
 
 static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
                const char *buf, size_t count)
@@ -182,7 +182,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
        return count;
 }
 
-static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
                const char *buf, size_t count)
 {
        unsigned int input;
@@ -223,7 +223,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
 define_one_rw(sampling_rate);
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
-define_one_rw(ignore_nice);
+define_one_rw(ignore_nice_load);
 
 static struct attribute * dbs_attributes[] = {
        &sampling_rate_max.attr,
@@ -231,7 +231,7 @@ static struct attribute * dbs_attributes[] = {
        &sampling_rate.attr,
        &sampling_down_factor.attr,
        &up_threshold.attr,
-       &ignore_nice.attr,
+       &ignore_nice_load.attr,
        NULL
 };
 
index 475d98f..780009c 100644 (file)
@@ -47,6 +47,8 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 
+#include <net/dst.h>
+
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
 MODULE_LICENSE("Dual BSD/GPL");
index ef3ee03..ed0c2ea 100644 (file)
@@ -43,6 +43,8 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 
+#include <net/dst.h>
+
 #include "ipoib.h"
 
 #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
index 64b4a30..bc2fce6 100644 (file)
@@ -235,7 +235,6 @@ static struct usb_device_id iforce_usb_ids [] = {
 MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
 
 struct usb_driver iforce_usb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "iforce",
        .probe =        iforce_usb_probe,
        .disconnect =   iforce_usb_disconnect,
index f8457ef..ca5b4a3 100644 (file)
@@ -1715,7 +1715,6 @@ hfc_usb_disconnect(struct usb_interface
 /* our driver information structure */
 /************************************/
 static struct usb_driver hfc_drv = {
-       .owner = THIS_MODULE,
        .name  = "hfc_usb",
        .id_table = hfcusb_idtab,
        .probe = hfc_usb_probe,
index 8e192a3..99cb0f3 100644 (file)
@@ -180,7 +180,6 @@ static struct usb_device_id st5481_ids[] = {
 MODULE_DEVICE_TABLE (usb, st5481_ids);
 
 static struct usb_driver st5481_usb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "st5481_usb",
        .probe =        probe_st5481,
        .disconnect =   disconnect_st5481,
index a6d3baa..a6f2dc6 100644 (file)
@@ -638,7 +638,7 @@ int dm_split_args(int *argc, char ***argvp, char *input)
 static void check_for_valid_limits(struct io_restrictions *rs)
 {
        if (!rs->max_sectors)
-               rs->max_sectors = MAX_SECTORS;
+               rs->max_sectors = SAFE_MAX_SECTORS;
        if (!rs->max_phys_segments)
                rs->max_phys_segments = MAX_PHYS_SEGMENTS;
        if (!rs->max_hw_segments)
index 0a78ba3..a6c91db 100644 (file)
@@ -544,7 +544,6 @@ static struct usb_device_id flexcop_usb_table [] = {
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver flexcop_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "b2c2_flexcop_usb",
        .probe          = flexcop_usb_probe,
        .disconnect = flexcop_usb_disconnect,
index 336fc28..b996fb5 100644 (file)
@@ -986,7 +986,6 @@ static const struct usb_device_id cinergyt2_table [] __devinitdata = {
 MODULE_DEVICE_TABLE(usb, cinergyt2_table);
 
 static struct usb_driver cinergyt2_driver = {
-       .owner  = THIS_MODULE,
        .name   = "cinergyT2",
        .probe  = cinergyt2_probe,
        .disconnect     = cinergyt2_disconnect,
index 8c7beff..ce44aa6 100644 (file)
@@ -144,7 +144,6 @@ static struct dvb_usb_properties a800_properties = {
 };
 
 static struct usb_driver a800_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_a800",
        .probe          = a800_probe,
        .disconnect = dvb_usb_device_exit,
index 3fe383f..d05fab0 100644 (file)
@@ -241,7 +241,6 @@ static struct dvb_usb_properties cxusb_properties = {
 };
 
 static struct usb_driver cxusb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_cxusb",
        .probe          = cxusb_probe,
        .disconnect = dvb_usb_device_exit,
index aa271a2..52ac3e5 100644 (file)
@@ -373,7 +373,6 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
 };
 
 static struct usb_driver dibusb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_dibusb_mb",
        .probe          = dibusb_probe,
        .disconnect = dvb_usb_device_exit,
index 6a0912e..55802fb 100644 (file)
@@ -82,7 +82,6 @@ static struct dvb_usb_properties dibusb_mc_properties = {
 };
 
 static struct usb_driver dibusb_mc_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_dibusb_mc",
        .probe          = dibusb_mc_probe,
        .disconnect = dvb_usb_device_exit,
index f98e306..450417a 100644 (file)
@@ -233,7 +233,6 @@ static struct dvb_usb_properties digitv_properties = {
 };
 
 static struct usb_driver digitv_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_digitv",
        .probe          = digitv_probe,
        .disconnect = dvb_usb_device_exit,
index b595476..6e2bac8 100644 (file)
@@ -198,7 +198,6 @@ static struct dvb_usb_properties wt220u_properties = {
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver dtt200u_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_dtt200u",
        .probe          = dtt200u_usb_probe,
        .disconnect = dvb_usb_device_exit,
index 1841a66..fac48fc 100644 (file)
@@ -202,7 +202,6 @@ static struct dvb_usb_properties nova_t_properties = {
 };
 
 static struct usb_driver nova_t_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_nova_t_usb2",
        .probe          = nova_t_probe,
        .disconnect = dvb_usb_device_exit,
index 6fd6765..14f1911 100644 (file)
@@ -128,7 +128,6 @@ static struct dvb_usb_properties umt_properties = {
 };
 
 static struct usb_driver umt_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_umt_010",
        .probe          = umt_probe,
        .disconnect = dvb_usb_device_exit,
index de13c04..afa00fd 100644 (file)
@@ -256,7 +256,6 @@ static struct dvb_usb_properties vp702x_properties = {
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp702x_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb-usb-vp702x",
        .probe          = vp702x_usb_probe,
        .disconnect = dvb_usb_device_exit,
index 75765e3..3835235 100644 (file)
@@ -253,7 +253,6 @@ static struct dvb_usb_properties vp7045_properties = {
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp7045_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "dvb_usb_vp7045",
        .probe          = vp7045_usb_probe,
        .disconnect = dvb_usb_device_exit,
index 9774e94..1439cb7 100644 (file)
@@ -582,7 +582,6 @@ MODULE_LICENSE("GPL");
 
 
 static struct usb_driver cpia_driver = {
-       .owner          = THIS_MODULE,
        .name           = "cpia",
        .probe          = cpia_probe,
        .disconnect     = cpia_disconnect,
index 06d7687..3a56120 100644 (file)
@@ -1884,7 +1884,6 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
 }
 
 static struct usb_driver em28xx_usb_driver = {
-       .owner = THIS_MODULE,
        .name = "em28xx",
        .probe = em28xx_usb_probe,
        .disconnect = em28xx_usb_disconnect,
index 4262a22..5378360 100644 (file)
@@ -313,13 +313,13 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
                u32      log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
                if (ioc->bus_type == FC)
                        mpt_fc_log_info(ioc, log_info);
-               else if (ioc->bus_type == SCSI)
+               else if (ioc->bus_type == SPI)
                        mpt_sp_log_info(ioc, log_info);
                else if (ioc->bus_type == SAS)
                        mpt_sas_log_info(ioc, log_info);
        }
        if (ioc_stat & MPI_IOCSTATUS_MASK) {
-               if (ioc->bus_type == SCSI &&
+               if (ioc->bus_type == SPI &&
                    cb_idx != mpt_stm_index &&
                    cb_idx != mpt_lan_index)
                        mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
@@ -1376,7 +1376,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        }
        else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
                ioc->prod_name = "LSI53C1030";
-               ioc->bus_type = SCSI;
+               ioc->bus_type = SPI;
                /* 1030 Chip Fix. Disable Split transactions
                 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
                 */
@@ -1389,7 +1389,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        }
        else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
                ioc->prod_name = "LSI53C1035";
-               ioc->bus_type = SCSI;
+               ioc->bus_type = SPI;
        }
        else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
                ioc->prod_name = "LSISAS1064";
@@ -3042,7 +3042,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
        /* Clear the internal flash bad bit - autoincrementing register,
         * so must do two writes.
         */
-       if (ioc->bus_type == SCSI) {
+       if (ioc->bus_type == SPI) {
                /*
                 * 1030 and 1035 H/W errata, workaround to access
                 * the ClearFlashBadSignatureBit
@@ -3152,7 +3152,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
        int cnt,cntdn;
 
        dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
-       if (ioc->bus_type == SCSI) {
+       if (ioc->bus_type == SPI) {
                /* Always issue a Msg Unit Reset first. This will clear some
                 * SCSI bus hang conditions.
                 */
@@ -3580,7 +3580,7 @@ initChainBuffers(MPT_ADAPTER *ioc)
        dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
                ioc->name, numSGE, num_sge, num_chain));
 
-       if (ioc->bus_type == SCSI)
+       if (ioc->bus_type == SPI)
                num_chain *= MPT_SCSI_CAN_QUEUE;
        else
                num_chain *= MPT_FC_CAN_QUEUE;
index bac8eb4..6c48d1f 100644 (file)
@@ -76,8 +76,8 @@
 #define COPYRIGHT      "Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "3.03.04"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.03.04"
+#define MPT_LINUX_VERSION_COMMON       "3.03.05"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.03.05"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -321,7 +321,7 @@ typedef struct _SYSIF_REGS
  *     Dynamic Multi-Pathing specific stuff...
  */
 
-/* VirtDevice negoFlags field */
+/* VirtTarget negoFlags field */
 #define MPT_TARGET_NO_NEGO_WIDE                0x01
 #define MPT_TARGET_NO_NEGO_SYNC                0x02
 #define MPT_TARGET_NO_NEGO_QAS         0x04
@@ -330,8 +330,7 @@ typedef struct _SYSIF_REGS
 /*
  *     VirtDevice - FC LUN device or SCSI target device
  */
-typedef struct _VirtDevice {
-       struct scsi_device      *device;
+typedef struct _VirtTarget {
        u8                       tflags;
        u8                       ioc_id;
        u8                       target_id;
@@ -342,21 +341,18 @@ typedef struct _VirtDevice {
        u8                       negoFlags;     /* bit field, see above */
        u8                       raidVolume;    /* set, if RAID Volume */
        u8                       type;          /* byte 0 of Inquiry data */
-       u8                       cflags;        /* controller flags */
-       u8                       rsvd1raid;
-       u16                      fc_phys_lun;
-       u16                      fc_xlat_lun;
        u32                      num_luns;
        u32                      luns[8];               /* Max LUNs is 256 */
-       u8                       pad[4];
        u8                       inq_data[8];
-               /* IEEE Registered Extended Identifier
-                  obtained via INQUIRY VPD page 0x83 */
-               /* NOTE: Do not separate uniq_prepad and uniq_data
-                  as they are treateed as a single entity in the code */
-       u8                       uniq_prepad[8];
-       u8                       uniq_data[20];
-       u8                       pad2[4];
+} VirtTarget;
+
+typedef struct _VirtDevice {
+       VirtTarget              *vtarget;
+       u8                       ioc_id;
+       u8                       bus_id;
+       u8                       target_id;
+       u8                       configured_lun;
+       u32                      lun;
 } VirtDevice;
 
 /*
@@ -903,7 +899,7 @@ typedef struct _MPT_LOCAL_REPLY {
 
 typedef enum {
        FC,
-       SCSI,
+       SPI,
        SAS
 } BUS_TYPE;
 
@@ -912,7 +908,7 @@ typedef struct _MPT_SCSI_HOST {
        int                       port;
        u32                       pad0;
        struct scsi_cmnd        **ScsiLookup;
-       VirtDevice              **Targets;
+       VirtTarget              **Targets;
        MPT_LOCAL_REPLY          *pLocal;               /* used for internal commands */
        struct timer_list         timer;
                /* Pool of memory for holding SCpnts before doing
index 602138f..959d2c5 100644 (file)
@@ -1245,7 +1245,7 @@ mptctl_gettargetinfo (unsigned long arg)
        MPT_ADAPTER             *ioc;
        struct Scsi_Host        *sh;
        MPT_SCSI_HOST           *hd;
-       VirtDevice              *vdev;
+       VirtTarget              *vdev;
        char                    *pmem;
        int                     *pdata;
        IOCPage2_t              *pIoc2;
@@ -1822,7 +1822,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
        case MPI_FUNCTION_SCSI_IO_REQUEST:
                if (ioc->sh) {
                        SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
-                       VirtDevice      *pTarget = NULL;
+                       VirtTarget      *pTarget = NULL;
                        MPT_SCSI_HOST   *hd = NULL;
                        int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
                        int scsidir = 0;
index a628be9..ba61e18 100644 (file)
@@ -84,13 +84,16 @@ static int  mptfcTaskCtx = -1;
 static int     mptfcInternalCtx = -1; /* Used only for internal commands */
 
 static struct scsi_host_template mptfc_driver_template = {
+       .module                         = THIS_MODULE,
        .proc_name                      = "mptfc",
        .proc_info                      = mptscsih_proc_info,
        .name                           = "MPT FC Host",
        .info                           = mptscsih_info,
        .queuecommand                   = mptscsih_qcmd,
+       .target_alloc                   = mptscsih_target_alloc,
        .slave_alloc                    = mptscsih_slave_alloc,
        .slave_configure                = mptscsih_slave_configure,
+       .target_destroy                 = mptscsih_target_destroy,
        .slave_destroy                  = mptscsih_slave_destroy,
        .change_queue_depth             = mptscsih_change_queue_depth,
        .eh_abort_handler               = mptscsih_abort,
@@ -167,13 +170,15 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(MYIOC_s_WARN_FMT
                  "Skipping because it's not operational!\n",
                  ioc->name);
-               return -ENODEV;
+               error = -ENODEV;
+               goto out_mptfc_probe;
        }
 
        if (!ioc->active) {
                printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
                  ioc->name);
-               return -ENODEV;
+               error = -ENODEV;
+               goto out_mptfc_probe;
        }
 
        /*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -198,7 +203,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(MYIOC_s_WARN_FMT
                        "Unable to register controller with SCSI subsystem\n",
                        ioc->name);
-                return -1;
+               error = -1;
+               goto out_mptfc_probe;
         }
 
        spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -266,7 +272,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        mem = kmalloc(sz, GFP_ATOMIC);
        if (mem == NULL) {
                error = -ENOMEM;
-               goto mptfc_probe_failed;
+               goto out_mptfc_probe;
        }
 
        memset(mem, 0, sz);
@@ -284,14 +290,14 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        mem = kmalloc(sz, GFP_ATOMIC);
        if (mem == NULL) {
                error = -ENOMEM;
-               goto mptfc_probe_failed;
+               goto out_mptfc_probe;
        }
 
        memset(mem, 0, sz);
-       hd->Targets = (VirtDevice **) mem;
+       hd->Targets = (VirtTarget **) mem;
 
        dprintk((KERN_INFO
-         "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+         "  vdev @ %p, sz=%d\n", hd->Targets, sz));
 
        /* Clear the TM flags
         */
@@ -330,13 +336,13 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if(error) {
                dprintk((KERN_ERR MYNAM
                  "scsi_add_host failed\n"));
-               goto mptfc_probe_failed;
+               goto out_mptfc_probe;
        }
 
        scsi_scan_host(sh);
        return 0;
 
-mptfc_probe_failed:
+out_mptfc_probe:
 
        mptscsih_remove(pdev);
        return error;
index e0a8bb8..17e9757 100644 (file)
@@ -228,31 +228,35 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
  * implement ->target_alloc.
  */
 static int
-mptsas_slave_alloc(struct scsi_device *device)
+mptsas_slave_alloc(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *host = device->host;
+       struct Scsi_Host        *host = sdev->host;
        MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
        struct sas_rphy         *rphy;
        struct mptsas_portinfo  *p;
+       VirtTarget              *vtarget;
        VirtDevice              *vdev;
-       uint                    target = device->id;
+       struct scsi_target      *starget;
        int i;
 
-       if ((vdev = hd->Targets[target]) != NULL)
-               goto out;
-
        vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
        if (!vdev) {
                printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
                                hd->ioc->name, sizeof(VirtDevice));
                return -ENOMEM;
        }
-
        memset(vdev, 0, sizeof(VirtDevice));
-       vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
        vdev->ioc_id = hd->ioc->id;
+       sdev->hostdata = vdev;
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+       vdev->vtarget = vtarget;
+       if (vtarget->num_luns == 0) {
+               vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
+               hd->Targets[sdev->id] = vtarget;
+       }
 
-       rphy = dev_to_rphy(device->sdev_target->dev.parent);
+       rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
        list_for_each_entry(p, &hd->ioc->sas_topology, list) {
                for (i = 0; i < p->num_phys; i++) {
                        if (p->phy_info[i].attached.sas_address ==
@@ -260,7 +264,7 @@ mptsas_slave_alloc(struct scsi_device *device)
                                vdev->target_id =
                                        p->phy_info[i].attached.target;
                                vdev->bus_id = p->phy_info[i].attached.bus;
-                               hd->Targets[device->id] = vdev;
+                               vdev->lun = sdev->lun;
                                goto out;
                        }
                }
@@ -271,19 +275,24 @@ mptsas_slave_alloc(struct scsi_device *device)
        return -ENODEV;
 
  out:
-       vdev->num_luns++;
-       device->hostdata = vdev;
+       vtarget->ioc_id = vdev->ioc_id;
+       vtarget->target_id = vdev->target_id;
+       vtarget->bus_id = vdev->bus_id;
+       vtarget->num_luns++;
        return 0;
 }
 
 static struct scsi_host_template mptsas_driver_template = {
+       .module                         = THIS_MODULE,
        .proc_name                      = "mptsas",
        .proc_info                      = mptscsih_proc_info,
        .name                           = "MPT SPI Host",
        .info                           = mptscsih_info,
        .queuecommand                   = mptscsih_qcmd,
+       .target_alloc                   = mptscsih_target_alloc,
        .slave_alloc                    = mptsas_slave_alloc,
        .slave_configure                = mptscsih_slave_configure,
+       .target_destroy                 = mptscsih_target_destroy,
        .slave_destroy                  = mptscsih_slave_destroy,
        .change_queue_depth             = mptscsih_change_queue_depth,
        .eh_abort_handler               = mptscsih_abort,
@@ -986,7 +995,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
                goto out_free_port_info;
 
        list_add_tail(&port_info->list, &ioc->sas_topology);
-
        for (i = 0; i < port_info->num_phys; i++) {
                mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
                        (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
@@ -1133,13 +1141,15 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(MYIOC_s_WARN_FMT
                  "Skipping because it's not operational!\n",
                  ioc->name);
-               return -ENODEV;
+               error = -ENODEV;
+               goto out_mptsas_probe;
        }
 
        if (!ioc->active) {
                printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
                  ioc->name);
-               return -ENODEV;
+               error = -ENODEV;
+               goto out_mptsas_probe;
        }
 
        /*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -1163,7 +1173,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(MYIOC_s_WARN_FMT
                        "Unable to register controller with SCSI subsystem\n",
                        ioc->name);
-                return -1;
+               error = -1;
+               goto out_mptsas_probe;
         }
 
        spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -1237,7 +1248,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        mem = kmalloc(sz, GFP_ATOMIC);
        if (mem == NULL) {
                error = -ENOMEM;
-               goto mptsas_probe_failed;
+               goto out_mptsas_probe;
        }
 
        memset(mem, 0, sz);
@@ -1255,14 +1266,14 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        mem = kmalloc(sz, GFP_ATOMIC);
        if (mem == NULL) {
                error = -ENOMEM;
-               goto mptsas_probe_failed;
+               goto out_mptsas_probe;
        }
 
        memset(mem, 0, sz);
-       hd->Targets = (VirtDevice **) mem;
+       hd->Targets = (VirtTarget **) mem;
 
        dprintk((KERN_INFO
-         "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+         "  vtarget @ %p, sz=%d\n", hd->Targets, sz));
 
        /* Clear the TM flags
         */
@@ -1308,14 +1319,14 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (error) {
                dprintk((KERN_ERR MYNAM
                  "scsi_add_host failed\n"));
-               goto mptsas_probe_failed;
+               goto out_mptsas_probe;
        }
 
        mptsas_scan_sas_topology(ioc);
 
        return 0;
 
-mptsas_probe_failed:
+out_mptsas_probe:
 
        mptscsih_remove(pdev);
        return error;
index b7b9846..93a16fa 100644 (file)
@@ -150,28 +150,29 @@ static int        mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar
 int            mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 int            mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
-static void    mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
-static void    mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
-static void    mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
+static void    mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
+static void    mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
 static void    mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
-static void    mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
+static void    mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
 static int     mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
 static int     mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
 int            mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static int     mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
-static int     mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
+static void    mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
+static void    mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
+static int     mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 
 static struct work_struct   mptscsih_persistTask;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 static int     mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
 static void    mptscsih_domainValidation(void *hd);
-static int     mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 static void    mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
 static int     mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
 static void    mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
 static void    mptscsih_fillbuf(char *buffer, int size, int index, int width);
 static void    mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
+static void    mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
 #endif
 
 void           mptscsih_remove(struct pci_dev *);
@@ -627,7 +628,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
                        "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
                        "resid=%d bufflen=%d xfer_cnt=%d\n",
-                       ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+                       ioc->id, sc->device->id, sc->device->lun,
                        status, scsi_state, scsi_status, sc->resid,
                        sc->request_bufflen, xfer_cnt));
 
@@ -641,7 +642,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                    pScsiReply->ResponseInfo) {
                        printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
                        "FCP_ResponseInfo=%08xh\n",
-                       ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+                       ioc->id, sc->device->id, sc->device->lun,
                        le32_to_cpu(pScsiReply->ResponseInfo));
                }
 
@@ -677,8 +678,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                        sc->result = DID_RESET << 16;
 
                        /* GEM Workaround. */
-                       if (ioc->bus_type == SCSI)
-                               mptscsih_no_negotiate(hd, sc->device->id);
+                       if (ioc->bus_type == SPI)
+                               mptscsih_no_negotiate(hd, sc);
                        break;
 
                case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
@@ -892,16 +893,15 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
  *             when a lun is disable by mid-layer.
  *             Do NOT access the referenced scsi_cmnd structure or
  *             members. Will cause either a paging or NULL ptr error.
- *     @hd: Pointer to a SCSI HOST structure
- *     @target: target id
- *     @lun: lun
+ *      @hd: Pointer to a SCSI HOST structure
+ *     @vdevice: per device private data
  *
  *     Returns: None.
  *
  *     Called from slave_destroy.
  */
 static void
-mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
+mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
        SCSIIORequest_t *mf = NULL;
        int              ii;
@@ -909,7 +909,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
        struct scsi_cmnd *sc;
 
        dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
-                       target, lun, max));
+                       vdevice->target_id, vdevice->lun, max));
 
        for (ii=0; ii < max; ii++) {
                if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -919,7 +919,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
                        dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
                                        hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
 
-                       if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
+                       if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
                                continue;
 
                        /* Cleanup
@@ -993,8 +993,10 @@ mptscsih_remove(struct pci_dev *pdev)
        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
        struct Scsi_Host        *host = ioc->sh;
        MPT_SCSI_HOST           *hd;
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
        int                     count;
        unsigned long           flags;
+#endif 
        int sz1;
 
        if(!host) {
@@ -1075,11 +1077,6 @@ mptscsih_shutdown(struct pci_dev *pdev)
 
        hd = (MPT_SCSI_HOST *)host->hostdata;
 
-       /* Flush the cache of this adapter
-        */
-       if(hd != NULL)
-               mptscsih_synchronize_cache(hd, 0);
-
 }
 
 #ifdef CONFIG_PM
@@ -1286,7 +1283,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        MPT_SCSI_HOST           *hd;
        MPT_FRAME_HDR           *mf;
        SCSIIORequest_t         *pScsiReq;
-       VirtDevice              *pTarget = SCpnt->device->hostdata;
+       VirtDevice              *vdev = SCpnt->device->hostdata;
        int      lun;
        u32      datalen;
        u32      scsictl;
@@ -1341,8 +1338,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        /* Default to untagged. Once a target structure has been allocated,
         * use the Inquiry data to determine if device supports tagged.
         */
-       if (pTarget
-           && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+       if (vdev
+           && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
            && (SCpnt->device->tagged_supported)) {
                scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
        } else {
@@ -1351,8 +1348,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 
        /* Use the above information to set up the message frame
         */
-       pScsiReq->TargetID = (u8) pTarget->target_id;
-       pScsiReq->Bus = pTarget->bus_id;
+       pScsiReq->TargetID = (u8) vdev->target_id;
+       pScsiReq->Bus = vdev->bus_id;
        pScsiReq->ChainOffset = 0;
        pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
        pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1403,8 +1400,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
        SCpnt->host_scribble = NULL;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-       if (hd->ioc->bus_type == SCSI) {
-               int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
+       if (hd->ioc->bus_type == SPI) {
+               int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
                int issueCmd = 1;
 
                if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -1437,7 +1434,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
                        /* Set the DV flags.
                         */
                        if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
-                               mptscsih_set_dvflags(hd, pScsiReq);
+                               mptscsih_set_dvflags(hd, SCpnt);
 
                        if (!issueCmd)
                                goto fail;
@@ -1741,6 +1738,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
        u32              ctx2abort;
        int              scpnt_idx;
        int              retval;
+       VirtDevice       *vdev;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
@@ -1790,8 +1788,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 
        hd->abortSCpnt = SCpnt;
 
+       vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-               SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
+               vdev->bus_id, vdev->target_id, vdev->lun,
                ctx2abort, 2 /* 2 second timeout */);
 
        printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
@@ -1822,6 +1821,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
        int              retval;
+       VirtDevice       *vdev;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
@@ -1839,8 +1839,9 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
               hd->ioc->name, SCpnt);
        scsi_print_command(SCpnt);
 
+       vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-               SCpnt->device->channel, SCpnt->device->id,
+               vdev->bus_id, vdev->target_id,
                0, 0, 5 /* 5 second timeout */);
 
        printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
@@ -1871,6 +1872,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
        int              retval;
+       VirtDevice       *vdev;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
@@ -1888,8 +1890,9 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
        if (hd->timeouts < -1)
                hd->timeouts++;
 
+       vdev = SCpnt->device->hostdata;
        retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-               SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
+               vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
 
        printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
                hd->ioc->name,
@@ -2148,26 +2151,39 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
        return 0;
 }
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *     OS entry point to allow host driver to alloc memory
+ *     for each scsi target. Called once per device the bus scan.
+ *     Return non-zero if allocation fails.
+ */
+int
+mptscsih_target_alloc(struct scsi_target *starget)
+{
+       VirtTarget              *vtarget;
+
+       vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
+       if (!vtarget)
+               return -ENOMEM;
+       memset(vtarget, 0, sizeof(VirtTarget));
+       starget->hostdata = vtarget;
+       return 0;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     OS entry point to allow host driver to alloc memory
  *     for each scsi device. Called once per device the bus scan.
  *     Return non-zero if allocation fails.
- *     Init memory once per id (not LUN).
  */
 int
-mptscsih_slave_alloc(struct scsi_device *device)
+mptscsih_slave_alloc(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *host = device->host;
+       struct Scsi_Host        *host = sdev->host;
        MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
+       VirtTarget              *vtarget;
        VirtDevice              *vdev;
-       uint                    target = device->id;
-
-       if (hd == NULL)
-               return -ENODEV;
-
-       if ((vdev = hd->Targets[target]) != NULL)
-               goto out;
+       struct scsi_target      *starget;
 
        vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
        if (!vdev) {
@@ -2177,25 +2193,33 @@ mptscsih_slave_alloc(struct scsi_device *device)
        }
 
        memset(vdev, 0, sizeof(VirtDevice));
-       vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
        vdev->ioc_id = hd->ioc->id;
-       vdev->target_id = device->id;
-       vdev->bus_id = device->channel;
-       vdev->raidVolume = 0;
-       hd->Targets[device->id] = vdev;
-       if (hd->ioc->bus_type == SCSI) {
-               if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
-                       vdev->raidVolume = 1;
-                       ddvtprintk((KERN_INFO
-                           "RAID Volume @ id %d\n", device->id));
+       vdev->target_id = sdev->id;
+       vdev->bus_id = sdev->channel;
+       vdev->lun = sdev->lun;
+       sdev->hostdata = vdev;
+
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+       vdev->vtarget = vtarget;
+
+       if (vtarget->num_luns == 0) {
+               hd->Targets[sdev->id] = vtarget;
+               vtarget->ioc_id = hd->ioc->id;
+               vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
+               vtarget->target_id = sdev->id;
+               vtarget->bus_id = sdev->channel;
+               if (hd->ioc->bus_type == SPI) {
+                       if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
+                               vtarget->raidVolume = 1;
+                               ddvtprintk((KERN_INFO
+                                   "RAID Volume @ id %d\n", sdev->id));
+                       }
+               } else {
+                       vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
                }
-       } else {
-               vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
        }
-
- out:
-       vdev->num_luns++;
-       device->hostdata = vdev;
+       vtarget->num_luns++;
        return 0;
 }
 
@@ -2204,40 +2228,52 @@ mptscsih_slave_alloc(struct scsi_device *device)
  *     Called if no device present or device being unloaded
  */
 void
-mptscsih_slave_destroy(struct scsi_device *device)
+mptscsih_target_destroy(struct scsi_target *starget)
 {
-       struct Scsi_Host        *host = device->host;
-       MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
-       VirtDevice              *vdev;
-       uint                    target = device->id;
-       uint                    lun = device->lun;
-
-       if (hd == NULL)
-               return;
-
-       mptscsih_search_running_cmds(hd, target, lun);
-
-       vdev = hd->Targets[target];
-       vdev->luns[0] &= ~(1 << lun);
-       if (--vdev->num_luns)
-               return;
-
-       kfree(hd->Targets[target]);
-       hd->Targets[target] = NULL;
-
-       if (hd->ioc->bus_type == SCSI) {
-               if (mptscsih_is_phys_disk(hd->ioc, target)) {
-                       hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
-               } else {
-                       hd->ioc->spi_data.dvStatus[target] =
-                               MPT_SCSICFG_NEGOTIATE;
+       if (starget->hostdata)
+               kfree(starget->hostdata);
+       starget->hostdata = NULL;
+}
 
-                       if (!hd->negoNvram) {
-                               hd->ioc->spi_data.dvStatus[target] |=
-                                       MPT_SCSICFG_DV_NOT_DONE;
+/*
+ *     OS entry point to allow for host driver to free allocated memory
+ *     Called if no device present or device being unloaded
+ */
+void
+mptscsih_slave_destroy(struct scsi_device *sdev)
+{
+       struct Scsi_Host        *host = sdev->host;
+       MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
+       VirtTarget              *vtarget;
+       VirtDevice              *vdevice;
+       struct scsi_target      *starget;
+
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+       vdevice = sdev->hostdata;
+
+       mptscsih_search_running_cmds(hd, vdevice);
+       vtarget->luns[0] &= ~(1 << vdevice->lun);
+       vtarget->num_luns--;
+       if (vtarget->num_luns == 0) {
+               mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
+               if (hd->ioc->bus_type == SPI) {
+                       if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
+                               hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
+                       } else {
+                               hd->ioc->spi_data.dvStatus[vtarget->target_id] =
+                                       MPT_SCSICFG_NEGOTIATE;
+                               if (!hd->negoNvram) {
+                                       hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
+                                               MPT_SCSICFG_DV_NOT_DONE;
+                               }
                        }
                }
+               hd->Targets[sdev->id] = NULL;
        }
+       mptscsih_synchronize_cache(hd, vdevice);
+       kfree(vdevice);
+       sdev->hostdata = NULL;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2251,22 +2287,21 @@ mptscsih_slave_destroy(struct scsi_device *device)
 int
 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
-       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
-       VirtDevice *pTarget;
-       int     max_depth;
-       int     tagged;
-
-       if (hd == NULL)
-               return 0;
-       if (!(pTarget = hd->Targets[sdev->id]))
-               return 0;
-
-       if (hd->ioc->bus_type == SCSI) {
-               if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
-                       if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
+       MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
+       VirtTarget              *vtarget;
+       struct scsi_target      *starget;
+       int                     max_depth;
+       int                     tagged;
+
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+
+       if (hd->ioc->bus_type == SPI) {
+               if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+                       if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
                                max_depth = 1;
-                       else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
-                                (pTarget->minSyncFactor <= MPT_ULTRA160 ))
+                       else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
+                                (vtarget->minSyncFactor <= MPT_ULTRA160 ))
                                max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
                        else
                                max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
@@ -2295,64 +2330,58 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
  *     Return non-zero if fails.
  */
 int
-mptscsih_slave_configure(struct scsi_device *device)
+mptscsih_slave_configure(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *sh = device->host;
-       VirtDevice              *pTarget;
+       struct Scsi_Host        *sh = sdev->host;
+       VirtTarget              *vtarget;
+       VirtDevice              *vdevice;
+       struct scsi_target      *starget;
        MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)sh->hostdata;
+       int                     indexed_lun, lun_index;
 
-       if ((hd == NULL) || (hd->Targets == NULL)) {
-               return 0;
-       }
+       starget = scsi_target(sdev);
+       vtarget = starget->hostdata;
+       vdevice = sdev->hostdata;
 
        dsprintk((MYIOC_s_INFO_FMT
                "device @ %p, id=%d, LUN=%d, channel=%d\n",
-               hd->ioc->name, device, device->id, device->lun, device->channel));
-       dsprintk((MYIOC_s_INFO_FMT
-               "sdtr %d wdtr %d ppr %d inq length=%d\n",
-               hd->ioc->name, device->sdtr, device->wdtr,
-               device->ppr, device->inquiry_len));
-
-       if (device->id > sh->max_id) {
+               hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
+       if (hd->ioc->bus_type == SPI)
+               dsprintk((MYIOC_s_INFO_FMT
+                   "sdtr %d wdtr %d ppr %d inq length=%d\n",
+                   hd->ioc->name, sdev->sdtr, sdev->wdtr,
+                   sdev->ppr, sdev->inquiry_len));
+
+       if (sdev->id > sh->max_id) {
                /* error case, should never happen */
-               scsi_adjust_queue_depth(device, 0, 1);
-               goto slave_configure_exit;
-       }
-
-       pTarget = hd->Targets[device->id];
-
-       if (pTarget == NULL) {
-               /* Driver doesn't know about this device.
-                * Kernel may generate a "Dummy Lun 0" which
-                * may become a real Lun if a
-                * "scsi add-single-device" command is executed
-                * while the driver is active (hot-plug a
-                * device).  LSI Raid controllers need
-                * queue_depth set to DEV_HIGH for this reason.
-                */
-               scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
-                       MPT_SCSI_CMD_PER_DEV_HIGH);
+               scsi_adjust_queue_depth(sdev, 0, 1);
                goto slave_configure_exit;
        }
 
-       mptscsih_initTarget(hd, device->channel, device->id, device->lun,
-               device->inquiry, device->inquiry_len );
-       mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
+       vdevice->configured_lun=1;
+       lun_index = (vdevice->lun >> 5);  /* 32 luns per lun_index */
+       indexed_lun = (vdevice->lun % 32);
+       vtarget->luns[lun_index] |= (1 << indexed_lun);
+       mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
+           sdev->inquiry_len );
+       mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
 
        dsprintk((MYIOC_s_INFO_FMT
                "Queue depth=%d, tflags=%x\n",
-               hd->ioc->name, device->queue_depth, pTarget->tflags));
+               hd->ioc->name, sdev->queue_depth, vtarget->tflags));
 
-       dsprintk((MYIOC_s_INFO_FMT
-               "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
-               hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
+       if (hd->ioc->bus_type == SPI)
+               dsprintk((MYIOC_s_INFO_FMT
+                   "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
+                   hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
+                   vtarget->minSyncFactor));
 
 slave_configure_exit:
 
        dsprintk((MYIOC_s_INFO_FMT
                "tagged %d, simple %d, ordered %d\n",
-               hd->ioc->name,device->tagged_supported, device->simple_tags,
-               device->ordered_tags));
+               hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
+               sdev->ordered_tags));
 
        return 0;
 }
@@ -2370,16 +2399,14 @@ slave_configure_exit:
 static void
 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
 {
-       VirtDevice      *target;
+       VirtDevice      *vdev;
        SCSIIORequest_t *pReq;
        u32              sense_count = le32_to_cpu(pScsiReply->SenseCount);
-       int              index;
 
        /* Get target structure
         */
        pReq = (SCSIIORequest_t *) mf;
-       index = (int) pReq->TargetID;
-       target = hd->Targets[index];
+       vdev = sc->device->hostdata;
 
        if (sense_count) {
                u8 *sense_data;
@@ -2393,7 +2420,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
                /* Log SMART data (asc = 0x5D, non-IM case only) if required.
                 */
                if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
-                       if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
+                       if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
                                int idx;
                                MPT_ADAPTER *ioc = hd->ioc;
 
@@ -2403,7 +2430,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
 
                                ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
                                        (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
-                                       (pReq->Bus << 8) || pReq->TargetID;
+                                       (sc->device->channel << 8) || sc->device->id;
 
                                ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
 
@@ -2503,9 +2530,9 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
                /* 2. Chain Buffer initialization
                 */
 
-               /* 4. Renegotiate to all devices, if SCSI
+               /* 4. Renegotiate to all devices, if SPI
                 */
-               if (ioc->bus_type == SCSI) {
+               if (ioc->bus_type == SPI) {
                        dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
                        mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
                }
@@ -2534,7 +2561,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 
                /* 7. Set flag to force DV and re-read IOC Page 3
                 */
-               if (ioc->bus_type == SCSI) {
+               if (ioc->bus_type == SPI) {
                        ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
                        ddvtprintk(("Set reload IOC Pg3 Flag\n"));
                }
@@ -2576,7 +2603,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
                break;
        case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
        case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
-               if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
+               if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
                        hd->soft_resets++;
                break;
        case MPI_EVENT_LOGOUT:                          /* 09 */
@@ -2597,11 +2624,11 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 
        case MPI_EVENT_INTEGRATED_RAID:                 /* 0B */
        {
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
                pMpiEventDataRaid_t pRaidEventData =
                    (pMpiEventDataRaid_t) pEvReply->Data;
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
                /* Domain Validation Needed */
-               if (ioc->bus_type == SCSI &&
+               if (ioc->bus_type == SPI &&
                    pRaidEventData->ReasonCode ==
                    MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
                        mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
@@ -2632,8 +2659,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 /*
  *     mptscsih_initTarget - Target, LUN alloc/free functionality.
  *     @hd: Pointer to MPT_SCSI_HOST structure
- *     @bus_id: Bus number (?)
- *     @target_id: SCSI target id
+ *     @vtarget: per target private data
  *     @lun: SCSI LUN id
  *     @data: Pointer to data
  *     @dlen: Number of INQUIRY bytes
@@ -2646,15 +2672,14 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
  *
  */
 static void
-mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
+mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
 {
-       int             indexed_lun, lun_index;
-       VirtDevice      *vdev;
        SpiCfgData      *pSpi;
        char            data_56;
+       int             inq_len;
 
        dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
-                       hd->ioc->name, bus_id, target_id, lun, hd));
+               hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
 
        /*
         * If the peripheral qualifier filter is enabled then if the target reports a 0x1
@@ -2674,75 +2699,68 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
        if (data[0] & 0xe0)
                return;
 
-       if ((vdev = hd->Targets[target_id]) == NULL) {
+       if (vtarget == NULL)
                return;
-       }
 
-       lun_index = (lun >> 5);  /* 32 luns per lun_index */
-       indexed_lun = (lun % 32);
-       vdev->luns[lun_index] |= (1 << indexed_lun);
-
-       if (hd->ioc->bus_type == SCSI) {
-               if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
-                       /* Treat all Processors as SAF-TE if
-                        * command line option is set */
-                       vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-                       mptscsih_writeIOCPage4(hd, target_id, bus_id);
-               }else if ((data[0] == TYPE_PROCESSOR) &&
-                       !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
-                       if ( dlen > 49 ) {
-                               vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-                               if ( data[44] == 'S' &&
-                                    data[45] == 'A' &&
-                                    data[46] == 'F' &&
-                                    data[47] == '-' &&
-                                    data[48] == 'T' &&
-                                    data[49] == 'E' ) {
-                                       vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-                                       mptscsih_writeIOCPage4(hd, target_id, bus_id);
-                               }
+       if (data)
+               vtarget->type = data[0];
+
+       if (hd->ioc->bus_type != SPI)
+               return;
+
+       if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
+               /* Treat all Processors as SAF-TE if
+                * command line option is set */
+               vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+               mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
+       }else if ((data[0] == TYPE_PROCESSOR) &&
+               !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
+               if ( dlen > 49 ) {
+                       vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+                       if ( data[44] == 'S' &&
+                            data[45] == 'A' &&
+                            data[46] == 'F' &&
+                            data[47] == '-' &&
+                            data[48] == 'T' &&
+                            data[49] == 'E' ) {
+                               vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+                               mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
                        }
                }
-               if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
-                       if ( dlen > 8 ) {
-                               memcpy (vdev->inq_data, data, 8);
-                       } else {
-                               memcpy (vdev->inq_data, data, dlen);
-                       }
+       }
+       if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
+               inq_len = dlen < 8 ? dlen : 8;
+               memcpy (vtarget->inq_data, data, inq_len);
+               /* If have not done DV, set the DV flag.
+                */
+               pSpi = &hd->ioc->spi_data;
+               if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
+                       if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
+                               pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
+               }
+               vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
 
-                       /* If have not done DV, set the DV flag.
+               data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
+               if (dlen > 56) {
+                       if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+                       /* Update the target capabilities
                         */
-                       pSpi = &hd->ioc->spi_data;
-                       if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
-                               if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
-                                       pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
-                       }
-
-                       vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-
-
-                       data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
-                       if (dlen > 56) {
-                               if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-                               /* Update the target capabilities
-                                */
-                                       data_56 = data[56];
-                                       vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-                               }
+                               data_56 = data[56];
+                               vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
                        }
-                       mptscsih_setTargetNegoParms(hd, vdev, data_56);
-               } else {
-                       /* Initial Inquiry may not request enough data bytes to
-                        * obtain byte 57.  DV will; if target doesn't return
-                        * at least 57 bytes, data[56] will be zero. */
-                       if (dlen > 56) {
-                               if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-                               /* Update the target capabilities
-                                */
-                                       data_56 = data[56];
-                                       vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-                                       mptscsih_setTargetNegoParms(hd, vdev, data_56);
-                               }
+               }
+               mptscsih_setTargetNegoParms(hd, vtarget, data_56);
+       } else {
+               /* Initial Inquiry may not request enough data bytes to
+                * obtain byte 57.  DV will; if target doesn't return
+                * at least 57 bytes, data[56] will be zero. */
+               if (dlen > 56) {
+                       if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+                       /* Update the target capabilities
+                        */
+                               data_56 = data[56];
+                               vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
+                               mptscsih_setTargetNegoParms(hd, vtarget, data_56);
                        }
                }
        }
@@ -2755,12 +2773,12 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
  *
  */
 static void
-mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
+mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
 {
        SpiCfgData *pspi_data = &hd->ioc->spi_data;
        int  id = (int) target->target_id;
        int  nvram;
-       VirtDevice      *vdev;
+       VirtTarget      *vtarget;
        int ii;
        u8 width = MPT_NARROW;
        u8 factor = MPT_ASYNC;
@@ -2905,9 +2923,9 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
 
                        ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
                        for (ii = 0; ii < id; ii++) {
-                               if ( (vdev = hd->Targets[ii]) ) {
-                                       vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-                                       mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
+                               if ( (vtarget = hd->Targets[ii]) ) {
+                                       vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+                                       mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
                                }
                        }
                }
@@ -2925,106 +2943,18 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
        }
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
- * Else set the NEED_DV flag after Read Capacity Issued (disks)
- * or Mode Sense (cdroms).
- *
- * Tapes, initTarget will set this flag on completion of Inquiry command.
- * Called only if DV_NOT_DONE flag is set
- */
-static void
-mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
-{
-       MPT_ADAPTER     *ioc = hd->ioc;
-       u8 cmd;
-       SpiCfgData      *pSpi;
-
-       ddvtprintk((MYIOC_s_NOTE_FMT
-               " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
-               hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
-
-       if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
-               return;
-
-       cmd = pReq->CDB[0];
-
-       if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
-               pSpi = &ioc->spi_data;
-               if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
-                       /* Set NEED_DV for all hidden disks
-                        */
-                       Ioc3PhysDisk_t *pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
-                       int             numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
-
-                       while (numPDisk) {
-                               pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
-                               ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
-                               pPDisk++;
-                               numPDisk--;
-                       }
-               }
-               pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
-               ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
-       }
-}
-
-/* mptscsih_raid_set_dv_flags()
- *
- * New or replaced disk. Set DV flag and schedule DV.
- */
-static void
-mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
-{
-       MPT_ADAPTER     *ioc = hd->ioc;
-       SpiCfgData      *pSpi = &ioc->spi_data;
-       Ioc3PhysDisk_t  *pPDisk;
-       int              numPDisk;
-
-       if (hd->negoNvram != 0)
-               return;
-
-       ddvtprintk(("DV requested for phys disk id %d\n", id));
-       if (ioc->raid_data.pIocPg3) {
-               pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
-               numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
-               while (numPDisk) {
-                       if (id == pPDisk->PhysDiskNum) {
-                               pSpi->dvStatus[pPDisk->PhysDiskID] =
-                                   (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
-                               pSpi->forceDv = MPT_SCSICFG_NEED_DV;
-                               ddvtprintk(("NEED_DV set for phys disk id %d\n",
-                                   pPDisk->PhysDiskID));
-                               break;
-                       }
-                       pPDisk++;
-                       numPDisk--;
-               }
-
-               if (numPDisk == 0) {
-                       /* The physical disk that needs DV was not found
-                        * in the stored IOC Page 3. The driver must reload
-                        * this page. DV routine will set the NEED_DV flag for
-                        * all phys disks that have DV_NOT_DONE set.
-                        */
-                       pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
-                       ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
-               }
-       }
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * If no Target, bus reset on 1st I/O. Set the flag to
  * prevent any future negotiations to this device.
  */
 static void
-mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
+mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
 {
+       VirtDevice      *vdev;
 
-       if ((hd->Targets) && (hd->Targets[target_id] == NULL))
-               hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
-
+       if ((vdev = sc->device->hostdata) != NULL)
+               hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
        return;
 }
 
@@ -3100,7 +3030,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
        MPT_ADAPTER             *ioc = hd->ioc;
        Config_t                *pReq;
        SCSIDevicePage1_t       *pData;
-       VirtDevice              *pTarget=NULL;
+       VirtTarget              *vtarget=NULL;
        MPT_FRAME_HDR           *mf;
        dma_addr_t               dataDma;
        u16                      req_idx;
@@ -3180,11 +3110,11 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
                /* If id is not a raid volume, get the updated
                 * transmission settings from the target structure.
                 */
-               if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-                       width = pTarget->maxWidth;
-                       factor = pTarget->minSyncFactor;
-                       offset = pTarget->maxOffset;
-                       negoFlags = pTarget->negoFlags;
+               if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
+                       width = vtarget->maxWidth;
+                       factor = vtarget->minSyncFactor;
+                       offset = vtarget->maxOffset;
+                       negoFlags = vtarget->negoFlags;
                }
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
@@ -3904,149 +3834,139 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *     mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
- *     @hd: Pointer to MPT_SCSI_HOST structure
- *     @portnum: IOC port number
+ *     mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
+ *     @hd: Pointer to a SCSI HOST structure
+ *     @vtarget: per device private data
  *
  *     Uses the ISR, but with special processing.
  *     MUST be single-threaded.
  *
- *     Return: 0 on completion
  */
-static int
-mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
+static void
+mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
 {
        MPT_ADAPTER             *ioc= hd->ioc;
-       VirtDevice              *pTarget;
-       SCSIDevicePage1_t       *pcfg1Data = NULL;
-       INTERNAL_CMD             iocmd;
+       SCSIDevicePage1_t       *pcfg1Data;
        CONFIGPARMS              cfg;
-       dma_addr_t               cfg1_dma_addr = -1;
-       ConfigPageHeader_t       header1;
-       int                      bus = 0;
-       int                      id = 0;
-       int                      lun;
-       int                      indexed_lun, lun_index;
-       int                      hostId = ioc->pfacts[portnum].PortSCSIID;
-       int                      max_id;
-       int                      requested, configuration, data;
-       int                      doConfig = 0;
+       dma_addr_t               cfg1_dma_addr;
+       ConfigPageHeader_t       header;
+       int                      id;
+       int                      requested, configuration, data,i;
        u8                       flags, factor;
 
-       max_id = ioc->sh->max_id - 1;
-
-       /* Following parameters will not change
-        * in this routine.
-        */
-       iocmd.cmd = SYNCHRONIZE_CACHE;
-       iocmd.flags = 0;
-       iocmd.physDiskNum = -1;
-       iocmd.data = NULL;
-       iocmd.data_dma = -1;
-       iocmd.size = 0;
-       iocmd.rsvd = iocmd.rsvd2 = 0;
-
-       /* No SCSI hosts
-        */
-       if (hd->Targets == NULL)
-               return 0;
-
-       /* Skip the host
-        */
-       if (id == hostId)
-               id++;
-
-       /* Write SDP1 for all SCSI devices
-        * Alloc memory and set up config buffer
-        */
-       if (ioc->bus_type == SCSI) {
-               if (ioc->spi_data.sdp1length > 0) {
-                       pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
-                                        ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
-
-                       if (pcfg1Data != NULL) {
-                               doConfig = 1;
-                               header1.PageVersion = ioc->spi_data.sdp1version;
-                               header1.PageLength = ioc->spi_data.sdp1length;
-                               header1.PageNumber = 1;
-                               header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-                               cfg.cfghdr.hdr = &header1;
-                               cfg.physAddr = cfg1_dma_addr;
-                               cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-                               cfg.dir = 1;
-                               cfg.timeout = 0;
-                       }
-               }
-       }
+       if (ioc->bus_type != SPI)
+               return;
 
-       /* loop through all devices on this port
-        */
-       while (bus < MPT_MAX_BUS) {
-               iocmd.bus = bus;
-               iocmd.id = id;
-               pTarget = hd->Targets[(int)id];
+       if (!ioc->spi_data.sdp1length)
+               return;
 
-               if (doConfig) {
+       pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
+                ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
 
-                       /* Set the negotiation flags */
-                       if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-                               flags = pTarget->negoFlags;
-                       } else {
-                               flags = hd->ioc->spi_data.noQas;
-                               if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-                                       data = hd->ioc->spi_data.nvram[id];
+       if (pcfg1Data == NULL)
+               return;
 
-                                       if (data & MPT_NVRAM_WIDE_DISABLE)
-                                               flags |= MPT_TARGET_NO_NEGO_WIDE;
+       header.PageVersion = ioc->spi_data.sdp1version;
+       header.PageLength = ioc->spi_data.sdp1length;
+       header.PageNumber = 1;
+       header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+       cfg.cfghdr.hdr = &header;
+       cfg.physAddr = cfg1_dma_addr;
+       cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+       cfg.dir = 1;
+       cfg.timeout = 0;
 
-                                       factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
-                                       if ((factor == 0) || (factor == MPT_ASYNC))
-                                               flags |= MPT_TARGET_NO_NEGO_SYNC;
-                               }
+       if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
+               for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+                       id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
+                       flags = hd->ioc->spi_data.noQas;
+                       if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+                               data = hd->ioc->spi_data.nvram[id];
+                               if (data & MPT_NVRAM_WIDE_DISABLE)
+                                       flags |= MPT_TARGET_NO_NEGO_WIDE;
+                               factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
+                               if ((factor == 0) || (factor == MPT_ASYNC))
+                                       flags |= MPT_TARGET_NO_NEGO_SYNC;
                        }
-
-                       /* Force to async, narrow */
                        mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
-                                       &configuration, flags);
+                               &configuration, flags);
                        dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
                                "offset=0 negoFlags=%x request=%x config=%x\n",
                                id, flags, requested, configuration));
                        pcfg1Data->RequestedParameters = cpu_to_le32(requested);
                        pcfg1Data->Reserved = 0;
                        pcfg1Data->Configuration = cpu_to_le32(configuration);
-                       cfg.pageAddr = (bus<<8) | id;
+                       cfg.pageAddr = (vtarget->bus_id<<8) | id;
                        mpt_config(hd->ioc, &cfg);
                }
+       } else {
+               flags = vtarget->negoFlags;
+               mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
+                               &configuration, flags);
+               dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+                       "offset=0 negoFlags=%x request=%x config=%x\n",
+                       vtarget->target_id, flags, requested, configuration));
+               pcfg1Data->RequestedParameters = cpu_to_le32(requested);
+               pcfg1Data->Reserved = 0;
+               pcfg1Data->Configuration = cpu_to_le32(configuration);
+               cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
+               mpt_config(hd->ioc, &cfg);
+       }
 
-               /* If target Ptr NULL or if this target is NOT a disk, skip.
-                */
-               if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
-                       for (lun=0; lun <= MPT_LAST_LUN; lun++) {
-                               /* If LUN present, issue the command
-                                */
-                               lun_index = (lun >> 5);  /* 32 luns per lun_index */
-                               indexed_lun = (lun % 32);
-                               if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
-                                       iocmd.lun = lun;
-                                       (void) mptscsih_do_cmd(hd, &iocmd);
-                               }
-                       }
-               }
+       if (pcfg1Data)
+               pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
+}
 
-               /* get next relevant device */
-               id++;
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *     mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
+ *     @hd: Pointer to a SCSI HOST structure
+ *     @vtarget: per device private data
+ *     @lun: lun
+ *
+ *     Uses the ISR, but with special processing.
+ *     MUST be single-threaded.
+ *
+ */
+static void
+mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
+{
+       INTERNAL_CMD             iocmd;
 
-               if (id == hostId)
-                       id++;
+       /* Following parameters will not change
+        * in this routine.
+        */
+       iocmd.cmd = SYNCHRONIZE_CACHE;
+       iocmd.flags = 0;
+       iocmd.physDiskNum = -1;
+       iocmd.data = NULL;
+       iocmd.data_dma = -1;
+       iocmd.size = 0;
+       iocmd.rsvd = iocmd.rsvd2 = 0;
+       iocmd.bus = vdevice->bus_id;
+       iocmd.id = vdevice->target_id;
+       iocmd.lun = (u8)vdevice->lun;
 
-               if (id > max_id) {
-                       id = 0;
-                       bus++;
-               }
-       }
+       if ((vdevice->vtarget->type & TYPE_DISK) &&
+           (vdevice->configured_lun))
+               mptscsih_do_cmd(hd, &iocmd);
+}
 
-       if (pcfg1Data) {
-               pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+static int
+mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
+{
+       int i;
+
+       if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
+               return 0;
+
+       for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+               if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+                       return 1;
        }
 
        return 0;
@@ -4101,8 +4021,8 @@ mptscsih_domainValidation(void *arg)
 
                        msleep(250);
 
-                       /* DV only to SCSI adapters */
-                       if (ioc->bus_type != SCSI)
+                       /* DV only to SPI adapters */
+                       if (ioc->bus_type != SPI)
                                continue;
 
                        /* Make sure everything looks ok */
@@ -4205,32 +4125,12 @@ mptscsih_domainValidation(void *arg)
        return;
 }
 
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-static int
-mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
-{
-       int i;
-
-       if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
-               return 0;
-
-       for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
-               if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
-                       return 1;
-       }
-
-       return 0;
-}
-
 /* Write SDP1 if no QAS has been enabled
  */
 static void
 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
 {
-       VirtDevice *pTarget;
+       VirtTarget *vtarget;
        int ii;
 
        if (hd->Targets == NULL)
@@ -4243,11 +4143,11 @@ mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
                if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
                        continue;
 
-               pTarget = hd->Targets[ii];
+               vtarget = hd->Targets[ii];
 
-               if ((pTarget != NULL) && (!pTarget->raidVolume)) {
-                       if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
-                               pTarget->negoFlags |= hd->ioc->spi_data.noQas;
+               if ((vtarget != NULL) && (!vtarget->raidVolume)) {
+                       if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
+                               vtarget->negoFlags |= hd->ioc->spi_data.noQas;
                                dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
                                mptscsih_writeSDP1(hd, 0, ii, 0);
                        }
@@ -4287,7 +4187,7 @@ static int
 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 {
        MPT_ADAPTER             *ioc = hd->ioc;
-       VirtDevice              *pTarget;
+       VirtTarget              *vtarget;
        SCSIDevicePage1_t       *pcfg1Data;
        SCSIDevicePage0_t       *pcfg0Data;
        u8                      *pbuf1;
@@ -4358,12 +4258,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
        iocmd.physDiskNum = -1;
        iocmd.rsvd = iocmd.rsvd2 = 0;
 
-       pTarget = hd->Targets[id];
+       vtarget = hd->Targets[id];
 
        /* Use tagged commands if possible.
         */
-       if (pTarget) {
-               if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+       if (vtarget) {
+               if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
                        iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
                else {
                        if (hd->ioc->facts.FWVersion.Word < 0x01000600)
@@ -4579,7 +4479,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
                /* Reset the size for disks
                 */
                inq0 = (*pbuf1) & 0x1F;
-               if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
+               if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
                        sz = 0x40;
                        iocmd.size = sz;
                }
@@ -4589,8 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
                 */
                if (inq0 == TYPE_PROCESSOR) {
                        mptscsih_initTarget(hd,
-                               bus,
-                               id,
+                               vtarget,
                                lun,
                                pbuf1,
                                sz);
@@ -4604,22 +4503,22 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
                        goto target_done;
 
                if (sz == 0x40) {
-                       if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
-                               && (pTarget->minSyncFactor > 0x09)) {
+                       if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
+                               && (vtarget->minSyncFactor > 0x09)) {
                                if ((pbuf1[56] & 0x04) == 0)
                                        ;
                                else if ((pbuf1[56] & 0x01) == 1) {
-                                       pTarget->minSyncFactor =
+                                       vtarget->minSyncFactor =
                                            nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
                                } else {
-                                       pTarget->minSyncFactor =
+                                       vtarget->minSyncFactor =
                                            nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
                                }
 
-                               dv.max.factor = pTarget->minSyncFactor;
+                               dv.max.factor = vtarget->minSyncFactor;
 
                                if ((pbuf1[56] & 0x02) == 0) {
-                                       pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+                                       vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
                                        hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
                                        ddvprintk((MYIOC_s_NOTE_FMT
                                            "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
@@ -4702,8 +4601,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
                                                    "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
                                                hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
                                                mptscsih_initTarget(hd,
-                                                       bus,
-                                                       id,
+                                                       vtarget,
                                                        lun,
                                                        pbuf1,
                                                        sz);
@@ -5204,7 +5102,7 @@ target_done:
 static void
 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 {
-       VirtDevice              *pTarget;
+       VirtTarget              *vtarget;
        SCSIDevicePage0_t       *pPage0;
        SCSIDevicePage1_t       *pPage1;
        int                     val = 0, data, configuration;
@@ -5224,11 +5122,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
                 * already throttled back.
                 */
                negoFlags = hd->ioc->spi_data.noQas;
-               if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
-                       width = pTarget->maxWidth;
-                       offset = pTarget->maxOffset;
-                       factor = pTarget->minSyncFactor;
-                       negoFlags |= pTarget->negoFlags;
+               if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
+                       width = vtarget->maxWidth;
+                       offset = vtarget->maxOffset;
+                       factor = vtarget->minSyncFactor;
+                       negoFlags |= vtarget->negoFlags;
                } else {
                        if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
                                data = hd->ioc->spi_data.nvram[id];
@@ -5430,11 +5328,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
                 * or overwrite nvram (phys disks only).
                 */
 
-               if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
-                       pTarget->maxWidth = dv->now.width;
-                       pTarget->maxOffset = dv->now.offset;
-                       pTarget->minSyncFactor = dv->now.factor;
-                       pTarget->negoFlags = dv->now.flags;
+               if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
+                       vtarget->maxWidth = dv->now.width;
+                       vtarget->maxOffset = dv->now.offset;
+                       vtarget->minSyncFactor = dv->now.factor;
+                       vtarget->negoFlags = dv->now.flags;
                } else {
                        /* Preserv all flags, use
                         * read-modify-write algorithm
@@ -5588,6 +5486,94 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width)
                break;
        }
 }
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
+ * Else set the NEED_DV flag after Read Capacity Issued (disks)
+ * or Mode Sense (cdroms).
+ *
+ * Tapes, initTarget will set this flag on completion of Inquiry command.
+ * Called only if DV_NOT_DONE flag is set
+ */
+static void
+mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
+{
+       MPT_ADAPTER     *ioc = hd->ioc;
+       u8 cmd;
+       SpiCfgData      *pSpi;
+
+       ddvtprintk((MYIOC_s_NOTE_FMT
+               " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
+               hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
+
+       if ((sc->device->lun != 0) || (hd->negoNvram != 0))
+               return;
+
+       cmd = sc->cmnd[0];
+
+       if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
+               pSpi = &ioc->spi_data;
+               if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
+                       /* Set NEED_DV for all hidden disks
+                        */
+                       Ioc3PhysDisk_t *pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
+                       int             numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+
+                       while (numPDisk) {
+                               pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
+                               ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
+                               pPDisk++;
+                               numPDisk--;
+                       }
+               }
+               pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
+               ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
+       }
+}
+
+/* mptscsih_raid_set_dv_flags()
+ *
+ * New or replaced disk. Set DV flag and schedule DV.
+ */
+static void
+mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
+{
+       MPT_ADAPTER     *ioc = hd->ioc;
+       SpiCfgData      *pSpi = &ioc->spi_data;
+       Ioc3PhysDisk_t  *pPDisk;
+       int              numPDisk;
+
+       if (hd->negoNvram != 0)
+               return;
+
+       ddvtprintk(("DV requested for phys disk id %d\n", id));
+       if (ioc->raid_data.pIocPg3) {
+               pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
+               numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+               while (numPDisk) {
+                       if (id == pPDisk->PhysDiskNum) {
+                               pSpi->dvStatus[pPDisk->PhysDiskID] =
+                                   (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
+                               pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+                               ddvtprintk(("NEED_DV set for phys disk id %d\n",
+                                   pPDisk->PhysDiskID));
+                               break;
+                       }
+                       pPDisk++;
+                       numPDisk--;
+               }
+
+               if (numPDisk == 0) {
+                       /* The physical disk that needs DV was not found
+                        * in the stored IOC Page 3. The driver must reload
+                        * this page. DV routine will set the NEED_DV flag for
+                        * all phys disks that have DV_NOT_DONE set.
+                        */
+                       pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
+                       ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
+               }
+       }
+}
 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
 
 EXPORT_SYMBOL(mptscsih_remove);
@@ -5599,7 +5585,9 @@ EXPORT_SYMBOL(mptscsih_resume);
 EXPORT_SYMBOL(mptscsih_proc_info);
 EXPORT_SYMBOL(mptscsih_info);
 EXPORT_SYMBOL(mptscsih_qcmd);
+EXPORT_SYMBOL(mptscsih_target_alloc);
 EXPORT_SYMBOL(mptscsih_slave_alloc);
+EXPORT_SYMBOL(mptscsih_target_destroy);
 EXPORT_SYMBOL(mptscsih_slave_destroy);
 EXPORT_SYMBOL(mptscsih_slave_configure);
 EXPORT_SYMBOL(mptscsih_abort);
index 971fda4..d3cba12 100644 (file)
@@ -91,7 +91,9 @@ extern int mptscsih_resume(struct pci_dev *pdev);
 extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
 extern const char * mptscsih_info(struct Scsi_Host *SChost);
 extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
+extern int mptscsih_target_alloc(struct scsi_target *starget);
 extern int mptscsih_slave_alloc(struct scsi_device *device);
+extern void mptscsih_target_destroy(struct scsi_target *starget);
 extern void mptscsih_slave_destroy(struct scsi_device *device);
 extern int mptscsih_slave_configure(struct scsi_device *device);
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
index 5c0e307..ce332a6 100644 (file)
@@ -103,13 +103,16 @@ static int        mptspiTaskCtx = -1;
 static int     mptspiInternalCtx = -1; /* Used only for internal commands */
 
 static struct scsi_host_template mptspi_driver_template = {
+       .module                         = THIS_MODULE,
        .proc_name                      = "mptspi",
        .proc_info                      = mptscsih_proc_info,
        .name                           = "MPT SPI Host",
        .info                           = mptscsih_info,
        .queuecommand                   = mptscsih_qcmd,
+       .target_alloc                   = mptscsih_target_alloc,
        .slave_alloc                    = mptscsih_slave_alloc,
        .slave_configure                = mptscsih_slave_configure,
+       .target_destroy                 = mptscsih_target_destroy,
        .slave_destroy                  = mptscsih_slave_destroy,
        .change_queue_depth             = mptscsih_change_queue_depth,
        .eh_abort_handler               = mptscsih_abort,
@@ -177,13 +180,15 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(MYIOC_s_WARN_FMT
                  "Skipping because it's not operational!\n",
                  ioc->name);
-               return -ENODEV;
+               error = -ENODEV;
+               goto out_mptspi_probe;
        }
 
        if (!ioc->active) {
                printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
                  ioc->name);
-               return -ENODEV;
+               error = -ENODEV;
+               goto out_mptspi_probe;
        }
 
        /*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -208,7 +213,8 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(MYIOC_s_WARN_FMT
                        "Unable to register controller with SCSI subsystem\n",
                        ioc->name);
-                return -1;
+               error = -1;
+               goto out_mptspi_probe;
         }
 
        spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -286,7 +292,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        mem = kmalloc(sz, GFP_ATOMIC);
        if (mem == NULL) {
                error = -ENOMEM;
-               goto mptspi_probe_failed;
+               goto out_mptspi_probe;
        }
 
        memset(mem, 0, sz);
@@ -304,14 +310,14 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        mem = kmalloc(sz, GFP_ATOMIC);
        if (mem == NULL) {
                error = -ENOMEM;
-               goto mptspi_probe_failed;
+               goto out_mptspi_probe;
        }
 
        memset(mem, 0, sz);
-       hd->Targets = (VirtDevice **) mem;
+       hd->Targets = (VirtTarget **) mem;
 
        dprintk((KERN_INFO
-         "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+         "  vdev @ %p, sz=%d\n", hd->Targets, sz));
 
        /* Clear the TM flags
         */
@@ -385,13 +391,13 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if(error) {
                dprintk((KERN_ERR MYNAM
                  "scsi_add_host failed\n"));
-               goto mptspi_probe_failed;
+               goto out_mptspi_probe;
        }
 
        scsi_scan_host(sh);
        return 0;
 
-mptspi_probe_failed:
+out_mptspi_probe:
 
        mptscsih_remove(pdev);
        return error;
index c22c051..fa176ff 100644 (file)
@@ -1539,7 +1539,6 @@ static void irda_usb_disconnect(struct usb_interface *intf)
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-       .owner          = THIS_MODULE,
        .name           = "irda-usb",
        .probe          = irda_usb_probe,
        .disconnect     = irda_usb_disconnect,
index 3961a75..31867e4 100644 (file)
@@ -1152,7 +1152,6 @@ static int stir_resume(struct usb_interface *intf)
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-       .owner          = THIS_MODULE,
        .name           = "stir4200",
        .probe          = stir_probe,
        .disconnect     = stir_disconnect,
index f857ae9..b0c3b6a 100644 (file)
 #include <linux/ethtool.h>
 #include <linux/timer.h>
 #include <linux/if_vlan.h>
+#include <linux/rtnetlink.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index a842ecc..9369f81 100644 (file)
@@ -85,7 +85,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb);
 static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
 
-static struct proto_ops pppoe_ops;
+static const struct proto_ops pppoe_ops;
 static DEFINE_RWLOCK(pppoe_hash_lock);
 
 static struct ppp_channel_ops pppoe_chan_ops;
@@ -383,8 +383,6 @@ static int pppoe_rcv(struct sk_buff *skb,
 {
        struct pppoe_hdr *ph;
        struct pppox_sock *po;
-       struct sock *sk;
-       int ret;
 
        if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
                goto drop;
@@ -395,24 +393,8 @@ static int pppoe_rcv(struct sk_buff *skb,
        ph = (struct pppoe_hdr *) skb->nh.raw;
 
        po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source);
-       if (!po) 
-               goto drop;
-
-       sk = sk_pppox(po);
-       bh_lock_sock(sk);
-
-       /* Socket state is unknown, must put skb into backlog. */
-       if (sock_owned_by_user(sk) != 0) {
-               sk_add_backlog(sk, skb);
-               ret = NET_RX_SUCCESS;
-       } else {
-               ret = pppoe_rcv_core(sk, skb);
-       }
-
-       bh_unlock_sock(sk);
-       sock_put(sk);
-
-       return ret;
+       if (po != NULL) 
+               return sk_receive_skb(sk_pppox(po), skb);
 drop:
        kfree_skb(skb);
 out:
@@ -1081,9 +1063,7 @@ static int __init pppoe_proc_init(void)
 static inline int pppoe_proc_init(void) { return 0; }
 #endif /* CONFIG_PROC_FS */
 
-/* ->ioctl are set at pppox_create */
-
-static struct proto_ops pppoe_ops = {
+static const struct proto_ops pppoe_ops = {
     .family            = AF_PPPOX,
     .owner             = THIS_MODULE,
     .release           = pppoe_release,
@@ -1099,7 +1079,8 @@ static struct proto_ops pppoe_ops = {
     .getsockopt                = sock_no_getsockopt,
     .sendmsg           = pppoe_sendmsg,
     .recvmsg           = pppoe_recvmsg,
-    .mmap              = sock_no_mmap
+    .mmap              = sock_no_mmap,
+    .ioctl             = pppox_ioctl,
 };
 
 static struct pppox_proto pppoe_proto = {
index 0c1e114..9315046 100644 (file)
@@ -68,8 +68,7 @@ EXPORT_SYMBOL(register_pppox_proto);
 EXPORT_SYMBOL(unregister_pppox_proto);
 EXPORT_SYMBOL(pppox_unbind_sock);
 
-static int pppox_ioctl(struct socket* sock, unsigned int cmd, 
-                      unsigned long arg)
+int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
        struct pppox_sock *po = pppox_sk(sk);
@@ -105,6 +104,7 @@ static int pppox_ioctl(struct socket* sock, unsigned int cmd,
        return rc;
 }
 
+EXPORT_SYMBOL(pppox_ioctl);
 
 static int pppox_create(struct socket *sock, int protocol)
 {
@@ -119,11 +119,7 @@ static int pppox_create(struct socket *sock, int protocol)
                goto out;
 
        rc = pppox_protos[protocol]->create(sock);
-       if (!rc) {
-               /* We get to set the ioctl handler. */
-               /* For everything else, pppox is just a shell. */
-               sock->ops->ioctl = pppox_ioctl;
-       }
+
        module_put(pppox_protos[protocol]->owner);
 out:
        return rc;
index e5591d3..9a76ac1 100644 (file)
 
 #include       "h/skversion.h"
 
+#include       <linux/in.h>
 #include       <linux/module.h>
 #include       <linux/moduleparam.h>
 #include       <linux/init.h>
index b8dfe33..b538e30 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index 2fc9893..eb86b05 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/compiler.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/in.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
@@ -3650,7 +3651,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                               TXD_FLAG_CPU_POST_DMA);
 
                skb->nh.iph->check = 0;
-               skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len);
+               skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
                if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
                        skb->h.th->check = 0;
                        base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
index cd034b7..cdfe502 100644 (file)
@@ -7455,8 +7455,7 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
        /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
        hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
        if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
-           ((is_multicast_ether_addr(hdr->addr1) ||
-             is_broadcast_ether_addr(hdr->addr1)) ?
+           (is_multicast_ether_addr(hdr->addr1) ?
             !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
                ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
@@ -7647,8 +7646,7 @@ static inline int is_network_packet(struct ipw_priv *priv,
                        return 0;
 
                /* {broad,multi}cast packets to our BSSID go through */
-               if (is_multicast_ether_addr(header->addr1) ||
-                   is_broadcast_ether_addr(header->addr1))
+               if (is_multicast_ether_addr(header->addr1))
                        return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
 
                /* packets to our adapter go through */
@@ -7661,8 +7659,7 @@ static inline int is_network_packet(struct ipw_priv *priv,
                        return 0;
 
                /* {broad,multi}cast packets to our BSS go through */
-               if (is_multicast_ether_addr(header->addr1) ||
-                   is_broadcast_ether_addr(header->addr1))
+               if (is_multicast_ether_addr(header->addr1))
                        return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
 
                /* packets to our adapter go through */
@@ -9656,8 +9653,7 @@ static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
        switch (priv->ieee->iw_mode) {
        case IW_MODE_ADHOC:
                hdr_len = IEEE80211_3ADDR_LEN;
-               unicast = !(is_multicast_ether_addr(hdr->addr1) ||
-                           is_broadcast_ether_addr(hdr->addr1));
+               unicast = !is_multicast_ether_addr(hdr->addr1);
                id = ipw_find_station(priv, hdr->addr1);
                if (id == IPW_INVALID_STATION) {
                        id = ipw_add_station(priv, hdr->addr1);
@@ -9672,8 +9668,7 @@ static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
 
        case IW_MODE_INFRA:
        default:
-               unicast = !(is_multicast_ether_addr(hdr->addr3) ||
-                           is_broadcast_ether_addr(hdr->addr3));
+               unicast = !is_multicast_ether_addr(hdr->addr3);
                hdr_len = IEEE80211_3ADDR_LEN;
                id = 0;
                break;
index e7ad269..4ce7438 100644 (file)
@@ -857,7 +857,7 @@ process_extended_message(struct Scsi_Host *host,
                printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
                       host->host_no, pun, lun,
                       NCR_700_phase[(dsps & 0xf00) >> 8]);
-               scsi_print_msg(hostdata->msgin);
+               spi_print_msg(hostdata->msgin);
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
@@ -887,7 +887,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
 #ifdef NCR_700_DEBUG
        printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
               NCR_700_phase[(dsps & 0xf00) >> 8]);
-       scsi_print_msg(hostdata->msgin);
+       spi_print_msg(hostdata->msgin);
        printk("\n");
 #endif
 
@@ -939,7 +939,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
                       host->host_no, pun, lun,
                       NCR_700_phase[(dsps & 0xf00) >> 8]);
 
-               scsi_print_msg(hostdata->msgin);
+               spi_print_msg(hostdata->msgin);
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
index 362d784..a8c83bb 100644 (file)
@@ -238,21 +238,23 @@ struct NCR_700_Host_Parameters {
 #ifdef CONFIG_53C700_LE_ON_BE
 #define bE     (hostdata->force_le_on_be ? 0 : 3)
 #define        bSWAP   (hostdata->force_le_on_be)
-/* This is terrible, but there's no raw version of ioread32.  That means
- * that on a be board we swap twice (once in ioread32 and once again to 
- * get the value correct) */
-#define bS_to_io(x)    ((hostdata->force_le_on_be) ? (x) : cpu_to_le32(x))
+#define bEBus  (!hostdata->force_le_on_be)
 #elif defined(__BIG_ENDIAN)
 #define bE     3
 #define bSWAP  0
-#define bS_to_io(x)    (x)
 #elif defined(__LITTLE_ENDIAN)
 #define bE     0
 #define bSWAP  0
-#define bS_to_io(x)    (x)
 #else
 #error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined, did you include byteorder.h?"
 #endif
+#ifndef bEBus
+#ifdef CONFIG_53C700_BE_BUS
+#define bEBus  1
+#else
+#define bEBus  0
+#endif
+#endif
 #define bS_to_cpu(x)   (bSWAP ? le32_to_cpu(x) : (x))
 #define bS_to_host(x)  (bSWAP ? cpu_to_le32(x) : (x))
 
@@ -466,14 +468,15 @@ NCR_700_readl(struct Scsi_Host *host, __u32 reg)
 {
        const struct NCR_700_Host_Parameters *hostdata
                = (struct NCR_700_Host_Parameters *)host->hostdata[0];
-       __u32 value = ioread32(hostdata->base + reg);
+       __u32 value = bEBus ? ioread32be(hostdata->base + reg) :
+               ioread32(hostdata->base + reg);
 #if 1
        /* sanity check the register */
        if((reg & 0x3) != 0)
                BUG();
 #endif
 
-       return bS_to_io(value);
+       return value;
 }
 
 static inline void
@@ -497,7 +500,8 @@ NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
                BUG();
 #endif
 
-       iowrite32(bS_to_io(value), hostdata->base + reg);
+       bEBus ? iowrite32be(value, hostdata->base + reg): 
+               iowrite32(value, hostdata->base + reg);
 }
 
 #endif
index 9cb5dd4..7894b8e 100644 (file)
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "53c7xx.h"
 #include <linux/stat.h>
 #include <linux/stddef.h>
@@ -1724,7 +1725,7 @@ NCR53c7xx_run_tests (struct Scsi_Host *host) {
                printk ("scsi%d : status ", host->host_no);
                scsi_print_status (status);
                printk ("\nscsi%d : message ", host->host_no);
-               scsi_print_msg (&msg);
+               spi_print_msg(&msg);
                printk ("\n");
            } else if (hostdata->test_completed == 3) {
                printk("scsi%d : test 2 no connection with target %d\n",
@@ -2313,7 +2314,7 @@ NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host, struct
            printk ("scsi%d : received message", host->host_no);
            if (c) 
                printk (" from target %d lun %d ", c->device->id, c->device->lun);
-           scsi_print_msg ((unsigned char *) hostdata->msg_buf);
+           spi_print_msg((unsigned char *) hostdata->msg_buf);
            printk("\n");
        }
        
@@ -5540,7 +5541,7 @@ print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) {
            i > 0 && !check_address ((unsigned long) ptr, 1);
            ptr += len, i -= len) {
            printk("               ");
-           len = scsi_print_msg (ptr);
+           len = spi_print_msg(ptr);
            printk("\n");
            if (!len)
                break;
index 20dd85a..4c42065 100644 (file)
@@ -336,6 +336,7 @@ config SCSI_ACARD
 config SCSI_AHA152X
        tristate "Adaptec AHA152X/2825 support"
        depends on ISA && SCSI && !64BIT
+       select SCSI_SPI_ATTRS
        ---help---
          This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
          SCSI host adapters. It also works for the AVA-1505, but the IRQ etc.
@@ -623,6 +624,7 @@ config SCSI_OMIT_FLASHPOINT
 config SCSI_DMX3191D
        tristate "DMX3191D SCSI support"
        depends on PCI && SCSI
+       select SCSI_SPI_ATTRS
        help
          This is support for Domex DMX3191D SCSI Host Adapters.
 
@@ -632,6 +634,7 @@ config SCSI_DMX3191D
 config SCSI_DTC3280
        tristate "DTC3180/3280 SCSI support"
        depends on ISA && SCSI
+       select SCSI_SPI_ATTRS
        help
          This is support for DTC 3180/3280 SCSI Host Adapters.  Please read
          the SCSI-HOWTO, available from
@@ -752,6 +755,7 @@ config SCSI_GDTH
 config SCSI_GENERIC_NCR5380
        tristate "Generic NCR5380/53c400 SCSI PIO support"
        depends on ISA && SCSI
+       select SCSI_SPI_ATTRS
        ---help---
          This is a driver for the old NCR 53c80 series of SCSI controllers
          on boards using PIO. Most boards such as the Trantor T130 fit this
@@ -771,6 +775,7 @@ config SCSI_GENERIC_NCR5380
 config SCSI_GENERIC_NCR5380_MMIO
        tristate "Generic NCR5380/53c400 SCSI MMIO support"
        depends on ISA && SCSI
+       select SCSI_SPI_ATTRS
        ---help---
          This is a driver for the old NCR 53c80 series of SCSI controllers
          on boards using memory mapped I/O. 
@@ -1254,6 +1259,7 @@ config SCSI_MCA_53C9X
 config SCSI_PAS16
        tristate "PAS16 SCSI support"
        depends on ISA && SCSI
+       select SCSI_SPI_ATTRS
        ---help---
          This is support for a SCSI host adapter.  It is explained in section
          3.10 of the SCSI-HOWTO, available from
@@ -1423,6 +1429,7 @@ config SCSI_DC390T
 config SCSI_T128
        tristate "Trantor T128/T128F/T228 SCSI support"
        depends on ISA && SCSI
+       select SCSI_SPI_ATTRS
        ---help---
          This is support for a SCSI host adapter. It is explained in section
          3.11 of the SCSI-HOWTO, available from
@@ -1681,6 +1688,7 @@ config OKTAGON_SCSI
 config ATARI_SCSI
        tristate "Atari native SCSI support"
        depends on ATARI && SCSI && BROKEN
+       select SCSI_SPI_ATTRS
        ---help---
          If you have an Atari with built-in NCR5380 SCSI controller (TT,
          Falcon, ...) say Y to get it supported. Of course also, if you have
@@ -1722,6 +1730,7 @@ config TT_DMA_EMUL
 config MAC_SCSI
        bool "Macintosh NCR5380 SCSI"
        depends on MAC && SCSI=y
+       select SCSI_SPI_ATTRS
        help
          This is the NCR 5380 SCSI controller included on most of the 68030
          based Macintoshes.  If you have one of these say Y and read the
@@ -1743,6 +1752,7 @@ config SCSI_MAC_ESP
 config MVME147_SCSI
        bool "WD33C93 SCSI driver for MVME147"
        depends on MVME147 && SCSI=y
+       select SCSI_SPI_ATTRS
        help
          Support for the on-board SCSI controller on the Motorola MVME147
          single-board computer.
@@ -1750,6 +1760,7 @@ config MVME147_SCSI
 config MVME16x_SCSI
        bool "NCR53C710 SCSI driver for MVME16x"
        depends on MVME16x && SCSI && BROKEN
+       select SCSI_SPI_ATTRS
        help
          The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
          SCSI controller chip.  Almost everyone using one of these boards
@@ -1758,6 +1769,7 @@ config MVME16x_SCSI
 config BVME6000_SCSI
        bool "NCR53C710 SCSI driver for BVME6000"
        depends on BVME6000 && SCSI && BROKEN
+       select SCSI_SPI_ATTRS
        help
          The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
          SCSI controller chip.  Almost everyone using one of these boards
@@ -1774,6 +1786,7 @@ config SCSI_NCR53C7xx_FAST
 config SUN3_SCSI
        tristate "Sun3 NCR5380 SCSI"
        depends on SUN3 && SCSI && BROKEN
+       select SCSI_SPI_ATTRS
        help
          This option will enable support for the OBIO (onboard io) NCR5380
          SCSI controller found in the Sun 3/50 and 3/60, as well as for
index cba9655..9f0ddbe 100644 (file)
@@ -87,6 +87,7 @@
  *      the high level code.
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 #ifndef NDEBUG
 #define NDEBUG 0
@@ -2377,7 +2378,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
  * 3..length+1  arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
                                        extended_msg[0] = EXTENDED_MESSAGE;
                                        /* Accept first byte by clearing ACK */
@@ -2424,7 +2425,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                default:
                                        if (!tmp) {
                                                printk("scsi%d: rejecting message ", instance->host_no);
-                                               scsi_print_msg(extended_msg);
+                                               spi_print_msg(extended_msg);
                                                printk("\n");
                                        } else if (tmp != EXTENDED_MESSAGE)
                                                scmd_printk(KERN_INFO, cmd,
@@ -2560,7 +2561,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
 
        if (!(msg[0] & 0x80)) {
                printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
-               scsi_print_msg(msg);
+               spi_print_msg(msg);
                abort = 1;
        } else {
                /* Accept message by clearing ACK */
index 9df23b6..cb2ee25 100644 (file)
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "aha152x.h"
 
 
@@ -1845,7 +1846,7 @@ static void msgi_run(struct Scsi_Host *shpnt)
 #if defined(AHA152X_DEBUG)
                if (HOSTDATA(shpnt)->debug & debug_msgi) {
                        printk(INFO_LEAD "inbound message %02x ", CMDINFO(CURRENT_SC), MSGI(0));
-                       scsi_print_msg(&MSGI(0));
+                       spi_print_msg(&MSGI(0));
                        printk("\n");
                }
 #endif
@@ -1933,7 +1934,7 @@ static void msgi_run(struct Scsi_Host *shpnt)
                                                break;
 
                                        printk(INFO_LEAD, CMDINFO(CURRENT_SC));
-                                       scsi_print_msg(&MSGI(0));
+                                       spi_print_msg(&MSGI(0));
                                        printk("\n");
 
                                        ticks = (MSGI(3) * 4 + 49) / 50;
@@ -2031,7 +2032,7 @@ static void msgo_init(struct Scsi_Host *shpnt)
                int i;
 
                printk(DEBUG_LEAD "messages( ", CMDINFO(CURRENT_SC));
-               for (i=0; i<MSGOLEN; i+=scsi_print_msg(&MSGO(i)), printk(" "))
+               for (i=0; i<MSGOLEN; i+=spi_print_msg(&MSGO(i)), printk(" "))
                        ;
                printk(")\n");
        }
index 6aab9da..1c8f872 100644 (file)
@@ -1064,6 +1064,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
        struct  Scsi_Host *host;
        char    *new_name;
        u_long  s;
+       int     retval;
 
        template->name = ahd->description;
        host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
@@ -1096,9 +1097,15 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
 
        host->transportt = ahd_linux_transport_template;
 
-       scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */
+       retval = scsi_add_host(host, &ahd->dev_softc->dev);
+       if (retval) {
+               printk(KERN_WARNING "aic79xx: scsi_add_host failed\n");
+               scsi_host_put(host);
+               return retval;
+       }
+
        scsi_scan_host(host);
-       return (0);
+       return 0;
 }
 
 uint64_t
index d866213..fd389e9 100644 (file)
@@ -1061,10 +1061,11 @@ uint32_t aic7xxx_verbose;
 int
 ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template)
 {
-       char     buf[80];
-       struct   Scsi_Host *host;
+       char    buf[80];
+       struct  Scsi_Host *host;
        char    *new_name;
-       u_long   s;
+       u_long  s;
+       int     retval;
 
        template->name = ahc->description;
        host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
@@ -1097,9 +1098,16 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
 
        host->transportt = ahc_linux_transport_template;
 
-       scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
+       retval = scsi_add_host(host,
+                       (ahc->dev_softc ? &ahc->dev_softc->dev : NULL));
+       if (retval) {
+               printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n");
+               scsi_host_put(host);
+               return retval;
+       }
+
        scsi_scan_host(host);
-       return (0);
+       return 0;
 }
 
 /*
index 13f2304..06d7601 100644 (file)
@@ -4,6 +4,7 @@
 config SCSI_ACORNSCSI_3
        tristate "Acorn SCSI card (aka30) support"
        depends on ARCH_ACORN && SCSI && BROKEN
+       select SCSI_SPI_ATTRS
        help
          This enables support for the Acorn SCSI card (aka30). If you have an
          Acorn system with one of these, say Y. If unsure, say N.
index b7b20c6..09ed057 100644 (file)
 #include "../scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "acornscsi.h"
 #include "msgqueue.h"
 #include "scsi.h"
@@ -1370,7 +1371,7 @@ void acornscsi_sendmessage(AS_Host *host)
 
        host->scsi.last_message = msg->msg[0];
 #if (DEBUG & DEBUG_MESSAGES)
-       scsi_print_msg(msg->msg);
+       spi_print_msg(msg->msg);
 #endif
        break;
 
@@ -1392,7 +1393,7 @@ void acornscsi_sendmessage(AS_Host *host)
        while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
            unsigned int i;
 #if (DEBUG & DEBUG_MESSAGES)
-           scsi_print_msg(msg);
+           spi_print_msg(msg);
 #endif
            i = 0;
            if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
@@ -1488,7 +1489,7 @@ void acornscsi_message(AS_Host *host)
 #if (DEBUG & DEBUG_MESSAGES)
     printk("scsi%d.%c: message in: ",
            host->host->host_no, acornscsi_target(host));
-    scsi_print_msg(message);
+    spi_print_msg(message);
     printk("\n");
 #endif
 
index 2ae31ce..57295bc 100644 (file)
@@ -74,6 +74,7 @@
  *     the high level code.
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) \
@@ -2355,7 +2356,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
  * 3..length+1 arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
                    extended_msg[0] = EXTENDED_MESSAGE;
                    /* Accept first byte by clearing ACK */
@@ -2408,7 +2409,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
                default:
                    if (!tmp) {
                        printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-                       scsi_print_msg (extended_msg);
+                       spi_print_msg(extended_msg);
                        printk("\n");
                    } else if (tmp != EXTENDED_MESSAGE)
                        printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2541,7 +2542,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
 
     if (!(msg[0] & 0x80)) {
        printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-       scsi_print_msg(msg);
+       spi_print_msg(msg);
        do_abort(instance);
        return;
     }
index ccbbae2..0920220 100644 (file)
@@ -75,7 +75,7 @@ static int vendor_counts[CH_TYPES-4];
 module_param_array(vendor_firsts, int, NULL, 0444);
 module_param_array(vendor_counts, int, NULL, 0444);
 
-static char *vendor_labels[CH_TYPES-4] = {
+static const char * vendor_labels[CH_TYPES-4] = {
        "v0", "v1", "v2", "v3"
 };
 // module_param_string_array(vendor_labels, NULL, 0444);
@@ -140,7 +140,7 @@ static struct file_operations changer_fops =
 #endif
 };
 
-static struct {
+static const struct {
        unsigned char  sense;
        unsigned char  asc;
        unsigned char  ascq;
index 09bc815..30a3353 100644 (file)
@@ -1065,7 +1065,7 @@ struct error_info2 {
        const char * fmt;
 };
 
-static struct error_info2 additional2[] =
+static const struct error_info2 additional2[] =
 {
        {0x40,0x00,0x7f,"Ram failure (%x)"},
        {0x40,0x80,0xff,"Diagnostic failure on component (%x)"},
@@ -1077,7 +1077,7 @@ static struct error_info2 additional2[] =
 };
 
 /* description of the sense key values */
-static const char *snstext[] = {
+static const char * const snstext[] = {
        "No Sense",         /* 0: There is no sense information */
        "Recovered Error",  /* 1: The last command completed successfully
                                  but used error correction */
@@ -1278,114 +1278,6 @@ void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
 }
 EXPORT_SYMBOL(scsi_print_req_sense);
 
-#ifdef CONFIG_SCSI_CONSTANTS
-static const char *one_byte_msgs[] = {
-/* 0x00 */ "Command Complete", NULL, "Save Pointers",
-/* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
-/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
-/* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
-/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
-/* 0x0f */ "Initiate Recovery", "Release Recovery"
-};
-#define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs)  / sizeof (const char *))
-
-static const char *two_byte_msgs[] = {
-/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag"
-/* 0x23 */ "Ignore Wide Residue"
-};
-#define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
-
-static const char *extended_msgs[] = {
-/* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
-/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request"
-};
-#define NO_EXTENDED_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
-
-
-int scsi_print_msg (const unsigned char *msg)
-{
-       int len = 0, i;
-       if (msg[0] == EXTENDED_MESSAGE) {
-               len = 3 + msg[1];
-               if (msg[2] < NO_EXTENDED_MSGS)
-                       printk ("%s ", extended_msgs[msg[2]]); 
-               else 
-                       printk ("Extended Message, reserved code (0x%02x) ",
-                               (int) msg[2]);
-               switch (msg[2]) {
-               case EXTENDED_MODIFY_DATA_POINTER:
-                       printk("pointer = %d", (int) (msg[3] << 24) |
-                               (msg[4] << 16) | (msg[5] << 8) | msg[6]);
-                       break;
-               case EXTENDED_SDTR:
-                       printk("period = %d ns, offset = %d",
-                               (int) msg[3] * 4, (int) msg[4]);
-                       break;
-               case EXTENDED_WDTR:
-                       printk("width = 2^%d bytes", msg[3]);
-                       break;
-               default:
-               for (i = 2; i < len; ++i) 
-                       printk("%02x ", msg[i]);
-               }
-       /* Identify */
-       } else if (msg[0] & 0x80) {
-               printk("Identify disconnect %sallowed %s %d ",
-                       (msg[0] & 0x40) ? "" : "not ",
-                       (msg[0] & 0x20) ? "target routine" : "lun",
-                       msg[0] & 0x7);
-               len = 1;
-       /* Normal One byte */
-       } else if (msg[0] < 0x1f) {
-               if (msg[0] < NO_ONE_BYTE_MSGS)
-                       printk(one_byte_msgs[msg[0]]);
-               else
-                       printk("reserved (%02x) ", msg[0]);
-               len = 1;
-       /* Two byte */
-       } else if (msg[0] <= 0x2f) {
-               if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
-                       printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
-                               msg[1]);
-               else 
-                       printk("reserved two byte (%02x %02x) ", 
-                               msg[0], msg[1]);
-               len = 2;
-       } else 
-               printk("reserved");
-       return len;
-}
-EXPORT_SYMBOL(scsi_print_msg);
-
-#else  /* ifndef CONFIG_SCSI_CONSTANTS */
-
-int scsi_print_msg (const unsigned char *msg)
-{
-       int len = 0, i;
-
-       if (msg[0] == EXTENDED_MESSAGE) {
-               len = 3 + msg[1];
-               for (i = 0; i < len; ++i)
-                       printk("%02x ", msg[i]);
-       /* Identify */
-       } else if (msg[0] & 0x80) {
-               printk("%02x ", msg[0]);
-               len = 1;
-       /* Normal One byte */
-       } else if (msg[0] < 0x1f) {
-               printk("%02x ", msg[0]);
-               len = 1;
-       /* Two byte */
-       } else if (msg[0] <= 0x2f) {
-               printk("%02x %02x", msg[0], msg[1]);
-               len = 2;
-       } else 
-               printk("%02x ", msg[0]);
-       return len;
-}
-EXPORT_SYMBOL(scsi_print_msg);
-#endif /* ! CONFIG_SCSI_CONSTANTS */
-
 void scsi_print_command(struct scsi_cmnd *cmd)
 {
        /* Assume appended output (i.e. not at start of line) */
@@ -1397,7 +1289,7 @@ EXPORT_SYMBOL(scsi_print_command);
 
 #ifdef CONFIG_SCSI_CONSTANTS
 
-static const char * hostbyte_table[]={
+static const char * const hostbyte_table[]={
 "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",
 "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
@@ -1422,12 +1314,12 @@ void scsi_print_hostbyte(int scsiresult)
 
 #ifdef CONFIG_SCSI_CONSTANTS
 
-static const char * driverbyte_table[]={
+static const char * const driverbyte_table[]={
 "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT",  "DRIVER_MEDIA", "DRIVER_ERROR", 
 "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
 #define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *))
 
-static const char * driversuggest_table[]={"SUGGEST_OK",
+static const char * const driversuggest_table[]={"SUGGEST_OK",
 "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
 "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
 #define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
index fa2cb35..b6714da 100644 (file)
@@ -5887,7 +5887,12 @@ static int __devinit ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg)
        ENTER;
        spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
        dev_dbg(&ioa_cfg->pdev->dev, "ioa_cfg adx: 0x%p\n", ioa_cfg);
-       _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE);
+       if (ioa_cfg->needs_hard_reset) {
+               ioa_cfg->needs_hard_reset = 0;
+               ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+       } else
+               _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa,
+                                       IPR_SHUTDOWN_NONE);
 
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
        wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
@@ -6264,6 +6269,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
        unsigned long ipr_regs_pci;
        void __iomem *ipr_regs;
        u32 rc = PCIBIOS_SUCCESSFUL;
+       volatile u32 mask, uproc;
 
        ENTER;
 
@@ -6356,6 +6362,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
                goto cleanup_nomem;
        }
 
+       /*
+        * If HRRQ updated interrupt is not masked, or reset alert is set,
+        * the card is in an unknown state and needs a hard reset
+        */
+       mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+       uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+       if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
+               ioa_cfg->needs_hard_reset = 1;
+
        ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
        rc = request_irq(pdev->irq, ipr_isr, SA_SHIRQ, IPR_NAME, ioa_cfg);
 
index 6bec673..b639332 100644 (file)
@@ -36,8 +36,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.1.0"
-#define IPR_DRIVER_DATE "(October 31, 2005)"
+#define IPR_DRIVER_VERSION "2.1.1"
+#define IPR_DRIVER_DATE "(November 15, 2005)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -922,6 +922,7 @@ struct ipr_ioa_cfg {
        u8 dump_taken:1;
        u8 allow_cmds:1;
        u8 allow_ml_add_del:1;
+       u8 needs_hard_reset:1;
 
        enum ipr_cache_state cache_state;
        u16 type; /* CCIN of the card */
index 3d8009f..10bcf42 100644 (file)
@@ -49,7 +49,7 @@ MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, "
              "Alex Aizman <itn780@yahoo.com>");
 MODULE_DESCRIPTION("iSCSI/TCP data-path");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0:4.409");
+MODULE_VERSION("0:4.445");
 /* #define DEBUG_TCP */
 /* #define DEBUG_SCSI */
 #define DEBUG_ASSERT
@@ -581,10 +581,16 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
                rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
                                     conn->in.ahslen);
+               if (cdgst != rdgst) {
+                       printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
+                              "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
+                              cdgst);
+                       return ISCSI_ERR_HDR_DGST;
+               }
        }
 
        /* save opcode for later */
-       conn->in.opcode = hdr->opcode;
+       conn->in.opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 
        /* verify itt (itt encoding: age+cid+itt) */
        if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
@@ -610,13 +616,6 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                  conn->in.ahslen, conn->in.datalen);
 
        if (conn->in.itt < session->cmds_max) {
-               if (conn->hdrdgst_en && cdgst != rdgst) {
-                       printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
-                              "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
-                              cdgst);
-                       return ISCSI_ERR_HDR_DGST;
-               }
-
                ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt];
 
                if (!ctask->sc) {
@@ -642,9 +641,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                switch(conn->in.opcode) {
                case ISCSI_OP_SCSI_CMD_RSP:
                        BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-                       if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE)
-                               rc = iscsi_cmd_rsp(conn, ctask);
-                       else if (!conn->in.datalen)
+                       if (!conn->in.datalen)
                                rc = iscsi_cmd_rsp(conn, ctask);
                        else
                                /*
@@ -666,8 +663,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                        break;
                case ISCSI_OP_R2T:
                        BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-                       if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE &&
-                           ctask->sc->sc_data_direction == DMA_TO_DEVICE)
+                       if (ctask->sc->sc_data_direction == DMA_TO_DEVICE)
                                rc = iscsi_r2t_rsp(conn, ctask);
                        else
                                rc = ISCSI_ERR_PROTO;
@@ -906,11 +902,20 @@ partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg,
        crypto_digest_update(conn->data_rx_tfm, &temp, 1);
 }
 
+static void
+iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len)
+{
+       struct scatterlist tmp;
+
+       sg_init_one(&tmp, buf, len);
+       crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
+}
+
 static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 {
        struct iscsi_cmd_task *ctask = conn->in.ctask;
        struct scsi_cmnd *sc = ctask->sc;
-       struct scatterlist tmp, *sg;
+       struct scatterlist *sg;
        int i, offset, rc = 0;
 
        BUG_ON((void*)ctask != sc->SCp.ptr);
@@ -924,10 +929,8 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
                                      sc->request_bufflen, ctask->data_offset);
                if (rc == -EAGAIN)
                        return rc;
-               if (conn->datadgst_en) {
-                       sg_init_one(&tmp, sc->request_buffer, i);
-                       crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
-               }
+               if (conn->datadgst_en) 
+                       iscsi_recv_digest_update(conn, sc->request_buffer, i);
                rc = 0;
                goto done;
        }
@@ -1021,6 +1024,9 @@ iscsi_data_recv(struct iscsi_conn *conn)
                conn->in.hdr = &conn->hdr;
                conn->senselen = (conn->data[0] << 8) | conn->data[1];
                rc = iscsi_cmd_rsp(conn, conn->in.ctask);
+               if (!rc && conn->datadgst_en) 
+                       iscsi_recv_digest_update(conn, conn->data,
+                                                conn->in.datalen);
        }
        break;
        case ISCSI_OP_TEXT_RSP:
@@ -1045,6 +1051,11 @@ iscsi_data_recv(struct iscsi_conn *conn)
                rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
                                    conn->data, conn->in.datalen);
 
+               if (!rc && conn->datadgst_en && 
+                       conn->in.opcode != ISCSI_OP_LOGIN_RSP)
+                       iscsi_recv_digest_update(conn, conn->data,
+                                               conn->in.datalen);
+
                if (mtask && conn->login_mtask != mtask) {
                        spin_lock(&session->lock);
                        __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
@@ -1053,6 +1064,8 @@ iscsi_data_recv(struct iscsi_conn *conn)
                }
        }
        break;
+       case ISCSI_OP_ASYNC_EVENT:
+       case ISCSI_OP_REJECT:
        default:
                BUG_ON(1);
        }
@@ -1114,8 +1127,7 @@ more:
                 */
                rc = iscsi_hdr_recv(conn);
                if (!rc && conn->in.datalen) {
-                       if (conn->datadgst_en &&
-                           conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+                       if (conn->datadgst_en) {
                                BUG_ON(!conn->data_rx_tfm);
                                crypto_digest_init(conn->data_rx_tfm);
                        }
@@ -1127,26 +1139,24 @@ more:
        }
 
        if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
+               uint32_t recv_digest;
                debug_tcp("extra data_recv offset %d copy %d\n",
                          conn->in.offset, conn->in.copy);
-               if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
-                       uint32_t recv_digest;
-                       skb_copy_bits(conn->in.skb, conn->in.offset,
-                                     &recv_digest, 4);
-                       conn->in.offset += 4;
-                       conn->in.copy -= 4;
-                       if (recv_digest != conn->in.datadgst) {
-                               debug_tcp("iscsi_tcp: data digest error!"
-                                         "0x%x != 0x%x\n", recv_digest,
-                                         conn->in.datadgst);
-                               iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
-                               return 0;
-                       } else {
-                               debug_tcp("iscsi_tcp: data digest match!"
-                                         "0x%x == 0x%x\n", recv_digest,
-                                         conn->in.datadgst);
-                               conn->in_progress = IN_PROGRESS_WAIT_HEADER;
-                       }
+               skb_copy_bits(conn->in.skb, conn->in.offset,
+                               &recv_digest, 4);
+               conn->in.offset += 4;
+               conn->in.copy -= 4;
+               if (recv_digest != conn->in.datadgst) {
+                       debug_tcp("iscsi_tcp: data digest error!"
+                                 "0x%x != 0x%x\n", recv_digest,
+                                 conn->in.datadgst);
+                       iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
+                       return 0;
+               } else {
+                       debug_tcp("iscsi_tcp: data digest match!"
+                                 "0x%x == 0x%x\n", recv_digest,
+                                 conn->in.datadgst);
+                       conn->in_progress = IN_PROGRESS_WAIT_HEADER;
                }
        }
 
@@ -1167,8 +1177,7 @@ more:
                }
                conn->in.copy -= conn->in.padding;
                conn->in.offset += conn->in.padding;
-               if (conn->datadgst_en &&
-                   conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+               if (conn->datadgst_en) {
                        if (conn->in.padding) {
                                debug_tcp("padding -> %d\n", conn->in.padding);
                                memset(pad, 0, conn->in.padding);
@@ -1237,8 +1246,9 @@ iscsi_tcp_state_change(struct sock *sk)
        conn = (struct iscsi_conn*)sk->sk_user_data;
        session = conn->session;
 
-       if (sk->sk_state == TCP_CLOSE_WAIT ||
-           sk->sk_state == TCP_CLOSE) {
+       if ((sk->sk_state == TCP_CLOSE_WAIT ||
+            sk->sk_state == TCP_CLOSE) &&
+           !atomic_read(&sk->sk_rmem_alloc)) {
                debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
                iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
        }
@@ -2388,6 +2398,15 @@ fault:
        return 0;
 }
 
+static int
+iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+{
+       if (depth > ISCSI_MAX_CMD_PER_LUN)
+               depth = ISCSI_MAX_CMD_PER_LUN;
+       scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+       return sdev->queue_depth;
+}
+
 static int
 iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
 {
@@ -2853,8 +2872,11 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag)
                 * in hdr_extract() and will be re-negotiated at
                 * set_param() time.
                 */
-               if (flag == STOP_CONN_RECOVER)
+               if (flag == STOP_CONN_RECOVER) {
                        conn->hdr_size = sizeof(struct iscsi_hdr);
+                       conn->hdrdgst_en = 0;
+                       conn->datadgst_en = 0;
+               }
        }
        up(&conn->xmitsema);
 }
@@ -3247,13 +3269,14 @@ iscsi_r2tpool_free(struct iscsi_session *session)
 static struct scsi_host_template iscsi_sht = {
        .name                   = "iSCSI Initiator over TCP/IP, v."
                                  ISCSI_VERSION_STR,
-        .queuecommand           = iscsi_queuecommand,
+       .queuecommand           = iscsi_queuecommand,
+       .change_queue_depth     = iscsi_change_queue_depth,
        .can_queue              = ISCSI_XMIT_CMDS_MAX - 1,
        .sg_tablesize           = ISCSI_SG_TABLESIZE,
-       .cmd_per_lun            = ISCSI_CMD_PER_LUN,
-        .eh_abort_handler       = iscsi_eh_abort,
-        .eh_host_reset_handler = iscsi_eh_host_reset,
-        .use_clustering         = DISABLE_CLUSTERING,
+       .cmd_per_lun            = ISCSI_DEF_CMD_PER_LUN,
+       .eh_abort_handler       = iscsi_eh_abort,
+       .eh_host_reset_handler  = iscsi_eh_host_reset,
+       .use_clustering         = DISABLE_CLUSTERING,
        .proc_name              = "iscsi_tcp",
        .this_id                = -1,
 };
index d23ae68..855f2df 100644 (file)
@@ -71,7 +71,8 @@
 #define ISCSI_MGMT_CMDS_MAX            32      /* must be power of 2 */
 #define ISCSI_MGMT_ITT_OFFSET          0xa00
 #define ISCSI_SG_TABLESIZE             SG_ALL
-#define ISCSI_CMD_PER_LUN              128
+#define ISCSI_DEF_CMD_PER_LUN          32
+#define ISCSI_MAX_CMD_PER_LUN          128
 #define ISCSI_TCP_MAX_CMD_LEN          16
 
 #define ITT_MASK                       (0xfff)
index 3062b39..38ffa8d 100644 (file)
@@ -29,9 +29,10 @@ struct lpfc_sli2_slim;
 #define LPFC_LC_HBA_Q_DEPTH    1024    /* max cmds per low cost hba */
 #define LPFC_LP101_HBA_Q_DEPTH 128     /* max cmds per low cost hba */
 
-#define LPFC_CMD_PER_LUN       30      /* max outstanding cmds per lun */
+#define LPFC_CMD_PER_LUN       3       /* max outstanding cmds per lun */
 #define LPFC_SG_SEG_CNT                64      /* sg element count per scsi cmnd */
 #define LPFC_IOCB_LIST_CNT     2250    /* list of IOCBs for fast-path usage. */
+#define LPFC_Q_RAMP_UP_INTERVAL 120     /* lun q_depth ramp up interval */
 
 /* Define macros for 64 bit support */
 #define putPaddrLow(addr)    ((uint32_t) (0xffffffff & (u64)(addr)))
@@ -45,6 +46,11 @@ struct lpfc_sli2_slim;
 
 #define MAX_HBAEVT     32
 
+enum lpfc_polling_flags {
+       ENABLE_FCP_RING_POLLING = 0x1,
+       DISABLE_FCP_RING_INT    = 0x2
+};
+
 /* Provide DMA memory definitions the driver uses per port instance. */
 struct lpfc_dmabuf {
        struct list_head list;
@@ -167,6 +173,7 @@ struct lpfc_hba {
        dma_addr_t slim2p_mapping;
        uint16_t pci_cfg_value;
 
+       struct semaphore hba_can_block;
        uint32_t hba_state;
 
 #define LPFC_INIT_START           1    /* Initial state after board reset */
@@ -286,6 +293,8 @@ struct lpfc_hba {
        uint32_t cfg_fcp_bind_method;
        uint32_t cfg_discovery_threads;
        uint32_t cfg_max_luns;
+       uint32_t cfg_poll;
+       uint32_t cfg_poll_tmo;
        uint32_t cfg_sg_seg_cnt;
        uint32_t cfg_sg_dma_buf_size;
 
@@ -337,7 +346,9 @@ struct lpfc_hba {
 #define VPD_PORT            0x8         /* valid vpd port data */
 #define VPD_MASK            0xf         /* mask for any vpd data */
 
+       struct timer_list fcp_poll_timer;
        struct timer_list els_tmofunc;
+
        /*
         * stat  counters
         */
@@ -348,6 +359,7 @@ struct lpfc_hba {
        struct lpfc_sysfs_mbox sysfs_mbox;
 
        /* fastpath list. */
+       spinlock_t scsi_buf_list_lock;
        struct list_head lpfc_scsi_buf_list;
        uint32_t total_scsi_bufs;
        struct list_head lpfc_iocb_list;
index 89e8222..5625a8c 100644 (file)
@@ -278,6 +278,71 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
                return -EIO;
 }
 
+static ssize_t
+lpfc_poll_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+
+       return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
+}
+
+static ssize_t
+lpfc_poll_store(struct class_device *cdev, const char *buf,
+               size_t count)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+       uint32_t creg_val;
+       uint32_t old_val;
+       int val=0;
+
+       if (!isdigit(buf[0]))
+               return -EINVAL;
+
+       if (sscanf(buf, "%i", &val) != 1)
+               return -EINVAL;
+
+       if ((val & 0x3) != val)
+               return -EINVAL;
+
+       spin_lock_irq(phba->host->host_lock);
+
+       old_val = phba->cfg_poll;
+
+       if (val & ENABLE_FCP_RING_POLLING) {
+               if ((val & DISABLE_FCP_RING_INT) &&
+                   !(old_val & DISABLE_FCP_RING_INT)) {
+                       creg_val = readl(phba->HCregaddr);
+                       creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+                       writel(creg_val, phba->HCregaddr);
+                       readl(phba->HCregaddr); /* flush */
+
+                       lpfc_poll_start_timer(phba);
+               }
+       } else if (val != 0x0) {
+               spin_unlock_irq(phba->host->host_lock);
+               return -EINVAL;
+       }
+
+       if (!(val & DISABLE_FCP_RING_INT) &&
+           (old_val & DISABLE_FCP_RING_INT))
+       {
+               spin_unlock_irq(phba->host->host_lock);
+               del_timer(&phba->fcp_poll_timer);
+               spin_lock_irq(phba->host->host_lock);
+               creg_val = readl(phba->HCregaddr);
+               creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+               writel(creg_val, phba->HCregaddr);
+               readl(phba->HCregaddr); /* flush */
+       }
+
+       phba->cfg_poll = val;
+
+       spin_unlock_irq(phba->host->host_lock);
+
+       return strlen(buf);
+}
 
 #define lpfc_param_show(attr)  \
 static ssize_t \
@@ -416,6 +481,15 @@ static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
 static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
                         lpfc_board_online_show, lpfc_board_online_store);
 
+static int lpfc_poll = 0;
+module_param(lpfc_poll, int, 0);
+MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
+                " 0 - none,"
+                " 1 - poll with interrupts enabled"
+                " 3 - poll and disable FCP ring interrupts");
+
+static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
+                        lpfc_poll_show, lpfc_poll_store);
 
 /*
 # lpfc_log_verbose: Only turn this flag on if you are willing to risk being
@@ -523,10 +597,10 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
 # is 0. Default value of cr_count is 1. The cr_count feature is disabled if
 # cr_delay is set to 0.
 */
-LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
+LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
                "interrupt response is generated");
 
-LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
+LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an"
                "interrupt response is generated");
 
 /*
@@ -553,6 +627,13 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
 LPFC_ATTR_R(max_luns, 256, 1, 32768,
             "Maximum number of LUNs per target driver will support");
 
+/*
+# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
+# Value range is [1,255], default value is 10.
+*/
+LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
+            "Milliseconds driver will wait between polling FCP ring");
+
 struct class_device_attribute *lpfc_host_attrs[] = {
        &class_device_attr_info,
        &class_device_attr_serialnum,
@@ -575,11 +656,15 @@ struct class_device_attribute *lpfc_host_attrs[] = {
        &class_device_attr_lpfc_topology,
        &class_device_attr_lpfc_scan_down,
        &class_device_attr_lpfc_link_speed,
+       &class_device_attr_lpfc_cr_delay,
+       &class_device_attr_lpfc_cr_count,
        &class_device_attr_lpfc_fdmi_on,
        &class_device_attr_lpfc_max_luns,
        &class_device_attr_nport_evt_cnt,
        &class_device_attr_management_version,
        &class_device_attr_board_online,
+       &class_device_attr_lpfc_poll,
+       &class_device_attr_lpfc_poll_tmo,
        NULL,
 };
 
@@ -1292,6 +1377,9 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
        lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
        lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
        lpfc_max_luns_init(phba, lpfc_max_luns);
+       lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
+
+       phba->cfg_poll = lpfc_poll;
 
        /*
         * The total number of segments is the configuration value plus 2
index d527d05..f1e7089 100644 (file)
@@ -143,6 +143,9 @@ LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
 int lpfc_mem_alloc(struct lpfc_hba *);
 void lpfc_mem_free(struct lpfc_hba *);
 
+void lpfc_poll_timeout(unsigned long ptr);
+void lpfc_poll_start_timer(struct lpfc_hba * phba);
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba);
 struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
 void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
 uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
index 084e762..ed6c816 100644 (file)
@@ -73,6 +73,8 @@ struct lpfc_nodelist {
        struct lpfc_hba      *nlp_phba;
        struct lpfc_work_evt nodev_timeout_evt;
        struct lpfc_work_evt els_retry_evt;
+       unsigned long last_ramp_up_time;        /* jiffy of last ramp up */
+       unsigned long last_q_full_time;         /* jiffy of last queue full */
 };
 
 /* Defines for nlp_flag (uint32) */
index bcc29ec..20f1a07 100644 (file)
@@ -720,6 +720,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
                }
@@ -869,6 +870,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        goto out;
                }
@@ -1054,6 +1056,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
                }
@@ -1205,6 +1208,7 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        goto out;
                }
index 259eeb1..a1f751e 100644 (file)
@@ -1017,12 +1017,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
        rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
        rport_ids.port_id = ndlp->nlp_DID;
        rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-       if (ndlp->nlp_type & NLP_FCP_TARGET)
-               rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
-       if (ndlp->nlp_type & NLP_FCP_INITIATOR)
-               rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 
-       scsi_block_requests(phba->host);
        ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
        if (!rport) {
                dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -1039,7 +1034,16 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
        }
        rdata = rport->dd_data;
        rdata->pnode = ndlp;
-       scsi_unblock_requests(phba->host);
+
+       if (ndlp->nlp_type & NLP_FCP_TARGET)
+               rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
+       if (ndlp->nlp_type & NLP_FCP_INITIATOR)
+               rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
+
+
+       if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
+               fc_remote_port_rolechg(rport, rport_ids.roles);
+
 
        return;
 }
@@ -1053,9 +1057,7 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba,
 
        ndlp->rport = NULL;
        rdata->pnode = NULL;
-       scsi_block_requests(phba->host);
        fc_remote_port_delete(rport);
-       scsi_unblock_requests(phba->host);
 
        return;
 }
index 86c4198..1ea565e 100644 (file)
@@ -266,9 +266,11 @@ struct lpfc_name {
                struct {
 #ifdef __BIG_ENDIAN_BITFIELD
                        uint8_t nameType:4;     /* FC Word 0, bit 28:31 */
-                       uint8_t IEEEextMsn:4;   /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+                       uint8_t IEEEextMsn:4;   /* FC Word 0, bit 24:27, bit
+                                                  8:11 of IEEE ext */
 #else  /*  __LITTLE_ENDIAN_BITFIELD */
-                       uint8_t IEEEextMsn:4;   /* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+                       uint8_t IEEEextMsn:4;   /* FC Word 0, bit 24:27, bit
+                                                  8:11 of IEEE ext */
                        uint8_t nameType:4;     /* FC Word 0, bit 28:31 */
 #endif
 
@@ -278,7 +280,8 @@ struct lpfc_name {
 #define NAME_IP_TYPE        0x4        /* IP address */
 #define NAME_CCITT_TYPE     0xC
 #define NAME_CCITT_GR_TYPE  0xE
-                       uint8_t IEEEextLsb;     /* FC Word 0, bit 16:23, IEEE extended Lsb */
+                       uint8_t IEEEextLsb;     /* FC Word 0, bit 16:23, IEEE
+                                                  extended Lsb */
                        uint8_t IEEE[6];        /* FC IEEE address */
                } s;
                uint8_t wwn[8];
@@ -1024,23 +1027,38 @@ typedef struct {
 /* Start FireFly Register definitions */
 #define PCI_VENDOR_ID_EMULEX        0x10df
 #define PCI_DEVICE_ID_FIREFLY       0x1ae5
-#define PCI_DEVICE_ID_SUPERFLY      0xf700
-#define PCI_DEVICE_ID_DRAGONFLY     0xf800
 #define PCI_DEVICE_ID_RFLY          0xf095
 #define PCI_DEVICE_ID_PFLY          0xf098
+#define PCI_DEVICE_ID_LP101         0xf0a1
 #define PCI_DEVICE_ID_TFLY          0xf0a5
+#define PCI_DEVICE_ID_BSMB          0xf0d1
+#define PCI_DEVICE_ID_BMID          0xf0d5
+#define PCI_DEVICE_ID_ZSMB          0xf0e1
+#define PCI_DEVICE_ID_ZMID          0xf0e5
+#define PCI_DEVICE_ID_NEPTUNE       0xf0f5
+#define PCI_DEVICE_ID_NEPTUNE_SCSP  0xf0f6
+#define PCI_DEVICE_ID_NEPTUNE_DCSP  0xf0f7
+#define PCI_DEVICE_ID_SUPERFLY      0xf700
+#define PCI_DEVICE_ID_DRAGONFLY     0xf800
 #define PCI_DEVICE_ID_CENTAUR       0xf900
 #define PCI_DEVICE_ID_PEGASUS       0xf980
 #define PCI_DEVICE_ID_THOR          0xfa00
 #define PCI_DEVICE_ID_VIPER         0xfb00
+#define PCI_DEVICE_ID_LP10000S      0xfc00
+#define PCI_DEVICE_ID_LP11000S      0xfc10
+#define PCI_DEVICE_ID_LPE11000S     0xfc20
 #define PCI_DEVICE_ID_HELIOS        0xfd00
-#define PCI_DEVICE_ID_BMID          0xf0d5
-#define PCI_DEVICE_ID_BSMB          0xf0d1
+#define PCI_DEVICE_ID_HELIOS_SCSP   0xfd11
+#define PCI_DEVICE_ID_HELIOS_DCSP   0xfd12
 #define PCI_DEVICE_ID_ZEPHYR        0xfe00
-#define PCI_DEVICE_ID_ZMID          0xf0e5
-#define PCI_DEVICE_ID_ZSMB          0xf0e1
-#define PCI_DEVICE_ID_LP101        0xf0a1
-#define PCI_DEVICE_ID_LP10000S     0xfc00
+#define PCI_DEVICE_ID_ZEPHYR_SCSP   0xfe11
+#define PCI_DEVICE_ID_ZEPHYR_DCSP   0xfe12
+
+#define PCI_SUBSYSTEM_ID_LP11000S      0xfc11
+#define PCI_SUBSYSTEM_ID_LP11002S      0xfc12
+#define PCI_SUBSYSTEM_ID_LPE11000S     0xfc21
+#define PCI_SUBSYSTEM_ID_LPE11002S     0xfc22
+#define PCI_SUBSYSTEM_ID_LPE11010S     0xfc2A
 
 #define JEDEC_ID_ADDRESS            0x0080001c
 #define FIREFLY_JEDEC_ID            0x1ACC
index 0749811..b7a603a 100644 (file)
@@ -126,34 +126,26 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
                return -ERESTART;
        }
 
-       /* The HBA's current state is provided by the ProgType and rr fields.
-        * Read and check the value of these fields before continuing to config
-        * this port.
+       /*
+        * The value of rr must be 1 since the driver set the cv field to 1.
+        * This setting requires the FW to set all revision fields.
         */
-       if (mb->un.varRdRev.rr == 0 || mb->un.varRdRev.un.b.ProgType != 2) {
-               /* Old firmware */
+       if (mb->un.varRdRev.rr == 0) {
                vp->rev.rBit = 0;
-               lpfc_printf_log(phba,
-                               KERN_ERR,
-                               LOG_INIT,
-                               "%d:0440 Adapter failed to init, mbxCmd x%x "
-                               "READ_REV detected outdated firmware"
-                               "Data: x%x\n",
-                               phba->brd_no,
-                               mb->mbxCommand, 0);
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "%d:0440 Adapter failed to init, READ_REV has "
+                               "missing revision information.\n",
+                               phba->brd_no);
                mempool_free(pmb, phba->mbox_mem_pool);
                return -ERESTART;
-       } else {
-               vp->rev.rBit = 1;
-               vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
-               memcpy(vp->rev.sli1FwName,
-                       (char*)mb->un.varRdRev.sli1FwName, 16);
-               vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
-               memcpy(vp->rev.sli2FwName,
-                                       (char *)mb->un.varRdRev.sli2FwName, 16);
        }
 
        /* Save information as VPD data */
+       vp->rev.rBit = 1;
+       vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
+       memcpy(vp->rev.sli1FwName, (char*) mb->un.varRdRev.sli1FwName, 16);
+       vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
+       memcpy(vp->rev.sli2FwName, (char *) mb->un.varRdRev.sli2FwName, 16);
        vp->rev.biuRev = mb->un.varRdRev.biuRev;
        vp->rev.smRev = mb->un.varRdRev.smRev;
        vp->rev.smFwRev = mb->un.varRdRev.un.smFwRev;
@@ -378,6 +370,10 @@ lpfc_config_port_post(struct lpfc_hba * phba)
        if (psli->num_rings > 3)
                status |= HC_R3INT_ENA;
 
+       if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) &&
+           (phba->cfg_poll & DISABLE_FCP_RING_INT))
+               status &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+
        writel(status, phba->HCregaddr);
        readl(phba->HCregaddr); /* flush */
        spin_unlock_irq(phba->host->host_lock);
@@ -571,6 +567,8 @@ lpfc_handle_latt(struct lpfc_hba * phba)
 
        rc = -EIO;
 
+       /* Cleanup any outstanding ELS commands */
+       lpfc_els_flush_cmd(phba);
 
        psli->slistat.link_event++;
        lpfc_read_la(phba, pmb, mp);
@@ -765,96 +763,139 @@ static void
 lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
 {
        lpfc_vpd_t *vp;
-       uint32_t id;
-       uint8_t hdrtype;
-       char str[16];
+       uint16_t dev_id = phba->pcidev->device;
+       uint16_t dev_subid = phba->pcidev->subsystem_device;
+       uint8_t hdrtype = phba->pcidev->hdr_type;
+       char *model_str = "";
 
        vp = &phba->vpd;
-       pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id);
-       pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
 
-       switch ((id >> 16) & 0xffff) {
+       switch (dev_id) {
        case PCI_DEVICE_ID_FIREFLY:
-               strcpy(str, "LP6000 1");
+               model_str = "LP6000 1Gb PCI";
                break;
        case PCI_DEVICE_ID_SUPERFLY:
                if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
-                       strcpy(str, "LP7000 1");
+                       model_str = "LP7000 1Gb PCI";
                else
-                       strcpy(str, "LP7000E 1");
+                       model_str = "LP7000E 1Gb PCI";
                break;
        case PCI_DEVICE_ID_DRAGONFLY:
-               strcpy(str, "LP8000 1");
+               model_str = "LP8000 1Gb PCI";
                break;
        case PCI_DEVICE_ID_CENTAUR:
                if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
-                       strcpy(str, "LP9002 2");
+                       model_str = "LP9002 2Gb PCI";
                else
-                       strcpy(str, "LP9000 1");
+                       model_str = "LP9000 1Gb PCI";
                break;
        case PCI_DEVICE_ID_RFLY:
-               strcpy(str, "LP952 2");
+               model_str = "LP952 2Gb PCI";
                break;
        case PCI_DEVICE_ID_PEGASUS:
-               strcpy(str, "LP9802 2");
+               model_str = "LP9802 2Gb PCI-X";
                break;
        case PCI_DEVICE_ID_THOR:
                if (hdrtype == 0x80)
-                       strcpy(str, "LP10000DC 2");
+                       model_str = "LP10000DC 2Gb 2-port PCI-X";
                else
-                       strcpy(str, "LP10000 2");
+                       model_str = "LP10000 2Gb PCI-X";
                break;
        case PCI_DEVICE_ID_VIPER:
-               strcpy(str, "LPX1000 10");
+               model_str = "LPX1000 10Gb PCI-X";
                break;
        case PCI_DEVICE_ID_PFLY:
-               strcpy(str, "LP982 2");
+               model_str = "LP982 2Gb PCI-X";
                break;
        case PCI_DEVICE_ID_TFLY:
                if (hdrtype == 0x80)
-                       strcpy(str, "LP1050DC 2");
+                       model_str = "LP1050DC 2Gb 2-port PCI-X";
                else
-                       strcpy(str, "LP1050 2");
+                       model_str = "LP1050 2Gb PCI-X";
                break;
        case PCI_DEVICE_ID_HELIOS:
                if (hdrtype == 0x80)
-                       strcpy(str, "LP11002 4");
+                       model_str = "LP11002 4Gb 2-port PCI-X2";
+               else
+                       model_str = "LP11000 4Gb PCI-X2";
+               break;
+       case PCI_DEVICE_ID_HELIOS_SCSP:
+               model_str = "LP11000-SP 4Gb PCI-X2";
+               break;
+       case PCI_DEVICE_ID_HELIOS_DCSP:
+               model_str = "LP11002-SP 4Gb 2-port PCI-X2";
+               break;
+       case PCI_DEVICE_ID_NEPTUNE:
+               if (hdrtype == 0x80)
+                       model_str = "LPe1002 4Gb 2-port";
                else
-                       strcpy(str, "LP11000 4");
+                       model_str = "LPe1000 4Gb PCIe";
+               break;
+       case PCI_DEVICE_ID_NEPTUNE_SCSP:
+               model_str = "LPe1000-SP 4Gb PCIe";
+               break;
+       case PCI_DEVICE_ID_NEPTUNE_DCSP:
+               model_str = "LPe1002-SP 4Gb 2-port PCIe";
                break;
        case PCI_DEVICE_ID_BMID:
-               strcpy(str, "LP1150 4");
+               model_str = "LP1150 4Gb PCI-X2";
                break;
        case PCI_DEVICE_ID_BSMB:
-               strcpy(str, "LP111 4");
+               model_str = "LP111 4Gb PCI-X2";
                break;
        case PCI_DEVICE_ID_ZEPHYR:
                if (hdrtype == 0x80)
-                       strcpy(str, "LPe11002 4");
+                       model_str = "LPe11002 4Gb 2-port PCIe";
                else
-                       strcpy(str, "LPe11000 4");
+                       model_str = "LPe11000 4Gb PCIe";
+               break;
+       case PCI_DEVICE_ID_ZEPHYR_SCSP:
+               model_str = "LPe11000-SP 4Gb PCIe";
+               break;
+       case PCI_DEVICE_ID_ZEPHYR_DCSP:
+               model_str = "LPe11002-SP 4Gb 2-port PCIe";
                break;
        case PCI_DEVICE_ID_ZMID:
-               strcpy(str, "LPe1150 4");
+               model_str = "LPe1150 4Gb PCIe";
                break;
        case PCI_DEVICE_ID_ZSMB:
-               strcpy(str, "LPe111 4");
+               model_str = "LPe111 4Gb PCIe";
                break;
        case PCI_DEVICE_ID_LP101:
-               strcpy(str, "LP101 2");
+               model_str = "LP101 2Gb PCI-X";
                break;
        case PCI_DEVICE_ID_LP10000S:
-               strcpy(str, "LP10000-S 2");
+               model_str = "LP10000-S 2Gb PCI";
+               break;
+       case PCI_DEVICE_ID_LP11000S:
+       case PCI_DEVICE_ID_LPE11000S:
+               switch (dev_subid) {
+               case PCI_SUBSYSTEM_ID_LP11000S:
+                       model_str = "LP11002-S 4Gb PCI-X2";
+                       break;
+               case PCI_SUBSYSTEM_ID_LP11002S:
+                       model_str = "LP11000-S 4Gb 2-port PCI-X2";
+                       break;
+               case PCI_SUBSYSTEM_ID_LPE11000S:
+                       model_str = "LPe11002-S 4Gb PCIe";
+                       break;
+               case PCI_SUBSYSTEM_ID_LPE11002S:
+                       model_str = "LPe11002-S 4Gb 2-port PCIe";
+                       break;
+               case PCI_SUBSYSTEM_ID_LPE11010S:
+                       model_str = "LPe11010-S 4Gb 10-port PCIe";
+                       break;
+               default:
+                       break;
+               }
                break;
        default:
-               memset(str, 0, 16);
                break;
        }
        if (mdp)
-               sscanf(str, "%s", mdp);
+               sscanf(model_str, "%s", mdp);
        if (descp)
-               sprintf(descp, "Emulex LightPulse %s Gigabit PCI Fibre "
-                       "Channel Adapter", str);
+               sprintf(descp, "Emulex %s Fibre Channel Adapter", model_str);
 }
 
 /**************************************************/
@@ -1196,6 +1237,7 @@ lpfc_stop_timer(struct lpfc_hba * phba)
                }
        }
 
+       del_timer_sync(&phba->fcp_poll_timer);
        del_timer_sync(&phba->fc_estabtmo);
        del_timer_sync(&phba->fc_disctmo);
        del_timer_sync(&phba->fc_fdmitmo);
@@ -1351,7 +1393,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
                goto out_put_host;
 
        host->unique_id = phba->brd_no;
-
+       init_MUTEX(&phba->hba_can_block);
        INIT_LIST_HEAD(&phba->ctrspbuflist);
        INIT_LIST_HEAD(&phba->rnidrspbuflist);
        INIT_LIST_HEAD(&phba->freebufList);
@@ -1375,6 +1417,10 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
        psli->mbox_tmo.function = lpfc_mbox_timeout;
        psli->mbox_tmo.data = (unsigned long)phba;
 
+       init_timer(&phba->fcp_poll_timer);
+       phba->fcp_poll_timer.function = lpfc_poll_timeout;
+       phba->fcp_poll_timer.data = (unsigned long)phba;
+
        /*
         * Get all the module params for configuring this host and then
         * establish the host parameters.
@@ -1489,6 +1535,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
        host->max_cmd_len = 16;
 
        /* Initialize the list of scsi buffers used by driver for scsi IO. */
+       spin_lock_init(&phba->scsi_buf_list_lock);
        INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list);
 
        host->transportt = lpfc_transport_template;
@@ -1520,6 +1567,12 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
        if (error)
                goto out_free_irq;
 
+       if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+               spin_lock_irq(phba->host->host_lock);
+               lpfc_poll_start_timer(phba);
+               spin_unlock_irq(phba->host->host_lock);
+       }
+
        /*
         * set fixed host attributes
         * Must done after lpfc_sli_hba_setup()
@@ -1679,14 +1732,28 @@ static struct pci_device_id lpfc_id_table[] = {
                PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PFLY,
                PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_SCSP,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_DCSP,
+               PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS,
                PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_SCSP,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_DCSP,
+               PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BMID,
                PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BSMB,
                PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR,
                PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_SCSP,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_DCSP,
+               PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZMID,
                PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZSMB,
@@ -1697,6 +1764,10 @@ static struct pci_device_id lpfc_id_table[] = {
                PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP10000S,
                PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP11000S,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LPE11000S,
+               PCI_ANY_ID, PCI_ANY_ID, },
        { 0 }
 };
 
index 507a6af..fbead78 100644 (file)
@@ -55,55 +55,76 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        return (1);
 }
 
-
 int
 lpfc_check_sparm(struct lpfc_hba * phba,
                 struct lpfc_nodelist * ndlp, struct serv_parm * sp,
                 uint32_t class)
 {
        volatile struct serv_parm *hsp = &phba->fc_sparam;
-       /* First check for supported version */
-
-       /* Next check for class validity */
+       uint16_t hsp_value, ssp_value = 0;
+
+       /*
+        * The receive data field size and buffer-to-buffer receive data field
+        * size entries are 16 bits but are represented as two 8-bit fields in
+        * the driver data structure to account for rsvd bits and other control
+        * bits.  Reconstruct and compare the fields as a 16-bit values before
+        * correcting the byte values.
+        */
        if (sp->cls1.classValid) {
-
-               if (sp->cls1.rcvDataSizeMsb > hsp->cls1.rcvDataSizeMsb)
-                       sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
-               if (sp->cls1.rcvDataSizeLsb > hsp->cls1.rcvDataSizeLsb)
+               hsp_value = (hsp->cls1.rcvDataSizeMsb << 8) |
+                               hsp->cls1.rcvDataSizeLsb;
+               ssp_value = (sp->cls1.rcvDataSizeMsb << 8) |
+                               sp->cls1.rcvDataSizeLsb;
+               if (ssp_value > hsp_value) {
                        sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb;
+                       sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
+               }
        } else if (class == CLASS1) {
-               return (0);
+               return 0;
        }
 
        if (sp->cls2.classValid) {
-
-               if (sp->cls2.rcvDataSizeMsb > hsp->cls2.rcvDataSizeMsb)
-                       sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
-               if (sp->cls2.rcvDataSizeLsb > hsp->cls2.rcvDataSizeLsb)
+               hsp_value = (hsp->cls2.rcvDataSizeMsb << 8) |
+                               hsp->cls2.rcvDataSizeLsb;
+               ssp_value = (sp->cls2.rcvDataSizeMsb << 8) |
+                               sp->cls2.rcvDataSizeLsb;
+               if (ssp_value > hsp_value) {
                        sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb;
+                       sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
+               }
        } else if (class == CLASS2) {
-               return (0);
+               return 0;
        }
 
        if (sp->cls3.classValid) {
-
-               if (sp->cls3.rcvDataSizeMsb > hsp->cls3.rcvDataSizeMsb)
-                       sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
-               if (sp->cls3.rcvDataSizeLsb > hsp->cls3.rcvDataSizeLsb)
+               hsp_value = (hsp->cls3.rcvDataSizeMsb << 8) |
+                               hsp->cls3.rcvDataSizeLsb;
+               ssp_value = (sp->cls3.rcvDataSizeMsb << 8) |
+                               sp->cls3.rcvDataSizeLsb;
+               if (ssp_value > hsp_value) {
                        sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb;
+                       sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
+               }
        } else if (class == CLASS3) {
-               return (0);
+               return 0;
        }
 
-       if (sp->cmn.bbRcvSizeMsb > hsp->cmn.bbRcvSizeMsb)
-               sp->cmn.bbRcvSizeMsb = hsp->cmn.bbRcvSizeMsb;
-       if (sp->cmn.bbRcvSizeLsb > hsp->cmn.bbRcvSizeLsb)
+       /*
+        * Preserve the upper four bits of the MSB from the PLOGI response.
+        * These bits contain the Buffer-to-Buffer State Change Number
+        * from the target and need to be passed to the FW.
+        */
+       hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;
+       ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;
+       if (ssp_value > hsp_value) {
                sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
+               sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |
+                                      (hsp->cmn.bbRcvSizeMsb & 0x0F);
+       }
 
-       /* If check is good, copy wwpn wwnn into ndlp */
        memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
        memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
-       return (1);
+       return 1;
 }
 
 static void *
index c63275e..9ee8218 100644 (file)
 #define LPFC_ABORT_WAIT  2
 
 
+static inline void
+lpfc_block_requests(struct lpfc_hba * phba)
+{
+       down(&phba->hba_can_block);
+       scsi_block_requests(phba->host);
+}
+
+static inline void
+lpfc_unblock_requests(struct lpfc_hba * phba)
+{
+       scsi_unblock_requests(phba->host);
+       up(&phba->hba_can_block);
+}
+
 /*
  * This routine allocates a scsi buffer, which contains all the necessary
  * information needed to initiate a SCSI I/O.  The non-DMAable buffer region
@@ -137,18 +151,22 @@ lpfc_new_scsi_buf(struct lpfc_hba * phba)
 }
 
 struct  lpfc_scsi_buf*
-lpfc_sli_get_scsi_buf(struct lpfc_hba * phba)
+lpfc_get_scsi_buf(struct lpfc_hba * phba)
 {
        struct  lpfc_scsi_buf * lpfc_cmd = NULL;
        struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
+       unsigned long iflag = 0;
 
+       spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
        list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+       spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
        return  lpfc_cmd;
 }
 
 static void
 lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
 {
+       unsigned long iflag = 0;
        /*
         * There are only two special cases to consider.  (1) the scsi command
         * requested scatter-gather usage or (2) the scsi command allocated
@@ -166,8 +184,10 @@ lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
                 }
        }
 
+       spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
        psb->pCmd = NULL;
        list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list);
+       spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
 }
 
 static int
@@ -389,7 +409,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
        struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
        struct lpfc_nodelist *pnode = rdata->pnode;
        struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
-       unsigned long iflag;
+       int result;
+       struct scsi_device *sdev, *tmp_sdev;
+       int depth = 0;
 
        lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
        lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
@@ -441,11 +463,64 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
                                *lp, *(lp + 3), cmd->retries, cmd->resid);
        }
 
+       result = cmd->result;
+       sdev = cmd->device;
        cmd->scsi_done(cmd);
 
-       spin_lock_irqsave(phba->host->host_lock, iflag);
+       if (!result &&
+          ((jiffies - pnode->last_ramp_up_time) >
+               LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
+          ((jiffies - pnode->last_q_full_time) >
+               LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
+          (phba->cfg_lun_queue_depth > sdev->queue_depth)) {
+               shost_for_each_device(tmp_sdev, sdev->host) {
+                       if (phba->cfg_lun_queue_depth > tmp_sdev->queue_depth) {
+                               if (tmp_sdev->id != sdev->id)
+                                       continue;
+                               if (tmp_sdev->ordered_tags)
+                                       scsi_adjust_queue_depth(tmp_sdev,
+                                               MSG_ORDERED_TAG,
+                                               tmp_sdev->queue_depth+1);
+                               else
+                                       scsi_adjust_queue_depth(tmp_sdev,
+                                               MSG_SIMPLE_TAG,
+                                               tmp_sdev->queue_depth+1);
+
+                               pnode->last_ramp_up_time = jiffies;
+                       }
+               }
+       }
+
+       /*
+        * Check for queue full.  If the lun is reporting queue full, then
+        * back off the lun queue depth to prevent target overloads.
+        */
+       if (result == SAM_STAT_TASK_SET_FULL) {
+               pnode->last_q_full_time = jiffies;
+
+               shost_for_each_device(tmp_sdev, sdev->host) {
+                       if (tmp_sdev->id != sdev->id)
+                               continue;
+                       depth = scsi_track_queue_full(tmp_sdev,
+                                       tmp_sdev->queue_depth - 1);
+               }
+               /*
+                * The queue depth cannot be lowered any more.
+                * Modify the returned error code to store
+                * the final depth value set by
+                * scsi_track_queue_full.
+                */
+               if (depth == -1)
+                       depth = sdev->host->cmd_per_lun;
+
+               if (depth) {
+                       lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+                               "%d:0711 detected queue full - lun queue depth "
+                               " adjusted to %d.\n", phba->brd_no, depth);
+               }
+       }
+
        lpfc_release_scsi_buf(phba, lpfc_cmd);
-       spin_unlock_irqrestore(phba->host->host_lock, iflag);
 }
 
 static void
@@ -693,6 +768,37 @@ lpfc_info(struct Scsi_Host *host)
        return lpfcinfobuf;
 }
 
+static __inline__ void lpfc_poll_rearm_timer(struct lpfc_hba * phba)
+{
+       unsigned long  poll_tmo_expires =
+               (jiffies + msecs_to_jiffies(phba->cfg_poll_tmo));
+
+       if (phba->sli.ring[LPFC_FCP_RING].txcmplq_cnt)
+               mod_timer(&phba->fcp_poll_timer,
+                         poll_tmo_expires);
+}
+
+void lpfc_poll_start_timer(struct lpfc_hba * phba)
+{
+       lpfc_poll_rearm_timer(phba);
+}
+
+void lpfc_poll_timeout(unsigned long ptr)
+{
+       struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+       unsigned long iflag;
+
+       spin_lock_irqsave(phba->host->host_lock, iflag);
+
+       if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+               lpfc_sli_poll_fcp_ring (phba);
+               if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+                       lpfc_poll_rearm_timer(phba);
+       }
+
+       spin_unlock_irqrestore(phba->host->host_lock, iflag);
+}
+
 static int
 lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
@@ -719,10 +825,11 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
                cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
                goto out_fail_command;
        }
-       lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+       lpfc_cmd = lpfc_get_scsi_buf (phba);
        if (lpfc_cmd == NULL) {
-               printk(KERN_WARNING "%s: No buffer available - list empty, "
-                      "total count %d\n", __FUNCTION__, phba->total_scsi_bufs);
+               lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+                               "%d:0707 driver's buffer pool is empty, "
+                               "IO busied\n", phba->brd_no);
                goto out_host_busy;
        }
 
@@ -746,11 +853,17 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
                                &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
        if (err)
                goto out_host_busy_free_buf;
+
+       if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+               lpfc_sli_poll_fcp_ring(phba);
+               if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+                       lpfc_poll_rearm_timer(phba);
+       }
+
        return 0;
 
  out_host_busy_free_buf:
        lpfc_release_scsi_buf(phba, lpfc_cmd);
-       cmnd->host_scribble = NULL;
  out_host_busy:
        return SCSI_MLQUEUE_HOST_BUSY;
 
@@ -759,11 +872,12 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
        return 0;
 }
 
+
 static int
-__lpfc_abort_handler(struct scsi_cmnd *cmnd)
+lpfc_abort_handler(struct scsi_cmnd *cmnd)
 {
-       struct lpfc_hba *phba =
-                       (struct lpfc_hba *)cmnd->device->host->hostdata[0];
+       struct Scsi_Host *shost = cmnd->device->host;
+       struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
        struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
        struct lpfc_iocbq *iocb;
        struct lpfc_iocbq *abtsiocb;
@@ -772,6 +886,8 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
        unsigned int loop_count = 0;
        int ret = SUCCESS;
 
+       lpfc_block_requests(phba);
+       spin_lock_irq(shost->host_lock);
 
        lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
        BUG_ON(!lpfc_cmd);
@@ -821,9 +937,15 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
                goto out;
        }
 
+       if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+               lpfc_sli_poll_fcp_ring (phba);
+
        /* Wait for abort to complete */
        while (lpfc_cmd->pCmd == cmnd)
        {
+               if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+                       lpfc_sli_poll_fcp_ring (phba);
+
                spin_unlock_irq(phba->host->host_lock);
                        schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
                spin_lock_irq(phba->host->host_lock);
@@ -844,26 +966,19 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
 
  out:
        lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
-                       "%d:0749 SCSI layer issued abort device: ret %#x, "
-                       "ID %d, LUN %d, snum %#lx\n",
+                       "%d:0749 SCSI Layer I/O Abort Request "
+                       "Status x%x ID %d LUN %d snum %#lx\n",
                        phba->brd_no, ret, cmnd->device->id,
                        cmnd->device->lun, cmnd->serial_number);
 
-       return ret;
-}
+       spin_unlock_irq(shost->host_lock);
+       lpfc_unblock_requests(phba);
 
-static int
-lpfc_abort_handler(struct scsi_cmnd *cmnd)
-{
-       int rc;
-       spin_lock_irq(cmnd->device->host->host_lock);
-       rc = __lpfc_abort_handler(cmnd);
-       spin_unlock_irq(cmnd->device->host->host_lock);
-       return rc;
+       return ret;
 }
 
 static int
-__lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
+lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
 {
        struct Scsi_Host *shost = cmnd->device->host;
        struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -871,9 +986,12 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        struct lpfc_iocbq *iocbq, *iocbqrsp;
        struct lpfc_rport_data *rdata = cmnd->device->hostdata;
        struct lpfc_nodelist *pnode = rdata->pnode;
+       uint32_t cmd_result = 0, cmd_status = 0;
        int ret = FAILED;
        int cnt, loopcnt;
 
+       lpfc_block_requests(phba);
+       spin_lock_irq(shost->host_lock);
        /*
         * If target is not in a MAPPED state, delay the reset until
         * target is rediscovered or nodev timeout expires.
@@ -891,7 +1009,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
                        break;
        }
 
-       lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+       lpfc_cmd = lpfc_get_scsi_buf (phba);
        if (lpfc_cmd == NULL)
                goto out;
 
@@ -916,26 +1034,28 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        if (ret == IOCB_SUCCESS)
                ret = SUCCESS;
 
-       lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4];
-       lpfc_cmd->status = iocbqrsp->iocb.ulpStatus;
-       if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT)
-               if (lpfc_cmd->result & IOERR_DRVR_MASK)
-                       lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
+
+       cmd_result = iocbqrsp->iocb.un.ulpWord[4];
+       cmd_status = iocbqrsp->iocb.ulpStatus;
+
+       lpfc_sli_release_iocbq(phba, iocbqrsp);
+       lpfc_release_scsi_buf(phba, lpfc_cmd);
 
        /*
-        * All outstanding txcmplq I/Os should have been aborted by the target.
+        * All outstanding txcmplq I/Os should have been aborted by the device.
         * Unfortunately, some targets do not abide by this forcing the driver
         * to double check.
         */
-       lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
-                           cmnd->device->id, cmnd->device->lun, 0,
-                           LPFC_CTX_LUN);
-
+       cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+                               cmnd->device->id, cmnd->device->lun,
+                               LPFC_CTX_LUN);
+       if (cnt)
+               lpfc_sli_abort_iocb(phba,
+                                   &phba->sli.ring[phba->sli.fcp_ring],
+                                   cmnd->device->id, cmnd->device->lun,
+                                   0, LPFC_CTX_LUN);
        loopcnt = 0;
-       while((cnt = lpfc_sli_sum_iocb(phba,
-                                      &phba->sli.ring[phba->sli.fcp_ring],
-                                      cmnd->device->id, cmnd->device->lun,
-                                      LPFC_CTX_LUN))) {
+       while(cnt) {
                spin_unlock_irq(phba->host->host_lock);
                schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
                spin_lock_irq(phba->host->host_lock);
@@ -943,6 +1063,11 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
                if (++loopcnt
                    > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
                        break;
+
+               cnt = lpfc_sli_sum_iocb(phba,
+                                       &phba->sli.ring[phba->sli.fcp_ring],
+                                       cmnd->device->id, cmnd->device->lun,
+                                       LPFC_CTX_LUN);
        }
 
        if (cnt) {
@@ -952,35 +1077,21 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
                ret = FAILED;
        }
 
-       lpfc_sli_release_iocbq(phba, iocbqrsp);
-
 out_free_scsi_buf:
        lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                        "%d:0713 SCSI layer issued LUN reset (%d, %d) "
                        "Data: x%x x%x x%x\n",
-                       phba->brd_no, lpfc_cmd->pCmd->device->id,
-                       lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status,
-                       lpfc_cmd->result);
-       lpfc_release_scsi_buf(phba, lpfc_cmd);
+                       phba->brd_no, cmnd->device->id,cmnd->device->lun,
+                       ret, cmd_status, cmd_result);
+
 out:
+       spin_unlock_irq(shost->host_lock);
+       lpfc_unblock_requests(phba);
        return ret;
 }
 
 static int
-lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
-{
-       int rc;
-       spin_lock_irq(cmnd->device->host->host_lock);
-       rc = __lpfc_reset_lun_handler(cmnd);
-       spin_unlock_irq(cmnd->device->host->host_lock);
-       return rc;
-}
-
-/*
- * Note: midlayer calls this function with the host_lock held
- */
-static int
-__lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
 {
        struct Scsi_Host *shost = cmnd->device->host;
        struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -991,7 +1102,10 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
        unsigned int midlayer_id = 0;
        struct lpfc_scsi_buf * lpfc_cmd;
 
-       lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+       lpfc_block_requests(phba);
+       spin_lock_irq(shost->host_lock);
+
+       lpfc_cmd = lpfc_get_scsi_buf(phba);
        if (lpfc_cmd == NULL)
                goto out;
 
@@ -1022,18 +1136,31 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
                lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data;
                ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba);
                if (ret != SUCCESS) {
-                       lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+                       lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                                "%d:0713 Bus Reset on target %d failed\n",
                                phba->brd_no, i);
                        err_count++;
                }
        }
 
+       if (err_count == 0)
+               ret = SUCCESS;
+
+       lpfc_release_scsi_buf(phba, lpfc_cmd);
+
+       /*
+        * All outstanding txcmplq I/Os should have been aborted by
+        * the targets.  Unfortunately, some targets do not abide by
+        * this forcing the driver to double check.
+        */
        cmnd->device->id = midlayer_id;
+       cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+                               0, 0, LPFC_CTX_HOST);
+       if (cnt)
+               lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+                                   0, 0, 0, LPFC_CTX_HOST);
        loopcnt = 0;
-       while((cnt = lpfc_sli_sum_iocb(phba,
-                               &phba->sli.ring[phba->sli.fcp_ring],
-                               0, 0, LPFC_CTX_HOST))) {
+       while(cnt) {
                spin_unlock_irq(phba->host->host_lock);
                schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
                spin_lock_irq(phba->host->host_lock);
@@ -1041,44 +1168,30 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
                if (++loopcnt
                    > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
                        break;
+
+               cnt = lpfc_sli_sum_iocb(phba,
+                                       &phba->sli.ring[phba->sli.fcp_ring],
+                                       0, 0, LPFC_CTX_HOST);
        }
 
        if (cnt) {
-               /* flush all outstanding commands on the host */
-               i = lpfc_sli_abort_iocb(phba,
-                               &phba->sli.ring[phba->sli.fcp_ring], 0, 0, 0,
-                               LPFC_CTX_HOST);
-
-               lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+               lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                   "%d:0715 Bus Reset I/O flush failure: cnt x%x left x%x\n",
                   phba->brd_no, cnt, i);
-       }
-
-       if (cnt == 0)
-               ret = SUCCESS;
-       else
                ret = FAILED;
+       }
 
-       lpfc_release_scsi_buf(phba, lpfc_cmd);
        lpfc_printf_log(phba,
                        KERN_ERR,
                        LOG_FCP,
                        "%d:0714 SCSI layer issued Bus Reset Data: x%x\n",
                        phba->brd_no, ret);
 out:
+       spin_unlock_irq(shost->host_lock);
+       lpfc_unblock_requests(phba);
        return ret;
 }
 
-static int
-lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
-{
-       int rc;
-       spin_lock_irq(cmnd->device->host->host_lock);
-       rc = __lpfc_reset_bus_handler(cmnd);
-       spin_unlock_irq(cmnd->device->host->host_lock);
-       return rc;
-}
-
 static int
 lpfc_slave_alloc(struct scsi_device *sdev)
 {
@@ -1127,10 +1240,10 @@ lpfc_slave_alloc(struct scsi_device *sdev)
                        break;
                }
 
-               spin_lock_irqsave(phba->host->host_lock, flags);
+               spin_lock_irqsave(&phba->scsi_buf_list_lock, flags);
                phba->total_scsi_bufs++;
                list_add_tail(&scsi_buf->list, &phba->lpfc_scsi_buf_list);
-               spin_unlock_irqrestore(phba->host->host_lock, flags);
+               spin_unlock_irqrestore(&phba->scsi_buf_list_lock, flags);
        }
        return 0;
 }
@@ -1154,6 +1267,12 @@ lpfc_slave_configure(struct scsi_device *sdev)
         */
        rport->dev_loss_tmo = phba->cfg_nodev_tmo + 5;
 
+       if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+               lpfc_sli_poll_fcp_ring(phba);
+               if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+                       lpfc_poll_rearm_timer(phba);
+       }
+
        return 0;
 }
 
index e2c08c5..7b785ad 100644 (file)
@@ -886,6 +886,182 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
        return rc;
 }
 
+static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba,
+                                       struct lpfc_sli_ring * pring)
+{
+       struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
+       /*
+        * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
+        * rsp ring <portRspMax>
+        */
+       lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                       "%d:0312 Ring %d handler: portRspPut %d "
+                       "is bigger then rsp ring %d\n",
+                       phba->brd_no, pring->ringno,
+                       le32_to_cpu(pgp->rspPutInx),
+                       pring->numRiocb);
+
+       phba->hba_state = LPFC_HBA_ERROR;
+
+       /*
+        * All error attention handlers are posted to
+        * worker thread
+        */
+       phba->work_ha |= HA_ERATT;
+       phba->work_hs = HS_FFER3;
+       if (phba->work_wait)
+               wake_up(phba->work_wait);
+
+       return;
+}
+
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
+{
+       struct lpfc_sli      * psli   = &phba->sli;
+       struct lpfc_sli_ring * pring = &psli->ring[LPFC_FCP_RING];
+       IOCB_t *irsp = NULL;
+       IOCB_t *entry = NULL;
+       struct lpfc_iocbq *cmdiocbq = NULL;
+       struct lpfc_iocbq rspiocbq;
+       struct lpfc_pgp *pgp;
+       uint32_t status;
+       uint32_t portRspPut, portRspMax;
+       int type;
+       uint32_t rsp_cmpl = 0;
+       void __iomem *to_slim;
+       uint32_t ha_copy;
+
+       pring->stats.iocb_event++;
+
+       /* The driver assumes SLI-2 mode */
+       pgp =  &phba->slim2p->mbx.us.s2.port[pring->ringno];
+
+       /*
+        * The next available response entry should never exceed the maximum
+        * entries.  If it does, treat it as an adapter hardware error.
+        */
+       portRspMax = pring->numRiocb;
+       portRspPut = le32_to_cpu(pgp->rspPutInx);
+       if (unlikely(portRspPut >= portRspMax)) {
+               lpfc_sli_rsp_pointers_error(phba, pring);
+               return;
+       }
+
+       rmb();
+       while (pring->rspidx != portRspPut) {
+
+               entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+               if (++pring->rspidx >= portRspMax)
+                       pring->rspidx = 0;
+
+               lpfc_sli_pcimem_bcopy((uint32_t *) entry,
+                                     (uint32_t *) &rspiocbq.iocb,
+                                     sizeof (IOCB_t));
+               irsp = &rspiocbq.iocb;
+               type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
+               pring->stats.iocb_rsp++;
+               rsp_cmpl++;
+
+               if (unlikely(irsp->ulpStatus)) {
+                       /* Rsp ring <ringno> error: IOCB */
+                       lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+                                       "%d:0326 Rsp Ring %d error: IOCB Data: "
+                                       "x%x x%x x%x x%x x%x x%x x%x x%x\n",
+                                       phba->brd_no, pring->ringno,
+                                       irsp->un.ulpWord[0],
+                                       irsp->un.ulpWord[1],
+                                       irsp->un.ulpWord[2],
+                                       irsp->un.ulpWord[3],
+                                       irsp->un.ulpWord[4],
+                                       irsp->un.ulpWord[5],
+                                       *(((uint32_t *) irsp) + 6),
+                                       *(((uint32_t *) irsp) + 7));
+               }
+
+               switch (type) {
+               case LPFC_ABORT_IOCB:
+               case LPFC_SOL_IOCB:
+                       /*
+                        * Idle exchange closed via ABTS from port.  No iocb
+                        * resources need to be recovered.
+                        */
+                       if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
+                               printk(KERN_INFO "%s: IOCB cmd 0x%x processed."
+                                      " Skipping completion\n", __FUNCTION__,
+                                      irsp->ulpCommand);
+                               break;
+                       }
+
+                       cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
+                                                        &rspiocbq);
+                       if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
+                               (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+                                                     &rspiocbq);
+                       }
+                       break;
+               default:
+                       if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
+                               char adaptermsg[LPFC_MAX_ADPTMSG];
+                               memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
+                               memcpy(&adaptermsg[0], (uint8_t *) irsp,
+                                      MAX_MSG_DATA);
+                               dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+                                        phba->brd_no, adaptermsg);
+                       } else {
+                               /* Unknown IOCB command */
+                               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                                               "%d:0321 Unknown IOCB command "
+                                               "Data: x%x, x%x x%x x%x x%x\n",
+                                               phba->brd_no, type,
+                                               irsp->ulpCommand,
+                                               irsp->ulpStatus,
+                                               irsp->ulpIoTag,
+                                               irsp->ulpContext);
+                       }
+                       break;
+               }
+
+               /*
+                * The response IOCB has been processed.  Update the ring
+                * pointer in SLIM.  If the port response put pointer has not
+                * been updated, sync the pgp->rspPutInx and fetch the new port
+                * response put pointer.
+                */
+               to_slim = phba->MBslimaddr +
+                       (SLIMOFF + (pring->ringno * 2) + 1) * 4;
+               writeb(pring->rspidx, to_slim);
+
+               if (pring->rspidx == portRspPut)
+                       portRspPut = le32_to_cpu(pgp->rspPutInx);
+       }
+
+       ha_copy = readl(phba->HAregaddr);
+       ha_copy >>= (LPFC_FCP_RING * 4);
+
+       if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) {
+               pring->stats.iocb_rsp_full++;
+               status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4));
+               writel(status, phba->CAregaddr);
+               readl(phba->CAregaddr);
+       }
+       if ((ha_copy & HA_R0CE_RSP) &&
+           (pring->flag & LPFC_CALL_RING_AVAILABLE)) {
+               pring->flag &= ~LPFC_CALL_RING_AVAILABLE;
+               pring->stats.iocb_cmd_empty++;
+
+               /* Force update of the local copy of cmdGetInx */
+               pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
+               lpfc_sli_resume_iocb(phba, pring);
+
+               if ((pring->lpfc_sli_cmd_available))
+                       (pring->lpfc_sli_cmd_available) (phba, pring);
+
+       }
+
+       return;
+}
+
 /*
  * This routine presumes LPFC_FCP_RING handling and doesn't bother
  * to check it explicitly.
@@ -917,24 +1093,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
        portRspMax = pring->numRiocb;
        portRspPut = le32_to_cpu(pgp->rspPutInx);
        if (unlikely(portRspPut >= portRspMax)) {
-               /*
-                * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
-                * rsp ring <portRspMax>
-                */
-               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-                               "%d:0312 Ring %d handler: portRspPut %d "
-                               "is bigger then rsp ring %d\n",
-                               phba->brd_no, pring->ringno, portRspPut,
-                               portRspMax);
-
-               phba->hba_state = LPFC_HBA_ERROR;
-
-               /* All error attention handlers are posted to worker thread */
-               phba->work_ha |= HA_ERATT;
-               phba->work_hs = HS_FFER3;
-               if (phba->work_wait)
-                       wake_up(phba->work_wait);
-
+               lpfc_sli_rsp_pointers_error(phba, pring);
                spin_unlock_irqrestore(phba->host->host_lock, iflag);
                return 1;
        }
@@ -947,6 +1106,10 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                 * network byte order and pci byte orders are different.
                 */
                entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+               if (++pring->rspidx >= portRspMax)
+                       pring->rspidx = 0;
+
                lpfc_sli_pcimem_bcopy((uint32_t *) entry,
                                      (uint32_t *) &rspiocbq.iocb,
                                      sizeof (IOCB_t));
@@ -1020,9 +1183,6 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                 * been updated, sync the pgp->rspPutInx and fetch the new port
                 * response put pointer.
                 */
-               if (++pring->rspidx >= portRspMax)
-                       pring->rspidx = 0;
-
                to_slim = phba->MBslimaddr +
                        (SLIMOFF + (pring->ringno * 2) + 1) * 4;
                writel(pring->rspidx, to_slim);
@@ -2615,6 +2775,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
        DECLARE_WAIT_QUEUE_HEAD(done_q);
        long timeleft, timeout_req = 0;
        int retval = IOCB_SUCCESS;
+       uint32_t creg_val;
 
        /*
         * If the caller has provided a response iocbq buffer, then context2
@@ -2630,6 +2791,13 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
        piocb->context_un.wait_queue = &done_q;
        piocb->iocb_flag &= ~LPFC_IO_WAKE;
 
+       if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+               creg_val = readl(phba->HCregaddr);
+               creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+               writel(creg_val, phba->HCregaddr);
+               readl(phba->HCregaddr); /* flush */
+       }
+
        retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
        if (retval == IOCB_SUCCESS) {
                timeout_req = timeout * HZ;
@@ -2663,6 +2831,13 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
                retval = IOCB_ERROR;
        }
 
+       if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+               creg_val = readl(phba->HCregaddr);
+               creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+               writel(creg_val, phba->HCregaddr);
+               readl(phba->HCregaddr); /* flush */
+       }
+
        if (prspiocbq)
                piocb->context2 = NULL;
 
index 4f0466f..fa681a9 100644 (file)
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.1.0"
+#define LPFC_DRIVER_VERSION "8.1.1"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
index 578143e..4a6feb1 100644 (file)
@@ -2,7 +2,7 @@
  *
  *                     Linux MegaRAID device driver
  *
- * Copyright Â© 2002  LSI Logic Corporation.
+ * Copyright (c) 2002  LSI Logic Corporation.
  *
  *        This program is free software; you can redistribute it and/or
  *        modify it under the terms of the GNU General Public License
@@ -17,7 +17,8 @@
  * Copyright (c) 2003  Christoph Hellwig  <hch@lst.de>
  *       - new-style, hotplug-aware pci probing and scsi registration
  *
- * Version : v2.00.3 (Feb 19, 2003) - Atul Mukker <Atul.Mukker@lsil.com>
+ * Version : v2.00.4 Mon Nov 14 14:02:43 EST 2005 - Seokmann Ju
+ *                                             <Seokmann.Ju@lsil.com>
  *
  * Description: Linux device driver for LSI Logic MegaRAID controller
  *
 
 #include "megaraid.h"
 
-#define MEGARAID_MODULE_VERSION "2.00.3"
+#define MEGARAID_MODULE_VERSION "2.00.4"
 
-MODULE_AUTHOR ("LSI Logic Corporation");
-MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
+MODULE_AUTHOR ("sju@lsil.com");
+MODULE_DESCRIPTION ("LSI Logic MegaRAID legacy driver");
 MODULE_LICENSE ("GPL");
 MODULE_VERSION(MEGARAID_MODULE_VERSION);
 
@@ -4553,7 +4554,7 @@ mega_internal_done(Scsi_Cmnd *scmd)
 static struct scsi_host_template megaraid_template = {
        .module                         = THIS_MODULE,
        .name                           = "MegaRAID",
-       .proc_name                      = "megaraid",
+       .proc_name                      = "megaraid_legacy",
        .info                           = megaraid_info,
        .queuecommand                   = megaraid_queue,       
        .bios_param                     = megaraid_biosparam,
@@ -5037,22 +5038,12 @@ megaraid_shutdown(struct pci_dev *pdev)
 }
 
 static struct pci_device_id megaraid_pci_tbl[] = {
-       {PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
-       {PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
        {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0,}
 };
 MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
@@ -5095,7 +5086,7 @@ static int __init megaraid_init(void)
         * First argument (major) to register_chrdev implies a dynamic
         * major number allocation.
         */
-       major = register_chrdev(0, "megadev", &megadev_fops);
+       major = register_chrdev(0, "megadev_legacy", &megadev_fops);
        if (!major) {
                printk(KERN_WARNING
                                "megaraid: failed to register char device\n");
@@ -5109,7 +5100,7 @@ static void __exit megaraid_exit(void)
        /*
         * Unregister the character device interface to the driver.
         */
-       unregister_chrdev(major, "megadev");
+       unregister_chrdev(major, "megadev_legacy");
 
        pci_unregister_driver(&megaraid_pci_driver);
 
index 7363e12..17419e3 100644 (file)
@@ -64,7 +64,6 @@ config MEGARAID_MAILBOX
        To compile this driver as a module, choose M here: the
        module will be called megaraid_mbox
 
-if MEGARAID_NEWGEN=n
 config MEGARAID_LEGACY
        tristate "LSI Logic Legacy MegaRAID Driver"
        depends on PCI && SCSI
@@ -75,7 +74,6 @@ config MEGARAID_LEGACY
 
        To compile this driver as a module, choose M here: the
        module will be called megaraid
-endif
 
 config MEGARAID_SAS
        tristate "LSI Logic MegaRAID SAS RAID Module"
index 4b5d420..d18a4bc 100644 (file)
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_mbox.c
- * Version     : v2.20.4.6 (Mar 07 2005)
+ * Version     : v2.20.4.7 (Nov 14 2005)
  *
  * Authors:
  *     Atul Mukker             <Atul.Mukker@lsil.com>
  *     Sreenivas Bagalkote     <Sreenivas.Bagalkote@lsil.com>
  *     Manoj Jose              <Manoj.Jose@lsil.com>
+ *     Seokmann Ju             <Seokmann.Ju@lsil.com>
  *
  * List of supported controllers
  *
@@ -136,7 +137,7 @@ static int wait_till_fw_empty(adapter_t *);
 
 
 
-MODULE_AUTHOR("LSI Logic Corporation");
+MODULE_AUTHOR("sju@lsil.com");
 MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MEGARAID_VERSION);
@@ -278,68 +279,14 @@ static struct pci_device_id pci_id_table_g[] =  {
        {
                PCI_VENDOR_ID_AMI,
                PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_VENDOR_ID_DELL,
-               PCI_SUBSYS_ID_PERC3_QC,
-       },
-       {
-               PCI_VENDOR_ID_AMI,
-               PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_VENDOR_ID_DELL,
-               PCI_SUBSYS_ID_PERC3_DC,
-       },
-       {
-               PCI_VENDOR_ID_AMI,
-               PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_VENDOR_ID_DELL,
-               PCI_SUBSYS_ID_PERC3_SC,
-       },
-       {
-               PCI_VENDOR_ID_AMI,
-               PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_VENDOR_ID_AMI,
-               PCI_SUBSYS_ID_PERC3_SC,
-       },
-       {
-               PCI_VENDOR_ID_AMI,
-               PCI_DEVICE_ID_AMI_MEGARAID3,
-               PCI_VENDOR_ID_AMI,
-               PCI_SUBSYS_ID_PERC3_DC,
-       },
-       {
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_MEGARAID_SCSI_320_0,
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_SUBSYS_ID_MEGARAID_SCSI_320_0,
-       },
-       {
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_MEGARAID_SCSI_320_1,
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_SUBSYS_ID_MEGARAID_SCSI_320_1,
-       },
-       {
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_MEGARAID_SCSI_320_2,
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_SUBSYS_ID_MEGARAID_SCSI_320_2,
-       },
-       {
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_MEGARAID_I4_133_RAID,
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_SUBSYS_ID_MEGARAID_I4_133_RAID,
-       },
-       {
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_MEGARAID_SATA_150_4,
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_SUBSYS_ID_MEGARAID_SATA_150_4,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
        },
        {
                PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_MEGARAID_SATA_150_6,
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_SUBSYS_ID_MEGARAID_SATA_150_6,
+               PCI_DEVICE_ID_AMI_MEGARAID3,
+               PCI_ANY_ID,
+               PCI_ANY_ID,
        },
        {
                PCI_VENDOR_ID_LSI_LOGIC,
@@ -347,18 +294,6 @@ static struct pci_device_id pci_id_table_g[] =  {
                PCI_ANY_ID,
                PCI_ANY_ID,
        },
-       {
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_INTEL_RAID_SRCS16,
-               PCI_VENDOR_ID_INTEL,
-               PCI_SUBSYS_ID_INTEL_RAID_SRCS16,
-       },
-       {
-               PCI_VENDOR_ID_LSI_LOGIC,
-               PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
-               PCI_VENDOR_ID_INTEL,
-               PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
-       },
        {0}     /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, pci_id_table_g);
@@ -2985,6 +2920,7 @@ mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[])
 
        for (i = 0; i < 0xFFFFF; i++) {
                if (mbox->numstatus != 0xFF) break;
+               rmb();
        }
 
        if (i == 0xFFFFF) {
index 644b91b..882fb1a 100644 (file)
@@ -21,8 +21,8 @@
 #include "megaraid_ioctl.h"
 
 
-#define MEGARAID_VERSION       "2.20.4.6"
-#define MEGARAID_EXT_VERSION   "(Release Date: Mon Mar 07 12:27:22 EST 2005)"
+#define MEGARAID_VERSION       "2.20.4.7"
+#define MEGARAID_EXT_VERSION   "(Release Date: Mon Nov 14 12:27:22 EST 2005)"
 
 
 /*
index 2434709..3235070 100644 (file)
 #define NAME53C                        "ncr53c"
 #define NAME53C8XX             "ncr53c8xx"
 
-#include "sym53c8xx_comm.h"
+
+/*==========================================================
+**
+**     Debugging tags
+**
+**==========================================================
+*/
+
+#define DEBUG_ALLOC    (0x0001)
+#define DEBUG_PHASE    (0x0002)
+#define DEBUG_QUEUE    (0x0008)
+#define DEBUG_RESULT   (0x0010)
+#define DEBUG_POINTER  (0x0020)
+#define DEBUG_SCRIPT   (0x0040)
+#define DEBUG_TINY     (0x0080)
+#define DEBUG_TIMING   (0x0100)
+#define DEBUG_NEGO     (0x0200)
+#define DEBUG_TAGS     (0x0400)
+#define DEBUG_SCATTER  (0x0800)
+#define DEBUG_IC        (0x1000)
+
+/*
+**    Enable/Disable debug messages.
+**    Can be changed at runtime too.
+*/
+
+#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
+static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
+       #define DEBUG_FLAGS ncr_debug
+#else
+       #define DEBUG_FLAGS     SCSI_NCR_DEBUG_FLAGS
+#endif
+
+static inline struct list_head *ncr_list_pop(struct list_head *head)
+{
+       if (!list_empty(head)) {
+               struct list_head *elem = head->next;
+
+               list_del(elem);
+               return elem;
+       }
+
+       return NULL;
+}
+
+/*==========================================================
+**
+**     Simple power of two buddy-like allocator.
+**
+**     This simple code is not intended to be fast, but to 
+**     provide power of 2 aligned memory allocations.
+**     Since the SCRIPTS processor only supplies 8 bit 
+**     arithmetic, this allocator allows simple and fast 
+**     address calculations  from the SCRIPTS code.
+**     In addition, cache line alignment is guaranteed for 
+**     power of 2 cache line size.
+**     Enhanced in linux-2.3.44 to provide a memory pool 
+**     per pcidev to support dynamic dma mapping. (I would 
+**     have preferred a real bus astraction, btw).
+**
+**==========================================================
+*/
+
+#define MEMO_SHIFT     4       /* 16 bytes minimum memory chunk */
+#if PAGE_SIZE >= 8192
+#define MEMO_PAGE_ORDER        0       /* 1 PAGE  maximum */
+#else
+#define MEMO_PAGE_ORDER        1       /* 2 PAGES maximum */
+#endif
+#define MEMO_FREE_UNUSED       /* Free unused pages immediately */
+#define MEMO_WARN      1
+#define MEMO_GFP_FLAGS GFP_ATOMIC
+#define MEMO_CLUSTER_SHIFT     (PAGE_SHIFT+MEMO_PAGE_ORDER)
+#define MEMO_CLUSTER_SIZE      (1UL << MEMO_CLUSTER_SHIFT)
+#define MEMO_CLUSTER_MASK      (MEMO_CLUSTER_SIZE-1)
+
+typedef u_long m_addr_t;       /* Enough bits to bit-hack addresses */
+typedef struct device *m_bush_t;       /* Something that addresses DMAable */
+
+typedef struct m_link {                /* Link between free memory chunks */
+       struct m_link *next;
+} m_link_s;
+
+typedef struct m_vtob {                /* Virtual to Bus address translation */
+       struct m_vtob *next;
+       m_addr_t vaddr;
+       m_addr_t baddr;
+} m_vtob_s;
+#define VTOB_HASH_SHIFT                5
+#define VTOB_HASH_SIZE         (1UL << VTOB_HASH_SHIFT)
+#define VTOB_HASH_MASK         (VTOB_HASH_SIZE-1)
+#define VTOB_HASH_CODE(m)      \
+       ((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
+
+typedef struct m_pool {                /* Memory pool of a given kind */
+       m_bush_t bush;
+       m_addr_t (*getp)(struct m_pool *);
+       void (*freep)(struct m_pool *, m_addr_t);
+       int nump;
+       m_vtob_s *(vtob[VTOB_HASH_SIZE]);
+       struct m_pool *next;
+       struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
+} m_pool_s;
+
+static void *___m_alloc(m_pool_s *mp, int size)
+{
+       int i = 0;
+       int s = (1 << MEMO_SHIFT);
+       int j;
+       m_addr_t a;
+       m_link_s *h = mp->h;
+
+       if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+               return NULL;
+
+       while (size > s) {
+               s <<= 1;
+               ++i;
+       }
+
+       j = i;
+       while (!h[j].next) {
+               if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+                       h[j].next = (m_link_s *)mp->getp(mp);
+                       if (h[j].next)
+                               h[j].next->next = NULL;
+                       break;
+               }
+               ++j;
+               s <<= 1;
+       }
+       a = (m_addr_t) h[j].next;
+       if (a) {
+               h[j].next = h[j].next->next;
+               while (j > i) {
+                       j -= 1;
+                       s >>= 1;
+                       h[j].next = (m_link_s *) (a+s);
+                       h[j].next->next = NULL;
+               }
+       }
+#ifdef DEBUG
+       printk("___m_alloc(%d) = %p\n", size, (void *) a);
+#endif
+       return (void *) a;
+}
+
+static void ___m_free(m_pool_s *mp, void *ptr, int size)
+{
+       int i = 0;
+       int s = (1 << MEMO_SHIFT);
+       m_link_s *q;
+       m_addr_t a, b;
+       m_link_s *h = mp->h;
+
+#ifdef DEBUG
+       printk("___m_free(%p, %d)\n", ptr, size);
+#endif
+
+       if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+               return;
+
+       while (size > s) {
+               s <<= 1;
+               ++i;
+       }
+
+       a = (m_addr_t) ptr;
+
+       while (1) {
+#ifdef MEMO_FREE_UNUSED
+               if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+                       mp->freep(mp, a);
+                       break;
+               }
+#endif
+               b = a ^ s;
+               q = &h[i];
+               while (q->next && q->next != (m_link_s *) b) {
+                       q = q->next;
+               }
+               if (!q->next) {
+                       ((m_link_s *) a)->next = h[i].next;
+                       h[i].next = (m_link_s *) a;
+                       break;
+               }
+               q->next = q->next->next;
+               a = a & b;
+               s <<= 1;
+               ++i;
+       }
+}
+
+static DEFINE_SPINLOCK(ncr53c8xx_lock);
+
+static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
+{
+       void *p;
+
+       p = ___m_alloc(mp, size);
+
+       if (DEBUG_FLAGS & DEBUG_ALLOC)
+               printk ("new %-10s[%4d] @%p.\n", name, size, p);
+
+       if (p)
+               memset(p, 0, size);
+       else if (uflags & MEMO_WARN)
+               printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
+
+       return p;
+}
+
+#define __m_calloc(mp, s, n)   __m_calloc2(mp, s, n, MEMO_WARN)
+
+static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
+{
+       if (DEBUG_FLAGS & DEBUG_ALLOC)
+               printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
+
+       ___m_free(mp, ptr, size);
+
+}
+
+/*
+ * With pci bus iommu support, we use a default pool of unmapped memory 
+ * for memory we donnot need to DMA from/to and one pool per pcidev for 
+ * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
+ */
+
+static m_addr_t ___mp0_getp(m_pool_s *mp)
+{
+       m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
+       if (m)
+               ++mp->nump;
+       return m;
+}
+
+static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
+{
+       free_pages(m, MEMO_PAGE_ORDER);
+       --mp->nump;
+}
+
+static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
+
+/*
+ * DMAable pools.
+ */
+
+/*
+ * With pci bus iommu support, we maintain one pool per pcidev and a 
+ * hashed reverse table for virtual to bus physical address translations.
+ */
+static m_addr_t ___dma_getp(m_pool_s *mp)
+{
+       m_addr_t vp;
+       m_vtob_s *vbp;
+
+       vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
+       if (vbp) {
+               dma_addr_t daddr;
+               vp = (m_addr_t) dma_alloc_coherent(mp->bush,
+                                               PAGE_SIZE<<MEMO_PAGE_ORDER,
+                                               &daddr, GFP_ATOMIC);
+               if (vp) {
+                       int hc = VTOB_HASH_CODE(vp);
+                       vbp->vaddr = vp;
+                       vbp->baddr = daddr;
+                       vbp->next = mp->vtob[hc];
+                       mp->vtob[hc] = vbp;
+                       ++mp->nump;
+                       return vp;
+               }
+       }
+       if (vbp)
+               __m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+       return 0;
+}
+
+static void ___dma_freep(m_pool_s *mp, m_addr_t m)
+{
+       m_vtob_s **vbpp, *vbp;
+       int hc = VTOB_HASH_CODE(m);
+
+       vbpp = &mp->vtob[hc];
+       while (*vbpp && (*vbpp)->vaddr != m)
+               vbpp = &(*vbpp)->next;
+       if (*vbpp) {
+               vbp = *vbpp;
+               *vbpp = (*vbpp)->next;
+               dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
+                                 (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
+               __m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+               --mp->nump;
+       }
+}
+
+static inline m_pool_s *___get_dma_pool(m_bush_t bush)
+{
+       m_pool_s *mp;
+       for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
+       return mp;
+}
+
+static m_pool_s *___cre_dma_pool(m_bush_t bush)
+{
+       m_pool_s *mp;
+       mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
+       if (mp) {
+               memset(mp, 0, sizeof(*mp));
+               mp->bush = bush;
+               mp->getp = ___dma_getp;
+               mp->freep = ___dma_freep;
+               mp->next = mp0.next;
+               mp0.next = mp;
+       }
+       return mp;
+}
+
+static void ___del_dma_pool(m_pool_s *p)
+{
+       struct m_pool **pp = &mp0.next;
+
+       while (*pp && *pp != p)
+               pp = &(*pp)->next;
+       if (*pp) {
+               *pp = (*pp)->next;
+               __m_free(&mp0, p, sizeof(*p), "MPOOL");
+       }
+}
+
+static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
+{
+       u_long flags;
+       struct m_pool *mp;
+       void *m = NULL;
+
+       spin_lock_irqsave(&ncr53c8xx_lock, flags);
+       mp = ___get_dma_pool(bush);
+       if (!mp)
+               mp = ___cre_dma_pool(bush);
+       if (mp)
+               m = __m_calloc(mp, size, name);
+       if (mp && !mp->nump)
+               ___del_dma_pool(mp);
+       spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+
+       return m;
+}
+
+static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
+{
+       u_long flags;
+       struct m_pool *mp;
+
+       spin_lock_irqsave(&ncr53c8xx_lock, flags);
+       mp = ___get_dma_pool(bush);
+       if (mp)
+               __m_free(mp, m, size, name);
+       if (mp && !mp->nump)
+               ___del_dma_pool(mp);
+       spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+}
+
+static m_addr_t __vtobus(m_bush_t bush, void *m)
+{
+       u_long flags;
+       m_pool_s *mp;
+       int hc = VTOB_HASH_CODE(m);
+       m_vtob_s *vp = NULL;
+       m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
+
+       spin_lock_irqsave(&ncr53c8xx_lock, flags);
+       mp = ___get_dma_pool(bush);
+       if (mp) {
+               vp = mp->vtob[hc];
+               while (vp && (m_addr_t) vp->vaddr != a)
+                       vp = vp->next;
+       }
+       spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+       return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
+}
+
+#define _m_calloc_dma(np, s, n)                __m_calloc_dma(np->dev, s, n)
+#define _m_free_dma(np, p, s, n)       __m_free_dma(np->dev, p, s, n)
+#define m_calloc_dma(s, n)             _m_calloc_dma(np, s, n)
+#define m_free_dma(p, s, n)            _m_free_dma(np, p, s, n)
+#define _vtobus(np, p)                 __vtobus(np->dev, p)
+#define vtobus(p)                      _vtobus(np, p)
+
+/*
+ *  Deal with DMA mapping/unmapping.
+ */
+
+/* To keep track of the dma mapping (sg/single) that has been set */
+#define __data_mapped  SCp.phase
+#define __data_mapping SCp.have_data_in
+
+static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+       switch(cmd->__data_mapped) {
+       case 2:
+               dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
+                               cmd->sc_data_direction);
+               break;
+       case 1:
+               dma_unmap_single(dev, cmd->__data_mapping,
+                                cmd->request_bufflen,
+                                cmd->sc_data_direction);
+               break;
+       }
+       cmd->__data_mapped = 0;
+}
+
+static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+       dma_addr_t mapping;
+
+       if (cmd->request_bufflen == 0)
+               return 0;
+
+       mapping = dma_map_single(dev, cmd->request_buffer,
+                                cmd->request_bufflen,
+                                cmd->sc_data_direction);
+       cmd->__data_mapped = 1;
+       cmd->__data_mapping = mapping;
+
+       return mapping;
+}
+
+static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+       int use_sg;
+
+       if (cmd->use_sg == 0)
+               return 0;
+
+       use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
+                       cmd->sc_data_direction);
+       cmd->__data_mapped = 2;
+       cmd->__data_mapping = use_sg;
+
+       return use_sg;
+}
+
+#define unmap_scsi_data(np, cmd)       __unmap_scsi_data(np->dev, cmd)
+#define map_scsi_single_data(np, cmd)  __map_scsi_single_data(np->dev, cmd)
+#define map_scsi_sg_data(np, cmd)      __map_scsi_sg_data(np->dev, cmd)
+
+/*==========================================================
+**
+**     Driver setup.
+**
+**     This structure is initialized from linux config 
+**     options. It can be overridden at boot-up by the boot 
+**     command line.
+**
+**==========================================================
+*/
+static struct ncr_driver_setup
+       driver_setup                    = SCSI_NCR_DRIVER_SETUP;
+
+#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+static struct ncr_driver_setup
+       driver_safe_setup __initdata    = SCSI_NCR_DRIVER_SAFE_SETUP;
+#endif
+
+#define initverbose (driver_setup.verbose)
+#define bootverbose (np->verbose)
+
+
+/*===================================================================
+**
+**     Driver setup from the boot command line
+**
+**===================================================================
+*/
+
+#ifdef MODULE
+#define        ARG_SEP ' '
+#else
+#define        ARG_SEP ','
+#endif
+
+#define OPT_TAGS               1
+#define OPT_MASTER_PARITY      2
+#define OPT_SCSI_PARITY                3
+#define OPT_DISCONNECTION      4
+#define OPT_SPECIAL_FEATURES   5
+#define OPT_UNUSED_1           6
+#define OPT_FORCE_SYNC_NEGO    7
+#define OPT_REVERSE_PROBE      8
+#define OPT_DEFAULT_SYNC       9
+#define OPT_VERBOSE            10
+#define OPT_DEBUG              11
+#define OPT_BURST_MAX          12
+#define OPT_LED_PIN            13
+#define OPT_MAX_WIDE           14
+#define OPT_SETTLE_DELAY       15
+#define OPT_DIFF_SUPPORT       16
+#define OPT_IRQM               17
+#define OPT_PCI_FIX_UP         18
+#define OPT_BUS_CHECK          19
+#define OPT_OPTIMIZE           20
+#define OPT_RECOVERY           21
+#define OPT_SAFE_SETUP         22
+#define OPT_USE_NVRAM          23
+#define OPT_EXCLUDE            24
+#define OPT_HOST_ID            25
+
+#ifdef SCSI_NCR_IARB_SUPPORT
+#define OPT_IARB               26
+#endif
+
+static char setup_token[] __initdata = 
+       "tags:"   "mpar:"
+       "spar:"   "disc:"
+       "specf:"  "ultra:"
+       "fsn:"    "revprob:"
+       "sync:"   "verb:"
+       "debug:"  "burst:"
+       "led:"    "wide:"
+       "settle:" "diff:"
+       "irqm:"   "pcifix:"
+       "buschk:" "optim:"
+       "recovery:"
+       "safe:"   "nvram:"
+       "excl:"   "hostid:"
+#ifdef SCSI_NCR_IARB_SUPPORT
+       "iarb:"
+#endif
+       ;       /* DONNOT REMOVE THIS ';' */
+
+#ifdef MODULE
+#define        ARG_SEP ' '
+#else
+#define        ARG_SEP ','
+#endif
+
+static int __init get_setup_token(char *p)
+{
+       char *cur = setup_token;
+       char *pc;
+       int i = 0;
+
+       while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+               ++pc;
+               ++i;
+               if (!strncmp(p, cur, pc - cur))
+                       return i;
+               cur = pc;
+       }
+       return 0;
+}
+
+
+static int __init sym53c8xx__setup(char *str)
+{
+#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+       char *cur = str;
+       char *pc, *pv;
+       int i, val, c;
+       int xi = 0;
+
+       while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+               char *pe;
+
+               val = 0;
+               pv = pc;
+               c = *++pv;
+
+               if      (c == 'n')
+                       val = 0;
+               else if (c == 'y')
+                       val = 1;
+               else
+                       val = (int) simple_strtoul(pv, &pe, 0);
+
+               switch (get_setup_token(cur)) {
+               case OPT_TAGS:
+                       driver_setup.default_tags = val;
+                       if (pe && *pe == '/') {
+                               i = 0;
+                               while (*pe && *pe != ARG_SEP && 
+                                       i < sizeof(driver_setup.tag_ctrl)-1) {
+                                       driver_setup.tag_ctrl[i++] = *pe++;
+                               }
+                               driver_setup.tag_ctrl[i] = '\0';
+                       }
+                       break;
+               case OPT_MASTER_PARITY:
+                       driver_setup.master_parity = val;
+                       break;
+               case OPT_SCSI_PARITY:
+                       driver_setup.scsi_parity = val;
+                       break;
+               case OPT_DISCONNECTION:
+                       driver_setup.disconnection = val;
+                       break;
+               case OPT_SPECIAL_FEATURES:
+                       driver_setup.special_features = val;
+                       break;
+               case OPT_FORCE_SYNC_NEGO:
+                       driver_setup.force_sync_nego = val;
+                       break;
+               case OPT_REVERSE_PROBE:
+                       driver_setup.reverse_probe = val;
+                       break;
+               case OPT_DEFAULT_SYNC:
+                       driver_setup.default_sync = val;
+                       break;
+               case OPT_VERBOSE:
+                       driver_setup.verbose = val;
+                       break;
+               case OPT_DEBUG:
+                       driver_setup.debug = val;
+                       break;
+               case OPT_BURST_MAX:
+                       driver_setup.burst_max = val;
+                       break;
+               case OPT_LED_PIN:
+                       driver_setup.led_pin = val;
+                       break;
+               case OPT_MAX_WIDE:
+                       driver_setup.max_wide = val? 1:0;
+                       break;
+               case OPT_SETTLE_DELAY:
+                       driver_setup.settle_delay = val;
+                       break;
+               case OPT_DIFF_SUPPORT:
+                       driver_setup.diff_support = val;
+                       break;
+               case OPT_IRQM:
+                       driver_setup.irqm = val;
+                       break;
+               case OPT_PCI_FIX_UP:
+                       driver_setup.pci_fix_up = val;
+                       break;
+               case OPT_BUS_CHECK:
+                       driver_setup.bus_check = val;
+                       break;
+               case OPT_OPTIMIZE:
+                       driver_setup.optimize = val;
+                       break;
+               case OPT_RECOVERY:
+                       driver_setup.recovery = val;
+                       break;
+               case OPT_USE_NVRAM:
+                       driver_setup.use_nvram = val;
+                       break;
+               case OPT_SAFE_SETUP:
+                       memcpy(&driver_setup, &driver_safe_setup,
+                               sizeof(driver_setup));
+                       break;
+               case OPT_EXCLUDE:
+                       if (xi < SCSI_NCR_MAX_EXCLUDES)
+                               driver_setup.excludes[xi++] = val;
+                       break;
+               case OPT_HOST_ID:
+                       driver_setup.host_id = val;
+                       break;
+#ifdef SCSI_NCR_IARB_SUPPORT
+               case OPT_IARB:
+                       driver_setup.iarb = val;
+                       break;
+#endif
+               default:
+                       printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
+                       break;
+               }
+
+               if ((cur = strchr(cur, ARG_SEP)) != NULL)
+                       ++cur;
+       }
+#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
+       return 1;
+}
+
+/*===================================================================
+**
+**     Get device queue depth from boot command line.
+**
+**===================================================================
+*/
+#define DEF_DEPTH      (driver_setup.default_tags)
+#define ALL_TARGETS    -2
+#define NO_TARGET      -1
+#define ALL_LUNS       -2
+#define NO_LUN         -1
+
+static int device_queue_depth(int unit, int target, int lun)
+{
+       int c, h, t, u, v;
+       char *p = driver_setup.tag_ctrl;
+       char *ep;
+
+       h = -1;
+       t = NO_TARGET;
+       u = NO_LUN;
+       while ((c = *p++) != 0) {
+               v = simple_strtoul(p, &ep, 0);
+               switch(c) {
+               case '/':
+                       ++h;
+                       t = ALL_TARGETS;
+                       u = ALL_LUNS;
+                       break;
+               case 't':
+                       if (t != target)
+                               t = (target == v) ? v : NO_TARGET;
+                       u = ALL_LUNS;
+                       break;
+               case 'u':
+                       if (u != lun)
+                               u = (lun == v) ? v : NO_LUN;
+                       break;
+               case 'q':
+                       if (h == unit &&
+                               (t == ALL_TARGETS || t == target) &&
+                               (u == ALL_LUNS    || u == lun))
+                               return v;
+                       break;
+               case '-':
+                       t = ALL_TARGETS;
+                       u = ALL_LUNS;
+                       break;
+               default:
+                       break;
+               }
+               p = ep;
+       }
+       return DEF_DEPTH;
+}
 
 
 /*==========================================================
@@ -2971,21 +3703,10 @@ struct host_data {
 
 static void ncr_print_msg(struct ccb *cp, char *label, u_char *msg)
 {
-       int i;
        PRINT_ADDR(cp->cmd, "%s: ", label);
 
-       printk ("%x",*msg);
-       if (*msg == M_EXTENDED) {
-               for (i = 1; i < 8; i++) {
-                       if (i - 1 > msg[1])
-                               break;
-                       printk ("-%x",msg[i]);
-               }
-       } else if ((*msg & 0xf0) == 0x20) {
-               printk ("-%x",msg[1]);
-       }
-
-       printk(".\n");
+       spi_print_msg(msg);
+       printk("\n");
 }
 
 /*==========================================================
index 05c7b83..6a7bef2 100644 (file)
@@ -2,6 +2,7 @@
 **  Device driver for the PCI-SCSI NCR538XX controller family.
 **
 **  Copyright (C) 1994  Wolfgang Stanglmeier
+**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.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
 **  And has been ported to NetBSD by
 **          Charles M. Hannum           <mycroft@gnu.ai.mit.edu>
 **
+**  NVRAM detection and reading.
+**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
+**
+**  Added support for MIPS big endian systems.
+**    Carsten Langgaard, carstenl@mips.com
+**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+**
+**  Added support for HP PARISC big endian systems.
+**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+**
 *******************************************************************************
 */
 
 #ifndef NCR53C8XX_H
 #define NCR53C8XX_H
 
+#include <linux/config.h>
 #include <scsi/scsi_host.h>
 
-#include "sym53c8xx_defs.h"
+/*
+**     If you want a driver as small as possible, do not define the 
+**     following options.
+*/
+#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+#define SCSI_NCR_DEBUG_INFO_SUPPORT
+
+/*
+**     To disable integrity checking, do not define the 
+**     following option.
+*/
+#ifdef CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
+#      define SCSI_NCR_ENABLE_INTEGRITY_CHECK
+#endif
+
+/* ---------------------------------------------------------------------
+** Take into account kernel configured parameters.
+** Most of these options can be overridden at startup by a command line.
+** ---------------------------------------------------------------------
+*/
+
+/*
+ * For Ultra2 and Ultra3 SCSI support option, use special features. 
+ *
+ * Value (default) means:
+ *     bit 0 : all features enabled, except:
+ *             bit 1 : PCI Write And Invalidate.
+ *             bit 2 : Data Phase Mismatch handling from SCRIPTS.
+ *
+ * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
+ * enabled by the driver.
+ */
+#define        SCSI_NCR_SETUP_SPECIAL_FEATURES         (3)
+
+#define SCSI_NCR_MAX_SYNC                      (80)
+
+/*
+ * Allow tags from 2 to 256, default 8
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+#if    CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
+#define SCSI_NCR_MAX_TAGS      (2)
+#elif  CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
+#define SCSI_NCR_MAX_TAGS      (256)
+#else
+#define        SCSI_NCR_MAX_TAGS       CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+#endif
+#else
+#define SCSI_NCR_MAX_TAGS      (8)
+#endif
+
+/*
+ * Allow tagged command queuing support if configured with default number 
+ * of tags set to max (see above).
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+#define        SCSI_NCR_SETUP_DEFAULT_TAGS     CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+#elif  defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
+#define        SCSI_NCR_SETUP_DEFAULT_TAGS     SCSI_NCR_MAX_TAGS
+#else
+#define        SCSI_NCR_SETUP_DEFAULT_TAGS     (0)
+#endif
+
+/*
+ * Immediate arbitration
+ */
+#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
+#define SCSI_NCR_IARB_SUPPORT
+#endif
+
+/*
+ * Sync transfer frequency at startup.
+ * Allow from 5Mhz to 80Mhz default 20 Mhz.
+ */
+#ifndef        CONFIG_SCSI_NCR53C8XX_SYNC
+#define        CONFIG_SCSI_NCR53C8XX_SYNC      (20)
+#elif  CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
+#undef CONFIG_SCSI_NCR53C8XX_SYNC
+#define        CONFIG_SCSI_NCR53C8XX_SYNC      SCSI_NCR_MAX_SYNC
+#endif
+
+#if    CONFIG_SCSI_NCR53C8XX_SYNC == 0
+#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (255)
+#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 5
+#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (50)
+#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 20
+#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (250/(CONFIG_SCSI_NCR53C8XX_SYNC))
+#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 33
+#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (11)
+#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 40
+#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (10)
+#else
+#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (9)
+#endif
+
+/*
+ * Disallow disconnections at boot-up
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
+#define SCSI_NCR_SETUP_DISCONNECTION   (0)
+#else
+#define SCSI_NCR_SETUP_DISCONNECTION   (1)
+#endif
+
+/*
+ * Force synchronous negotiation for all targets
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (1)
+#else
+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (0)
+#endif
+
+/*
+ * Disable master parity checking (flawed hardwares need that)
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
+#define SCSI_NCR_SETUP_MASTER_PARITY   (0)
+#else
+#define SCSI_NCR_SETUP_MASTER_PARITY   (1)
+#endif
+
+/*
+ * Disable scsi parity checking (flawed devices may need that)
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
+#define SCSI_NCR_SETUP_SCSI_PARITY     (0)
+#else
+#define SCSI_NCR_SETUP_SCSI_PARITY     (1)
+#endif
+
+/*
+ * Settle time after reset at boot-up
+ */
+#define SCSI_NCR_SETUP_SETTLE_TIME     (2)
+
+/*
+**     Bridge quirks work-around option defaulted to 1.
+*/
+#ifndef        SCSI_NCR_PCIQ_WORK_AROUND_OPT
+#define        SCSI_NCR_PCIQ_WORK_AROUND_OPT   1
+#endif
+
+/*
+**     Work-around common bridge misbehaviour.
+**
+**     - Do not flush posted writes in the opposite 
+**       direction on read.
+**     - May reorder DMA writes to memory.
+**
+**     This option should not affect performances 
+**     significantly, so it is the default.
+*/
+#if    SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
+#define        SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+#define        SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+#define        SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+
+/*
+**     Same as option 1, but also deal with 
+**     misconfigured interrupts.
+**
+**     - Edge triggerred instead of level sensitive.
+**     - No interrupt line connected.
+**     - IRQ number misconfigured.
+**     
+**     If no interrupt is delivered, the driver will 
+**     catch the interrupt conditions 10 times per 
+**     second. No need to say that this option is 
+**     not recommended.
+*/
+#elif  SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
+#define        SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+#define        SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+#define        SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+#define        SCSI_NCR_PCIQ_BROKEN_INTR
+
+/*
+**     Some bridge designers decided to flush 
+**     everything prior to deliver the interrupt.
+**     This option tries to deal with such a 
+**     behaviour.
+*/
+#elif  SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
+#define        SCSI_NCR_PCIQ_SYNC_ON_INTR
+#endif
+
+/*
+**     Other parameters not configurable with "make config"
+**     Avoid to change these constants, unless you know what you are doing.
+*/
+
+#define SCSI_NCR_ALWAYS_SIMPLE_TAG
+#define SCSI_NCR_MAX_SCATTER   (127)
+#define SCSI_NCR_MAX_TARGET    (16)
+
+/*
+**   Compute some desirable value for CAN_QUEUE 
+**   and CMD_PER_LUN.
+**   The driver will use lower values if these 
+**   ones appear to be too large.
+*/
+#define SCSI_NCR_CAN_QUEUE     (8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
+#define SCSI_NCR_CMD_PER_LUN   (SCSI_NCR_MAX_TAGS)
+
+#define SCSI_NCR_SG_TABLESIZE  (SCSI_NCR_MAX_SCATTER)
+#define SCSI_NCR_TIMER_INTERVAL        (HZ)
+
+#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
+#define SCSI_NCR_MAX_LUN       (16)
+#else
+#define SCSI_NCR_MAX_LUN       (1)
+#endif
+
+/*
+ *  IO functions definition for big/little endian CPU support.
+ *  For now, the NCR is only supported in little endian addressing mode, 
+ */
+
+#ifdef __BIG_ENDIAN
+
+#define        inw_l2b         inw
+#define        inl_l2b         inl
+#define        outw_b2l        outw
+#define        outl_b2l        outl
+
+#define        readb_raw       readb
+#define        writeb_raw      writeb
+
+#if defined(SCSI_NCR_BIG_ENDIAN)
+#define        readw_l2b       __raw_readw
+#define        readl_l2b       __raw_readl
+#define        writew_b2l      __raw_writew
+#define        writel_b2l      __raw_writel
+#define        readw_raw       __raw_readw
+#define        readl_raw       __raw_readl
+#define        writew_raw      __raw_writew
+#define        writel_raw      __raw_writel
+#else  /* Other big-endian */
+#define        readw_l2b       readw
+#define        readl_l2b       readl
+#define        writew_b2l      writew
+#define        writel_b2l      writel
+#define        readw_raw       readw
+#define        readl_raw       readl
+#define        writew_raw      writew
+#define        writel_raw      writel
+#endif
+
+#else  /* little endian */
+
+#define        inw_raw         inw
+#define        inl_raw         inl
+#define        outw_raw        outw
+#define        outl_raw        outl
+
+#define        readb_raw       readb
+#define        readw_raw       readw
+#define        readl_raw       readl
+#define        writeb_raw      writeb
+#define        writew_raw      writew
+#define        writel_raw      writel
+
+#endif
+
+#if !defined(__hppa__) && !defined(__mips__)
+#ifdef SCSI_NCR_BIG_ENDIAN
+#error "The NCR in BIG ENDIAN addressing mode is not (yet) supported"
+#endif
+#endif
+
+#define MEMORY_BARRIER()       mb()
+
+
+/*
+ *  If the NCR uses big endian addressing mode over the 
+ *  PCI, actual io register addresses for byte and word 
+ *  accesses must be changed according to lane routing.
+ *  Btw, ncr_offb() and ncr_offw() macros only apply to 
+ *  constants and so donnot generate bloated code.
+ */
+
+#if    defined(SCSI_NCR_BIG_ENDIAN)
+
+#define ncr_offb(o)    (((o)&~3)+((~((o)&3))&3))
+#define ncr_offw(o)    (((o)&~3)+((~((o)&3))&2))
+
+#else
+
+#define ncr_offb(o)    (o)
+#define ncr_offw(o)    (o)
+
+#endif
+
+/*
+ *  If the CPU and the NCR use same endian-ness addressing,
+ *  no byte reordering is needed for script patching.
+ *  Macro cpu_to_scr() is to be used for script patching.
+ *  Macro scr_to_cpu() is to be used for getting a DWORD 
+ *  from the script.
+ */
+
+#if    defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw) cpu_to_le32(dw)
+#define scr_to_cpu(dw) le32_to_cpu(dw)
+
+#elif  defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw) cpu_to_be32(dw)
+#define scr_to_cpu(dw) be32_to_cpu(dw)
+
+#else
+
+#define cpu_to_scr(dw) (dw)
+#define scr_to_cpu(dw) (dw)
+
+#endif
+
+/*
+ *  Access to the controller chip.
+ *
+ *  If the CPU and the NCR use same endian-ness addressing,
+ *  no byte reordering is needed for accessing chip io 
+ *  registers. Functions suffixed by '_raw' are assumed 
+ *  to access the chip over the PCI without doing byte 
+ *  reordering. Functions suffixed by '_l2b' are 
+ *  assumed to perform little-endian to big-endian byte 
+ *  reordering, those suffixed by '_b2l' blah, blah,
+ *  blah, ...
+ */
+
+/*
+ *  MEMORY mapped IO input / output
+ */
+
+#define INB_OFF(o)             readb_raw((char __iomem *)np->reg + ncr_offb(o))
+#define OUTB_OFF(o, val)       writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
+
+#if    defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o)             readw_l2b((char __iomem *)np->reg + ncr_offw(o))
+#define INL_OFF(o)             readl_l2b((char __iomem *)np->reg + (o))
+
+#define OUTW_OFF(o, val)       writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val)       writel_b2l((val), (char __iomem *)np->reg + (o))
+
+#elif  defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o)             readw_b2l((char __iomem *)np->reg + ncr_offw(o))
+#define INL_OFF(o)             readl_b2l((char __iomem *)np->reg + (o))
+
+#define OUTW_OFF(o, val)       writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val)       writel_l2b((val), (char __iomem *)np->reg + (o))
+
+#else
+
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+/* Only 8 or 32 bit transfers allowed */
+#define INW_OFF(o)             (readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
+#else
+#define INW_OFF(o)             readw_raw((char __iomem *)np->reg + ncr_offw(o))
+#endif
+#define INL_OFF(o)             readl_raw((char __iomem *)np->reg + (o))
+
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+/* Only 8 or 32 bit transfers allowed */
+#define OUTW_OFF(o, val)       do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
+#else
+#define OUTW_OFF(o, val)       writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
+#endif
+#define OUTL_OFF(o, val)       writel_raw((val), (char __iomem *)np->reg + (o))
+
+#endif
+
+#define INB(r)         INB_OFF (offsetof(struct ncr_reg,r))
+#define INW(r)         INW_OFF (offsetof(struct ncr_reg,r))
+#define INL(r)         INL_OFF (offsetof(struct ncr_reg,r))
+
+#define OUTB(r, val)   OUTB_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTW(r, val)   OUTW_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTL(r, val)   OUTL_OFF (offsetof(struct ncr_reg,r), (val))
+
+/*
+ *  Set bit field ON, OFF 
+ */
+
+#define OUTONB(r, m)   OUTB(r, INB(r) | (m))
+#define OUTOFFB(r, m)  OUTB(r, INB(r) & ~(m))
+#define OUTONW(r, m)   OUTW(r, INW(r) | (m))
+#define OUTOFFW(r, m)  OUTW(r, INW(r) & ~(m))
+#define OUTONL(r, m)   OUTL(r, INL(r) | (m))
+#define OUTOFFL(r, m)  OUTL(r, INL(r) & ~(m))
+
+/*
+ *  We normally want the chip to have a consistent view
+ *  of driver internal data structures when we restart it.
+ *  Thus these macros.
+ */
+#define OUTL_DSP(v)                            \
+       do {                                    \
+               MEMORY_BARRIER();               \
+               OUTL (nc_dsp, (v));             \
+       } while (0)
+
+#define OUTONB_STD()                           \
+       do {                                    \
+               MEMORY_BARRIER();               \
+               OUTONB (nc_dcntl, (STD|NOCOM)); \
+       } while (0)
+
+
+/*
+**   NCR53C8XX devices features table.
+*/
+struct ncr_chip {
+       unsigned short  revision_id;
+       unsigned char   burst_max;      /* log-base-2 of max burst */
+       unsigned char   offset_max;
+       unsigned char   nr_divisor;
+       unsigned int    features;
+#define FE_LED0                (1<<0)
+#define FE_WIDE                (1<<1)    /* Wide data transfers */
+#define FE_ULTRA       (1<<2)    /* Ultra speed 20Mtrans/sec */
+#define FE_DBLR                (1<<4)    /* Clock doubler present */
+#define FE_QUAD                (1<<5)    /* Clock quadrupler present */
+#define FE_ERL         (1<<6)    /* Enable read line */
+#define FE_CLSE                (1<<7)    /* Cache line size enable */
+#define FE_WRIE                (1<<8)    /* Write & Invalidate enable */
+#define FE_ERMP                (1<<9)    /* Enable read multiple */
+#define FE_BOF         (1<<10)   /* Burst opcode fetch */
+#define FE_DFS         (1<<11)   /* DMA fifo size */
+#define FE_PFEN                (1<<12)   /* Prefetch enable */
+#define FE_LDSTR       (1<<13)   /* Load/Store supported */
+#define FE_RAM         (1<<14)   /* On chip RAM present */
+#define FE_VARCLK      (1<<15)   /* SCSI clock may vary */
+#define FE_RAM8K       (1<<16)   /* On chip RAM sized 8Kb */
+#define FE_64BIT       (1<<17)   /* Have a 64-bit PCI interface */
+#define FE_IO256       (1<<18)   /* Requires full 256 bytes in PCI space */
+#define FE_NOPM                (1<<19)   /* Scripts handles phase mismatch */
+#define FE_LEDC                (1<<20)   /* Hardware control of LED */
+#define FE_DIFF                (1<<21)   /* Support Differential SCSI */
+#define FE_66MHZ       (1<<23)   /* 66MHz PCI Support */
+#define FE_DAC         (1<<24)   /* Support DAC cycles (64 bit addressing) */
+#define FE_ISTAT1      (1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
+#define FE_DAC_IN_USE  (1<<26)   /* Platform does DAC cycles */
+#define FE_EHP         (1<<27)   /* 720: Even host parity */
+#define FE_MUX         (1<<28)   /* 720: Multiplexed bus */
+#define FE_EA          (1<<29)   /* 720: Enable Ack */
+
+#define FE_CACHE_SET   (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
+#define FE_SCSI_SET    (FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
+#define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
+};
+
+
+/*
+**     Driver setup structure.
+**
+**     This structure is initialized from linux config options.
+**     It can be overridden at boot-up by the boot command line.
+*/
+#define SCSI_NCR_MAX_EXCLUDES 8
+struct ncr_driver_setup {
+       u8      master_parity;
+       u8      scsi_parity;
+       u8      disconnection;
+       u8      special_features;
+       u8      force_sync_nego;
+       u8      reverse_probe;
+       u8      pci_fix_up;
+       u8      use_nvram;
+       u8      verbose;
+       u8      default_tags;
+       u16     default_sync;
+       u16     debug;
+       u8      burst_max;
+       u8      led_pin;
+       u8      max_wide;
+       u8      settle_delay;
+       u8      diff_support;
+       u8      irqm;
+       u8      bus_check;
+       u8      optimize;
+       u8      recovery;
+       u8      host_id;
+       u16     iarb;
+       u32     excludes[SCSI_NCR_MAX_EXCLUDES];
+       char    tag_ctrl[100];
+};
+
+/*
+**     Initial setup.
+**     Can be overriden at startup by a command line.
+*/
+#define SCSI_NCR_DRIVER_SETUP                  \
+{                                              \
+       SCSI_NCR_SETUP_MASTER_PARITY,           \
+       SCSI_NCR_SETUP_SCSI_PARITY,             \
+       SCSI_NCR_SETUP_DISCONNECTION,           \
+       SCSI_NCR_SETUP_SPECIAL_FEATURES,        \
+       SCSI_NCR_SETUP_FORCE_SYNC_NEGO,         \
+       0,                                      \
+       0,                                      \
+       1,                                      \
+       0,                                      \
+       SCSI_NCR_SETUP_DEFAULT_TAGS,            \
+       SCSI_NCR_SETUP_DEFAULT_SYNC,            \
+       0x00,                                   \
+       7,                                      \
+       0,                                      \
+       1,                                      \
+       SCSI_NCR_SETUP_SETTLE_TIME,             \
+       0,                                      \
+       0,                                      \
+       1,                                      \
+       0,                                      \
+       0,                                      \
+       255,                                    \
+       0x00                                    \
+}
+
+/*
+**     Boot fail safe setup.
+**     Override initial setup from boot command line:
+**     ncr53c8xx=safe:y
+*/
+#define SCSI_NCR_DRIVER_SAFE_SETUP             \
+{                                              \
+       0,                                      \
+       1,                                      \
+       0,                                      \
+       0,                                      \
+       0,                                      \
+       0,                                      \
+       0,                                      \
+       1,                                      \
+       2,                                      \
+       0,                                      \
+       255,                                    \
+       0x00,                                   \
+       255,                                    \
+       0,                                      \
+       0,                                      \
+       10,                                     \
+       1,                                      \
+       1,                                      \
+       1,                                      \
+       0,                                      \
+       0,                                      \
+       255                                     \
+}
+
+/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
+
+/*-----------------------------------------------------------------
+**
+**     The ncr 53c810 register structure.
+**
+**-----------------------------------------------------------------
+*/
+
+struct ncr_reg {
+/*00*/  u8     nc_scntl0;    /* full arb., ena parity, par->ATN  */
+
+/*01*/  u8     nc_scntl1;    /* no reset                         */
+        #define   ISCON   0x10  /* connected to scsi               */
+        #define   CRST    0x08  /* force reset                      */
+        #define   IARB    0x02  /* immediate arbitration            */
+
+/*02*/  u8     nc_scntl2;    /* no disconnect expected           */
+       #define   SDU     0x80  /* cmd: disconnect will raise error */
+       #define   CHM     0x40  /* sta: chained mode                */
+       #define   WSS     0x08  /* sta: wide scsi send           [W]*/
+       #define   WSR     0x01  /* sta: wide scsi received       [W]*/
+
+/*03*/  u8     nc_scntl3;    /* cnf system clock dependent       */
+       #define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
+       #define   ULTRA   0x80  /* cmd: ULTRA enable                */
+                               /* bits 0-2, 7 rsvd for C1010       */
+
+/*04*/  u8     nc_scid;        /* cnf host adapter scsi address    */
+       #define   RRE     0x40  /* r/w:e enable response to resel.  */
+       #define   SRE     0x20  /* r/w:e enable response to select  */
+
+/*05*/  u8     nc_sxfer;       /* ### Sync speed and count         */
+                               /* bits 6-7 rsvd for C1010          */
+
+/*06*/  u8     nc_sdid;        /* ### Destination-ID               */
+
+/*07*/  u8     nc_gpreg;       /* ??? IO-Pins                      */
+
+/*08*/  u8     nc_sfbr;        /* ### First byte in phase          */
+
+/*09*/  u8     nc_socl;
+       #define   CREQ    0x80  /* r/w: SCSI-REQ                    */
+       #define   CACK    0x40  /* r/w: SCSI-ACK                    */
+       #define   CBSY    0x20  /* r/w: SCSI-BSY                    */
+       #define   CSEL    0x10  /* r/w: SCSI-SEL                    */
+       #define   CATN    0x08  /* r/w: SCSI-ATN                    */
+       #define   CMSG    0x04  /* r/w: SCSI-MSG                    */
+       #define   CC_D    0x02  /* r/w: SCSI-C_D                    */
+       #define   CI_O    0x01  /* r/w: SCSI-I_O                    */
+
+/*0a*/  u8     nc_ssid;
+
+/*0b*/  u8     nc_sbcl;
+
+/*0c*/  u8     nc_dstat;
+        #define   DFE     0x80  /* sta: dma fifo empty              */
+        #define   MDPE    0x40  /* int: master data parity error    */
+        #define   BF      0x20  /* int: script: bus fault           */
+        #define   ABRT    0x10  /* int: script: command aborted     */
+        #define   SSI     0x08  /* int: script: single step         */
+        #define   SIR     0x04  /* int: script: interrupt instruct. */
+        #define   IID     0x01  /* int: script: illegal instruct.   */
+
+/*0d*/  u8     nc_sstat0;
+        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
+        #define   ORF     0x40  /* sta: data in SODR register lsb   */
+        #define   OLF     0x20  /* sta: data in SODL register lsb   */
+        #define   AIP     0x10  /* sta: arbitration in progress     */
+        #define   LOA     0x08  /* sta: arbitration lost            */
+        #define   WOA     0x04  /* sta: arbitration won             */
+        #define   IRST    0x02  /* sta: scsi reset signal           */
+        #define   SDP     0x01  /* sta: scsi parity signal          */
+
+/*0e*/  u8     nc_sstat1;
+       #define   FF3210  0xf0  /* sta: bytes in the scsi fifo      */
+
+/*0f*/  u8     nc_sstat2;
+        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
+        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
+        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
+        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
+        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
+
+/*10*/  u8     nc_dsa; /* --> Base page                    */
+/*11*/  u8     nc_dsa1;
+/*12*/  u8     nc_dsa2;
+/*13*/  u8     nc_dsa3;
+
+/*14*/  u8     nc_istat;       /* --> Main Command and status      */
+        #define   CABRT   0x80  /* cmd: abort current operation     */
+        #define   SRST    0x40  /* mod: reset chip                  */
+        #define   SIGP    0x20  /* r/w: message from host to ncr    */
+        #define   SEM     0x10  /* r/w: message between host + ncr  */
+        #define   CON     0x08  /* sta: connected to scsi           */
+        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
+        #define   SIP     0x02  /* sta: scsi-interrupt              */
+        #define   DIP     0x01  /* sta: host/script interrupt       */
+
+/*15*/  u8     nc_istat1;      /* 896 and later cores only */
+        #define   FLSH    0x04  /* sta: chip is flushing            */
+        #define   SRUN    0x02  /* sta: scripts are running         */
+        #define   SIRQD   0x01  /* r/w: disable INT pin             */
+
+/*16*/  u8     nc_mbox0;       /* 896 and later cores only */
+/*17*/  u8     nc_mbox1;       /* 896 and later cores only */
+
+/*18*/ u8      nc_ctest0;
+       #define   EHP     0x04  /* 720 even host parity             */
+/*19*/  u8     nc_ctest1;
+
+/*1a*/  u8     nc_ctest2;
+       #define   CSIGP   0x40
+                               /* bits 0-2,7 rsvd for C1010        */
+
+/*1b*/  u8     nc_ctest3;
+       #define   FLF     0x08  /* cmd: flush dma fifo              */
+       #define   CLF     0x04  /* cmd: clear dma fifo              */
+       #define   FM      0x02  /* mod: fetch pin mode              */
+       #define   WRIE    0x01  /* mod: write and invalidate enable */
+                               /* bits 4-7 rsvd for C1010          */
+
+/*1c*/  u32    nc_temp;        /* ### Temporary stack              */
+
+/*20*/ u8      nc_dfifo;
+/*21*/  u8     nc_ctest4;
+       #define   MUX     0x80  /* 720 host bus multiplex mode      */
+       #define   BDIS    0x80  /* mod: burst disable               */
+       #define   MPEE    0x08  /* mod: master parity error enable  */
+
+/*22*/  u8     nc_ctest5;
+       #define   DFS     0x20  /* mod: dma fifo size               */
+                               /* bits 0-1, 3-7 rsvd for C1010          */
+/*23*/  u8     nc_ctest6;
+
+/*24*/  u32    nc_dbc; /* ### Byte count and command       */
+/*28*/  u32    nc_dnad;        /* ### Next command register        */
+/*2c*/  u32    nc_dsp; /* --> Script Pointer               */
+/*30*/  u32    nc_dsps;        /* --> Script pointer save/opcode#2 */
+
+/*34*/  u8     nc_scratcha;  /* Temporary register a            */
+/*35*/  u8     nc_scratcha1;
+/*36*/  u8     nc_scratcha2;
+/*37*/  u8     nc_scratcha3;
+
+/*38*/  u8     nc_dmode;
+       #define   BL_2    0x80  /* mod: burst length shift value +2 */
+       #define   BL_1    0x40  /* mod: burst length shift value +1 */
+       #define   ERL     0x08  /* mod: enable read line            */
+       #define   ERMP    0x04  /* mod: enable read multiple        */
+       #define   BOF     0x02  /* mod: burst op code fetch         */
+
+/*39*/  u8     nc_dien;
+/*3a*/  u8     nc_sbr;
+
+/*3b*/  u8     nc_dcntl;       /* --> Script execution control     */
+       #define   CLSE    0x80  /* mod: cache line size enable      */
+       #define   PFF     0x40  /* cmd: pre-fetch flush             */
+       #define   PFEN    0x20  /* mod: pre-fetch enable            */
+       #define   EA      0x20  /* mod: 720 enable-ack              */
+       #define   SSM     0x10  /* mod: single step mode            */
+       #define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
+       #define   STD     0x04  /* cmd: start dma mode              */
+       #define   IRQD    0x02  /* mod: irq disable                 */
+       #define   NOCOM   0x01  /* cmd: protect sfbr while reselect */
+                               /* bits 0-1 rsvd for C1010          */
+
+/*3c*/  u32    nc_adder;
+
+/*40*/  u16    nc_sien;        /* -->: interrupt enable            */
+/*42*/  u16    nc_sist;        /* <--: interrupt status            */
+        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
+        #define   STO     0x0400/* sta: timeout (select)            */
+        #define   GEN     0x0200/* sta: timeout (general)           */
+        #define   HTH     0x0100/* sta: timeout (handshake)         */
+        #define   MA      0x80  /* sta: phase mismatch              */
+        #define   CMP     0x40  /* sta: arbitration complete        */
+        #define   SEL     0x20  /* sta: selected by another device  */
+        #define   RSL     0x10  /* sta: reselected by another device*/
+        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
+        #define   UDC     0x04  /* sta: unexpected disconnect       */
+        #define   RST     0x02  /* sta: scsi bus reset detected     */
+        #define   PAR     0x01  /* sta: scsi parity error           */
+
+/*44*/  u8     nc_slpar;
+/*45*/  u8     nc_swide;
+/*46*/  u8     nc_macntl;
+/*47*/  u8     nc_gpcntl;
+/*48*/  u8     nc_stime0;    /* cmd: timeout for select&handshake*/
+/*49*/  u8     nc_stime1;    /* cmd: timeout user defined        */
+/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
+
+/*4c*/  u8     nc_stest0;
+
+/*4d*/  u8     nc_stest1;
+       #define   SCLK    0x80  /* Use the PCI clock as SCSI clock      */
+       #define   DBLEN   0x08  /* clock doubler running                */
+       #define   DBLSEL  0x04  /* clock doubler selected               */
+  
+
+/*4e*/  u8     nc_stest2;
+       #define   ROF     0x40  /* reset scsi offset (after gross error!) */
+       #define   DIF     0x20  /* 720 SCSI differential mode             */
+       #define   EXT     0x02  /* extended filtering                     */
+
+/*4f*/  u8     nc_stest3;
+       #define   TE     0x80   /* c: tolerAnt enable */
+       #define   HSC    0x20   /* c: Halt SCSI Clock */
+       #define   CSF    0x02   /* c: clear scsi fifo */
+
+/*50*/  u16   nc_sidl; /* Lowlevel: latched from scsi data */
+/*52*/  u8     nc_stest4;
+       #define   SMODE  0xc0   /* SCSI bus mode      (895/6 only) */
+       #define    SMODE_HVD 0x40       /* High Voltage Differential       */
+       #define    SMODE_SE  0x80       /* Single Ended                    */
+       #define    SMODE_LVD 0xc0       /* Low Voltage Differential        */
+       #define   LCKFRQ 0x20   /* Frequency Lock (895/6 only)     */
+                               /* bits 0-5 rsvd for C1010          */
+
+/*53*/  u8     nc_53_;
+/*54*/  u16    nc_sodl;        /* Lowlevel: data out to scsi data  */
+/*56*/ u8      nc_ccntl0;      /* Chip Control 0 (896)             */
+       #define   ENPMJ  0x80   /* Enable Phase Mismatch Jump       */
+       #define   PMJCTL 0x40   /* Phase Mismatch Jump Control      */
+       #define   ENNDJ  0x20   /* Enable Non Data PM Jump          */
+       #define   DISFC  0x10   /* Disable Auto FIFO Clear          */
+       #define   DILS   0x02   /* Disable Internal Load/Store      */
+       #define   DPR    0x01   /* Disable Pipe Req                 */
+
+/*57*/ u8      nc_ccntl1;      /* Chip Control 1 (896)             */
+       #define   ZMOD   0x80   /* High Impedance Mode              */
+       #define   DIC    0x10   /* Disable Internal Cycles          */
+       #define   DDAC   0x08   /* Disable Dual Address Cycle       */
+       #define   XTIMOD 0x04   /* 64-bit Table Ind. Indexing Mode  */
+       #define   EXTIBMV 0x02  /* Enable 64-bit Table Ind. BMOV    */
+       #define   EXDBMV 0x01   /* Enable 64-bit Direct BMOV        */
+
+/*58*/  u16    nc_sbdl;        /* Lowlevel: data from scsi data    */
+/*5a*/  u16    nc_5a_;
+
+/*5c*/  u8     nc_scr0;        /* Working register B               */
+/*5d*/  u8     nc_scr1;        /*                                  */
+/*5e*/  u8     nc_scr2;        /*                                  */
+/*5f*/  u8     nc_scr3;        /*                                  */
+
+/*60*/  u8     nc_scrx[64];    /* Working register C-R             */
+/*a0*/ u32     nc_mmrs;        /* Memory Move Read Selector        */
+/*a4*/ u32     nc_mmws;        /* Memory Move Write Selector       */
+/*a8*/ u32     nc_sfs;         /* Script Fetch Selector            */
+/*ac*/ u32     nc_drs;         /* DSA Relative Selector            */
+/*b0*/ u32     nc_sbms;        /* Static Block Move Selector       */
+/*b4*/ u32     nc_dbms;        /* Dynamic Block Move Selector      */
+/*b8*/ u32     nc_dnad64;      /* DMA Next Address 64              */
+/*bc*/ u16     nc_scntl4;      /* C1010 only                       */
+       #define   U3EN   0x80   /* Enable Ultra 3                   */
+       #define   AIPEN  0x40   /* Allow check upper byte lanes     */
+       #define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
+                                       transfer edge               */
+       #define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
+                                       transfer edge               */
+
+/*be*/  u8     nc_aipcntl0;    /* Epat Control 1 C1010 only        */
+/*bf*/  u8     nc_aipcntl1;    /* AIP Control C1010_66 Only        */
+
+/*c0*/ u32     nc_pmjad1;      /* Phase Mismatch Jump Address 1    */
+/*c4*/ u32     nc_pmjad2;      /* Phase Mismatch Jump Address 2    */
+/*c8*/ u8      nc_rbc;         /* Remaining Byte Count             */
+/*c9*/ u8      nc_rbc1;        /*                                  */
+/*ca*/ u8      nc_rbc2;        /*                                  */
+/*cb*/ u8      nc_rbc3;        /*                                  */
+
+/*cc*/ u8      nc_ua;          /* Updated Address                  */
+/*cd*/ u8      nc_ua1;         /*                                  */
+/*ce*/ u8      nc_ua2;         /*                                  */
+/*cf*/ u8      nc_ua3;         /*                                  */
+/*d0*/ u32     nc_esa;         /* Entry Storage Address            */
+/*d4*/ u8      nc_ia;          /* Instruction Address              */
+/*d5*/ u8      nc_ia1;
+/*d6*/ u8      nc_ia2;
+/*d7*/ u8      nc_ia3;
+/*d8*/ u32     nc_sbc;         /* SCSI Byte Count (3 bytes only)   */
+/*dc*/ u32     nc_csbc;        /* Cumulative SCSI Byte Count       */
+
+                               /* Following for C1010 only         */
+/*e0*/  u16    nc_crcpad;      /* CRC Value                        */
+/*e2*/  u8     nc_crccntl0;    /* CRC control register             */
+       #define   SNDCRC  0x10  /* Send CRC Request                 */
+/*e3*/  u8     nc_crccntl1;    /* CRC control register             */
+/*e4*/  u32    nc_crcdata;     /* CRC data register                */ 
+/*e8*/  u32    nc_e8_;         /* rsvd                             */
+/*ec*/  u32    nc_ec_;         /* rsvd                             */
+/*f0*/  u16    nc_dfbc;        /* DMA FIFO byte count              */ 
+
+};
+
+/*-----------------------------------------------------------
+**
+**     Utility macros for the script.
+**
+**-----------------------------------------------------------
+*/
+
+#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
+#define REG(r) REGJ (nc_, r)
+
+typedef u32 ncrcmd;
+
+/*-----------------------------------------------------------
+**
+**     SCSI phases
+**
+**     DT phases illegal for ncr driver.
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_DATA_OUT    0x00000000
+#define        SCR_DATA_IN     0x01000000
+#define        SCR_COMMAND     0x02000000
+#define        SCR_STATUS      0x03000000
+#define SCR_DT_DATA_OUT        0x04000000
+#define SCR_DT_DATA_IN 0x05000000
+#define SCR_MSG_OUT    0x06000000
+#define SCR_MSG_IN      0x07000000
+
+#define SCR_ILG_OUT    0x04000000
+#define SCR_ILG_IN     0x05000000
+
+/*-----------------------------------------------------------
+**
+**     Data transfer via SCSI.
+**
+**-----------------------------------------------------------
+**
+**     MOVE_ABS (LEN)
+**     <<start address>>
+**
+**     MOVE_IND (LEN)
+**     <<dnad_offset>>
+**
+**     MOVE_TBL
+**     <<dnad_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define OPC_MOVE          0x08000000
+
+#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
+
+#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
+#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
+#define SCR_CHMOV_TBL     (0x10000000)
+
+struct scr_tblmove {
+        u32  size;
+        u32  addr;
+};
+
+/*-----------------------------------------------------------
+**
+**     Selection
+**
+**-----------------------------------------------------------
+**
+**     SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
+**     <<alternate_address>>
+**
+**     SEL_TBL | << dnad_offset>>  [ | REL_JMP]
+**     <<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_SEL_ABS     0x40000000
+#define        SCR_SEL_ABS_ATN 0x41000000
+#define        SCR_SEL_TBL     0x42000000
+#define        SCR_SEL_TBL_ATN 0x43000000
+
+
+#ifdef SCSI_NCR_BIG_ENDIAN
+struct scr_tblsel {
+        u8     sel_scntl3;
+        u8     sel_id;
+        u8     sel_sxfer;
+        u8     sel_scntl4;     
+};
+#else
+struct scr_tblsel {
+        u8     sel_scntl4;     
+        u8     sel_sxfer;
+        u8     sel_id;
+        u8     sel_scntl3;
+};
+#endif
+
+#define SCR_JMP_REL     0x04000000
+#define SCR_ID(id)     (((u32)(id)) << 16)
+
+/*-----------------------------------------------------------
+**
+**     Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**     WAIT_DISC
+**     dummy: <<alternate_address>>
+**
+**     WAIT_RESEL
+**     <<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_WAIT_DISC   0x48000000
+#define SCR_WAIT_RESEL  0x50000000
+
+/*-----------------------------------------------------------
+**
+**     Bit Set / Reset
+**
+**-----------------------------------------------------------
+**
+**     SET (flags {|.. })
+**
+**     CLR (flags {|.. })
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_SET(f)     (0x58000000 | (f))
+#define SCR_CLR(f)     (0x60000000 | (f))
+
+#define        SCR_CARRY       0x00000400
+#define        SCR_TRG         0x00000200
+#define        SCR_ACK         0x00000040
+#define        SCR_ATN         0x00000008
+
+
+
+
+/*-----------------------------------------------------------
+**
+**     Memory to memory move
+**
+**-----------------------------------------------------------
+**
+**     COPY (bytecount)
+**     << source_address >>
+**     << destination_address >>
+**
+**     SCR_COPY   sets the NO FLUSH option by default.
+**     SCR_COPY_F does not set this option.
+**
+**     For chips which do not support this option,
+**     ncr_copy_and_bind() will remove this bit.
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_FLUSH 0x01000000
+
+#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
+#define SCR_COPY_F(n) (0xc0000000 | (n))
+
+/*-----------------------------------------------------------
+**
+**     Register move and binary operations
+**
+**-----------------------------------------------------------
+**
+**     SFBR_REG (reg, op, data)        reg  = SFBR op data
+**     << 0 >>
+**
+**     REG_SFBR (reg, op, data)        SFBR = reg op data
+**     << 0 >>
+**
+**     REG_REG  (reg, op, data)        reg  = reg op data
+**     << 0 >>
+**
+**-----------------------------------------------------------
+**     On 810A, 860, 825A, 875, 895 and 896 chips the content 
+**     of SFBR register can be used as data (SCR_SFBR_DATA).
+**     The 896 has additionnal IO registers starting at 
+**     offset 0x80. Bit 7 of register offset is stored in 
+**     bit 7 of the SCRIPTS instruction first DWORD.
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
+
+#define SCR_SFBR_REG(reg,op,data) \
+        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_SFBR(reg,op,data) \
+        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_REG(reg,op,data) \
+        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+
+#define      SCR_LOAD   0x00000000
+#define      SCR_SHL    0x01000000
+#define      SCR_OR     0x02000000
+#define      SCR_XOR    0x03000000
+#define      SCR_AND    0x04000000
+#define      SCR_SHR    0x05000000
+#define      SCR_ADD    0x06000000
+#define      SCR_ADDC   0x07000000
+
+#define      SCR_SFBR_DATA   (0x00800000>>8ul) /* Use SFBR as data */
+
+/*-----------------------------------------------------------
+**
+**     FROM_REG (reg)            SFBR = reg
+**     << 0 >>
+**
+**     TO_REG   (reg)            reg  = SFBR
+**     << 0 >>
+**
+**     LOAD_REG (reg, data)      reg  = <data>
+**     << 0 >>
+**
+**     LOAD_SFBR(data)           SFBR = <data>
+**     << 0 >>
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_FROM_REG(reg) \
+       SCR_REG_SFBR(reg,SCR_OR,0)
+
+#define        SCR_TO_REG(reg) \
+       SCR_SFBR_REG(reg,SCR_OR,0)
+
+#define        SCR_LOAD_REG(reg,data) \
+       SCR_REG_REG(reg,SCR_LOAD,data)
+
+#define SCR_LOAD_SFBR(data) \
+        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
+
+/*-----------------------------------------------------------
+**
+**     LOAD  from memory   to register.
+**     STORE from register to memory.
+**
+**     Only supported by 810A, 860, 825A, 875, 895 and 896.
+**
+**-----------------------------------------------------------
+**
+**     LOAD_ABS (LEN)
+**     <<start address>>
+**
+**     LOAD_REL (LEN)        (DSA relative)
+**     <<dsa_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
+#define SCR_NO_FLUSH2  0x02000000
+#define SCR_DSA_REL2   0x10000000
+
+#define SCR_LOAD_R(reg, how, n) \
+        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_STORE_R(reg, how, n) \
+        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_LOAD_ABS(reg, n)   SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_LOAD_REL(reg, n)   SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
+#define SCR_LOAD_ABS_F(reg, n) SCR_LOAD_R(reg, 0, n)
+#define SCR_LOAD_REL_F(reg, n) SCR_LOAD_R(reg, SCR_DSA_REL2, n)
+
+#define SCR_STORE_ABS(reg, n)  SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_STORE_REL(reg, n)  SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
+#define SCR_STORE_ABS_F(reg, n)        SCR_STORE_R(reg, 0, n)
+#define SCR_STORE_REL_F(reg, n)        SCR_STORE_R(reg, SCR_DSA_REL2, n)
+
+
+/*-----------------------------------------------------------
+**
+**     Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**     JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<address>>
+**
+**     JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<distance>>
+**
+**     CALL            [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<address>>
+**
+**     CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<distance>>
+**
+**     RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<dummy>>
+**
+**     INT             [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<ident>>
+**
+**     INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<ident>>
+**
+**     Conditions:
+**          WHEN (phase)
+**          IF   (phase)
+**          CARRYSET
+**          DATA (data, mask)
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_OP       0x80000000
+#define SCR_JUMP        0x80080000
+#define SCR_JUMP64      0x80480000
+#define SCR_JUMPR       0x80880000
+#define SCR_CALL        0x88080000
+#define SCR_CALLR       0x88880000
+#define SCR_RETURN      0x90080000
+#define SCR_INT         0x98080000
+#define SCR_INT_FLY     0x98180000
+
+#define IFFALSE(arg)   (0x00080000 | (arg))
+#define IFTRUE(arg)    (0x00000000 | (arg))
+
+#define WHEN(phase)    (0x00030000 | (phase))
+#define IF(phase)      (0x00020000 | (phase))
+
+#define DATA(D)        (0x00040000 | ((D) & 0xff))
+#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
+
+#define CARRYSET       (0x00200000)
+
+/*-----------------------------------------------------------
+**
+**     SCSI  constants.
+**
+**-----------------------------------------------------------
+*/
+
+/*
+**     Messages
+*/
+
+#define        M_COMPLETE      COMMAND_COMPLETE
+#define        M_EXTENDED      EXTENDED_MESSAGE
+#define        M_SAVE_DP       SAVE_POINTERS
+#define        M_RESTORE_DP    RESTORE_POINTERS
+#define        M_DISCONNECT    DISCONNECT
+#define        M_ID_ERROR      INITIATOR_ERROR
+#define        M_ABORT         ABORT_TASK_SET
+#define        M_REJECT        MESSAGE_REJECT
+#define        M_NOOP          NOP
+#define        M_PARITY        MSG_PARITY_ERROR
+#define        M_LCOMPLETE     LINKED_CMD_COMPLETE
+#define        M_FCOMPLETE     LINKED_FLG_CMD_COMPLETE
+#define        M_RESET         TARGET_RESET
+#define        M_ABORT_TAG     ABORT_TASK
+#define        M_CLEAR_QUEUE   CLEAR_TASK_SET
+#define        M_INIT_REC      INITIATE_RECOVERY
+#define        M_REL_REC       RELEASE_RECOVERY
+#define        M_TERMINATE     (0x11)
+#define        M_SIMPLE_TAG    SIMPLE_QUEUE_TAG
+#define        M_HEAD_TAG      HEAD_OF_QUEUE_TAG
+#define        M_ORDERED_TAG   ORDERED_QUEUE_TAG
+#define        M_IGN_RESIDUE   IGNORE_WIDE_RESIDUE
+#define        M_IDENTIFY      (0x80)
+
+#define        M_X_MODIFY_DP   EXTENDED_MODIFY_DATA_POINTER
+#define        M_X_SYNC_REQ    EXTENDED_SDTR
+#define        M_X_WIDE_REQ    EXTENDED_WDTR
+#define        M_X_PPR_REQ     EXTENDED_PPR
+
+/*
+**     Status
+*/
+
+#define        S_GOOD          (0x00)
+#define        S_CHECK_COND    (0x02)
+#define        S_COND_MET      (0x04)
+#define        S_BUSY          (0x08)
+#define        S_INT           (0x10)
+#define        S_INT_COND_MET  (0x14)
+#define        S_CONFLICT      (0x18)
+#define        S_TERMINATED    (0x20)
+#define        S_QUEUE_FULL    (0x28)
+#define        S_ILLEGAL       (0xff)
+#define        S_SENSE         (0x80)
+
+/*
+ * End of ncrreg from FreeBSD
+ */
 
 /*
        Build a scatter/gather entry.
index c1c1c68..5205c4e 100644 (file)
@@ -1,55 +1,70 @@
 config SCSI_QLA2XXX
-       tristate
-       default (SCSI && PCI)
-       depends on SCSI && PCI
+       tristate "QLogic QLA2XXX Fibre Channel Support"
+       depends on PCI && SCSI
+       select SCSI_FC_ATTRS
+       select FW_LOADER
+       ---help---
+       This qla2xxx driver supports all QLogic Fibre Channel
+       PCI and PCIe host adapters.
 
-config SCSI_QLA21XX
-       tristate "QLogic ISP2100 host adapter family support"
+       By default, firmware for the ISP parts will be loaded
+       via the Firmware Loader interface.
+
+       ISP             Firmware Filename
+       ----------      -----------------
+       21xx            ql2100_fw.bin
+       22xx            ql2200_fw.bin
+       2300, 2312      ql2300_fw.bin
+       2322            ql2322_fw.bin
+       6312, 6322      ql6312_fw.bin
+       24xx            ql2400_fw.bin
+
+       Upon request, the driver caches the firmware image until
+       the driver is unloaded.
+
+       NOTE: The original method of building firmware-loader
+       modules has been deprecated as the firmware-images will
+       be removed from the kernel sources.
+
+config SCSI_QLA2XXX_EMBEDDED_FIRMWARE
+       bool "  Use firmware-loader modules (DEPRECATED)"
        depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-       select FW_LOADER
+
+config SCSI_QLA21XX
+       tristate "  Build QLogic ISP2100 firmware-module"
+       depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
        ---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
-        select SCSI_FC_ATTRS
-       select FW_LOADER
+       tristate "  Build QLogic ISP2200 firmware-module"
+       depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
        ---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
-        select SCSI_FC_ATTRS
-       select FW_LOADER
+       tristate "  Build QLogic ISP2300 firmware-module"
+       depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
        ---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
-        select SCSI_FC_ATTRS
-       select FW_LOADER
+       tristate "  Build QLogic ISP2322 firmware-module"
+       depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
        ---help---
        This driver supports the QLogic 2322 (ISP2322) host adapter family.
 
 config SCSI_QLA6312
-       tristate "QLogic ISP63xx host adapter family support"
-       depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-       select FW_LOADER
+       tristate "  Build QLogic ISP63xx firmware-module"
+       depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
        ---help---
        This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
        adapter family.
 
 config SCSI_QLA24XX
-       tristate "QLogic ISP24xx host adapter family support"
-       depends on SCSI_QLA2XXX
-       select SCSI_FC_ATTRS
-       select FW_LOADER
+       tristate "  Build QLogic ISP24xx firmware-module"
+       depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
        ---help---
        This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
        adapter family.
index b169687..40c0de1 100644 (file)
@@ -3,15 +3,18 @@ EXTRA_CFLAGS += -DUNIQUE_FW_NAME
 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
                qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o
 
+obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx.o
+
 qla2100-y := ql2100.o ql2100_fw.o
 qla2200-y := ql2200.o ql2200_fw.o
 qla2300-y := ql2300.o ql2300_fw.o
 qla2322-y := ql2322.o ql2322_fw.o
 qla6312-y := ql6312.o ql6312_fw.o
+qla2400-y := ql2400.o ql2400_fw.o
 
 obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
 obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o
 obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
 obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
 obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o
-obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o
+obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o
diff --git a/drivers/scsi/qla2xxx/ql2400.c b/drivers/scsi/qla2xxx/ql2400.c
new file mode 100644 (file)
index 0000000..6c7165f
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "qla_def.h"
+
+static char qla_driver_name[] = "qla2400";
+
+extern uint32_t fw2400_version_str[];
+extern uint32_t fw2400_addr01;
+extern uint32_t fw2400_code01[];
+extern uint32_t fw2400_length01;
+extern uint32_t fw2400_addr02;
+extern uint32_t fw2400_code02[];
+extern uint32_t fw2400_length02;
+
+static struct qla_fw_info qla_fw_tbl[] = {
+       {
+               .addressing     = FW_INFO_ADDR_EXTENDED,
+               .fwcode         = (unsigned short *)&fw2400_code01[0],
+               .fwlen          = (unsigned short *)&fw2400_length01,
+               .lfwstart       = (unsigned long *)&fw2400_addr01,
+       },
+       {
+               .addressing     = FW_INFO_ADDR_EXTENDED,
+               .fwcode         = (unsigned short *)&fw2400_code02[0],
+               .fwlen          = (unsigned short *)&fw2400_length02,
+               .lfwstart       = (unsigned long *)&fw2400_addr02,
+       },
+       { FW_INFO_ADDR_NOMORE, },
+};
+
+static struct qla_board_info qla_board_tbl[] = {
+       {
+               .drv_name       = qla_driver_name,
+               .isp_name       = "ISP2422",
+               .fw_info        = qla_fw_tbl,
+               .fw_fname       = "ql2400_fw.bin",
+       },
+       {
+               .drv_name       = qla_driver_name,
+               .isp_name       = "ISP2432",
+               .fw_info        = qla_fw_tbl,
+               .fw_fname       = "ql2400_fw.bin",
+       },
+};
+
+static struct pci_device_id qla24xx_pci_tbl[] = {
+       {
+               .vendor         = PCI_VENDOR_ID_QLOGIC,
+               .device         = PCI_DEVICE_ID_QLOGIC_ISP2422,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (unsigned long)&qla_board_tbl[0],
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_QLOGIC,
+               .device         = PCI_DEVICE_ID_QLOGIC_ISP2432,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (unsigned long)&qla_board_tbl[1],
+       },
+       {0, 0},
+};
+MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl);
+
+static int __devinit
+qla24xx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       return qla2x00_probe_one(pdev,
+           (struct qla_board_info *)id->driver_data);
+}
+
+static void __devexit
+qla24xx_remove_one(struct pci_dev *pdev)
+{
+       qla2x00_remove_one(pdev);
+}
+
+static struct pci_driver qla24xx_pci_driver = {
+       .name           = "qla2400",
+       .id_table       = qla24xx_pci_tbl,
+       .probe          = qla24xx_probe_one,
+       .remove         = __devexit_p(qla24xx_remove_one),
+};
+
+static int __init
+qla24xx_init(void)
+{
+       return pci_module_init(&qla24xx_pci_driver);
+}
+
+static void __exit
+qla24xx_exit(void)
+{
+       pci_unregister_driver(&qla24xx_pci_driver);
+}
+
+module_init(qla24xx_init);
+module_exit(qla24xx_exit);
+
+MODULE_AUTHOR("QLogic Corporation");
+MODULE_DESCRIPTION("QLogic ISP24xx FC-SCSI Host Bus Adapter driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(QLA2XXX_VERSION);
diff --git a/drivers/scsi/qla2xxx/ql2400_fw.c b/drivers/scsi/qla2xxx/ql2400_fw.c
new file mode 100644 (file)
index 0000000..5977795
--- /dev/null
@@ -0,0 +1,12376 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+#include <linux/types.h>
+
+/*
+ *     Firmware Version 4.00.16 (08:09 Oct 26, 2005)
+ */
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_version = 4*1024+0;
+#else
+uint32_t risc_code_version = 4*1024+0;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_version_str[] = {4, 0,16};
+#else
+uint32_t firmware_version[] = {4, 0,16};
+#endif
+
+#ifdef UNIQUE_FW_NAME
+#define fw2400_VERSION_STRING "4.00.16"
+#else
+#define FW_VERSION_STRING "4.00.16"
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_addr01 = 0x00100000 ;
+#else
+uint32_t risc_code_addr01 = 0x00100000 ;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_code01[] = {
+#else
+uint32_t risc_code01[] = {
+#endif
+       0x0401f17c, 0x0010e000, 0x00100000, 0x0000ab4a,
+       0x00000004, 0x00000000, 0x00000010, 0x00000002,
+       0x00000003, 0x00000000, 0x20434f50, 0x59524947,
+       0x48542032, 0x30303520, 0x514c4f47, 0x49432043,
+       0x4f52504f, 0x52415449, 0x4f4e2020, 0x20495350,
+       0x32347878, 0x20466972, 0x6d776172, 0x65202020,
+       0x56657273, 0x696f6e20, 0x342e302e, 0x31362020,
+       0x20202024, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x42001800, 0x0010014f, 0x42002000, 0x0010b8fe,
+       0x500c0800, 0x800c1800, 0x500c1000, 0x800c1800,
+       0x54042000, 0x80102000, 0x80040800, 0x80081040,
+       0x040207fc, 0x500c0800, 0x800409c0, 0x040207f6,
+       0x44002000, 0x80102000, 0x40100000, 0x44040000,
+       0x80000000, 0x44080000, 0x80000000, 0x440c0000,
+       0x80000000, 0x44100000, 0x80000000, 0x44140000,
+       0x80000000, 0x44180000, 0x80000000, 0x441c0000,
+       0x80000000, 0x44200000, 0x80000000, 0x44240000,
+       0x80000000, 0x44280000, 0x80000000, 0x442c0000,
+       0x80000000, 0x44300000, 0x80000000, 0x44340000,
+       0x80000000, 0x44380000, 0x80000000, 0x443c0000,
+       0x80000000, 0x44400000, 0x80000000, 0x44440000,
+       0x80000000, 0x44480000, 0x80000000, 0x444c0000,
+       0x80000000, 0x44500000, 0x80000000, 0x44540000,
+       0x80000000, 0x44580000, 0x80000000, 0x445c0000,
+       0x80000000, 0x44600000, 0x80000000, 0x44640000,
+       0x80000000, 0x44680000, 0x80000000, 0x446c0000,
+       0x80000000, 0x44700000, 0x80000000, 0x44740000,
+       0x80000000, 0x44780000, 0x80000000, 0x447c0000,
+       0x80000000, 0x44800000, 0x80000000, 0x44840000,
+       0x80000000, 0x44880000, 0x80000000, 0x448c0000,
+       0x80000000, 0x44900000, 0x80000000, 0x44940000,
+       0x80000000, 0x44980000, 0x80000000, 0x449c0000,
+       0x80000000, 0x44a00000, 0x80000000, 0x44a40000,
+       0x80000000, 0x44a80000, 0x80000000, 0x44ac0000,
+       0x80000000, 0x44b00000, 0x80000000, 0x44b40000,
+       0x80000000, 0x44b80000, 0x80000000, 0x44bc0000,
+       0x80000000, 0x44c00000, 0x80000000, 0x44c40000,
+       0x80000000, 0x44c80000, 0x80000000, 0x44cc0000,
+       0x80000000, 0x44d00000, 0x80000000, 0x44d80000,
+       0x80000000, 0x44d40000, 0x80000000, 0x44dc0000,
+       0x80000000, 0x44e00000, 0x80000000, 0x44e40000,
+       0x80000000, 0x44e80000, 0x80000000, 0x44ec0000,
+       0x80000000, 0x44f00000, 0x80000000, 0x44f40000,
+       0x80000000, 0x44f80000, 0x80000000, 0x44fc0000,
+       0x80000000, 0x45000000, 0x80000000, 0x45040000,
+       0x80000000, 0x45080000, 0x80000000, 0x450c0000,
+       0x80000000, 0x45100000, 0x80000000, 0x45140000,
+       0x80000000, 0x45180000, 0x80000000, 0x451c0000,
+       0x80000000, 0x45200000, 0x80000000, 0x45240000,
+       0x80000000, 0x45280000, 0x80000000, 0x452c0000,
+       0x80000000, 0x45300000, 0x80000000, 0x45340000,
+       0x80000000, 0x45380000, 0x80000000, 0x453c0000,
+       0x80000000, 0x45400000, 0x80000000, 0x45440000,
+       0x80000000, 0x45480000, 0x80000000, 0x454c0000,
+       0x80000000, 0x45500000, 0x80000000, 0x45540000,
+       0x80000000, 0x45580000, 0x80000000, 0x455c0000,
+       0x80000000, 0x45600000, 0x80000000, 0x45640000,
+       0x80000000, 0x45680000, 0x80000000, 0x456c0000,
+       0x80000000, 0x45700000, 0x80000000, 0x45740000,
+       0x80000000, 0x45780000, 0x80000000, 0x457c0000,
+       0x80000000, 0x45800000, 0x80000000, 0x45840000,
+       0x80000000, 0x45880000, 0x80000000, 0x458c0000,
+       0x80000000, 0x45900000, 0x80000000, 0x45940000,
+       0x80000000, 0x45980000, 0x80000000, 0x459c0000,
+       0x80000000, 0x45a00000, 0x80000000, 0x45a40000,
+       0x80000000, 0x45a80000, 0x80000000, 0x45ac0000,
+       0x80000000, 0x45b00000, 0x80000000, 0x45b40000,
+       0x80000000, 0x45b80000, 0x80000000, 0x45bc0000,
+       0x80000000, 0x45c00000, 0x80000000, 0x45c40000,
+       0x80000000, 0x45c80000, 0x80000000, 0x45cc0000,
+       0x80000000, 0x45d00000, 0x80000000, 0x45d40000,
+       0x80000000, 0x45d80000, 0x80000000, 0x45dc0000,
+       0x80000000, 0x45e00000, 0x80000000, 0x45e40000,
+       0x80000000, 0x45e80000, 0x80000000, 0x45ec0000,
+       0x80000000, 0x45f00000, 0x80000000, 0x45f40000,
+       0x80000000, 0x45f80000, 0x80000000, 0x45fc0000,
+       0x4a03c020, 0x00004000, 0x4a03c011, 0x40000010,
+       0x04006000, 0x4203e000, 0x40000000, 0x59e00017,
+       0x8c000508, 0x04000003, 0x4a03c017, 0x00000000,
+       0x4203e000, 0x30000001, 0x0401f000, 0x0000bf00,
+       0x00000080, 0x0000bfe0, 0x00000020, 0x0000ff00,
+       0x00000080, 0x0000ffd0, 0x00000030, 0x00007100,
+       0x00000010, 0x00007200, 0x00000008, 0x00007209,
+       0x00000007, 0x00007300, 0x00000008, 0x00007309,
+       0x00000007, 0x00007400, 0x00000008, 0x00007409,
+       0x00000007, 0x00007600, 0x000000b0, 0x00007700,
+       0x00000040, 0x00003000, 0x00000070, 0x00004000,
+       0x000000c0, 0x00006000, 0x00000050, 0x00006100,
+       0x00000010, 0x00006130, 0x00000010, 0x00006150,
+       0x00000010, 0x00006170, 0x00000010, 0x00006190,
+       0x00000010, 0x000061b0, 0x00000010, 0x00000000,
+       0x42000000, 0x00000100, 0x4202f000, 0x00000000,
+       0x42000800, 0x00021f00, 0x45780800, 0x80040800,
+       0x80000040, 0x040207fd, 0x4203f000, 0x00021fff,
+       0x40000000, 0x4203e000, 0x90000100, 0x40000000,
+       0x0201f800, 0x001006fd, 0x42000000, 0x00001000,
+       0x50000000, 0x82000480, 0x24320002, 0x04020015,
+       0x42000800, 0x00000064, 0x80040840, 0x04000007,
+       0x4a030000, 0x00000001, 0x40000000, 0x59800000,
+       0x8c000500, 0x040007f9, 0x04000008, 0x42000800,
+       0x00007a17, 0x50040000, 0x8c00050e, 0x04020003,
+       0x8400054e, 0x44000800, 0x4a030000, 0x00000000,
+       0x4a03c020, 0x00000004, 0x4203e000, 0x6000000f,
+       0x59e00023, 0x8c000500, 0x04020039, 0x42000000,
+       0x00100001, 0x50000800, 0x82040c00, 0x00000004,
+       0x58042003, 0x42001000, 0xffffffff, 0x0201f800,
+       0x001006f4, 0x0402004e, 0x58042003, 0x42001000,
+       0xffffffff, 0x0201f800, 0x001006f4, 0x04020048,
+       0x58042003, 0x42001000, 0x00ffffff, 0x0201f800,
+       0x001006f4, 0x04020042, 0x58042003, 0x42001000,
+       0x00ffffff, 0x0201f800, 0x001006f4, 0x0402003c,
+       0x42000000, 0x00100001, 0x5000a000, 0x8250a400,
+       0x00000004, 0x4200a800, 0x00020000, 0x5850b003,
+       0x0201f800, 0x0010ab17, 0x8250a400, 0x00000005,
+       0x4a0370e8, 0x00000003, 0x4200a800, 0x0000c000,
+       0x5850b003, 0x0201f800, 0x0010ab17, 0x4a0378e8,
+       0x00000003, 0x4200a800, 0x00008000, 0x5850b003,
+       0x0201f800, 0x0010ab17, 0x0401f02b, 0x42000800,
+       0x00020000, 0x58042003, 0x42001000, 0xffffffff,
+       0x0201f800, 0x001006f4, 0x04020019, 0x4a0370e8,
+       0x00000003, 0x42000800, 0x0000c000, 0x58042003,
+       0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff,
+       0x0201f800, 0x001006f4, 0x0402000d, 0x4a0378e8,
+       0x00000003, 0x42000800, 0x00008000, 0x58042003,
+       0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff,
+       0x0201f800, 0x001006f4, 0x0400000b, 0x4a03c020,
+       0x00004010, 0x4a03c011, 0x40100011, 0x04006000,
+       0x4203e000, 0x40000000, 0x4203e000, 0x30000001,
+       0x0401f000, 0x0201f800, 0x00100791, 0x42001000,
+       0x0010ab4a, 0x40080000, 0x80140480, 0x82001d00,
+       0xffffff00, 0x04020003, 0x40001800, 0x0401f003,
+       0x42001800, 0x000000ff, 0x480bc840, 0x480fc842,
+       0x04011000, 0x400c0000, 0x80081400, 0x40140000,
+       0x80080580, 0x040207f0, 0x4817500d, 0x45782800,
+       0x59c40000, 0x82000500, 0xffff0000, 0x80000120,
+       0x82000580, 0x00002422, 0x04020005, 0x59a80005,
+       0x8400054e, 0x48035005, 0x0401f008, 0x59e00003,
+       0x82000500, 0x00030000, 0x04000004, 0x59a80005,
+       0x84000554, 0x48035005, 0x42000800, 0x00000040,
+       0x59a80005, 0x8c000514, 0x0402000e, 0x42000800,
+       0x00001000, 0x82141480, 0x0017ffff, 0x04021009,
+       0x80040902, 0x82141480, 0x0013ffff, 0x04021005,
+       0x80040902, 0x82141480, 0x0011ffff, 0x04001b8d,
+       0x4807500e, 0x42001000, 0x00000024, 0x0201f800,
+       0x00106681, 0x82040c00, 0x0010d1c0, 0x4807500b,
+       0x4a03c810, 0x00100000, 0x4a03c811, 0x0010ab4a,
+       0x4a03c829, 0x00000004, 0x59e40001, 0x82000540,
+       0x0003001d, 0x4803c801, 0x4a03c014, 0x001c001c,
+       0x42001000, 0x0000001c, 0x0201f800, 0x001006e2,
+       0x4202c000, 0x0010d1c0, 0x59aab00b, 0x59aaa00b,
+       0x59aaa80b, 0x59aac80e, 0x49675069, 0x59a8000b,
+       0x4803500c, 0x0401fbf5, 0x0201f800, 0x00107903,
+       0x0201f800, 0x001007be, 0x0201f800, 0x00100807,
+       0x0201f800, 0x00101a05, 0x0201f800, 0x00101354,
+       0x0201f800, 0x00100969, 0x0201f800, 0x00101354,
+       0x0201f800, 0x00100f4c, 0x0201f800, 0x001066c1,
+       0x0401fb1a, 0x0201f800, 0x0010220e, 0x0201f800,
+       0x001053bb, 0x0201f800, 0x00104c90, 0x0201f800,
+       0x00106194, 0x0201f800, 0x00105f28, 0x0201f800,
+       0x001013ed, 0x0201f800, 0x0010126f, 0x4203e000,
+       0xf0000001, 0x42000000, 0x00001000, 0x50000000,
+       0x82000480, 0x24220001, 0x04000016, 0x59e00002,
+       0x8c00051e, 0x42000000, 0x7ffe00fe, 0x04020003,
+       0x42000000, 0x7ffe01fe, 0x50000800, 0x48075058,
+       0x80040920, 0x82040580, 0x0000013a, 0x04000004,
+       0x82040580, 0x0000013b, 0x04020006, 0x59a80005,
+       0x84000552, 0x48035005, 0x4a0378e4, 0x000c0000,
+       0x4a03c018, 0x0000000f, 0x4203e000, 0x20000511,
+       0x4203e000, 0x50010000, 0x4a03c020, 0x00000000,
+       0x04027013, 0x59e00020, 0x82000580, 0x00000002,
+       0x0402000f, 0x4a03c020, 0x00004000, 0x4a03c011,
+       0x40000010, 0x04006000, 0x4203e000, 0x40000000,
+       0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017,
+       0x00000000, 0x4203e000, 0x30000001, 0x4202d800,
+       0x00000000, 0x4203e000, 0xb0600000, 0x59a80005,
+       0x42000800, 0x00000002, 0x8c000512, 0x04020007,
+       0x42000800, 0x0000000f, 0x8c000514, 0x04020003,
+       0x42000800, 0x00000001, 0x4007f800, 0x59a80005,
+       0x8c000514, 0x02020000, 0x00020004, 0x59e00003,
+       0x82000500, 0x00030000, 0x82000580, 0x00000000,
+       0x04020af8, 0x0201f000, 0x00020004, 0x4df00000,
+       0x4203e000, 0x50000000, 0x416c0000, 0x82000c80,
+       0x00000008, 0x04021aef, 0x0c01f804, 0x5c03e000,
+       0x0201f000, 0x00020008, 0x001002f7, 0x0010030a,
+       0x001003d7, 0x001002f6, 0x00100452, 0x001002f6,
+       0x001002f6, 0x00100593, 0x0401fae2, 0x42000800,
+       0x0010b4a4, 0x5804001d, 0x4803c857, 0x8c000500,
+       0x0400000d, 0x84000500, 0x4800081d, 0x4202d800,
+       0x00000004, 0x0401fbd3, 0x49f3c857, 0x5c000800,
+       0x5c000000, 0x82000540, 0x00003e00, 0x4c000000,
+       0x4c040000, 0x1c01f000, 0x0401fbbd, 0x0201f800,
+       0x0010513b, 0x04000009, 0x0201f800, 0x00105151,
+       0x0402002e, 0x59c40006, 0x82000540, 0x000000c0,
+       0x48038806, 0x0401f029, 0x0201f800, 0x001050a2,
+       0x836c0580, 0x00000001, 0x040200bc, 0x59a80017,
+       0x82000580, 0x00000009, 0x040200b8, 0x497b5010,
+       0x4a038893, 0x00000001, 0x42001000, 0x000000f0,
+       0x0201f800, 0x0010193d, 0x0201f800, 0x00105149,
+       0x59c41006, 0x04020006, 0x82081540, 0x000000f1,
+       0x82081500, 0xbbffffff, 0x0401f003, 0x82081540,
+       0x440000f1, 0x480b8806, 0x0201f800, 0x0010609e,
+       0x4a0378e4, 0x00002000, 0x42000000, 0x0010b83a,
+       0x0201f800, 0x0010aa47, 0x42001000, 0x00008030,
+       0x497b5013, 0x0401f035, 0x0201f800, 0x00103b38,
+       0x59c400a4, 0x82000500, 0x0000000f, 0x82000480,
+       0x00000007, 0x04021091, 0x0201f800, 0x0010609e,
+       0x59c400a3, 0x82000500, 0xffefffff, 0x480388a3,
+       0x59a8004b, 0x800001c0, 0x04020004, 0x0201f800,
+       0x00104139, 0x0401f085, 0x59a80015, 0x84000546,
+       0x48035015, 0x0201f800, 0x00105141, 0x59c41006,
+       0x04020006, 0x82081540, 0x44000001, 0x82081500,
+       0xffffff0f, 0x0401f003, 0x82081540, 0x440000f1,
+       0x480b8806, 0x497b9005, 0x4a038802, 0x0000ffff,
+       0x4a0378e4, 0x00003000, 0x42000000, 0x0010b80c,
+       0x0201f800, 0x0010aa47, 0x59a81010, 0x42000800,
+       0x00000003, 0x0201f800, 0x00106c78, 0x42001000,
+       0x00008010, 0x59a8180a, 0x0201f800, 0x00103a3e,
+       0x0201f800, 0x00101815, 0x59a80805, 0x82040d00,
+       0xffffffdf, 0x48075005, 0x0201f800, 0x0010483d,
+       0x0201f800, 0x0010513b, 0x0400000a, 0x0201f800,
+       0x0010413e, 0x04000007, 0x4a035013, 0x00000001,
+       0x497b5021, 0x0201f800, 0x00103c80, 0x0401f04f,
+       0x0201f800, 0x001048ec, 0x04000005, 0x59c41002,
+       0x8408150c, 0x480b8802, 0x0401f012, 0x0201f800,
+       0x0010513b, 0x04020006, 0x59a8001d, 0x80000540,
+       0x02000800, 0x0010930f, 0x0401f00a, 0x0201f800,
+       0x0010930f, 0x59a80026, 0x8c000506, 0x04020005,
+       0x59a8001d, 0x80000540, 0x02020800, 0x00104245,
+       0x497b5028, 0x497b5027, 0x497b5018, 0x0201f800,
+       0x0010513b, 0x59a81026, 0x0402000a, 0x0201f800,
+       0x0010162a, 0x80001580, 0x59a8002a, 0x82000500,
+       0xffff0000, 0x80040d40, 0x4807502a, 0x0401f005,
+       0x59a8002a, 0x82000500, 0xffff0000, 0x4803502a,
+       0x599c0017, 0x8c00050a, 0x04000002, 0x84081544,
+       0x480b5026, 0x0201f800, 0x0010513b, 0x04000004,
+       0x0201f800, 0x0010162a, 0x48078880, 0x42001000,
+       0x00000005, 0x0201f800, 0x001070b0, 0x497b5028,
+       0x497b501b, 0x4a03501c, 0x0000ffff, 0x4a0378e4,
+       0x000000c0, 0x4202d800, 0x00000002, 0x0201f800,
+       0x0010513b, 0x04000007, 0x59a80026, 0x82000500,
+       0x0000000c, 0x82000580, 0x00000004, 0x04000003,
+       0x0201f800, 0x00101e45, 0x1c01f000, 0x59a8001c,
+       0x82000580, 0x0000ffff, 0x04000004, 0x0201f800,
+       0x00101e45, 0x0401f074, 0x59a80026, 0x8c00050a,
+       0x04020003, 0x8c000506, 0x0400001c, 0x8c000500,
+       0x0400001a, 0x4a038802, 0x0000ffbf, 0x8c000502,
+       0x04000016, 0x599c0018, 0x8c000516, 0x04020010,
+       0x59a80027, 0x82000580, 0x0000ffff, 0x0400000c,
+       0x0201f800, 0x00101f9a, 0x59a80026, 0x8c000504,
+       0x0402005d, 0x42001000, 0x00000003, 0x417a5800,
+       0x0201f800, 0x00101fbf, 0x0401f057, 0x59a80028,
+       0x80000540, 0x04020054, 0x59a80026, 0x8c000508,
+       0x04020005, 0x59a8001b, 0x80000540, 0x0402004e,
+       0x0401f003, 0x8c000516, 0x0400004b, 0x0201f800,
+       0x001048ec, 0x04020048, 0x599c0018, 0x8c000516,
+       0x04020004, 0x0201f800, 0x00104c51, 0x04020042,
+       0x599c0017, 0x8c00050a, 0x0400000d, 0x4200b000,
+       0x000007f0, 0x417a8800, 0x0201f800, 0x00020245,
+       0x04020004, 0x59340200, 0x8c00051a, 0x04020036,
+       0x81468800, 0x8058b040, 0x040207f8, 0x4a038802,
+       0x0000ffff, 0x42001800, 0x0010b4eb, 0x0401fb8c,
+       0x42001800, 0x0010b4f8, 0x0401fb89, 0x59a80005,
+       0x84000502, 0x48035005, 0x4a0378e4, 0x00000080,
+       0x4202d800, 0x00000003, 0x4a03501c, 0x0000ffff,
+       0x0401fa7f, 0x80000580, 0x0201f800, 0x00101590,
+       0x599c0018, 0x8c000516, 0x04000004, 0x0201f800,
+       0x00103b10, 0x0401f009, 0x42001800, 0x0000ffff,
+       0x42002000, 0x00000006, 0x42003000, 0x00000000,
+       0x0201f800, 0x00103aae, 0x0201f800, 0x00105151,
+       0x0400000b, 0x59c40006, 0x0201f800, 0x0010513b,
+       0x04000004, 0x82000500, 0xffffff0f, 0x0401f003,
+       0x82000500, 0xfbffffff, 0x48038806, 0x0201f800,
+       0x00106f36, 0x1c01f000, 0x4c040000, 0x4c080000,
+       0x4c100000, 0x59a8003e, 0x82000c80, 0x00000004,
+       0x04021980, 0x0c01f805, 0x5c002000, 0x5c001000,
+       0x5c000800, 0x1c01f000, 0x00100462, 0x001004ea,
+       0x00100516, 0x00100577, 0x42000000, 0x00000001,
+       0x0201f800, 0x00101590, 0x0201f800, 0x0010609e,
+       0x59c408a3, 0x82040d00, 0xfffffff7, 0x480788a3,
+       0x0201f800, 0x00105141, 0x0400000e, 0x0201f800,
+       0x00105151, 0x0400000b, 0x0201f800, 0x00105149,
+       0x04020964, 0x59c400a3, 0x84000532, 0x84000570,
+       0x480388a3, 0x4a038808, 0x00000008, 0x0401f010,
+       0x59c400a3, 0x84000530, 0x82000500, 0xbf7fffff,
+       0x480388a3, 0x42000800, 0x000000f8, 0x0201f800,
+       0x00104200, 0x59c400a3, 0x82000540, 0x00018000,
+       0x8400051c, 0x480388a3, 0x497b8808, 0x59c40006,
+       0x82000500, 0xfbffff0e, 0x48038806, 0x497b2822,
+       0x497b2823, 0x42000800, 0x000001f4, 0x42001000,
+       0x00100591, 0x0201f800, 0x00105f83, 0x59c40805,
+       0x42001000, 0x00000001, 0x0201f800, 0x0010193d,
+       0x0201f800, 0x0010163b, 0x0402000a, 0x42000000,
+       0x00000001, 0x0201f800, 0x0010188c, 0x42000000,
+       0x00000001, 0x0201f800, 0x00101821, 0x0401f022,
+       0x0201f800, 0x00101642, 0x04020008, 0x41780000,
+       0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+       0x00101821, 0x0401f018, 0x0201f800, 0x00101649,
+       0x0402000a, 0x42000000, 0x00000002, 0x0201f800,
+       0x0010188c, 0x42000000, 0x00000002, 0x0201f800,
+       0x00101821, 0x0401f00c, 0x0201f800, 0x00101650,
+       0x04020918, 0x59a80049, 0x800001c0, 0x04000006,
+       0x0201f800, 0x00101656, 0x4a03503e, 0x00000001,
+       0x0401f021, 0x0201f800, 0x00101927, 0x4a03503e,
+       0x00000001, 0x0201f800, 0x00105141, 0x0400000c,
+       0x0201f800, 0x00105151, 0x04000009, 0x0201f800,
+       0x00105149, 0x04020903, 0x4a035033, 0x00000001,
+       0x0201f800, 0x001050a2, 0x0401f00f, 0x59c400a4,
+       0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+       0x04000003, 0x4a038805, 0x04000000, 0x59c400a3,
+       0x82000540, 0x0001c000, 0x480388a3, 0x84000520,
+       0x480388a3, 0x1c01f000, 0x0401f8a3, 0x04020004,
+       0x4a03503e, 0x00000003, 0x0401f027, 0x0201f800,
+       0x00101650, 0x04020011, 0x59a80049, 0x800001c0,
+       0x0400000e, 0x0201f800, 0x00101656, 0x59a80048,
+       0x8c00051e, 0x0400001c, 0x0201f800, 0x00105149,
+       0x04020009, 0x4a035033, 0x00000001, 0x0201f800,
+       0x001050a2, 0x0401f004, 0x0201f800, 0x001018d3,
+       0x04020011, 0x0201f800, 0x00101815, 0x4a03503e,
+       0x00000002, 0x497b5049, 0x59c400a3, 0x84000520,
+       0x480388a3, 0x497b2822, 0x497b2823, 0x42000800,
+       0x0000002d, 0x42001000, 0x00100591, 0x0201f800,
+       0x00105f83, 0x1c01f000, 0x0401f877, 0x04020004,
+       0x4a03503e, 0x00000003, 0x0401f05b, 0x4a038805,
+       0x000000f0, 0x0201f800, 0x001018d3, 0x04020050,
+       0x0201f800, 0x00105149, 0x04000044, 0x59c400a4,
+       0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+       0x04000020, 0x59c40005, 0x8c000534, 0x0402001d,
+       0x59940022, 0x82000580, 0x00000001, 0x04020046,
+       0x0201f800, 0x00105151, 0x04020043, 0x4a038805,
+       0x000000f0, 0x0201f800, 0x00105196, 0x4a035032,
+       0x0000aaaa, 0x4a035033, 0x00000000, 0x59c408a3,
+       0x82040d40, 0x00000008, 0x480788a3, 0x4202d800,
+       0x00000001, 0x4a03503e, 0x00000000, 0x4a038805,
+       0x00000001, 0x497b2822, 0x497b2823, 0x0401f01f,
+       0x0201f800, 0x00105151, 0x04020007, 0x59a80032,
+       0x82000580, 0x0000aaaa, 0x04020003, 0x4a035010,
+       0x00ffffff, 0x497b5032, 0x59c40006, 0x82000540,
+       0x04000001, 0x48038806, 0x59a80805, 0x8c040d06,
+       0x04020005, 0x59c408a3, 0x82040d40, 0x00000008,
+       0x480788a3, 0x4202d800, 0x00000001, 0x4a03503e,
+       0x00000000, 0x4a038805, 0x00000001, 0x497b2822,
+       0x497b2823, 0x0401f010, 0x59c40005, 0x82000500,
+       0x000000c0, 0x0400000c, 0x59c40006, 0x82000540,
+       0x000000f1, 0x48038806, 0x0401f7ef, 0x0201f800,
+       0x00101650, 0x04020004, 0x59a80049, 0x800001c0,
+       0x040207a4, 0x497b8885, 0x1c01f000, 0x4803c856,
+       0x42000000, 0x00000001, 0x0201f800, 0x00101590,
+       0x4a03503e, 0x00000000, 0x0201f800, 0x00101650,
+       0x0402000b, 0x59a80052, 0x800001c0, 0x04000004,
+       0x80000040, 0x48035052, 0x04020005, 0x4a035052,
+       0x0000000a, 0x4a035049, 0x00000001, 0x497b8885,
+       0x0401f0ed, 0x59940022, 0x59940823, 0x80040540,
+       0x1c01f000, 0x497b2823, 0x1c01f000, 0x4c080000,
+       0x42001000, 0x000000f0, 0x0201f800, 0x0010193d,
+       0x5c001000, 0x1c01f000, 0x4a03505c, 0x00000004,
+       0x4a03505d, 0x00000000, 0x4a03505e, 0x00000010,
+       0x4a03505f, 0x00000002, 0x4a035010, 0x00ffffff,
+       0x0201f800, 0x0010930f, 0x4a03502a, 0x20200000,
+       0x4a03502b, 0x88000200, 0x4a03502c, 0x00ff001f,
+       0x4a03502d, 0x000007d0, 0x4a03502e, 0x80000000,
+       0x4a03502f, 0x00000200, 0x4a035030, 0x00ff0000,
+       0x4a035031, 0x00010000, 0x4a03503a, 0x514c4f47,
+       0x4a03503b, 0x49432020, 0x1c01f000, 0x4d440000,
+       0x417a8800, 0x41780800, 0x0201f800, 0x00020245,
+       0x04020005, 0x0201f800, 0x001049e7, 0x04020002,
+       0x80040800, 0x81468800, 0x83440580, 0x000007f0,
+       0x040207f6, 0x5c028800, 0x1c01f000, 0x4803c857,
+       0x5c000000, 0x4c000000, 0x4803c857, 0x0401f809,
+       0x485fc857, 0x4203e000, 0x50000000, 0x5c000000,
+       0x4d780000, 0x4200b800, 0x00008002, 0x0401f006,
+       0x485fc857, 0x4203e000, 0x50000000, 0x4200b800,
+       0x00008002, 0x04006000, 0x4c000000, 0x4c040000,
+       0x59bc00ea, 0x82000500, 0x00000007, 0x82000580,
+       0x00000001, 0x04020005, 0x42000800, 0x00000000,
+       0x0201f800, 0x00106c6c, 0x5c000800, 0x4807c025,
+       0x80040920, 0x4807c026, 0x5c000000, 0x4803c023,
+       0x80000120, 0x4803c024, 0x5c000000, 0x4803c857,
+       0x4803c021, 0x80000120, 0x4803c022, 0x41f80000,
+       0x4803c027, 0x80000120, 0x4803c028, 0x42000000,
+       0x00001000, 0x50000000, 0x82000480, 0x24320001,
+       0x4803c857, 0x0400104f, 0x42000800, 0x00000064,
+       0x80040840, 0x04000007, 0x4a030000, 0x00000001,
+       0x40000000, 0x59800000, 0x8c000500, 0x040007f9,
+       0x04000042, 0x42000800, 0x0010c1a3, 0x46000800,
+       0xfaceface, 0x80040800, 0x42001000, 0x00007a00,
+       0x58080013, 0x44000800, 0x80040800, 0x58080019,
+       0x44000800, 0x80040800, 0x5808001a, 0x44000800,
+       0x80040800, 0x5808001b, 0x44000800, 0x80040800,
+       0x5808001c, 0x44000800, 0x80040800, 0x5808001f,
+       0x44000800, 0x80040800, 0x42001000, 0x00007a40,
+       0x42001800, 0x0000000b, 0x50080000, 0x44000800,
+       0x80081000, 0x80040800, 0x800c1840, 0x040207fb,
+       0x42001800, 0x00000003, 0x42001000, 0x00007b00,
+       0x480c1003, 0x58080005, 0x44000800, 0x80040800,
+       0x800c1840, 0x040217fb, 0x42001000, 0x00007c00,
+       0x58080002, 0x44000800, 0x80040800, 0x58080003,
+       0x44000800, 0x80040800, 0x58080020, 0x44000800,
+       0x80040800, 0x58080021, 0x44000800, 0x80040800,
+       0x58080022, 0x44000800, 0x80040800, 0x58080023,
+       0x44000800, 0x80040800, 0x4a030000, 0x00000000,
+       0x485fc020, 0x905cb9c0, 0x825cbd40, 0x00000012,
+       0x485fc011, 0x4203e000, 0x40000000, 0x4202d800,
+       0x00000005, 0x59e00017, 0x8c000508, 0x04000003,
+       0x4a03c017, 0x00000002, 0x4203e000, 0x30000001,
+       0x0401f81a, 0x0401f7ff, 0x4a03c850, 0x0010c1bf,
+       0x4a03c851, 0x0010d1be, 0x4a03c853, 0x00000800,
+       0x4a03c855, 0x0001eb5a, 0x59e40001, 0x82000540,
+       0x00003f00, 0x4803c801, 0x4a03b104, 0x70000002,
+       0x4a03a804, 0x70000002, 0x4a03b004, 0x70000002,
+       0x42000000, 0x0010b8ec, 0x49780001, 0x49780002,
+       0x1c01f000, 0x1c01f000, 0x59a8006b, 0x8c000530,
+       0x040207fe, 0x4c080000, 0x42001000, 0x00000004,
+       0x0401f862, 0x5c001000, 0x4201d000, 0x00028b0a,
+       0x0201f800, 0x0010608e, 0x4c080000, 0x42001000,
+       0x00000008, 0x0401f859, 0x5c001000, 0x4201d000,
+       0x00028b0a, 0x0201f800, 0x0010608e, 0x4c080000,
+       0x42001000, 0x00000010, 0x0401f850, 0x5c001000,
+       0x4201d000, 0x00028b0a, 0x0201f800, 0x0010608e,
+       0x0401f7e2, 0x8c00050c, 0x59a8086b, 0x04020003,
+       0x84040d30, 0x0401f006, 0x84040d70, 0x4807506b,
+       0x42001000, 0x00000000, 0x0401f040, 0x4807506b,
+       0x836c0500, 0x00000007, 0x0c01f001, 0x001006e1,
+       0x001006c7, 0x001006c7, 0x001006af, 0x001006d4,
+       0x001006c7, 0x001006c7, 0x001006d4, 0x59a80005,
+       0x8c000514, 0x04020013, 0x59c40801, 0x82040d00,
+       0x00018000, 0x82040580, 0x00010000, 0x0400000a,
+       0x82040580, 0x00008000, 0x04000004, 0x42001000,
+       0x42004000, 0x0401f006, 0x42001000, 0x22002000,
+       0x0401f003, 0x42001000, 0x12001000, 0x0401f025,
+       0x42001000, 0x00001004, 0x0401f022, 0x59a80005,
+       0x8c000514, 0x04020008, 0x59a8006b, 0x8c000534,
+       0x04020004, 0x42001000, 0x74057005, 0x0401f819,
+       0x1c01f000, 0x42001000, 0x00002008, 0x0401f7fc,
+       0x59a8006b, 0x8c000534, 0x0402000a, 0x59a80005,
+       0x8c000514, 0x04000004, 0x42001000, 0x24052005,
+       0x0401f00c, 0x42001000, 0x74057005, 0x0401f009,
+       0x1c01f000, 0x1c01f000, 0x82081500, 0x0000001c,
+       0x82081540, 0x001c0000, 0x480bc013, 0x1c01f000,
+       0x59a8006b, 0x8c000530, 0x04000002, 0x84081570,
+       0x480b506b, 0x8c000530, 0x04020005, 0x82081500,
+       0x00007000, 0x80081114, 0x0401fff0, 0x1c01f000,
+       0x41780000, 0x50041800, 0x800c0400, 0x80040800,
+       0x80102040, 0x040207fc, 0x80080500, 0x80000540,
+       0x1c01f000, 0x4202f000, 0x00000000, 0x41780000,
+       0x41780800, 0x41781000, 0x41781800, 0x41782000,
+       0x41782800, 0x41783000, 0x41783800, 0x41784000,
+       0x41784800, 0x41785000, 0x41785800, 0x41786000,
+       0x41786800, 0x41787000, 0x41787800, 0x41788000,
+       0x41788800, 0x41789000, 0x41789800, 0x4178a000,
+       0x4178a800, 0x4178b000, 0x4178b800, 0x4178c000,
+       0x4178c800, 0x4178d000, 0x4178d800, 0x4178e000,
+       0x4178e800, 0x4178f000, 0x4178f800, 0x41790000,
+       0x41790800, 0x41791000, 0x41791800, 0x41792000,
+       0x41792800, 0x41793000, 0x41793800, 0x41794000,
+       0x41794800, 0x41795000, 0x41795800, 0x41796000,
+       0x41796800, 0x41797000, 0x41797800, 0x41798000,
+       0x41798800, 0x42019000, 0x0010b537, 0x42019800,
+       0x0010b50e, 0x4179a000, 0x4179b000, 0x4179a800,
+       0x4179b800, 0x4179c800, 0x4179c000, 0x4179d000,
+       0x4179d800, 0x4179e000, 0x4179e800, 0x4179f000,
+       0x4179f800, 0x417a0000, 0x417a0800, 0x417a1000,
+       0x417a1800, 0x417a2000, 0x42022800, 0x00006100,
+       0x417a3000, 0x417a3800, 0x417a4000, 0x417a4800,
+       0x417a5000, 0x417a5800, 0x417a6000, 0x417a6800,
+       0x417a7000, 0x417a7800, 0x417a8000, 0x417a8800,
+       0x417a9000, 0x417a9800, 0x417ae800, 0x417af800,
+       0x42030000, 0x00007c00, 0x42031000, 0x0010b806,
+       0x42031800, 0x0000bf1d, 0x42032000, 0x0000bf32,
+       0x42032800, 0x0010b7ce, 0x42033000, 0x0010b46e,
+       0x42034000, 0x0010b4a4, 0x42033800, 0x0010b4c3,
+       0x42034800, 0x0010b544, 0x42035000, 0x0010b400,
+       0x42035800, 0x0010ac00, 0x42030800, 0x0010b505,
+       0x417b6000, 0x42036800, 0x00006f00, 0x4203c800,
+       0x00003000, 0x42037000, 0x0000ff00, 0x42037800,
+       0x0000bf00, 0x42038000, 0x00007700, 0x42038800,
+       0x00004000, 0x42039000, 0x00006000, 0x42039800,
+       0x0010bedb, 0x4203a000, 0x00007600, 0x4203a800,
+       0x00007400, 0x4203b000, 0x00007200, 0x4203b800,
+       0x00007100, 0x4203c000, 0x00007000, 0x4203d000,
+       0x00000000, 0x4203e800, 0x00101b95, 0x417bd800,
+       0x1c01f000, 0x42000800, 0x00100000, 0x50040000,
+       0x4c000000, 0x42000000, 0x0000aaaa, 0x44000800,
+       0x42001800, 0x00005555, 0x41782000, 0x82102400,
+       0x00010000, 0x40100000, 0x80042c00, 0x440c2800,
+       0x42003000, 0x0000000a, 0x80183040, 0x040207ff,
+       0x50140000, 0x800c0580, 0x04020004, 0x50040000,
+       0x800c0580, 0x040207f2, 0x5c000000, 0x44000800,
+       0x80142840, 0x4817c861, 0x1c01f000, 0x59a8081f,
+       0x800409c0, 0x04020009, 0x49781c0c, 0x4a001a0c,
+       0x00000200, 0x4a001804, 0x07000000, 0x59a80010,
+       0x9c0001c0, 0x48001805, 0x0401fe01, 0x9c0409c0,
+       0x48041806, 0x1c01f000, 0x59a8080c, 0x4006d000,
+       0x4202b800, 0x00000001, 0x59a8180d, 0x480fc857,
+       0x82041400, 0x00000014, 0x82082400, 0x00000014,
+       0x40100000, 0x800c0480, 0x04001006, 0x44080800,
+       0x40080800, 0x40101000, 0x815eb800, 0x0401f7f7,
+       0x45780800, 0x495f5020, 0x1c01f000, 0x835c0480,
+       0x00000020, 0x04001009, 0x496bc857, 0x815eb840,
+       0x416a5800, 0x592ed000, 0x497a5800, 0x497a5801,
+       0x812e59c0, 0x1c01f000, 0x42000000, 0x0010b853,
+       0x0201f800, 0x0010aa47, 0x417a5800, 0x0401f7f9,
+       0x815eb840, 0x04001008, 0x416a5800, 0x492fc857,
+       0x592ed000, 0x497a5800, 0x497a5801, 0x812e59c0,
+       0x1c01f000, 0x42000000, 0x0010b853, 0x0201f800,
+       0x0010aa47, 0x417ab800, 0x417a5800, 0x0401f7f8,
+       0x492fc857, 0x496a5800, 0x412ed000, 0x815eb800,
+       0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+       0x1c01f000, 0x492fc857, 0x812e59c0, 0x04000007,
+       0x592c0001, 0x497a5801, 0x4c000000, 0x0401fff1,
+       0x5c025800, 0x0401f7f9, 0x1c01f000, 0x4807c856,
+       0x42007000, 0x0010b7f8, 0x4a007001, 0x00000000,
+       0x59e00003, 0x82000540, 0x00008080, 0x4803c003,
+       0x4a03b805, 0x90000001, 0x59dc0006, 0x4a03b805,
+       0x70000000, 0x59dc0006, 0x4a03b805, 0x30000000,
+       0x4200b000, 0x00000020, 0x497bb807, 0x8058b040,
+       0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006,
+       0x4a03b805, 0x60000001, 0x59dc0006, 0x4a03b805,
+       0x70000001, 0x59dc0006, 0x4a03b805, 0x30000002,
+       0x4200b000, 0x00000020, 0x497bb807, 0x8058b040,
+       0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006,
+       0x4a03b805, 0x60000001, 0x0401ffa1, 0x04000da5,
+       0x42001000, 0x0010b7f6, 0x452c1000, 0x4a025801,
+       0x00000001, 0x4a025802, 0x00000100, 0x4a025809,
+       0x00107149, 0x497a580a, 0x497a580b, 0x497a580c,
+       0x0401ff93, 0x04000d97, 0x42001000, 0x0010b7f7,
+       0x452c1000, 0x4a025801, 0x00000000, 0x4a025802,
+       0x00000100, 0x4a025809, 0x001011bc, 0x497a5803,
+       0x497a5807, 0x497a5808, 0x497a580a, 0x59a80005,
+       0x8c00050e, 0x04000006, 0x4a03b805, 0xe0000001,
+       0x59dc0006, 0x8c000522, 0x040007fc, 0x1c01f000,
+       0x4df00000, 0x4203e000, 0x50000000, 0x4c380000,
+       0x40087000, 0x480bc857, 0x4a007002, 0x00000000,
+       0x42007000, 0x0010b7f8, 0x82080400, 0x00000000,
+       0x45780000, 0x58380005, 0x48087005, 0x80000540,
+       0x04000005, 0x82000400, 0x00000000, 0x44080000,
+       0x0401f003, 0x480bc857, 0x48087006, 0x58380001,
+       0x80000540, 0x0400080c, 0x5c007000, 0x5c03e000,
+       0x1c01f000, 0x4c380000, 0x42007000, 0x0010b7f8,
+       0x58380001, 0x80000540, 0x04000803, 0x5c007000,
+       0x1c01f000, 0x42007000, 0x0010b7f8, 0x58380001,
+       0x82000580, 0x00000000, 0x04020012, 0x58380000,
+       0x0c01f001, 0x0010088e, 0x0010088d, 0x0010088d,
+       0x0010088d, 0x0010088d, 0x0010088d, 0x0010088d,
+       0x0010088d, 0x0401fd4b, 0x58380808, 0x800409c0,
+       0x04020024, 0x58380006, 0x80000540, 0x04020002,
+       0x1c01f000, 0x4803c857, 0x48007002, 0x40006800,
+       0x58340000, 0x80000540, 0x04020002, 0x48007005,
+       0x48007006, 0x4a03b805, 0x20000000, 0x59dc0006,
+       0x4a03b805, 0x30000000, 0x58340007, 0x4803b800,
+       0x58340008, 0x4803b801, 0x58340004, 0x48007003,
+       0x58340003, 0x48007004, 0x4803b803, 0x58340001,
+       0x8c000500, 0x04000004, 0x4a007001, 0x00000001,
+       0x0401f028, 0x4a007001, 0x00000002, 0x0401f03d,
+       0x0201f800, 0x001093ea, 0x0201f800, 0x0010a69d,
+       0x04000017, 0x4a03b805, 0x20000000, 0x59dc0006,
+       0x4a03b805, 0x30000000, 0x4807b800, 0x480bb801,
+       0x4a007003, 0x00000010, 0x480c7009, 0x42001000,
+       0x00100875, 0x0201f800, 0x00105f9a, 0x58380008,
+       0x82000400, 0x00000004, 0x48007004, 0x4803b803,
+       0x4a007001, 0x00000007, 0x0401f022, 0x0201f800,
+       0x00109402, 0x42000800, 0x00000001, 0x42001000,
+       0x00100875, 0x0201f800, 0x00105f76, 0x0401f7ba,
+       0x4c040000, 0x4c080000, 0x58380803, 0x42001000,
+       0x00003fff, 0x82040480, 0x00003fff, 0x04021003,
+       0x40041000, 0x80000580, 0x48007003, 0x800800c4,
+       0x4803b802, 0x4a03b805, 0x30000002, 0x59dc0006,
+       0x4a03b805, 0x70000001, 0x59dc0006, 0x4a03b805,
+       0x10000000, 0x5c001000, 0x5c000800, 0x1c01f000,
+       0x483bc857, 0x4c040000, 0x4c080000, 0x58380803,
+       0x42001000, 0x00003fff, 0x82040480, 0x00003fff,
+       0x04021003, 0x40041000, 0x80000580, 0x48007003,
+       0x800800c4, 0x4803b802, 0x4a03b805, 0x10000002,
+       0x5c001000, 0x5c000800, 0x1c01f000, 0x4c040000,
+       0x4c380000, 0x42007000, 0x0010b7f8, 0x59dc0806,
+       0x4807c857, 0x4a03b805, 0x20000000, 0x8c040d3e,
+       0x04000007, 0x8c040d08, 0x04020cca, 0x58380001,
+       0x82000500, 0x00000007, 0x0c01f804, 0x5c007000,
+       0x5c000800, 0x1c01f000, 0x0010087d, 0x0010091e,
+       0x0010092e, 0x001005d8, 0x001005d8, 0x001005d8,
+       0x001005d8, 0x001011ea, 0x4807c856, 0x82040d00,
+       0x43000f80, 0x04020009, 0x58380003, 0x80000540,
+       0x0400001c, 0x59dc0000, 0x4803b800, 0x59dc0001,
+       0x4803b801, 0x0401f7af, 0x58380802, 0x4a000802,
+       0x00000200, 0x0401f01e, 0x4807c856, 0x82040d00,
+       0x43000f80, 0x04020009, 0x58380003, 0x80000540,
+       0x0400000c, 0x59dc0000, 0x4803b800, 0x59dc0001,
+       0x4803b801, 0x0401f7b7, 0x58380002, 0x82000400,
+       0x00000002, 0x46000000, 0x00000200, 0x0401f00c,
+       0x4c340000, 0x58386802, 0x59dc0000, 0x4803c857,
+       0x48006807, 0x59dc0001, 0x4803c857, 0x48006808,
+       0x4a006802, 0x00000100, 0x5c006800, 0x4a007001,
+       0x00000000, 0x4c300000, 0x58386002, 0x0401f80c,
+       0x04000009, 0x58300009, 0x82000c80, 0x0010ab4a,
+       0x04021c84, 0x82000c80, 0x00020000, 0x04001c81,
+       0x0801f800, 0x5c006000, 0x0401f723, 0x4833c857,
+       0x803061c0, 0x04000009, 0x59a8000c, 0x80300480,
+       0x04001007, 0x59a8000d, 0x80300480, 0x04021004,
+       0x82000540, 0x00000001, 0x1c01f000, 0x80000580,
+       0x1c01f000, 0x4803c856, 0x4dc00000, 0x42007000,
+       0x0010b803, 0x4a007400, 0x00000000, 0x49787001,
+       0x42038000, 0x00007720, 0x4a038006, 0x60000001,
+       0x4a038009, 0xf4f60000, 0x42038000, 0x00007700,
+       0x4a038006, 0x60000001, 0x4a038009, 0xf4f60000,
+       0x4a03c822, 0x00000010, 0x4a0370e8, 0x00000000,
+       0x0401f809, 0x4a0370e9, 0x00003a0f, 0x4a0370e8,
+       0x00000000, 0x4a0370e8, 0x00000001, 0x5c038000,
+       0x1c01f000, 0x4c5c0000, 0x4178b800, 0x0401f80a,
+       0x5c00b800, 0x1c01f000, 0x4803c856, 0x4c5c0000,
+       0x825cbd40, 0x00000001, 0x0401f803, 0x5c00b800,
+       0x1c01f000, 0x4803c856, 0x4dc00000, 0x4c500000,
+       0x4c580000, 0x4c540000, 0x4a0370e8, 0x00000000,
+       0x805cb9c0, 0x04000009, 0x4a038807, 0x00000004,
+       0x59b800ea, 0x8c000510, 0x04000004, 0x59b800e0,
+       0x0401f87b, 0x0401f7fb, 0x42038000, 0x00007720,
+       0x0201f800, 0x00100ec1, 0x59c00007, 0x4a038006,
+       0x20000000, 0x59c00007, 0x4a038006, 0x8000000a,
+       0x59c00007, 0x4a038006, 0x8000000b, 0x59c00007,
+       0x4a038006, 0x40000001, 0x83c00580, 0x00007700,
+       0x04000004, 0x42038000, 0x00007700, 0x0401f7ed,
+       0x42038000, 0x00007720, 0x42000800, 0x00000800,
+       0x59c00007, 0x8c00051e, 0x04000006, 0x4a038006,
+       0x90000001, 0x80040840, 0x040207fa, 0x0401fc11,
+       0x83c00580, 0x00007700, 0x04000004, 0x42038000,
+       0x00007700, 0x0401f7f1, 0x805cb9c0, 0x0402001d,
+       0x4200b000, 0x00000020, 0x83b8ac00, 0x00000020,
+       0x0201f800, 0x0010ab20, 0x4a0370fb, 0x00000001,
+       0x4a037020, 0x001010bd, 0x59a80039, 0x82000500,
+       0x0000ffff, 0x48037021, 0x4a037035, 0x0010bddb,
+       0x4a037030, 0x0010b410, 0x4a037031, 0x0010ac00,
+       0x4a037032, 0x0010b519, 0x4a037036, 0x0010b524,
+       0x59840002, 0x48037034, 0x4a037038, 0x001010b4,
+       0x4a0370fb, 0x00000001, 0x4178a000, 0x4200b000,
+       0x00000020, 0x83b8ac00, 0x00000000, 0x0201f800,
+       0x0010ab20, 0x4200b000, 0x00000040, 0x83b8ac00,
+       0x00000040, 0x0201f800, 0x0010ab20, 0x805cb9c0,
+       0x04020004, 0x4a0370e4, 0xaaaaaaaa, 0x0401f003,
+       0x4a0370e4, 0xa2aaaa82, 0x4a0370e5, 0xaaaaaaaa,
+       0x4a0370e6, 0xaaaaaaaa, 0x4a0370fb, 0x00000000,
+       0x4a0370e6, 0xaaaaaaaa, 0x42038000, 0x00007720,
+       0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e,
+       0x02020800, 0x001005d8, 0x42038000, 0x00007700,
+       0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e,
+       0x02020800, 0x001005d8, 0x5c00a800, 0x5c00b000,
+       0x5c00a000, 0x5c038000, 0x1c01f000, 0x4d300000,
+       0x4d380000, 0x40026000, 0x82000500, 0x7f000000,
+       0x82000580, 0x00000003, 0x0402000f, 0x83326500,
+       0x00ffffff, 0x59300203, 0x82000580, 0x00000004,
+       0x04020009, 0x59300c06, 0x82040580, 0x00000009,
+       0x04020005, 0x42027000, 0x00000047, 0x0201f800,
+       0x000207a1, 0x5c027000, 0x5c026000, 0x1c01f000,
+       0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000,
+       0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000,
+       0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000,
+       0x4c640000, 0x4cc80000, 0x4ccc0000, 0x4cf00000,
+       0x4cf40000, 0x4cf80000, 0x4cfc0000, 0x4d000000,
+       0x4d040000, 0x0201f800, 0x00020015, 0x5c020800,
+       0x5c020000, 0x5c01f800, 0x5c01f000, 0x5c01e800,
+       0x5c01e000, 0x5c019800, 0x5c019000, 0x5c00c800,
+       0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800,
+       0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800,
+       0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000,
+       0x1c01f000, 0x493bc857, 0x0201f000, 0x00020044,
+       0x83300500, 0x1f000000, 0x04000008, 0x81326580,
+       0x80000130, 0x82000c80, 0x00000014, 0x02021800,
+       0x001005d8, 0x0c01f013, 0x83300500, 0x000000ff,
+       0x82000c80, 0x00000007, 0x02021800, 0x001005d8,
+       0x0c01f025, 0x1c01f000, 0x82000d00, 0xc0000038,
+       0x02020800, 0x001005d0, 0x0201f800, 0x001005d8,
+       0x00000000, 0x00000048, 0x00000054, 0x00000053,
+       0x00100a9b, 0x00100abf, 0x00100aba, 0x00100adf,
+       0x00100aa6, 0x00100ab2, 0x00100a9b, 0x00100ada,
+       0x00100b1a, 0x00100a9b, 0x00100a9b, 0x00100a9b,
+       0x00100a9b, 0x00100b1d, 0x00100b23, 0x00100b34,
+       0x00100b45, 0x00100a9b, 0x00100b4e, 0x00100b5a,
+       0x00100a9b, 0x00100a9b, 0x00100a9b, 0x0201f800,
+       0x001005d8, 0x00100aa4, 0x00100bff, 0x00100aec,
+       0x00100b0f, 0x00100aa4, 0x00100aa4, 0x00100aa4,
+       0x0201f800, 0x001005d8, 0x4803c856, 0x59300004,
+       0x8c00053e, 0x04020005, 0x42027000, 0x00000055,
+       0x0201f000, 0x000207a1, 0x0201f800, 0x00106f60,
+       0x040007fa, 0x1c01f000, 0x4803c856, 0x0401f8a9,
+       0x40002800, 0x41782000, 0x42027000, 0x00000056,
+       0x0201f000, 0x000207a1, 0x4803c856, 0x42027000,
+       0x00000057, 0x0201f000, 0x000207a1, 0x4803c856,
+       0x59300007, 0x8c00051a, 0x04020010, 0x59325808,
+       0x812e59c0, 0x04000014, 0x592c0408, 0x8c00051c,
+       0x04020003, 0x4a026011, 0xffffffff, 0x59300004,
+       0x8c00053e, 0x04020009, 0x42027000, 0x00000048,
+       0x0201f000, 0x000207a1, 0x59325808, 0x4a025a06,
+       0x00000007, 0x0401f7f4, 0x0201f800, 0x00106f60,
+       0x040007f6, 0x1c01f000, 0x4803c856, 0x83300500,
+       0x00ffffff, 0x0201f000, 0x001064d7, 0x1c01f000,
+       0x4c040000, 0x59b808ea, 0x82040d00, 0x00000007,
+       0x82040580, 0x00000003, 0x04000004, 0x42000000,
+       0x60000000, 0x0401f8ab, 0x5c000800, 0x1c01f000,
+       0x0401f8f9, 0x59325808, 0x812e59c0, 0x04000018,
+       0x592c0204, 0x82000500, 0x000000ff, 0x82000d80,
+       0x00000029, 0x04020012, 0x59300203, 0x82000580,
+       0x00000003, 0x0400000b, 0x59300807, 0x84040d26,
+       0x48066007, 0x0201f800, 0x00020086, 0x4a03900d,
+       0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000,
+       0x0201f800, 0x00106f60, 0x040007f4, 0x59880052,
+       0x80000000, 0x48031052, 0x4a03900d, 0x00000040,
+       0x42000000, 0xc0000000, 0x0401f05a, 0x42007800,
+       0x0010bde2, 0x42002000, 0x00003000, 0x42003000,
+       0x00000105, 0x0201f800, 0x00105e04, 0x4a0370e4,
+       0x02000000, 0x1c01f000, 0x4933c857, 0x0201f000,
+       0x0002077d, 0x41300800, 0x800409c0, 0x02020800,
+       0x001005d8, 0x0201f800, 0x001005d0, 0x4933c857,
+       0x813261c0, 0x02000800, 0x001005d8, 0x0401f835,
+       0x40002800, 0x0201f800, 0x0010a99c, 0x0401f8ae,
+       0x04000007, 0x59326809, 0x59340200, 0x8c00050e,
+       0x59300414, 0x02020800, 0x001092ce, 0x1c01f000,
+       0x4933c857, 0x813261c0, 0x02000800, 0x001005d8,
+       0x0401f8a1, 0x0400000b, 0x59325808, 0x0201f800,
+       0x00109037, 0x04000007, 0x592c0208, 0x8400054e,
+       0x48025a08, 0x417a7800, 0x0201f800, 0x00108be3,
+       0x1c01f000, 0x485fc857, 0x5c000000, 0x4d780000,
+       0x4203e000, 0x50000000, 0x4200b800, 0x00008005,
+       0x0201f000, 0x001005dd, 0x4933c857, 0x83300480,
+       0x00000020, 0x02021800, 0x001005d8, 0x83300c00,
+       0x0010b8cc, 0x50040000, 0x80000000, 0x04001002,
+       0x44000800, 0x1c01f000, 0x4933c857, 0x0401f7f4,
+       0x4807c856, 0x59b800ea, 0x8c000510, 0x040007fd,
+       0x59b800e0, 0x4803c857, 0x1c01f000, 0x4803c856,
+       0x42000000, 0x10000000, 0x41300800, 0x0401f02d,
+       0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff,
+       0x80040d40, 0x4807c857, 0x59b800ea, 0x8c000516,
+       0x04020003, 0x480770e1, 0x1c01f000, 0x8c000510,
+       0x040007fa, 0x4c040000, 0x0401f809, 0x5c000800,
+       0x82100480, 0x00000008, 0x040017f4, 0x4c040000,
+       0x0401febc, 0x5c000800, 0x0401f7f0, 0x59b800e2,
+       0x59b820e2, 0x80100580, 0x040207fd, 0x80102114,
+       0x0401f006, 0x59b800e2, 0x59b820e2, 0x80100580,
+       0x040207fd, 0x0401f001, 0x40101800, 0x800c190a,
+       0x82100500, 0x0000001f, 0x820c1d00, 0x0000001f,
+       0x800c2480, 0x82102500, 0x0000001f, 0x1c01f000,
+       0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff,
+       0x80040d40, 0x4807c857, 0x42001000, 0x0010b804,
+       0x50080000, 0x80000540, 0x04020005, 0x4a0370e5,
+       0x00000003, 0x4a0370e4, 0x00000300, 0x80000000,
+       0x44001000, 0x42001000, 0x00000400, 0x59b800ea,
+       0x8c000510, 0x0400000c, 0x0401ffd5, 0x82100480,
+       0x00000008, 0x04001007, 0x4c040000, 0x4c080000,
+       0x0401fe88, 0x5c001000, 0x5c000800, 0x0401f020,
+       0x59b800ea, 0x8c000516, 0x0402001d, 0x4a0370e4,
+       0x00300000, 0x480770e1, 0x42001000, 0x0000ff00,
+       0x80081040, 0x04000012, 0x59b808e4, 0x8c040d28,
+       0x040207fc, 0x42001000, 0x0010b804, 0x50080000,
+       0x80000040, 0x04020005, 0x4a0370e5, 0x00000002,
+       0x4a0370e4, 0x00000200, 0x02001800, 0x001005d8,
+       0x44001000, 0x8c040d2c, 0x1c01f000, 0x41f80000,
+       0x50000000, 0x0201f800, 0x001005d8, 0x80081040,
+       0x040207d3, 0x41f80000, 0x50000000, 0x0201f800,
+       0x001005d8, 0x4d380000, 0x59300c06, 0x82040580,
+       0x00000009, 0x04020006, 0x42027000, 0x00000047,
+       0x0201f800, 0x000207a1, 0x80000580, 0x5c027000,
+       0x1c01f000, 0x4c500000, 0x4a03900d, 0x00000001,
+       0x59c8a020, 0x4a03900d, 0x00000002, 0x59c80820,
+       0x8c50a52e, 0x04000002, 0x900409c0, 0x82040d00,
+       0x0000ffff, 0x0201f800, 0x00105dd7, 0x02000800,
+       0x001005d8, 0x4933c857, 0x8250a500, 0xff000000,
+       0x82500580, 0x05000000, 0x04000003, 0x82000540,
+       0x00000001, 0x5c00a000, 0x1c01f000, 0x0401ffe6,
+       0x4933c857, 0x59300406, 0x82000580, 0x00000000,
+       0x04000040, 0x59c82021, 0x4a03900d, 0x00000001,
+       0x59c82821, 0x82142d00, 0x0000ffff, 0x59325808,
+       0x812e59c0, 0x04000037, 0x59326809, 0x0201f800,
+       0x001048d9, 0x02020800, 0x001092b6, 0x599c0019,
+       0x8c00050c, 0x04020018, 0x0201f800, 0x001048d9,
+       0x04020015, 0x59300811, 0x4807c857, 0x592c0408,
+       0x8c00051c, 0x0402000e, 0x8400055c, 0x48025c08,
+       0x592c0a04, 0x82040d00, 0x000000ff, 0x82040580,
+       0x00000048, 0x04000004, 0x82040580, 0x00000018,
+       0x04020003, 0x59300811, 0x48065803, 0x4a026011,
+       0x7fffffff, 0x48166013, 0x0201f800, 0x001010dd,
+       0x04020014, 0x0401f9fd, 0x40280000, 0x4802600d,
+       0x04000005, 0x4832600b, 0x50200000, 0x4802600a,
+       0x4822600c, 0x59300414, 0x8c00051c, 0x04020004,
+       0x599c0019, 0x8c00050c, 0x0402086e, 0x4a03900d,
+       0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000,
+       0x59880052, 0x80000000, 0x48031052, 0x4a03900d,
+       0x00000040, 0x42000000, 0xc0000000, 0x0401f71d,
+       0x4cf80000, 0x58f40000, 0x8001f540, 0x0401f820,
+       0x41781800, 0x0401f8e4, 0x04020014, 0x44140800,
+       0x0401f82a, 0x04000011, 0x40043800, 0x42001800,
+       0x00000001, 0x40142000, 0x0401f8db, 0x0402000b,
+       0x801c3800, 0x501c0000, 0x44000800, 0x0401f810,
+       0x801c0580, 0x04000004, 0x44103800, 0x801c3840,
+       0x44143800, 0x0401f819, 0x5c01f000, 0x1c01f000,
+       0x80f9f1c0, 0x04020003, 0x58f41202, 0x0401f003,
+       0x42001000, 0x00000007, 0x1c01f000, 0x80f9f1c0,
+       0x04020006, 0x58f40401, 0x82000480, 0x00000002,
+       0x80f40400, 0x0401f005, 0x58f80401, 0x82000480,
+       0x00000002, 0x80f80400, 0x50002800, 0x80000000,
+       0x50002000, 0x1c01f000, 0x80f9f1c0, 0x04020008,
+       0x58f40401, 0x82000480, 0x00000002, 0x02001800,
+       0x001005d8, 0x4801ec01, 0x0401f00b, 0x58f80401,
+       0x82000480, 0x00000002, 0x02001800, 0x001005d8,
+       0x4801f401, 0x82000580, 0x00000002, 0x04020002,
+       0x0401f809, 0x58f40202, 0x80000040, 0x4801ea02,
+       0x02000800, 0x001005d8, 0x82000580, 0x00000001,
+       0x1c01f000, 0x4d2c0000, 0x40fa5800, 0x0201f800,
+       0x001007f4, 0x4979e800, 0x4179f000, 0x5c025800,
+       0x1c01f000, 0x80f5e9c0, 0x04000009, 0x80f9f1c0,
+       0x04020ff5, 0x4d2c0000, 0x40f65800, 0x0201f800,
+       0x001007f4, 0x4179e800, 0x5c025800, 0x1c01f000,
+       0x4cf40000, 0x59300807, 0x82040500, 0x00003100,
+       0x04020032, 0x8c040d22, 0x04000032, 0x5930001f,
+       0x8001ed40, 0x02000800, 0x001005d8, 0x82000580,
+       0xffffffff, 0x04000029, 0x58f40201, 0x82000580,
+       0x0000dcb3, 0x02020800, 0x001005d8, 0x58f40a02,
+       0x82040500, 0x0000fffe, 0x04000003, 0x0401ff89,
+       0x58f40a02, 0x82040480, 0x0000000f, 0x04021059,
+       0x80040800, 0x4805ea02, 0x82040580, 0x00000008,
+       0x0400005d, 0x82040480, 0x00000008, 0x0400100a,
+       0x58f40000, 0x8001ed40, 0x02000800, 0x001005d8,
+       0x58f40201, 0x82000580, 0x0000ddb9, 0x02020800,
+       0x001005d8, 0x58f40401, 0x82000c00, 0x00000002,
+       0x4805ec01, 0x80f40400, 0x59300812, 0x44040000,
+       0x80000000, 0x45780000, 0x5c01e800, 0x1c01f000,
+       0x42001000, 0x00000400, 0x59b800e4, 0x8c000524,
+       0x04020023, 0x4a0370e4, 0x00030000, 0x40000000,
+       0x59b800e4, 0x8c000524, 0x0402001b, 0x59300807,
+       0x84040d62, 0x48066007, 0x4a0370e4, 0x00020000,
+       0x4d2c0000, 0x0201f800, 0x001007d3, 0x04000025,
+       0x492e601f, 0x4a025a01, 0x0000dcb3, 0x59300008,
+       0x80001d40, 0x02000800, 0x001005d8, 0x580c080f,
+       0x48065803, 0x59301811, 0x40040000, 0x800c0580,
+       0x0402000d, 0x497a5a02, 0x4a025c01, 0x00000004,
+       0x0401f011, 0x4a0370e4, 0x00020000, 0x40000000,
+       0x40000000, 0x80081040, 0x02000800, 0x001005d8,
+       0x0401f7d6, 0x4a025a02, 0x00000001, 0x4a025c01,
+       0x00000006, 0x497a5804, 0x400c0000, 0x80040480,
+       0x48025805, 0x412de800, 0x5c025800, 0x0401f7a9,
+       0x5c025800, 0x4a02601f, 0xffffffff, 0x0401f7c3,
+       0x4d2c0000, 0x58f65800, 0x0201f800, 0x001007f4,
+       0x40f65800, 0x0201f800, 0x001007f4, 0x5c025800,
+       0x0401f7f5, 0x4d2c0000, 0x0201f800, 0x001007d3,
+       0x040007f8, 0x4a025a01, 0x0000ddb9, 0x4a025c01,
+       0x00000002, 0x492de800, 0x412de800, 0x5c025800,
+       0x0401f7a5, 0x0401ff33, 0x82f40400, 0x00000004,
+       0x800c0400, 0x40000800, 0x50040000, 0x80100580,
+       0x04000016, 0x82040c00, 0x00000002, 0x80081040,
+       0x040207fa, 0x80f9f1c0, 0x04000011, 0x58f41202,
+       0x82081480, 0x00000007, 0x82f80400, 0x00000002,
+       0x800c0400, 0x40000800, 0x50040000, 0x80100580,
+       0x04000006, 0x82040c00, 0x00000002, 0x80081040,
+       0x040207fa, 0x0401f002, 0x1c01f000, 0x82000540,
+       0x00000001, 0x0401f7fd, 0x4cf40000, 0x4cf80000,
+       0x4001e800, 0x592c0a06, 0x800409c0, 0x0402001d,
+       0x82f40580, 0xffffffff, 0x04000017, 0x58f40201,
+       0x82000580, 0x0000dcb3, 0x02020800, 0x001005d8,
+       0x58f40000, 0x8001f540, 0x04000006, 0x58f80201,
+       0x82000580, 0x0000ddb9, 0x02020800, 0x001005d8,
+       0x41783800, 0x0401f839, 0x04020006, 0x0401ff32,
+       0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000,
+       0x0401ff2d, 0x4a025a06, 0x00000011, 0x0401f7f9,
+       0x82f40580, 0xffffffff, 0x04020f27, 0x0401f7f5,
+       0x4cf40000, 0x4cf80000, 0x4001e800, 0x82040580,
+       0x00000001, 0x0402001f, 0x82f40580, 0xffffffff,
+       0x04000019, 0x58f40201, 0x82000580, 0x0000dcb3,
+       0x02020800, 0x001005d8, 0x58f40000, 0x8001f540,
+       0x04000006, 0x58f80201, 0x82000580, 0x0000ddb9,
+       0x02020800, 0x001005d8, 0x41783800, 0x0401f813,
+       0x04020008, 0x0401ff0c, 0x42000800, 0x00000001,
+       0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000,
+       0x0401ff05, 0x42000800, 0x00000011, 0x0401f7f9,
+       0x4c040000, 0x82f40580, 0xffffffff, 0x04020efe,
+       0x5c000800, 0x0401f7f3, 0x4803c856, 0x401c2000,
+       0x41781800, 0x0401ff8c, 0x0402002c, 0x58f42003,
+       0x42001800, 0x00000001, 0x0401ff87, 0x04020027,
+       0x0401feb8, 0x40082800, 0x82f40400, 0x00000004,
+       0x40003000, 0x50182000, 0x40100000, 0x801c0580,
+       0x04000005, 0x42001800, 0x00000001, 0x0401ff7a,
+       0x0402001a, 0x82183400, 0x00000002, 0x80142840,
+       0x040207f5, 0x80f9f1c0, 0x04000013, 0x58f42a02,
+       0x82142c80, 0x00000007, 0x82f80400, 0x00000003,
+       0x40003000, 0x50182000, 0x40100000, 0x801c0580,
+       0x04000005, 0x42001800, 0x00000001, 0x0401ff66,
+       0x04020006, 0x82183400, 0x00000002, 0x80142840,
+       0x040207f5, 0x1c01f000, 0x82000540, 0x00000001,
+       0x0401f7fd, 0x0201f800, 0x001005d8, 0x58380207,
+       0x8c000502, 0x040007fc, 0x50200000, 0x80387c00,
+       0x583c2800, 0x583c2001, 0x58380404, 0x80001540,
+       0x04020002, 0x58381407, 0x58c83401, 0x58380c08,
+       0x59303807, 0x497a6012, 0x497a6013, 0x0201f000,
+       0x000200be, 0x592c0408, 0x8c000502, 0x040007ea,
+       0x592c0409, 0x80000540, 0x040007e7, 0x82000c80,
+       0x00000002, 0x04001011, 0x58380001, 0x80007540,
+       0x02000800, 0x001005d8, 0x58380204, 0x82000500,
+       0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+       0x40040000, 0x800409c0, 0x04000005, 0x82040c80,
+       0x00000005, 0x040217f1, 0x80204400, 0x50200000,
+       0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002,
+       0x592c0a07, 0x592c4c08, 0x592c300d, 0x59303807,
+       0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f,
+       0x480a6010, 0x481a6011, 0x80040840, 0x4806600d,
+       0x02000000, 0x000200c6, 0x80204000, 0x50201800,
+       0x800c19c0, 0x0402000c, 0x58380001, 0x80007540,
+       0x02000800, 0x001005d8, 0x58380204, 0x82000500,
+       0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+       0x50201800, 0x483a600b, 0x480e600a, 0x4822600c,
+       0x0201f000, 0x000200c6, 0x4803c856, 0x592c0208,
+       0x8c00051e, 0x04020017, 0x50200000, 0x80306c00,
+       0x40240000, 0x0c01f001, 0x00100e46, 0x00100e46,
+       0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e46,
+       0x00100e46, 0x00100e46, 0x00100e4f, 0x00100e46,
+       0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e4f,
+       0x00100e46, 0x00100e46, 0x0201f800, 0x001005d8,
+       0x8400051e, 0x48025a08, 0x50200000, 0x80306c00,
+       0x58343801, 0x481e600f, 0x0401f007, 0x58341802,
+       0x58342800, 0x58343801, 0x480e6010, 0x4816600e,
+       0x481e600f, 0x0401f246, 0x4933c857, 0x5931f808,
+       0x59300a06, 0x800409c0, 0x04000005, 0x80040906,
+       0x04020002, 0x80040800, 0x4805fc06, 0x4a026206,
+       0x00000002, 0x592c0409, 0x82000500, 0x00000008,
+       0x0400000b, 0x0401f834, 0x59300203, 0x82000580,
+       0x00000004, 0x04020005, 0x42027000, 0x00000048,
+       0x0201f800, 0x000207a1, 0x1c01f000, 0x4cfc0000,
+       0x58fc0204, 0x82000500, 0x000000ff, 0x82000580,
+       0x00000048, 0x0402000c, 0x58fc000b, 0x800001c0,
+       0x04000009, 0x58fc0407, 0x800001c0, 0x04000006,
+       0x58fc080b, 0x8c040d16, 0x04000017, 0x58fc0007,
+       0x0401f00a, 0x58fc0408, 0x8c000512, 0x04020014,
+       0x58fc0c09, 0x8c040d16, 0x04020003, 0x5c01f800,
+       0x1c01f000, 0x58fc000a, 0x59300811, 0x80040580,
+       0x04020009, 0x59300007, 0x84000500, 0x48026007,
+       0x42027000, 0x00000048, 0x5c01f800, 0x0201f000,
+       0x000207a1, 0x5c01f800, 0x1c01f000, 0x58fdf809,
+       0x0401f7ec, 0x4933c857, 0x59b808ea, 0x82040d00,
+       0x00000007, 0x82040580, 0x00000000, 0x0400001e,
+       0x82040580, 0x00000003, 0x0400001b, 0x59300406,
+       0x4c000000, 0x4a026406, 0x00000000, 0x42003000,
+       0x00000041, 0x42000000, 0x50000000, 0x41300800,
+       0x4c180000, 0x0401fce7, 0x5c003000, 0x0400000b,
+       0x42000000, 0x0000001e, 0x80000040, 0x040207ff,
+       0x80183040, 0x040207f4, 0x42000000, 0x40000000,
+       0x41300800, 0x0401fcdb, 0x5c000000, 0x48026406,
+       0x1c01f000, 0x59300007, 0x84000500, 0x48026007,
+       0x0401f7fc, 0x59c00007, 0x4a038006, 0x30000000,
+       0x40000000, 0x59c00007, 0x8c00050a, 0x040207fe,
+       0x1c01f000, 0x5c000000, 0x4c000000, 0x4803c857,
+       0x4dc00000, 0x4a0370e8, 0x00000000, 0x42038000,
+       0x00007720, 0x0401fff0, 0x42038000, 0x00007700,
+       0x0401ffed, 0x0201f800, 0x0010513b, 0x04020013,
+       0x4a038891, 0x0000ffff, 0x497b8880, 0x497b8892,
+       0x42001000, 0x00000190, 0x40000000, 0x40000000,
+       0x80081040, 0x040207fd, 0x42000000, 0x0010b8a6,
+       0x0201f800, 0x0010aa47, 0x0401f80e, 0x5c038000,
+       0x0201f000, 0x00105258, 0x0401f82d, 0x42000000,
+       0x0010b8a7, 0x0201f800, 0x0010aa47, 0x0401f805,
+       0x48178892, 0x480b8880, 0x5c038000, 0x1c01f000,
+       0x496fc857, 0x836c0580, 0x00000003, 0x0402000b,
+       0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048,
+       0x42001800, 0x0000ffff, 0x0201f800, 0x00103a3e,
+       0x5c001800, 0x5c001000, 0x42000800, 0x0000003c,
+       0x0201f800, 0x00101345, 0x59a8006c, 0x80000540,
+       0x04000006, 0x59a8106d, 0x800811c0, 0x04000003,
+       0x0201f800, 0x00101aaf, 0x4a038891, 0x0000ffff,
+       0x4a03900d, 0x00000040, 0x0201f800, 0x0010098e,
+       0x4a0370e8, 0x00000001, 0x1c01f000, 0x5c000000,
+       0x4c000000, 0x4803c857, 0x59c41080, 0x497b8880,
+       0x59c42892, 0x497b8892, 0x0201f800, 0x0010513b,
+       0x04020002, 0x1c01f000, 0x42002000, 0x00000260,
+       0x59c418a4, 0x820c1d00, 0x0000000f, 0x820c0580,
+       0x00000000, 0x04000010, 0x59c41805, 0x820c1d00,
+       0x00000001, 0x0402000e, 0x59c418a4, 0x820c1d00,
+       0x0000000f, 0x820c0480, 0x00000007, 0x04001004,
+       0x820c0480, 0x0000000c, 0x04001003, 0x80102040,
+       0x040207ec, 0x497b8891, 0x1c01f000, 0x4c100000,
+       0x42002000, 0x00000019, 0x46000000, 0x00000001,
+       0x0201f800, 0x00101937, 0x50001800, 0x820c1d00,
+       0x00000001, 0x04000005, 0x80102040, 0x040207f7,
+       0x5c002000, 0x0401f7f0, 0x5c002000, 0x0401f7ec,
+       0x4803c856, 0x1c01f000, 0x4d2c0000, 0x59325808,
+       0x592c0a04, 0x4807c857, 0x82040d00, 0x000000ff,
+       0x82040500, 0x0000000f, 0x0c01f001, 0x00100f67,
+       0x00100f67, 0x00100f67, 0x00100f7f, 0x00100f67,
+       0x00100f67, 0x00100f67, 0x00100f67, 0x00100f67,
+       0x00100f7f, 0x00100f67, 0x00100f69, 0x00100f67,
+       0x00100f67, 0x00100f67, 0x00100f67, 0x0201f800,
+       0x001005d8, 0x82040580, 0x0000003b, 0x02020800,
+       0x001005d8, 0x592c020a, 0x8c000500, 0x0400005f,
+       0x592c1a07, 0x82040500, 0x0000000f, 0x82000400,
+       0x001010bd, 0x50001000, 0x50080000, 0x59302013,
+       0x4802600a, 0x492e600b, 0x480a600c, 0x480e600d,
+       0x48126012, 0x5c025800, 0x1c01f000, 0x82040500,
+       0x0000000f, 0x82000400, 0x001010bd, 0x50001000,
+       0x50080000, 0x592c1a07, 0x4802600a, 0x492e600b,
+       0x480a600c, 0x480e600d, 0x497a6012, 0x0401f7f2,
+       0x8c040d00, 0x04020041, 0x82040d00, 0x00000080,
+       0x0400003e, 0x0201f000, 0x000200cf, 0x59300013,
+       0x59301012, 0x80080580, 0x0402000c, 0x42007800,
+       0x80000005, 0x592c1208, 0x82080500, 0xffff7fff,
+       0x48025a08, 0x8c08151e, 0x0402002d, 0x823c7d40,
+       0x00000020, 0x0401f02a, 0x480bc857, 0x42000000,
+       0x0010b851, 0x0201f800, 0x0010aa47, 0x59300414,
+       0x4803c857, 0x8c000514, 0x04020007, 0x599c1819,
+       0x8c0c1d12, 0x04020004, 0x820c1d40, 0x00000001,
+       0x0401f01d, 0x59302013, 0x0401f92b, 0x0402001a,
+       0x42007800, 0x80000005, 0x5930500d, 0x592c0208,
+       0x4803c857, 0x8c00051e, 0x04020005, 0x823c7d40,
+       0x00000020, 0x5930400c, 0x0401f004, 0x8400051e,
+       0x48025a08, 0x0401f8da, 0x50201800, 0x480e600a,
+       0x4832600b, 0x4822600c, 0x482a600d, 0x480fc857,
+       0x4833c857, 0x4823c857, 0x482bc857, 0x80000580,
+       0x483e6004, 0x1c01f000, 0x0201f800, 0x001005d8,
+       0x4933c857, 0x4d2c0000, 0x59900004, 0x81300580,
+       0x02020800, 0x001005d8, 0x0201f800, 0x00109037,
+       0x02000800, 0x001005d8, 0x59325808, 0x4d3c0000,
+       0x4d400000, 0x59300004, 0x4803c857, 0x4c000000,
+       0x0201f800, 0x00106dc3, 0x0201f800, 0x00106b8a,
+       0x5c000000, 0x8c000516, 0x04000010, 0x592c000f,
+       0x4803c857, 0x48025807, 0x41780800, 0x42028000,
+       0x00000002, 0x0201f800, 0x00104e70, 0x4a025c06,
+       0x0000ffff, 0x0201f800, 0x000202da, 0x0201f800,
+       0x00107911, 0x0401f015, 0x4a026203, 0x00000002,
+       0x592c0208, 0x8400054e, 0x48025a08, 0x59300406,
+       0x82000580, 0x00000006, 0x04020009, 0x811800ca,
+       0x81c80c00, 0x58040939, 0x592c000d, 0x80040480,
+       0x592c080f, 0x80040480, 0x4802580b, 0x417a7800,
+       0x0201f800, 0x00108be3, 0x5c028000, 0x5c027800,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+       0x59900004, 0x81300580, 0x02020800, 0x001005d8,
+       0x0201f800, 0x00109037, 0x02000800, 0x001005d8,
+       0x59325808, 0x592c0208, 0x84000540, 0x48025a08,
+       0x0401f7bf, 0x491bc857, 0x49d3c857, 0x4dd00000,
+       0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600,
+       0x4a03a005, 0x80000002, 0x42000000, 0x00001000,
+       0x50000000, 0x82000480, 0x24220001, 0x04020029,
+       0x59d01006, 0x82080500, 0x00006000, 0x82000580,
+       0x00006000, 0x0400002f, 0x82080500, 0x40008000,
+       0x040007f8, 0x800409c0, 0x0402002a, 0x811a31c0,
+       0x04000028, 0x42000000, 0x00001002, 0x50001000,
+       0x46000000, 0x00000512, 0x42001800, 0x0000000a,
+       0x59e00000, 0x8c00051a, 0x040207fc, 0x800c1840,
+       0x040207fc, 0x42000000, 0x00001002, 0x46000000,
+       0x00000514, 0x42001800, 0x0000000a, 0x59e00000,
+       0x8c00053a, 0x040207fc, 0x800c1840, 0x040207fc,
+       0x42000000, 0x00001002, 0x44080000, 0x0401f00d,
+       0x59d01006, 0x82080500, 0x00006000, 0x82000580,
+       0x00006000, 0x04000007, 0x8c08151e, 0x040007f9,
+       0x59d01006, 0x82080500, 0x00006000, 0x040207f5,
+       0x83d3a400, 0x00000020, 0x80040800, 0x82040480,
+       0x00000005, 0x040017bf, 0x5c03a000, 0x1c01f000,
+       0x491bc857, 0x49d3c857, 0x4dd00000, 0x41780800,
+       0x8007a0ca, 0x83d3a400, 0x00007600, 0x4a03a005,
+       0x80000001, 0x59d00006, 0x83d3a400, 0x00000020,
+       0x80040800, 0x82040480, 0x00000005, 0x040017f8,
+       0x5c03a000, 0x1c01f000, 0x59d00006, 0x8c00053e,
+       0x0400001e, 0x59902804, 0x4817c857, 0x801429c0,
+       0x04000013, 0x5990000a, 0x5990080b, 0x5990100c,
+       0x5990180d, 0x4800280a, 0x4804280b, 0x4808280c,
+       0x480c280d, 0x59d00000, 0x59d00801, 0x59d01002,
+       0x59d01803, 0x59d02004, 0x4800280e, 0x4804280f,
+       0x48082810, 0x480c2811, 0x48102812, 0x59900006,
+       0x82000500, 0xffff0000, 0x48032006, 0x4a03a005,
+       0x30000000, 0x59d00006, 0x1c01f000, 0x4803c856,
+       0x80204000, 0x50200000, 0x80000540, 0x04000003,
+       0x80285040, 0x1c01f000, 0x58300001, 0x80000540,
+       0x0400000e, 0x4802600b, 0x40006000, 0x58300204,
+       0x82000500, 0x0000000f, 0x82000400, 0x001010bd,
+       0x50004000, 0x802041c0, 0x02000800, 0x001005d8,
+       0x80285040, 0x1c01f000, 0x40005000, 0x1c01f000,
+       0x00000005, 0x00000008, 0x0000000b, 0x0000000e,
+       0x00000011, 0x00000000, 0x00000000, 0x0000000b,
+       0x00000000, 0x00000000, 0x00000000, 0x001010b8,
+       0x001010b7, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x001010b8, 0x001010b7, 0x001010b4,
+       0x001010b8, 0x001010b7, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x001010b8,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x001010b8, 0x001010b8, 0x001010b8,
+       0x00000000, 0x001010b8, 0x00000000, 0x00000000,
+       0x00000000, 0x4813c857, 0x492fc857, 0x4933c857,
+       0x48126012, 0x592c5207, 0x802851c0, 0x0400004a,
+       0x412c6000, 0x0401f84b, 0x04000009, 0x82240580,
+       0x00000002, 0x04020003, 0x5830000d, 0x80102480,
+       0x50200000, 0x80004540, 0x0400003f, 0x50200000,
+       0x80000540, 0x0400000b, 0x80301400, 0x58080002,
+       0x80102480, 0x0400101e, 0x801021c0, 0x04000009,
+       0x80285040, 0x04000034, 0x80204000, 0x0401f7f4,
+       0x58300001, 0x80006540, 0x0400002f, 0x0401f7e6,
+       0x80285040, 0x0400002c, 0x80204000, 0x50200000,
+       0x80000540, 0x0402000a, 0x58300001, 0x80006540,
+       0x04000025, 0x58300204, 0x82004d00, 0x0000000f,
+       0x82244400, 0x001010bd, 0x50204000, 0x592c0208,
+       0x8400051e, 0x48025a08, 0x0401f013, 0x80102080,
+       0x80102000, 0x48126010, 0x4813c857, 0x58080802,
+       0x40100000, 0x80042480, 0x02001800, 0x001005d8,
+       0x58080000, 0x58081801, 0x80102400, 0x4812600e,
+       0x480e600f, 0x4813c857, 0x592c0208, 0x8400055e,
+       0x48025a08, 0x4833c857, 0x4823c857, 0x482bc857,
+       0x4832600b, 0x4822600c, 0x482a600d, 0x80000580,
+       0x0401f003, 0x82000540, 0x00000001, 0x1c01f000,
+       0x58300204, 0x82004d00, 0x0000000f, 0x82244400,
+       0x001010bd, 0x82000500, 0x000000ff, 0x82000580,
+       0x00000029, 0x0402001b, 0x50204000, 0x592c0409,
+       0x80000540, 0x02000800, 0x001005d8, 0x82000c80,
+       0x00000002, 0x04001011, 0x58300001, 0x80006540,
+       0x02000800, 0x001005d8, 0x58300204, 0x82000500,
+       0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+       0x40040000, 0x800409c0, 0x04000006, 0x82040c80,
+       0x00000005, 0x040217f1, 0x80204400, 0x80000580,
+       0x1c01f000, 0x59e00004, 0x8c00050e, 0x02020000,
+       0x00100903, 0x1c01f000, 0x4c5c0000, 0x59e4b800,
+       0x485fc857, 0x825c0500, 0x0000001f, 0x04000004,
+       0x59e40862, 0x0201f800, 0x001005d8, 0x825c0500,
+       0x000000e0, 0x02000800, 0x001005d8, 0x8c5cbd0e,
+       0x04020807, 0x8c5cbd0c, 0x04020809, 0x8c5cbd0a,
+       0x04020878, 0x5c00b800, 0x1c01f000, 0x4803c856,
+       0x4a03c800, 0x00000080, 0x1c01f000, 0x4d2c0000,
+       0x42007800, 0x0010b8ec, 0x583c0001, 0x583c0802,
+       0x80040540, 0x0400003f, 0x42000800, 0x0010b7f7,
+       0x50065800, 0x592c0002, 0x82000580, 0x00000000,
+       0x0400000e, 0x59e40850, 0x59e41853, 0x400c0000,
+       0x80040400, 0x59e40852, 0x4807c857, 0x80041480,
+       0x04021008, 0x40001000, 0x480bc857, 0x4a007800,
+       0x00000001, 0x0401f006, 0x4803c857, 0x0401f029,
+       0x59e41050, 0x480bc857, 0x49787800, 0x480bc857,
+       0x480fc857, 0x592c0003, 0x80000540, 0x04000006,
+       0x80080580, 0x04020004, 0x592c0003, 0x4803c857,
+       0x480bc857, 0x480a5803, 0x592c0007, 0x800001c0,
+       0x04000007, 0x592c1007, 0x480bc857, 0x583c0003,
+       0x4803c857, 0x80080480, 0x04001003, 0x583c1001,
+       0x480bc857, 0x583c0802, 0x480bc857, 0x4807c857,
+       0x4a025801, 0x00000000, 0x4a025809, 0x001011bc,
+       0x480a5807, 0x48065808, 0x59e40053, 0x48025804,
+       0x412c1000, 0x492fc857, 0x0201f800, 0x00100858,
+       0x5c025800, 0x4a03c800, 0x00000040, 0x1c01f000,
+       0x42007800, 0x0010b7f7, 0x503c7800, 0x4a007802,
+       0x00000100, 0x42007800, 0x0010b8ec, 0x583c0000,
+       0x4803c857, 0x82000d80, 0x00000001, 0x04000004,
+       0x80000000, 0x48007800, 0x0401f019, 0x49787800,
+       0x583c1806, 0x583c0005, 0x800c1800, 0x480c7806,
+       0x800c0580, 0x04020002, 0x49787806, 0x583c0807,
+       0x800409c0, 0x0400000e, 0x583c0008, 0x80000000,
+       0x48007808, 0x80040580, 0x04020009, 0x49787808,
+       0x583c2006, 0x42001800, 0x00000001, 0x42001000,
+       0x00008028, 0x0201f800, 0x00103a3e, 0x1c01f000,
+       0x4a03c800, 0x00000020, 0x0201f800, 0x0010aa40,
+       0x59e40000, 0x1c01f000, 0x4d2c0000, 0x4a007001,
+       0x00000000, 0x82040d00, 0x43000f80, 0x02020800,
+       0x001005d8, 0x58380009, 0x4803c00f, 0x0201f800,
+       0x00109402, 0x583a5808, 0x592c0000, 0x48007008,
+       0x800001c0, 0x04020002, 0x49787007, 0x0201f800,
+       0x001007f4, 0x5c025800, 0x0201f000, 0x0010087d,
+       0x4803c856, 0x4c3c0000, 0x4d2c0000, 0x4d300000,
+       0x5830000a, 0x80025d40, 0x02000800, 0x001005d8,
+       0x592e6008, 0x4c300000, 0x0201f800, 0x0010941a,
+       0x5c006000, 0x02000800, 0x001005d8, 0x58300002,
+       0x82000580, 0x00000100, 0x04020010, 0x5930780b,
+       0x583c0001, 0x80000540, 0x0400000e, 0x4802600b,
+       0x40007800, 0x82000400, 0x00000002, 0x48006003,
+       0x583c0000, 0x48006004, 0x40301000, 0x0201f800,
+       0x00100858, 0x0401f00c, 0x4a025a06, 0x00000002,
+       0x4c300000, 0x0201f800, 0x000202da, 0x5c006000,
+       0x40325800, 0x0201f800, 0x001007f4, 0x0201f800,
+       0x0002077d, 0x5c026000, 0x5c025800, 0x5c007800,
+       0x1c01f000, 0x4803c856, 0x4d2c0000, 0x4d300000,
+       0x42007000, 0x0010b7f8, 0x58380801, 0x82040580,
+       0x00000002, 0x04020011, 0x58386002, 0x5830000a,
+       0x812c0580, 0x0402000d, 0x59e00004, 0x8c00050e,
+       0x040007fe, 0x59dc0006, 0x4803c857, 0x4a03b805,
+       0x20000000, 0x8c00053e, 0x040007f8, 0x4a007001,
+       0x00000000, 0x0401f019, 0x58386006, 0x40305000,
+       0x803061c0, 0x02000800, 0x001005d8, 0x5830000a,
+       0x812c0580, 0x04000004, 0x40305000, 0x58306000,
+       0x0401f7f8, 0x40280000, 0x80300580, 0x58300000,
+       0x04000006, 0x48005000, 0x800001c0, 0x04020007,
+       0x48287005, 0x0401f005, 0x800001c0, 0x04020002,
+       0x48007005, 0x48007006, 0x40325800, 0x0201f800,
+       0x001007f4, 0x42007000, 0x0010b7f8, 0x58380001,
+       0x82000580, 0x00000000, 0x02000800, 0x0010087d,
+       0x5c026000, 0x5c025800, 0x1c01f000, 0x4803c856,
+       0x42000800, 0x0000003c, 0x48079000, 0x59c80000,
+       0x80040500, 0x040207fe, 0x497b9005, 0x4a039035,
+       0x00880200, 0x59a8000e, 0x800000e0, 0x4803900e,
+       0x4a039011, 0x00000024, 0x4a03900f, 0x0010d1c0,
+       0x4a039010, 0x0010d1c0, 0x4a039015, 0x0000007f,
+       0x4a03900d, 0x00000040, 0x4a039000, 0x00001600,
+       0x1c01f000, 0x59c80007, 0x8c000508, 0x040208b7,
+       0x59c80800, 0x8c040d16, 0x04020004, 0x82000500,
+       0x00000006, 0x0c01f005, 0x4807c857, 0x82000500,
+       0x0000000e, 0x0c01f001, 0x001012a8, 0x001012a6,
+       0x00105999, 0x001012a6, 0x001012aa, 0x001012a6,
+       0x001012aa, 0x001012aa, 0x001012a6, 0x001012a6,
+       0x001012a6, 0x001012a6, 0x001012aa, 0x001012a6,
+       0x001012aa, 0x001012a6, 0x0201f800, 0x001005d8,
+       0x4803c857, 0x1c01f000, 0x59c8080c, 0x4807c857,
+       0x82040500, 0x00006000, 0x04000004, 0x0201f800,
+       0x0010aa03, 0x0401f006, 0x82040500, 0x007f0000,
+       0x04000006, 0x0201f800, 0x0010a9d5, 0x0201f800,
+       0x00106eb3, 0x0401f02b, 0x82040500, 0x00000014,
+       0x04000014, 0x0201f800, 0x0010aa32, 0x836c0580,
+       0x00000003, 0x0400000d, 0x0201f800, 0x0010513b,
+       0x04000004, 0x0201f800, 0x0010411d, 0x0401f007,
+       0x4a035033, 0x00000001, 0x4202d800, 0x00000001,
+       0x0201f800, 0x001050a2, 0x0401f817, 0x0401f015,
+       0x82040500, 0x00001c00, 0x04000005, 0x0201f800,
+       0x0010aa11, 0x0401f810, 0x0401f00e, 0x82040500,
+       0x00000140, 0x04000005, 0x0201f800, 0x0010aa24,
+       0x0401f809, 0x0401f007, 0x82040500, 0x00008000,
+       0x04000004, 0x0201f800, 0x0010a9fc, 0x0401f802,
+       0x1c01f000, 0x4c0c0000, 0x4c100000, 0x4c140000,
+       0x0201f800, 0x00100ec9, 0x5c002800, 0x5c002000,
+       0x5c001800, 0x1c01f000, 0x4803c856, 0x59a80804,
+       0x59a8002b, 0x82000500, 0xfffff000, 0x80040540,
+       0x4803502b, 0x59a8002f, 0x82000500, 0xfffff000,
+       0x80040540, 0x4803502f, 0x48078882, 0x82041c00,
+       0x0000000f, 0x800c1908, 0x820c1c00, 0x00000004,
+       0x400c2000, 0x901029c0, 0x82040480, 0x000001e4,
+       0x04021005, 0x42001000, 0x00000008, 0x801020c6,
+       0x0401f031, 0x82040480, 0x00000230, 0x04021009,
+       0x42001000, 0x00000007, 0x801000c2, 0x800000c2,
+       0x80100400, 0x80100400, 0x80102400, 0x0401f026,
+       0x82040480, 0x00000298, 0x04021008, 0x42001000,
+       0x00000006, 0x801000c2, 0x800000c2, 0x80100400,
+       0x80102400, 0x0401f01c, 0x82040480, 0x00000328,
+       0x04021007, 0x42001000, 0x00000005, 0x801000c2,
+       0x800000c2, 0x80102400, 0x0401f013, 0x82040480,
+       0x00000404, 0x04021005, 0x42001000, 0x00000004,
+       0x801020c4, 0x0401f00c, 0x82040480, 0x0000056c,
+       0x04021006, 0x42001000, 0x00000003, 0x801000c2,
+       0x80102400, 0x0401f004, 0x42001000, 0x00000002,
+       0x801020c2, 0x82100480, 0x00000110, 0x80000080,
+       0x80002000, 0x800800d0, 0x80140540, 0x80100540,
+       0x48039035, 0x1c01f000, 0x59c80815, 0x0201f800,
+       0x001005d0, 0x82040d00, 0x0000007c, 0x48079000,
+       0x59c80000, 0x80040500, 0x040207fe, 0x8c040d04,
+       0x04000003, 0x59c80035, 0x48039035, 0x59c80000,
+       0x82000540, 0x00001200, 0x48039000, 0x1c01f000,
+       0x4803c856, 0x497b88a9, 0x4a038807, 0x00000001,
+       0x497b8807, 0x59c40005, 0x48038805, 0x0201f800,
+       0x00101815, 0x4201d000, 0x000001f4, 0x0201f800,
+       0x0010608e, 0x497b880e, 0x4200b000, 0x000001f4,
+       0x42000000, 0x00000001, 0x42000800, 0x00000014,
+       0x0201f800, 0x00101944, 0x42000800, 0x00000014,
+       0x0201f800, 0x0010193f, 0x8c040d00, 0x04000005,
+       0x8058b040, 0x040207f3, 0x0201f800, 0x001005d8,
+       0x4200b000, 0x00000032, 0x42000000, 0x00000001,
+       0x42000800, 0x000000b4, 0x0201f800, 0x00101944,
+       0x42000800, 0x000000b4, 0x0201f800, 0x0010193f,
+       0x8c040d00, 0x04000005, 0x8058b040, 0x040207f3,
+       0x0201f800, 0x001005d8, 0x59c40005, 0x48038805,
+       0x42000000, 0x00000089, 0x800008d0, 0x48075054,
+       0x48075055, 0x48075056, 0x42000800, 0x000000e0,
+       0x0201f800, 0x00101944, 0x42000800, 0x000000f4,
+       0x0201f800, 0x0010193f, 0x82040500, 0xffffffd1,
+       0x82000540, 0x00000002, 0x42000800, 0x000000f4,
+       0x0201f800, 0x00101944, 0x42000800, 0x000000a0,
+       0x0201f800, 0x0010193f, 0x82040540, 0x00000001,
+       0x42000800, 0x000000a0, 0x0201f800, 0x00101944,
+       0x42000800, 0x00000000, 0x0201f800, 0x0010193f,
+       0x82040540, 0x00000001, 0x42000800, 0x00000000,
+       0x0201f800, 0x00101944, 0x4201d000, 0x0001d4c0,
+       0x0201f800, 0x0010608e, 0x0401fa2b, 0x4a0388a7,
+       0x0000f7f7, 0x4a0388a3, 0x8000403c, 0x4a0388ae,
+       0x000061a8, 0x4a038801, 0x00032063, 0x4a038810,
+       0x00410108, 0x4a038811, 0x00520608, 0x4a038812,
+       0x00450320, 0x4a038813, 0x00440405, 0x4a03881c,
+       0x004132e1, 0x4a038850, 0x80000108, 0x4a038860,
+       0x00000008, 0x4a038870, 0x00000008, 0x4a038851,
+       0x80000508, 0x4a038861, 0x00800000, 0x4a038871,
+       0x00800000, 0x4a038852, 0x80000708, 0x4a038862,
+       0x00800000, 0x4a038872, 0x00800000, 0x4a038853,
+       0x80000608, 0x497b8863, 0x4a038873, 0x00800000,
+       0x4a038882, 0x00000840, 0x4a0388a5, 0x0000001e,
+       0x4a0388a6, 0x0000001e, 0x4a0388b0, 0x00007530,
+       0x4a038802, 0x0000ffff, 0x4a038806, 0xc0e00800,
+       0x1c01f000, 0x497b5022, 0x4a035021, 0x00000001,
+       0x42000800, 0x00000040, 0x0201f800, 0x0010193f,
+       0x82040500, 0xffffffaf, 0x82000540, 0x00000000,
+       0x42000800, 0x00000040, 0x0201f800, 0x00101944,
+       0x42000800, 0x000000f4, 0x0201f800, 0x0010193f,
+       0x4c040000, 0x40040000, 0x84000548, 0x42000800,
+       0x000000f4, 0x0201f800, 0x00101944, 0x42000800,
+       0x00000000, 0x0201f800, 0x0010193f, 0x82040500,
+       0xffffffc1, 0x82000540, 0x00000038, 0x42000800,
+       0x00000000, 0x0201f800, 0x00101944, 0x5c000000,
+       0x42000800, 0x000000f4, 0x0201f000, 0x00101944,
+       0x59c40805, 0x4807c857, 0x59c40006, 0x80040d00,
+       0x02000800, 0x001005d8, 0x82040500, 0x00e00800,
+       0x04020004, 0x8c040d3e, 0x040208c4, 0x0401f007,
+       0x82040500, 0x00800800, 0x02020800, 0x001005d0,
+       0x0201f800, 0x001005d8, 0x4c5c0000, 0x4c600000,
+       0x59c4b805, 0x485fc857, 0x59c40006, 0x8c000500,
+       0x04000003, 0x8c5cbd00, 0x04020079, 0x0201f800,
+       0x0010513b, 0x04000014, 0x59c40005, 0x82000500,
+       0x000000c0, 0x04000036, 0x0201f800, 0x00105151,
+       0x04020033, 0x4a038805, 0x04000000, 0x59c400a3,
+       0x82000500, 0xbf203fff, 0x480388a3, 0x497b5049,
+       0x4a038805, 0x000000c0, 0x0201f800, 0x00105065,
+       0x0401f063, 0x8c5cbd34, 0x04020025, 0x59c40005,
+       0x8c00050c, 0x04020012, 0x8c00050e, 0x04020013,
+       0x8c00050a, 0x04020014, 0x8c000508, 0x0400000b,
+       0x59a80017, 0x82000580, 0x00000009, 0x04020007,
+       0x42000000, 0x0010b844, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x00105318, 0x0401f04b, 0x4a035033,
+       0x00000000, 0x0401f00b, 0x4a035033, 0x00000002,
+       0x0401f008, 0x42000000, 0x0010b846, 0x0201f800,
+       0x0010aa47, 0x0201f800, 0x001052c2, 0x0401f03e,
+       0x0201f800, 0x00105378, 0x0401f03b, 0x8c5cbd34,
+       0x04000037, 0x59c40005, 0x8c00053a, 0x04020005,
+       0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+       0x4a038805, 0x02000000, 0x0201f800, 0x0010513b,
+       0x04020010, 0x4a038805, 0x04000000, 0x0201f800,
+       0x00105149, 0x04020008, 0x4a035033, 0x00000001,
+       0x4202d800, 0x00000001, 0x0201f800, 0x001050a2,
+       0x0401f05b, 0x41780000, 0x0201f800, 0x00105113,
+       0x0201f800, 0x001019fe, 0x4000c000, 0x0201f800,
+       0x00101963, 0x836c1580, 0x00000004, 0x0402000d,
+       0x8c5cbd00, 0x04020012, 0x59a81005, 0x8c081506,
+       0x04020005, 0x59c410a3, 0x82081540, 0x00000008,
+       0x480b88a3, 0x59c41006, 0x84081540, 0x480b8806,
+       0x4a038805, 0x04000000, 0x4202d800, 0x00000001,
+       0x497b5014, 0x0201f800, 0x00103b38, 0x8c5cbd3c,
+       0x04020858, 0x8c5cbd00, 0x04000036, 0x42000000,
+       0x0010b8ca, 0x0201f800, 0x0010aa47, 0x4a038805,
+       0x00000001, 0x4200b000, 0x000003e8, 0x4201d000,
+       0x00000064, 0x4c580000, 0x0201f800, 0x0010608e,
+       0x0201f800, 0x001018d3, 0x5c00b000, 0x04000004,
+       0x8058b040, 0x040207f6, 0x0401f004, 0x4a038805,
+       0x00000001, 0x0401f01f, 0x59c40006, 0x84000500,
+       0x48038806, 0x0201f800, 0x00106ede, 0x497b8880,
+       0x0201f800, 0x0010a9c0, 0x59c4000d, 0x8c000500,
+       0x02020800, 0x0010a9ce, 0x59c400a3, 0x82000500,
+       0xfcf8ffff, 0x480388a3, 0x4a03504c, 0x00000002,
+       0x4202d800, 0x00000004, 0x4a038805, 0x00000001,
+       0x0201f800, 0x001006d4, 0x0401fb3b, 0x497b5052,
+       0x4a035049, 0x00000001, 0x0201f800, 0x00100452,
+       0x825cbd00, 0xbbfffffe, 0x485f8805, 0x5c00c000,
+       0x5c00b800, 0x1c01f000, 0x59c41004, 0x480bc857,
+       0x8c081500, 0x04000006, 0x4803c856, 0x497b2807,
+       0x0201f800, 0x00106fa4, 0x0401f00a, 0x82080500,
+       0x000001f0, 0x04000007, 0x4803c856, 0x417a3000,
+       0x0201f800, 0x00106062, 0x0201f800, 0x00106fc6,
+       0x4a038805, 0x80000000, 0x1c01f000, 0x59c408a3,
+       0x4807c857, 0x84040d40, 0x480788a3, 0x1c01f000,
+       0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+       0x4a038805, 0x40000000, 0x42000000, 0x0010b8c6,
+       0x0201f800, 0x0010aa47, 0x0201f800, 0x00106c55,
+       0x59c41004, 0x8c081500, 0x04000054, 0x598e600d,
+       0x497b2807, 0x813261c0, 0x04000032, 0x59300403,
+       0x82000580, 0x00000032, 0x0402002e, 0x5930001c,
+       0x48038833, 0x4a038807, 0x00018000, 0x4201d000,
+       0x00000002, 0x0201f800, 0x0010608e, 0x497b8807,
+       0x4201d000, 0x00000002, 0x0201f800, 0x0010608e,
+       0x0201f800, 0x00106e21, 0x4201d000, 0x00007530,
+       0x0201f800, 0x0010608e, 0x59c408a4, 0x82040d00,
+       0x0000000f, 0x82040d80, 0x00000000, 0x04000005,
+       0x42000000, 0x00200000, 0x0201f800, 0x00101949,
+       0x0201f800, 0x00106bbf, 0x59300008, 0x80000540,
+       0x02000800, 0x001005d8, 0x40025800, 0x4a025a04,
+       0x00000103, 0x5931d821, 0x58ef400b, 0x58ec0009,
+       0x0801f800, 0x0201f800, 0x0002077d, 0x0401f047,
+       0x598c000f, 0x82001c80, 0x000000c8, 0x0402100f,
+       0x80000000, 0x4803180f, 0x59c400a4, 0x82000500,
+       0x0000000f, 0x82000580, 0x00000002, 0x04020004,
+       0x42000000, 0x00200000, 0x0401fbf7, 0x0201f800,
+       0x0010604d, 0x0401f035, 0x4933c857, 0x0201f800,
+       0x00106e21, 0x813261c0, 0x04000030, 0x4a026203,
+       0x00000001, 0x42027000, 0x00000027, 0x0201f800,
+       0x000207a1, 0x0401f029, 0x8c081508, 0x04000027,
+       0x417a3000, 0x0201f800, 0x001070d8, 0x42032000,
+       0x0000bf32, 0x0201f800, 0x00106062, 0x59926004,
+       0x813261c0, 0x04000012, 0x42001800, 0x000000c8,
+       0x0201f800, 0x001070a4, 0x0402000d, 0x59c400a4,
+       0x82000500, 0x0000000f, 0x82000580, 0x00000002,
+       0x04020004, 0x42000000, 0x00200000, 0x0401fbce,
+       0x0201f800, 0x00106052, 0x0401f00c, 0x4933c857,
+       0x0201f800, 0x00106dc3, 0x813261c0, 0x04000007,
+       0x42027000, 0x0000004f, 0x4a026203, 0x00000003,
+       0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800,
+       0x5c03a000, 0x5c032000, 0x0201f000, 0x00106c4b,
+       0x4803c857, 0x59a80821, 0x48035021, 0x80041580,
+       0x04000045, 0x800409c0, 0x04000023, 0x497b504c,
+       0x42000000, 0x0010b80d, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x0010aaf9, 0x42001000, 0x00008011,
+       0x59c40001, 0x82000500, 0x00018000, 0x82001d80,
+       0x00000000, 0x04000009, 0x82001d80, 0x00008000,
+       0x04000009, 0x82001d80, 0x00010000, 0x04000009,
+       0x0201f800, 0x001005d8, 0x42001800, 0x00000000,
+       0x0401f006, 0x42001800, 0x00000001, 0x0401f003,
+       0x42001800, 0x00000003, 0x0201f800, 0x00103a3e,
+       0x0401f021, 0x59a8084c, 0x800409c0, 0x04020007,
+       0x59c4000d, 0x8c000520, 0x04000004, 0x42001800,
+       0x00000003, 0x0401f002, 0x40041800, 0x0201f800,
+       0x0010aadd, 0x42001000, 0x00008012, 0x0201f800,
+       0x00103a3e, 0x0201f800, 0x001006d4, 0x0201f800,
+       0x0010ab33, 0x0402000c, 0x0401f853, 0x4d400000,
+       0x4d3c0000, 0x42028000, 0x00000028, 0x42027800,
+       0x00000408, 0x0201f800, 0x00101fe5, 0x5c027800,
+       0x5c028000, 0x1c01f000, 0x4803c857, 0x82000400,
+       0x0010210e, 0x50000800, 0x82040d00, 0x000000ff,
+       0x1c01f000, 0x4803c856, 0x4c580000, 0x4200b000,
+       0x00000010, 0x497b88ac, 0x497b88ad, 0x8058b040,
+       0x040207fe, 0x5c00b000, 0x1c01f000, 0x4807c857,
+       0x48075010, 0x80041108, 0x4200b000, 0x00000010,
+       0x497b88ac, 0x80000580, 0x800811c0, 0x04020006,
+       0x82040500, 0x0000000f, 0x82000400, 0x0010ab38,
+       0x50000000, 0x480388ad, 0x80081040, 0x8058b040,
+       0x040207f5, 0x1c01f000, 0x59a80005, 0x04000003,
+       0x84000546, 0x0401f002, 0x84000506, 0x48035005,
+       0x4803c857, 0x1c01f000, 0x4803c857, 0x4c080000,
+       0x4c040000, 0x4c000000, 0x59c40892, 0x4807c857,
+       0x80041580, 0x04000010, 0x80041480, 0x04021007,
+       0x80081080, 0x80081000, 0x4008b000, 0x42000000,
+       0x00000201, 0x0401f004, 0x4008b000, 0x42000000,
+       0x00000210, 0x48038886, 0x8058b040, 0x040207fe,
+       0x497b8886, 0x5c000000, 0x5c000800, 0x5c001000,
+       0x1c01f000, 0x4803c856, 0x0201f800, 0x00103b25,
+       0x04000005, 0x42028000, 0x0000002e, 0x0201f000,
+       0x0010a449, 0x1c01f000, 0x42000800, 0x00000002,
+       0x59a80005, 0x8c000514, 0x0402000b, 0x59c80835,
+       0x82040d00, 0x00001f00, 0x80040910, 0x80040800,
+       0x59a8006c, 0x80000540, 0x04000003, 0x42000800,
+       0x0000025a, 0x4807c857, 0x1c01f000, 0x4c000000,
+       0x59a80053, 0x4803c857, 0x82000580, 0x00000000,
+       0x5c000000, 0x1c01f000, 0x4c000000, 0x59a80053,
+       0x4803c857, 0x82000580, 0x00000001, 0x5c000000,
+       0x1c01f000, 0x4c000000, 0x59a80053, 0x4803c857,
+       0x82000580, 0x00000003, 0x5c000000, 0x1c01f000,
+       0x4c000000, 0x59a80053, 0x82000580, 0x00000002,
+       0x5c000000, 0x1c01f000, 0x4c000000, 0x4c040000,
+       0x4c080000, 0x4c380000, 0x59a80040, 0x82000c80,
+       0x00000007, 0x02021800, 0x001005d8, 0x0c01f806,
+       0x5c007000, 0x5c001000, 0x5c000800, 0x5c000000,
+       0x1c01f000, 0x0010166c, 0x0010167f, 0x00101693,
+       0x00101695, 0x001016bc, 0x001016be, 0x001016c0,
+       0x4803c856, 0x4a035042, 0x00000000, 0x42000000,
+       0x00000002, 0x0401fa1b, 0x42000000, 0x00000002,
+       0x0401f9ad, 0x0401fab2, 0x4803c856, 0x4a035040,
+       0x00000006, 0x42000800, 0x0000001e, 0x42001000,
+       0x001016c1, 0x0201f000, 0x0010606e, 0x497b5045,
+       0x4a035050, 0x00000036, 0x4a03504f, 0x0000002a,
+       0x4803c856, 0x4a035042, 0x00000001, 0x42000000,
+       0x00000002, 0x0401f998, 0x4803c856, 0x4a035040,
+       0x00000006, 0x42000800, 0x0000001e, 0x42001000,
+       0x001016c1, 0x0201f000, 0x0010606e, 0x0201f800,
+       0x001005d8, 0x4a035050, 0x00000036, 0x4803c856,
+       0x4a035042, 0x00000003, 0x42000800, 0x00000000,
+       0x0401faa3, 0x82040d00, 0x00000090, 0x82040580,
+       0x00000090, 0x04000009, 0x82040580, 0x00000010,
+       0x04000009, 0x82040580, 0x00000000, 0x04000008,
+       0x0201f800, 0x001005d8, 0x42000000, 0x00000001,
+       0x0401f005, 0x41780000, 0x0401f003, 0x42000000,
+       0x00000002, 0x0401f970, 0x497b5046, 0x4803c856,
+       0x4a035040, 0x00000006, 0x42000800, 0x0000001e,
+       0x42001000, 0x001016c1, 0x0201f000, 0x0010606e,
+       0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8,
+       0x1c01f000, 0x4c000000, 0x4c040000, 0x4c080000,
+       0x4c380000, 0x59a80042, 0x82000c80, 0x00000007,
+       0x02021800, 0x001005d8, 0x0c01f806, 0x5c007000,
+       0x5c001000, 0x5c000800, 0x5c000000, 0x1c01f000,
+       0x001016d7, 0x001016f6, 0x0010174a, 0x00101761,
+       0x00101778, 0x00101781, 0x00101783, 0x0401f9fc,
+       0x0402001b, 0x59a81048, 0x42000800, 0x00000000,
+       0x0401fa63, 0x82040d00, 0x00000090, 0x82040580,
+       0x00000090, 0x04000009, 0x82040580, 0x00000010,
+       0x04000008, 0x82040580, 0x00000000, 0x04000007,
+       0x0201f800, 0x001005d8, 0x84081540, 0x0401f004,
+       0x84081542, 0x0401f002, 0x84081544, 0x480b5048,
+       0x4a035040, 0x00000001, 0x0401f003, 0x0401f8cb,
+       0x0401ff82, 0x1c01f000, 0x0401f88f, 0x04000052,
+       0x0401f9db, 0x0402002a, 0x42000800, 0x00000000,
+       0x0401fa43, 0x82040d00, 0x00000090, 0x82040580,
+       0x00000000, 0x04000044, 0x82040580, 0x00000010,
+       0x04000006, 0x82040580, 0x00000090, 0x04000009,
+       0x0201f800, 0x001005d8, 0x59c40801, 0x82040d00,
+       0x00018000, 0x82040580, 0x00000000, 0x04000036,
+       0x42000800, 0x00000000, 0x0401fa2d, 0x82040d00,
+       0x00000090, 0x82040580, 0x00000010, 0x04000006,
+       0x82040580, 0x00000090, 0x04000006, 0x02020800,
+       0x001005d8, 0x59a80048, 0x84000542, 0x0401f003,
+       0x59a80048, 0x84000540, 0x48035048, 0x59a80045,
+       0x80000000, 0x48035045, 0x82000580, 0x00000005,
+       0x04000003, 0x0401f861, 0x0401f01e, 0x497b5045,
+       0x59c40801, 0x82040d00, 0x00018000, 0x82040580,
+       0x00000000, 0x04000009, 0x82040580, 0x00008000,
+       0x04000009, 0x82040580, 0x00010000, 0x04000008,
+       0x0201f800, 0x001005d8, 0x42000000, 0x00000001,
+       0x0401f005, 0x41780000, 0x0401f003, 0x42000000,
+       0x00000002, 0x0401f94b, 0x4a035042, 0x00000002,
+       0x0401f004, 0x4a035040, 0x00000003, 0x0401f002,
+       0x0401ff42, 0x1c01f000, 0x0401f83b, 0x04000015,
+       0x59a8004f, 0x80000040, 0x4803504f, 0x0401f984,
+       0x04020005, 0x4a035040, 0x00000003, 0x497b5041,
+       0x0401f00c, 0x59a8004f, 0x80000540, 0x04020003,
+       0x0401f89e, 0x0401f002, 0x0401f84b, 0x0401f82f,
+       0x497b5045, 0x4a035042, 0x00000001, 0x0401ff2b,
+       0x1c01f000, 0x0401f824, 0x04000015, 0x0401f970,
+       0x0402000f, 0x59a80046, 0x80000000, 0x48035046,
+       0x82000580, 0x00000007, 0x0402000c, 0x4a035052,
+       0x0000000a, 0x497b5049, 0x59a80048, 0x8400055e,
+       0x48035048, 0x4803c857, 0x0401f005, 0x0401f817,
+       0x4a035042, 0x00000004, 0x0401ff3d, 0x1c01f000,
+       0x0401f80d, 0x04000007, 0x0401f959, 0x04020003,
+       0x0401ff1b, 0x0401f003, 0x0401f80c, 0x0401ff34,
+       0x1c01f000, 0x0201f800, 0x001005d8, 0x0201f800,
+       0x001005d8, 0x59a80050, 0x80000040, 0x48035050,
+       0x0400088d, 0x1c01f000, 0x4c040000, 0x42000800,
+       0x00000000, 0x0401f9b2, 0x82040d00, 0x00000090,
+       0x82040580, 0x00000090, 0x04000009, 0x82040580,
+       0x00000010, 0x04000009, 0x82040580, 0x00000000,
+       0x04000009, 0x0201f800, 0x001005d8, 0x42000000,
+       0x00000002, 0x0401f005, 0x42000000, 0x00000001,
+       0x0401f002, 0x41780000, 0x0401f8ea, 0x5c000800,
+       0x1c01f000, 0x4c040000, 0x59c40801, 0x82040d00,
+       0x00018000, 0x82040580, 0x00000000, 0x04000009,
+       0x82040580, 0x00008000, 0x04000009, 0x82040580,
+       0x00010000, 0x04000009, 0x0201f800, 0x001005d8,
+       0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+       0x00000001, 0x0401f002, 0x41780000, 0x0401f866,
+       0x5c000800, 0x1c01f000, 0x4c040000, 0x59a80045,
+       0x80000000, 0x48035045, 0x82000580, 0x00000005,
+       0x04020018, 0x497b5045, 0x59c40801, 0x82040d00,
+       0x00018000, 0x82040580, 0x00000000, 0x04000009,
+       0x82040580, 0x00008000, 0x04000009, 0x82040580,
+       0x00010000, 0x04000009, 0x0201f800, 0x001005d8,
+       0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+       0x00000001, 0x0401f002, 0x41780000, 0x0401f846,
+       0x42000800, 0x00000000, 0x0401f961, 0x82040d00,
+       0x00000090, 0x82040580, 0x00000090, 0x04000009,
+       0x82040580, 0x00000010, 0x04000009, 0x82040580,
+       0x00000000, 0x04000009, 0x0201f800, 0x001005d8,
+       0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+       0x00000001, 0x0401f002, 0x41780000, 0x0401f899,
+       0x5c000800, 0x1c01f000, 0x4c200000, 0x59a80048,
+       0x82000500, 0x00007fff, 0x02000800, 0x001005d8,
+       0x59a84047, 0x80204102, 0x02001800, 0x001005d8,
+       0x48235047, 0x80204500, 0x040007fa, 0x8c000504,
+       0x04020007, 0x8c000502, 0x04020008, 0x8c000500,
+       0x04020008, 0x0201f800, 0x001005d8, 0x42000000,
+       0x00000002, 0x0401f005, 0x41780000, 0x0401f003,
+       0x42000000, 0x00000001, 0x0401f80f, 0x5c004000,
+       0x1c01f000, 0x04011000, 0x4a03c840, 0x0010b440,
+       0x4a03c842, 0x00000009, 0x40000000, 0x040117ff,
+       0x4a035047, 0x00000004, 0x4a03503e, 0x00000000,
+       0x1c01f000, 0x59a80858, 0x82040d80, 0x01391077,
+       0x04020008, 0x59e00813, 0x8c040d00, 0x04000005,
+       0x82000d80, 0x00000002, 0x04020002, 0x41780000,
+       0x4c000000, 0x0401f9b1, 0x5c000000, 0x800001c0,
+       0x04000040, 0x82000d80, 0x00000001, 0x0402001d,
+       0x42000800, 0x000000a0, 0x0401f909, 0x82040540,
+       0x00000004, 0x42000800, 0x000000a0, 0x0401f909,
+       0x42000800, 0x000000c0, 0x0401f901, 0x82040540,
+       0x00000020, 0x42000800, 0x000000c0, 0x0401f901,
+       0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+       0x00000000, 0x48038801, 0x59a80054, 0x80000110,
+       0x42000800, 0x000000e0, 0x0401f8f6, 0x0401f03c,
+       0x82000d80, 0x00000002, 0x02020800, 0x001005d8,
+       0x42000800, 0x000000a0, 0x0401f8e9, 0x82040500,
+       0xfffffffb, 0x42000800, 0x000000a0, 0x0401f8e9,
+       0x42000800, 0x000000c0, 0x0401f8e1, 0x82040500,
+       0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8e1,
+       0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+       0x00010000, 0x48038801, 0x59a80056, 0x80000110,
+       0x42000800, 0x000000e0, 0x0401f8d6, 0x0401f01c,
+       0x42000800, 0x000000a0, 0x0401f8cd, 0x82040540,
+       0x00000004, 0x42000800, 0x000000a0, 0x0401f8cd,
+       0x42000800, 0x000000c0, 0x0401f8c5, 0x82040500,
+       0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8c5,
+       0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+       0x00008000, 0x48038801, 0x59a80055, 0x80000110,
+       0x42000800, 0x000000e0, 0x0401f8ba, 0x0401f163,
+       0x4803c857, 0x59a80858, 0x82040d80, 0x01391077,
+       0x04020008, 0x59e00813, 0x8c040d00, 0x04000005,
+       0x82000d80, 0x00000002, 0x04020002, 0x41780000,
+       0x4c000000, 0x0401f94d, 0x5c000000, 0x800001c0,
+       0x04000026, 0x82000d80, 0x00000001, 0x04020010,
+       0x59a8006c, 0x80000540, 0x04000004, 0x42001000,
+       0x00000000, 0x0401fa0a, 0x42000800, 0x00000000,
+       0x0401f897, 0x82040540, 0x00000090, 0x42000800,
+       0x00000000, 0x0401f897, 0x0401f024, 0x82000d80,
+       0x00000002, 0x02020800, 0x001005d8, 0x59a8006c,
+       0x80000540, 0x04000004, 0x42001000, 0x00010000,
+       0x0401f9f7, 0x42000800, 0x00000000, 0x0401f884,
+       0x82040500, 0xffffff6f, 0x42000800, 0x00000000,
+       0x0401f884, 0x0401f011, 0x59a8006c, 0x80000540,
+       0x04000004, 0x42001000, 0x00008000, 0x0401f9e8,
+       0x42000800, 0x00000000, 0x0401f875, 0x82040500,
+       0xffffff6f, 0x82000540, 0x00000010, 0x42000800,
+       0x00000000, 0x0401f873, 0x0401f124, 0x4c580000,
+       0x4200b000, 0x00000014, 0x8058b040, 0x04000043,
+       0x59c4000d, 0x8c000520, 0x040207fc, 0x0401f85c,
+       0x59c4000d, 0x8c000520, 0x040207f8, 0x59c40808,
+       0x84040d50, 0x48078808, 0x4200b000, 0x000000c8,
+       0x8058b040, 0x040207ff, 0x4200b000, 0x00000014,
+       0x8058b040, 0x04000031, 0x59c4000d, 0x8c000520,
+       0x0402002e, 0x42000800, 0x00001000, 0x50040800,
+       0x82040c80, 0x24220001, 0x04020003, 0x8c000504,
+       0x040007f4, 0x0401f842, 0x59c4000d, 0x8c000520,
+       0x04020022, 0x42000800, 0x00001000, 0x50040800,
+       0x82040c80, 0x24220001, 0x04020003, 0x8c000504,
+       0x040007e8, 0x4200b000, 0x0000000a, 0x8058b040,
+       0x04000003, 0x0401f832, 0x0401f7fd, 0x4200b000,
+       0x00000064, 0x59c4000d, 0x8c00051e, 0x0400000f,
+       0x8058b040, 0x040207fc, 0x42000000, 0x00001000,
+       0x50000000, 0x82000480, 0x24220001, 0x04020004,
+       0x59c40808, 0x84040d10, 0x48078808, 0x80000580,
+       0x4803c857, 0x0401f00c, 0x42000000, 0x00001000,
+       0x50000000, 0x82000480, 0x24220001, 0x04020004,
+       0x59c40808, 0x84040d10, 0x48078808, 0x82000540,
+       0x00000001, 0x5c00b000, 0x1c01f000, 0x42000800,
+       0x000000a0, 0x0401f816, 0x82040500, 0xfffffffe,
+       0x42000800, 0x000000a0, 0x0401f816, 0x42000800,
+       0x00000000, 0x0401f80e, 0x82040500, 0xfffffffe,
+       0x42000800, 0x00000000, 0x0401f00e, 0x40000000,
+       0x40000000, 0x40000000, 0x40000000, 0x40000000,
+       0x1c01f000, 0x480b8805, 0x1c01f000, 0x4807880e,
+       0x59c4080f, 0x82040d00, 0x000000ff, 0x1c01f000,
+       0x900001c0, 0x80040d40, 0x84040d40, 0x4807880e,
+       0x1c01f000, 0x82000d80, 0x00200000, 0x04000009,
+       0x82000d80, 0x02000000, 0x04000006, 0x82000d80,
+       0x01000000, 0x04000006, 0x59c408a3, 0x0401f006,
+       0x59c408a3, 0x84040d30, 0x0401f003, 0x59c408a3,
+       0x84040d32, 0x80040540, 0x480388a3, 0x480788a3,
+       0x1c01f000, 0x59c400a3, 0x84000556, 0x480388a3,
+       0x84000516, 0x480388a3, 0x1c01f000, 0x485fc857,
+       0x4863c857, 0x4c640000, 0x4d3c0000, 0x4d400000,
+       0x0201f800, 0x00106ede, 0x4863500a, 0x0201f800,
+       0x0010ab33, 0x0402006c, 0x82600d00, 0x0000ff00,
+       0x800409c0, 0x0400000c, 0x4200c800, 0x00000001,
+       0x59a80010, 0x82000500, 0x000000ff, 0x80041110,
+       0x80081580, 0x04000021, 0x82041580, 0x0000ff00,
+       0x0400000a, 0x59c410a3, 0x82081500, 0x00008000,
+       0x04000009, 0x59c410a7, 0x82081500, 0x0000ff00,
+       0x82081580, 0x0000ff00, 0x4200c800, 0x00000000,
+       0x04000012, 0x59a80005, 0x8c000502, 0x04020008,
+       0x8c000500, 0x0402000d, 0x599c1017, 0x8c08151a,
+       0x0400003e, 0x84000542, 0x48035005, 0x4200c800,
+       0x00000002, 0x42028000, 0x00000004, 0x42027800,
+       0x00000008, 0x0401f008, 0x59a80805, 0x84040d40,
+       0x48075005, 0x42028000, 0x00000004, 0x42027800,
+       0x00000400, 0x59a80006, 0x8c000502, 0x04020006,
+       0x59a80805, 0x8c040d0a, 0x04020033, 0x84040d4a,
+       0x48075005, 0x42000000, 0x0010b812, 0x0201f800,
+       0x0010aa47, 0x59a8180a, 0x42001000, 0x00008013,
+       0x0201f800, 0x00103a3e, 0x0201f800, 0x00103b25,
+       0x04000015, 0x4d400000, 0x82600500, 0x000000ff,
+       0x42028800, 0x0000ffff, 0x40643000, 0x42028000,
+       0x0000000e, 0x0201f800, 0x0010a446, 0x42000800,
+       0x00000001, 0x42001000, 0x00000100, 0x0201f800,
+       0x0010618b, 0x5c028000, 0x599c0817, 0x8c040d0a,
+       0x04020011, 0x493fc857, 0x4943c857, 0x0201f800,
+       0x00101fe5, 0x0401f00c, 0x0201f800, 0x00103b25,
+       0x04000009, 0x42028000, 0x0000000f, 0x42028800,
+       0x0000ffff, 0x42003000, 0x00000000, 0x0201f800,
+       0x0010a449, 0x497b8880, 0x5c028000, 0x5c027800,
+       0x5c00c800, 0x1c01f000, 0x42000800, 0x000000a0,
+       0x0401ff5f, 0x82040540, 0x00000002, 0x42000800,
+       0x000000a0, 0x0401f75f, 0x42000800, 0x00000000,
+       0x0401ff57, 0x82040540, 0x00000002, 0x42000800,
+       0x00000000, 0x0401f757, 0x42000800, 0x000000a0,
+       0x0401ff4f, 0x82040500, 0xfffffffd, 0x42000800,
+       0x000000a0, 0x0401f74f, 0x42000800, 0x00000000,
+       0x0401ff47, 0x82040500, 0xfffffffd, 0x42000800,
+       0x00000000, 0x0401f747, 0x59c408a8, 0x0401ff38,
+       0x0401ff37, 0x59c400a8, 0x80040d80, 0x040207fb,
+       0x1c01f000, 0x4803c856, 0x4a038807, 0x00000001,
+       0x497b8807, 0x59c40005, 0x48038805, 0x497b506c,
+       0x497b506d, 0x41785800, 0x42006000, 0x00000001,
+       0x42006800, 0x00000003, 0x0401f824, 0x0401f82f,
+       0x40400000, 0x4803c857, 0x82408580, 0x00000000,
+       0x0402001d, 0x41785800, 0x42006000, 0x0000001e,
+       0x42006800, 0x00000014, 0x0401f818, 0x0401f823,
+       0x40400000, 0x4803c857, 0x82408580, 0x00000800,
+       0x04020011, 0x42005800, 0x00000001, 0x42006000,
+       0x0000001e, 0x42006800, 0x00000014, 0x0401f80b,
+       0x0401f816, 0x40400000, 0x4803c857, 0x82408580,
+       0x0000ffff, 0x04020004, 0x4a03506c, 0x00000001,
+       0x4803c856, 0x1c01f000, 0x41785000, 0x0401f812,
+       0x0401f838, 0x40347000, 0x40340800, 0x0401f03d,
+       0x42005000, 0x00000001, 0x0401f80b, 0x0401f831,
+       0x40340800, 0x0401f037, 0x42005000, 0x00000002,
+       0x0401f805, 0x0401f81d, 0x0401f835, 0x40048000,
+       0x1c01f000, 0x0401f808, 0x0401f814, 0x40280800,
+       0x0401f826, 0x402c0800, 0x0401f827, 0x40300800,
+       0x0401f025, 0x42000800, 0x0000ffff, 0x42001000,
+       0x00000001, 0x0401f829, 0x42001000, 0x00000010,
+       0x0401f826, 0x42000800, 0x0000ffff, 0x42001000,
+       0x00000010, 0x0401f021, 0x41780800, 0x42001000,
+       0x00000002, 0x0401f01d, 0x0401f92e, 0x4a03d000,
+       0x00050004, 0x0401f92b, 0x4a03d000, 0x00050005,
+       0x0401f928, 0x4a03d000, 0x00050004, 0x42000800,
+       0x00000001, 0x42001000, 0x00000001, 0x0401f00f,
+       0x42000800, 0x00000002, 0x42001000, 0x00000002,
+       0x0401f00a, 0x42001000, 0x00000005, 0x0401f007,
+       0x42001000, 0x00000010, 0x0401f004, 0x42001000,
+       0x00000010, 0x0401f01b, 0x0401f912, 0x82082c00,
+       0x0010ab38, 0x50142800, 0x82081500, 0xffffffff,
+       0x04000013, 0x0401f90b, 0x80081040, 0x80142902,
+       0x40040000, 0x80140500, 0x04000007, 0x4a03d000,
+       0x00070006, 0x0401f903, 0x4a03d000, 0x00070007,
+       0x0401f006, 0x4a03d000, 0x00070004, 0x0401f8fd,
+       0x4a03d000, 0x00070005, 0x0401f7ec, 0x1c01f000,
+       0x41780800, 0x82082c00, 0x0010ab38, 0x50142800,
+       0x82081500, 0xffffffff, 0x04000010, 0x0401f8f1,
+       0x4a03d000, 0x00050001, 0x0401f8ee, 0x59e81800,
+       0x80081040, 0x80142902, 0x8c0c1d06, 0x04000004,
+       0x40140000, 0x80040d40, 0x0401f8e6, 0x4a03d000,
+       0x00070000, 0x0401f7ef, 0x1c01f000, 0x480bc857,
+       0x480b506d, 0x59c40001, 0x82000500, 0xffffefff,
+       0x48038801, 0x41781800, 0x0401f8c4, 0x41785800,
+       0x42006000, 0x0000001e, 0x42006800, 0x00000004,
+       0x0401ff7a, 0x42006800, 0x0000003c, 0x0401ff7d,
+       0x41785800, 0x42006000, 0x0000001e, 0x42006800,
+       0x00000004, 0x0401ff71, 0x41786800, 0x0401ff75,
+       0x41785800, 0x42006000, 0x0000001e, 0x41786800,
+       0x0401ff6a, 0x42006800, 0x00000002, 0x0401ff6d,
+       0x42006800, 0x00000001, 0x0401ff64, 0x42006800,
+       0x000000f5, 0x0401ff67, 0x41785800, 0x42006000,
+       0x0000001e, 0x42006800, 0x00000004, 0x0401ff5b,
+       0x42006800, 0x00000020, 0x0401ff5e, 0x59a8106d,
+       0x0401f865, 0x42001800, 0x000200f5, 0x0401f897,
+       0x59a8106d, 0x0401f879, 0x41785800, 0x42006000,
+       0x0000001e, 0x42006800, 0x00000004, 0x0401ff4b,
+       0x41786800, 0x0401ff4f, 0x59c40001, 0x82000540,
+       0x00001000, 0x48038801, 0x41785800, 0x42006000,
+       0x0000001e, 0x42006800, 0x00000015, 0x0401ff3f,
+       0x0401ff4a, 0x40400000, 0x82000540, 0x00000002,
+       0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+       0x42006800, 0x00000015, 0x0401ff34, 0x5c000000,
+       0x40006800, 0x0401ff37, 0x41785800, 0x42006000,
+       0x0000001e, 0x42006800, 0x00000015, 0x0401ff2b,
+       0x0401ff36, 0x40400000, 0x82000500, 0x0000fffd,
+       0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+       0x42006800, 0x00000015, 0x0401ff20, 0x5c000000,
+       0x40006800, 0x0401ff23, 0x41785800, 0x42006000,
+       0x0000001e, 0x42006800, 0x00000014, 0x0401ff17,
+       0x0401ff22, 0x40400000, 0x82000540, 0x00000040,
+       0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+       0x42006800, 0x00000014, 0x0401ff0c, 0x5c000000,
+       0x40006800, 0x0401ff0f, 0x41785800, 0x42006000,
+       0x0000001e, 0x42006800, 0x00000014, 0x0401ff03,
+       0x0401ff0e, 0x40400000, 0x82000500, 0x0000ffbf,
+       0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+       0x42006800, 0x00000014, 0x0401fef8, 0x5c000000,
+       0x40006800, 0x0401fefb, 0x4a038886, 0x00002020,
+       0x0401f04c, 0x480bc857, 0x82080580, 0x00010000,
+       0x04020007, 0x82040d40, 0x00010000, 0x42001800,
+       0x00000001, 0x0401f82d, 0x0401f00f, 0x82080580,
+       0x00008000, 0x04000007, 0x82040d40, 0x00000000,
+       0x42001800, 0x00900001, 0x0401f824, 0x0401f006,
+       0x82040d40, 0x00008000, 0x42001800, 0x00100001,
+       0x0401f81e, 0x1c01f000, 0x480bc857, 0x82080580,
+       0x00010000, 0x04020008, 0x42001800, 0x000000a1,
+       0x0401f816, 0x42001800, 0x000000c1, 0x0401f813,
+       0x0401f011, 0x82080580, 0x00008000, 0x04000008,
+       0x42001800, 0x000400a1, 0x0401f80c, 0x42001800,
+       0x002000c1, 0x0401f809, 0x0401f007, 0x42001800,
+       0x000400a1, 0x0401f805, 0x42001800, 0x000000c1,
+       0x0401f802, 0x1c01f000, 0x480fc857, 0x41785800,
+       0x42006000, 0x0000001e, 0x41786800, 0x0401feb7,
+       0x400c6800, 0x80346960, 0x0401feba, 0x42006800,
+       0x00000001, 0x0401feb1, 0x400c6800, 0x0401feb5,
+       0x42006800, 0x00000003, 0x0401feac, 0x0401feb7,
+       0x40400000, 0x8c000504, 0x040207fc, 0x1c01f000,
+       0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+       0x1c01f000, 0x00020103, 0x00101bd5, 0x00101bdb,
+       0x00101be1, 0x00101be9, 0x00101bef, 0x00101bf7,
+       0x00101bff, 0x00101c09, 0x00101c0f, 0x00101c17,
+       0x00101c1f, 0x00101c29, 0x00101c31, 0x00101c3b,
+       0x00101c45, 0x000200f8, 0x00101c51, 0x00101c59,
+       0x00101c61, 0x00101c6b, 0x00101c73, 0x00101c7d,
+       0x00101c87, 0x00101c93, 0x00101c9b, 0x00101ca5,
+       0x00101caf, 0x00101cbb, 0x00101cc5, 0x00101cd1,
+       0x00101cdd, 0x000200fd, 0x00101ceb, 0x00101cf3,
+       0x00101cfb, 0x00101d05, 0x00101d0d, 0x00101d17,
+       0x00101d21, 0x00101d2d, 0x00101d35, 0x00101d3f,
+       0x00101d49, 0x00101d55, 0x00101d5f, 0x00101d6b,
+       0x00101d77, 0x00101d85, 0x00101d8d, 0x00101d97,
+       0x00101da1, 0x00101dad, 0x00101db7, 0x00101dc3,
+       0x00101dcf, 0x00101ddd, 0x00101de7, 0x00101df3,
+       0x00101dff, 0x00101e0d, 0x00101e19, 0x00101e27,
+       0x00101e35, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00101418, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020729, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00020729, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020015, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020015, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020015, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+       0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+       0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+       0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+       0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+       0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+       0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+       0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+       0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+       0x00020101, 0x4c5c0000, 0x4c600000, 0x4178b800,
+       0x0201f800, 0x001048ec, 0x040200fd, 0x59a8c026,
+       0x0201f800, 0x0010513b, 0x04000003, 0x8c60c506,
+       0x0400000e, 0x8c60c500, 0x04020004, 0x8c60c50e,
+       0x040008f6, 0x0401f0f2, 0x0401fab4, 0x040200f0,
+       0x0201f800, 0x0010513b, 0x04020004, 0x4a03501c,
+       0x0000ffff, 0x0401f0ea, 0x8c60c504, 0x04000004,
+       0x4a03501c, 0x0000ffff, 0x0401f0e5, 0x59a8c010,
+       0x8260c500, 0x000000ff, 0x59a81013, 0x8c081500,
+       0x0400005d, 0x8c081502, 0x0402005b, 0x59a8b81c,
+       0x825c0d80, 0x0000ffff, 0x04020003, 0x4200b800,
+       0x00000001, 0x805c1104, 0x82086400, 0x0010be21,
+       0x50300800, 0x825c0500, 0x00000003, 0x0c01f001,
+       0x00101e81, 0x00101e7c, 0x00101e80, 0x00101e7e,
+       0x80040910, 0x0401f004, 0x80040930, 0x0401f002,
+       0x80040920, 0x82040500, 0x000000ff, 0x82000d80,
+       0x000000ff, 0x0400000f, 0x4c000000, 0x82000400,
+       0x0010210e, 0x50000800, 0x80040910, 0x82040580,
+       0x00000080, 0x5c000000, 0x04000030, 0x80600d80,
+       0x0400002e, 0x80000540, 0x0400002c, 0x0401f00b,
+       0x59a81005, 0x82081500, 0x00000003, 0x0402002b,
+       0x59a81013, 0x84081542, 0x480b5013, 0x4a03501c,
+       0x0000ffff, 0x0401f028, 0x4c000000, 0x59a80005,
+       0x8c000514, 0x42001000, 0x00000010, 0x02020800,
+       0x00104c6d, 0x5c000000, 0x0402001c, 0x417a8800,
+       0x0201f800, 0x00105c9a, 0x04020016, 0x0201f800,
+       0x001045e5, 0x04000006, 0x0201f800, 0x00104c62,
+       0x0401f8b1, 0x0400000f, 0x0401f00c, 0x599c0019,
+       0x8c00050e, 0x04020009, 0x0201f800, 0x001045a6,
+       0x04020008, 0x0201f800, 0x00104c62, 0x0401f9e1,
+       0x0401f8be, 0x04000003, 0x805cb800, 0x0401f7b2,
+       0x485f501c, 0x0401f086, 0x4a03501c, 0x0000ffff,
+       0x0401f083, 0x42003000, 0x0000007e, 0x59a8001c,
+       0x82001580, 0x0000ffff, 0x04020005, 0x80000d80,
+       0x4018b000, 0x4803c856, 0x0401f009, 0x8018b480,
+       0x04001004, 0x40000800, 0x4803c856, 0x0401f004,
+       0x4a03501c, 0x0000ffff, 0x0401f071, 0x4c040000,
+       0x4c580000, 0x82040400, 0x0010210e, 0x50000000,
+       0x82000500, 0x000000ff, 0x80604580, 0x0400005c,
+       0x0201f800, 0x00105c9b, 0x04020061, 0x59a80005,
+       0x8c000514, 0x42001000, 0x00000010, 0x02020800,
+       0x00104c6d, 0x5c00b000, 0x5c000800, 0x040207d7,
+       0x4c040000, 0x4c580000, 0x845cbd00, 0x0201f800,
+       0x00020245, 0x04000008, 0x599c0019, 0x8c00050e,
+       0x04020047, 0x0201f800, 0x001045ab, 0x0402004c,
+       0x0401f002, 0x845cbd40, 0x0201f800, 0x00104c62,
+       0x0201f800, 0x001049e7, 0x04020007, 0x59a80005,
+       0x8c000502, 0x04000033, 0x59340200, 0x8c00050e,
+       0x04020030, 0x59a81013, 0x8c081502, 0x04000025,
+       0x0201f800, 0x00104a09, 0x04000031, 0x8c5cbd00,
+       0x04020004, 0x0201f800, 0x001045ff, 0x0401f02c,
+       0x0401f9cd, 0x0400002a, 0x42026000, 0x0010bde9,
+       0x49366009, 0x497a6008, 0x417a7800, 0x0401f925,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x00103b25, 0x0400001d, 0x41782800,
+       0x42003000, 0x00000008, 0x4d400000, 0x4d440000,
+       0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+       0x0010a446, 0x5c028800, 0x5c028000, 0x0401f010,
+       0x4937c857, 0x599c0019, 0x8c00050e, 0x0402000c,
+       0x0401f96c, 0x0401f849, 0x04000011, 0x0401f008,
+       0x59a80013, 0x8c000500, 0x04000003, 0x0401f9a6,
+       0x04000003, 0x0401f828, 0x04000009, 0x5c00b000,
+       0x5c000800, 0x80040800, 0x8058b040, 0x04020798,
+       0x4a03501c, 0x0000ffff, 0x0401f005, 0x4937c857,
+       0x5c00b000, 0x5c000800, 0x4807501c, 0x5c00c000,
+       0x5c00b800, 0x1c01f000, 0x4803c856, 0x4a03501c,
+       0x00000001, 0x42028800, 0x000007fe, 0x42003000,
+       0x00fffffe, 0x0201f800, 0x001045a6, 0x0402000c,
+       0x0401f948, 0x0401f825, 0x04000009, 0x59a80026,
+       0x8400054e, 0x48035026, 0x0201f800, 0x0010930f,
+       0x82000540, 0x00000001, 0x1c01f000, 0x80000580,
+       0x0401f7fe, 0x4937c857, 0x0201f800, 0x00107942,
+       0x04000015, 0x49366009, 0x4a026406, 0x00000001,
+       0x417a7800, 0x0201f800, 0x00104567, 0x59a8001b,
+       0x80000000, 0x4803501b, 0x42027000, 0x00000004,
+       0x599c0019, 0x8c00050e, 0x04000003, 0x42027000,
+       0x00000000, 0x0201f800, 0x000207a1, 0x82000540,
+       0x00000001, 0x1c01f000, 0x4937c857, 0x0201f800,
+       0x00107942, 0x0400001c, 0x49366009, 0x59340403,
+       0x82000580, 0x000007fe, 0x04000005, 0x4d3c0000,
+       0x417a7800, 0x0401f8b7, 0x5c027800, 0x4a026406,
+       0x00000001, 0x417a7800, 0x0201f800, 0x00104567,
+       0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+       0x59a8001b, 0x80000000, 0x4803501b, 0x42027000,
+       0x00000002, 0x0201f800, 0x000207a1, 0x82000540,
+       0x00000001, 0x1c01f000, 0x4803c856, 0x42028800,
+       0x000007fc, 0x42003000, 0x00fffffc, 0x0201f800,
+       0x001045a6, 0x04020005, 0x0401f805, 0x04000003,
+       0x4a035027, 0x0000ffff, 0x1c01f000, 0x4937c857,
+       0x0201f800, 0x00107942, 0x04000014, 0x49366009,
+       0x4a026406, 0x00000001, 0x417a7800, 0x0201f800,
+       0x00104567, 0x42000800, 0x00000003, 0x0201f800,
+       0x00104571, 0x59a80028, 0x80000000, 0x48035028,
+       0x42027000, 0x00000002, 0x0201f800, 0x000207a1,
+       0x82000540, 0x00000001, 0x1c01f000, 0x480bc857,
+       0x492fc857, 0x4c5c0000, 0x4008b800, 0x42028800,
+       0x000007fd, 0x42003000, 0x00fffffd, 0x0201f800,
+       0x001045a6, 0x0402001a, 0x0201f800, 0x0002075a,
+       0x04000017, 0x49366009, 0x5934000a, 0x84000544,
+       0x4802680a, 0x812e59c0, 0x04000005, 0x592c0404,
+       0x8c00051e, 0x04000002, 0x48ee6021, 0x492e6008,
+       0x4a026406, 0x00000001, 0x485e601c, 0x42027000,
+       0x00000022, 0x0201f800, 0x000207a1, 0x82000540,
+       0x00000001, 0x5c00b800, 0x1c01f000, 0x80000580,
+       0x0401f7fd, 0x5c000000, 0x4c000000, 0x4803c857,
+       0x4943c857, 0x493fc857, 0x4d340000, 0x4d440000,
+       0x4c580000, 0x4d2c0000, 0x4c5c0000, 0x0201f800,
+       0x00106c55, 0x4df00000, 0x0201f800, 0x001069f1,
+       0x0201f800, 0x00106aac, 0x0201f800, 0x00106737,
+       0x0201f800, 0x0010848a, 0x5c03e000, 0x02000800,
+       0x00106c4b, 0x4200b000, 0x000007f0, 0x417a8800,
+       0x0201f800, 0x00020245, 0x0402001f, 0x8d3e7d14,
+       0x04000005, 0x59340212, 0x82000500, 0x0000ff00,
+       0x04000019, 0x8d3e7d06, 0x04000004, 0x59340200,
+       0x8c00050e, 0x04020014, 0x8d3e7d18, 0x0400000f,
+       0x5934b80f, 0x805cb9c0, 0x04000009, 0x49425a06,
+       0x592cb800, 0x0201f800, 0x000202ce, 0x805cb9c0,
+       0x040207fb, 0x497a680f, 0x497a6810, 0x4a026c00,
+       0x00000707, 0x0401f004, 0x4937c857, 0x0201f800,
+       0x001042b4, 0x81468800, 0x8058b040, 0x040207dd,
+       0x8d3e7d02, 0x04000011, 0x497b501d, 0x42028800,
+       0x000007f0, 0x4200b000, 0x00000010, 0x0201f800,
+       0x00020245, 0x04020006, 0x4937c857, 0x4a026c00,
+       0x00000707, 0x0201f800, 0x001042b4, 0x81468800,
+       0x8058b040, 0x040207f6, 0x5c00b800, 0x5c025800,
+       0x5c00b000, 0x5c028800, 0x5c026800, 0x1c01f000,
+       0x5c000000, 0x4c000000, 0x4803c857, 0x4933c857,
+       0x493fc857, 0x4d340000, 0x4d400000, 0x4d440000,
+       0x4d2c0000, 0x4c5c0000, 0x0201f800, 0x00106c55,
+       0x4df00000, 0x59326809, 0x813669c0, 0x04000020,
+       0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+       0x00106a50, 0x0201f800, 0x00106ab4, 0x0201f800,
+       0x001067fd, 0x0201f800, 0x0010a2ff, 0x4937c857,
+       0x8d3e7d18, 0x04000010, 0x5934b80f, 0x805cb9c0,
+       0x0400000a, 0x405e5800, 0x49425a06, 0x592cb800,
+       0x0201f800, 0x000202ce, 0x805cb9c0, 0x040207fa,
+       0x497a680f, 0x497a6810, 0x4a026c00, 0x00000707,
+       0x0401f003, 0x0201f800, 0x001042b4, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x5c00b800, 0x5c025800,
+       0x5c028800, 0x5c028000, 0x5c026800, 0x1c01f000,
+       0x4933c857, 0x59a80026, 0x8c000508, 0x04020012,
+       0x59305009, 0x482bc857, 0x836c0580, 0x00000002,
+       0x0402000d, 0x0401f813, 0x0402000b, 0x58280403,
+       0x82000580, 0x000007fc, 0x04000008, 0x59a8001b,
+       0x80000040, 0x4803c857, 0x02001800, 0x001005d8,
+       0x4803501b, 0x1c01f000, 0x59a80028, 0x80000040,
+       0x4803c857, 0x040017fc, 0x48035028, 0x1c01f000,
+       0x59300008, 0x800001c0, 0x04020009, 0x59300403,
+       0x82000580, 0x00000001, 0x04020004, 0x82000540,
+       0x00000001, 0x0401f002, 0x80000580, 0x1c01f000,
+       0x4937c857, 0x59340200, 0x84000502, 0x48026a00,
+       0x1c01f000, 0x4933c857, 0x493fc857, 0x4947c857,
+       0x4d3c0000, 0x4d400000, 0x4d340000, 0x4d440000,
+       0x4c580000, 0x0201f800, 0x00106c55, 0x4df00000,
+       0x813e79c0, 0x04020004, 0x4200b000, 0x00000001,
+       0x0401f004, 0x4200b000, 0x000007f0, 0x417a8800,
+       0x41440000, 0x81ac0400, 0x50000000, 0x80026d40,
+       0x04000019, 0x42027800, 0x00000001, 0x0201f800,
+       0x001048f6, 0x42028000, 0x00000029, 0x417a7800,
+       0x0201f800, 0x00106a50, 0x0201f800, 0x00106ab4,
+       0x0201f800, 0x001067fd, 0x0201f800, 0x001049e7,
+       0x04020005, 0x4937c857, 0x4a026c00, 0x00000404,
+       0x0401f003, 0x0201f800, 0x00104a14, 0x0201f800,
+       0x0010a2ff, 0x81468800, 0x8058b040, 0x040207e1,
+       0x5c03e000, 0x02000800, 0x00106c4b, 0x5c00b000,
+       0x5c028800, 0x5c026800, 0x5c028000, 0x5c027800,
+       0x1c01f000, 0x4937c857, 0x4947c857, 0x4c5c0000,
+       0x4c600000, 0x4c640000, 0x59a80013, 0x8c000500,
+       0x0400001f, 0x599c0017, 0x8c00050a, 0x0402001c,
+       0x5934ba02, 0x825cbd00, 0x000000ff, 0x485fc857,
+       0x4178c000, 0x4178c800, 0x82600400, 0x0010be21,
+       0x50002000, 0x8060c1c0, 0x04000008, 0x82100500,
+       0x000000ff, 0x82002d80, 0x000000ff, 0x0400000c,
+       0x805c0580, 0x0400000d, 0x80102110, 0x8064c800,
+       0x82640580, 0x00000004, 0x040207f5, 0x8060c000,
+       0x82600580, 0x00000020, 0x040207eb, 0x4813c857,
+       0x82000540, 0x00000001, 0x5c00c800, 0x5c00c000,
+       0x5c00b800, 0x1c01f000, 0x59a80026, 0x4803c857,
+       0x8c000512, 0x1c01f000, 0x00007eef, 0x00007de8,
+       0x00007ce4, 0x000080e2, 0x00007be1, 0x000080e0,
+       0x000080dc, 0x000080da, 0x00007ad9, 0x000080d6,
+       0x000080d5, 0x000080d4, 0x000080d3, 0x000080d2,
+       0x000080d1, 0x000079ce, 0x000078cd, 0x000080cc,
+       0x000080cb, 0x000080ca, 0x000080c9, 0x000080c7,
+       0x000080c6, 0x000077c5, 0x000076c3, 0x000080bc,
+       0x000080ba, 0x000075b9, 0x000080b6, 0x000074b5,
+       0x000073b4, 0x000072b3, 0x000080b2, 0x000080b1,
+       0x000080ae, 0x000071ad, 0x000080ac, 0x000070ab,
+       0x00006faa, 0x00006ea9, 0x000080a7, 0x00006da6,
+       0x00006ca5, 0x00006ba3, 0x00006a9f, 0x0000699e,
+       0x0000689d, 0x0000809b, 0x00008098, 0x00006797,
+       0x00006690, 0x0000658f, 0x00006488, 0x00006384,
+       0x00006282, 0x00008081, 0x00008080, 0x0000617c,
+       0x0000607a, 0x00008079, 0x00005f76, 0x00008075,
+       0x00008074, 0x00008073, 0x00008072, 0x00008071,
+       0x0000806e, 0x00005e6d, 0x0000806c, 0x00005d6b,
+       0x00005c6a, 0x00005b69, 0x00008067, 0x00005a66,
+       0x00005965, 0x00005863, 0x0000575c, 0x0000565a,
+       0x00005559, 0x00008056, 0x00008055, 0x00005454,
+       0x00005353, 0x00005252, 0x00005151, 0x0000504e,
+       0x00004f4d, 0x0000804c, 0x0000804b, 0x00004e4a,
+       0x00004d49, 0x00008047, 0x00004c46, 0x00008045,
+       0x00008043, 0x0000803c, 0x0000803a, 0x00008039,
+       0x00008036, 0x00004b35, 0x00008034, 0x00004a33,
+       0x00004932, 0x00004831, 0x0000802e, 0x0000472d,
+       0x0000462c, 0x0000452b, 0x0000442a, 0x00004329,
+       0x00004227, 0x00008026, 0x00008025, 0x00004123,
+       0x0000401f, 0x00003f1e, 0x00003e1d, 0x00003d1b,
+       0x00003c18, 0x00008017, 0x00008010, 0x00003b0f,
+       0x00003a08, 0x00008004, 0x00003902, 0x00008001,
+       0x00008000, 0x00008000, 0x00003800, 0x00003700,
+       0x00003600, 0x00008000, 0x00003500, 0x00008000,
+       0x00008000, 0x00008000, 0x00003400, 0x00008000,
+       0x00008000, 0x00008000, 0x00008000, 0x00008000,
+       0x00008000, 0x00003300, 0x00003200, 0x00008000,
+       0x00008000, 0x00008000, 0x00008000, 0x00008000,
+       0x00008000, 0x00003100, 0x00003000, 0x00008000,
+       0x00008000, 0x00002f00, 0x00008000, 0x00002e00,
+       0x00002d00, 0x00002c00, 0x00008000, 0x00008000,
+       0x00008000, 0x00002b00, 0x00008000, 0x00002a00,
+       0x00002900, 0x00002800, 0x00008000, 0x00002700,
+       0x00002600, 0x00002500, 0x00002400, 0x00002300,
+       0x00002200, 0x00008000, 0x00008000, 0x00002100,
+       0x00002000, 0x00001f00, 0x00001e00, 0x00001d00,
+       0x00001c00, 0x00008000, 0x00008000, 0x00001b00,
+       0x00001a00, 0x00008000, 0x00001900, 0x00008000,
+       0x00008000, 0x00008000, 0x00008000, 0x00008000,
+       0x00008000, 0x00001800, 0x00008000, 0x00001700,
+       0x00001600, 0x00001500, 0x00008000, 0x00001400,
+       0x00001300, 0x00001200, 0x00001100, 0x00001000,
+       0x00000f00, 0x00008000, 0x00008000, 0x00000e00,
+       0x00000d00, 0x00000c00, 0x00000b00, 0x00000a00,
+       0x00000900, 0x00008000, 0x00008000, 0x00000800,
+       0x00000700, 0x00008000, 0x00000600, 0x00008000,
+       0x00008000, 0x00008000, 0x00000500, 0x00000400,
+       0x00000300, 0x00008000, 0x00000200, 0x00008000,
+       0x00008000, 0x00008000, 0x00000100, 0x00008000,
+       0x00008000, 0x00008000, 0x00008000, 0x00008000,
+       0x00008000, 0x00000000, 0x00008000, 0x00008000,
+       0x00008000, 0x00008000, 0x00008000, 0x00008000,
+       0x00008000, 0x00008000, 0x00008000, 0x00008000,
+       0x00008000, 0x00008000, 0x00008000, 0x00008000,
+       0x00008000, 0x00008000, 0x0201f800, 0x001007d3,
+       0x02000800, 0x001005d8, 0x492f4016, 0x1c01f000,
+       0x83a0ac00, 0x00000006, 0x83a00580, 0x0010b4a4,
+       0x0400000c, 0x492fc857, 0x812e59c0, 0x02000800,
+       0x001005d8, 0x832ca400, 0x00000006, 0x4200b000,
+       0x0000000d, 0x0201f800, 0x0010ab17, 0x0401f00f,
+       0x4200b000, 0x00000010, 0x83e0a400, 0x00000020,
+       0x50500000, 0x8050a000, 0x50500800, 0x900409c0,
+       0x80040540, 0x4400a800, 0x8050a000, 0x8054a800,
+       0x8058b040, 0x040207f7, 0x1c01f000, 0x59a00206,
+       0x4803c857, 0x82000c80, 0x0000007f, 0x040210c9,
+       0x59a80821, 0x0c01f001, 0x001022c0, 0x00102300,
+       0x00102300, 0x0010234b, 0x0010236d, 0x00102300,
+       0x001022c0, 0x0010238f, 0x001023a0, 0x00102300,
+       0x00102300, 0x001023ad, 0x001023c5, 0x001023dd,
+       0x00102300, 0x001023e7, 0x001023f4, 0x00102300,
+       0x0010241d, 0x00102300, 0x0010247a, 0x00102300,
+       0x00102300, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102300, 0x00102491, 0x00102300,
+       0x001024e3, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x001024e8, 0x00102560, 0x00102300,
+       0x00102567, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102300, 0x00102569, 0x001025ea,
+       0x00102727, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102300, 0x00102736, 0x00102300,
+       0x00102300, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102300, 0x00102753, 0x001027a6,
+       0x00102802, 0x00102816, 0x00102835, 0x00102a70,
+       0x00102dff, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102300, 0x00102300, 0x00102300,
+       0x00102300, 0x00102fb4, 0x00103028, 0x00102300,
+       0x00102300, 0x00103094, 0x00102300, 0x00103126,
+       0x001031d8, 0x00102300, 0x00102300, 0x0010320f,
+       0x0010326b, 0x00102300, 0x001032bd, 0x00103419,
+       0x00102300, 0x0010342d, 0x001034b8, 0x00102300,
+       0x00102300, 0x00102300, 0x00102300, 0x00103522,
+       0x00103526, 0x00103545, 0x00102300, 0x001035e7,
+       0x00102300, 0x00102300, 0x00103615, 0x00102300,
+       0x00103643, 0x00102300, 0x00102300, 0x001036aa,
+       0x001037b7, 0x00103814, 0x00102300, 0x0010387a,
+       0x00102300, 0x00102300, 0x001038d3, 0x00103936,
+       0x00102300, 0x48efc857, 0x4031d800, 0x58ef400b,
+       0x58ec0002, 0x82000580, 0x00000200, 0x04000045,
+       0x48efc857, 0x4a034206, 0x00004000, 0x0201f800,
+       0x00103a15, 0x83a00580, 0x0010b4a4, 0x0400000d,
+       0x58ee580a, 0x4d2c0000, 0x0401f856, 0x41a25800,
+       0x0201f800, 0x001007f4, 0x40ee5800, 0x0201f800,
+       0x001007f4, 0x5c025800, 0x0201f000, 0x000202da,
+       0x04026007, 0x59a0001d, 0x84000542, 0x4803401d,
+       0x4a01d809, 0x001022d4, 0x1c01f000, 0x59a00206,
+       0x82000d80, 0x00004000, 0x04000006, 0x900001c0,
+       0x82000540, 0x00000011, 0x4803c011, 0x0401f005,
+       0x900001c0, 0x82000540, 0x00000010, 0x4803c011,
+       0x0401f845, 0x59e00017, 0x8c000508, 0x0402000c,
+       0x4203e000, 0x30000001, 0x4203e000, 0x40000000,
+       0x40ee5800, 0x0201f800, 0x001007f4, 0x59a0001d,
+       0x84000504, 0x4803401d, 0x1c01f000, 0x4a03c017,
+       0x00000000, 0x59a00206, 0x82000d80, 0x00004000,
+       0x040007f0, 0x4a03c017, 0x00000001, 0x0401f7ed,
+       0x4803c856, 0x4a034206, 0x00004001, 0x0401f7c0,
+       0x4803c856, 0x4a034206, 0x00004002, 0x0401f7bc,
+       0x4803c856, 0x4a034206, 0x00004003, 0x0401f7b8,
+       0x4803c856, 0x4a034206, 0x00004005, 0x0401f7b4,
+       0x4803c856, 0x4a034206, 0x00004006, 0x0401f7b0,
+       0x4803c856, 0x4a034206, 0x0000400b, 0x0401f7ac,
+       0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a8,
+       0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a4,
+       0x48efc857, 0x58eca80a, 0x8054a9c0, 0x02000800,
+       0x001005d8, 0x83a0a400, 0x00000006, 0x8254ac00,
+       0x00000006, 0x4200b000, 0x0000000d, 0x0201f000,
+       0x0010ab17, 0x59a00206, 0x4803c857, 0x59a00406,
+       0x4803c857, 0x59a00207, 0x4803c857, 0x59a00407,
+       0x4803c857, 0x59a00208, 0x4803c857, 0x59a00408,
+       0x4803c857, 0x59a00209, 0x4803c857, 0x83e0ac00,
+       0x00000020, 0x83a0a400, 0x00000006, 0x4200b000,
+       0x00000010, 0x50500000, 0x4400a800, 0x8054a800,
+       0x900001c0, 0x4400a800, 0x8054a800, 0x8050a000,
+       0x8058b040, 0x040207f8, 0x1c01f000, 0x59a00406,
+       0x800000c2, 0x59a00a07, 0x900409c0, 0x80040540,
+       0x84000540, 0x59a00c07, 0x8c040d00, 0x04000018,
+       0x59a80805, 0x8c040d0e, 0x040207ba, 0x42000800,
+       0x00000064, 0x80040840, 0x04000007, 0x4a030000,
+       0x00000001, 0x40000000, 0x59801000, 0x8c081500,
+       0x040007f9, 0x04000005, 0x48030004, 0x4a030000,
+       0x00000000, 0x0401f75b, 0x4a030000, 0x00000000,
+       0x4a034406, 0x00000004, 0x040007a2, 0x4803880e,
+       0x0401f754, 0x59a00406, 0x800000c2, 0x59a00c07,
+       0x8c040d00, 0x0400001a, 0x59a80805, 0x8c040d0e,
+       0x0402079c, 0x42000800, 0x00000064, 0x80040840,
+       0x04000007, 0x4a030000, 0x00000001, 0x40000000,
+       0x59801000, 0x8c081500, 0x040007f9, 0x04000007,
+       0x48030004, 0x59800805, 0x48074406, 0x4a030000,
+       0x00000000, 0x0401f73b, 0x4a030000, 0x00000000,
+       0x4a034406, 0x00000004, 0x04000782, 0x4803880e,
+       0x59c4080f, 0x48074406, 0x0401f732, 0x59a01c06,
+       0x59a00207, 0x900c19c0, 0x800c1d40, 0x580c0803,
+       0x80000580, 0x500c1000, 0x80080400, 0x800c1800,
+       0x80040840, 0x040207fc, 0x48034406, 0x900001c0,
+       0x48034207, 0x800001c0, 0x04000722, 0x0401f769,
+       0x4a034406, 0x00000004, 0x4a034207, 0x00000000,
+       0x4a034407, 0x00000010, 0x59a8000d, 0x48034208,
+       0x900001c0, 0x48034408, 0x4a034209, 0x00000002,
+       0x0401f714, 0x59a00407, 0x59a01207, 0x900811c0,
+       0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+       0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0,
+       0x80040d40, 0x59a0020a, 0x82002480, 0x00000010,
+       0x04001754, 0x59a02406, 0x900001c0, 0x80100540,
+       0x59a8280d, 0x80142480, 0x0400174e, 0x0201f000,
+       0x00103a25, 0x59a00407, 0x59a01207, 0x900811c0,
+       0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+       0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0,
+       0x80040d40, 0x59a0020a, 0x82002480, 0x00000010,
+       0x0400173c, 0x59a02406, 0x900001c0, 0x80100540,
+       0x59a8280d, 0x80142480, 0x04001736, 0x0201f000,
+       0x00103a28, 0x59a00a0a, 0x59a00406, 0x900409c0,
+       0x80040d40, 0x59a01407, 0x59a00207, 0x900811c0,
+       0x80081540, 0x44080800, 0x0401f6da, 0x59a00a0a,
+       0x59a00406, 0x900409c0, 0x80040d40, 0x50040000,
+       0x82000d00, 0x0000ffff, 0x48074207, 0x82000d00,
+       0xffff0000, 0x900409c0, 0x48074407, 0x0401f6cd,
+       0x59a00406, 0x8c000500, 0x04000020, 0x59a01207,
+       0x59a01c07, 0x59a02208, 0x480b5054, 0x480f5055,
+       0x48135056, 0x59c40801, 0x82040d00, 0x00018000,
+       0x82040580, 0x00000000, 0x04000009, 0x82040580,
+       0x00008000, 0x04000008, 0x82040580, 0x00010000,
+       0x04000007, 0x0201f800, 0x001005d8, 0x40080000,
+       0x0401f004, 0x400c0000, 0x0401f002, 0x40100000,
+       0x80000110, 0x42000800, 0x000000e0, 0x0201f800,
+       0x00101944, 0x0401f007, 0x59a81054, 0x59a81855,
+       0x59a82056, 0x480b4207, 0x480f4407, 0x48134208,
+       0x0401f6a4, 0x4d2c0000, 0x4d340000, 0x4d300000,
+       0x4d440000, 0x59a28c06, 0x0201f800, 0x00020245,
+       0x04000006, 0x5c028800, 0x5c026000, 0x5c026800,
+       0x5c025800, 0x0401f6e7, 0x59a04407, 0x59a00207,
+       0x900001c0, 0x80204540, 0x0401f81e, 0x04000009,
+       0x4a034208, 0x00000001, 0x4a034406, 0x0000ffff,
+       0x4a034207, 0x0000ffff, 0x497b4407, 0x0401f00b,
+       0x0401f822, 0x0400000e, 0x4a034208, 0x00000002,
+       0x59300402, 0x48034406, 0x59300202, 0x48034207,
+       0x59300206, 0x48034407, 0x5c028800, 0x5c026000,
+       0x5c026800, 0x5c025800, 0x0401f67a, 0x5c028800,
+       0x5c026000, 0x5c026800, 0x5c025800, 0x0401f6c1,
+       0x4937c856, 0x4823c856, 0x4d2c0000, 0x5934000f,
+       0x80025d40, 0x04000007, 0x592c0005, 0x80200580,
+       0x592c0000, 0x040207fb, 0x82000540, 0x00000001,
+       0x5c025800, 0x1c01f000, 0x4823c857, 0x4d2c0000,
+       0x4d300000, 0x42026000, 0x0010d1c0, 0x59300406,
+       0x82000d80, 0x00000003, 0x04000004, 0x82000d80,
+       0x00000006, 0x04020007, 0x59325808, 0x812e59c0,
+       0x04000004, 0x592c0005, 0x80200580, 0x0400000a,
+       0x83326400, 0x00000024, 0x41580000, 0x81300480,
+       0x040017ef, 0x80000580, 0x5c026000, 0x5c025800,
+       0x1c01f000, 0x82000540, 0x00000001, 0x5c026000,
+       0x5c025800, 0x1c01f000, 0x83a00580, 0x0010b4a4,
+       0x04020684, 0x59a80005, 0x8c00050e, 0x04020003,
+       0x4a030000, 0x00000000, 0x4a034206, 0x00004000,
+       0x4a03c011, 0x40000010, 0x0401fea7, 0x59e00017,
+       0x8c000508, 0x04000003, 0x4a03c017, 0x00000000,
+       0x4203e000, 0x30000001, 0x4203e000, 0x40000000,
+       0x0401f000, 0x800409c0, 0x04000004, 0x4a034406,
+       0x00000001, 0x0401f677, 0x836c0580, 0x00000003,
+       0x04020010, 0x59a80010, 0x497b4406, 0x0201f800,
+       0x0010513b, 0x0400000f, 0x82000d00, 0x00ffff00,
+       0x0402000c, 0x82000c00, 0x0010210e, 0x50040800,
+       0x80040910, 0x82041580, 0x00000080, 0x04020004,
+       0x4a034406, 0x00000007, 0x0401f662, 0x48074406,
+       0x82000d00, 0x0000ffff, 0x48074207, 0x80000120,
+       0x48034407, 0x59a80026, 0x82001500, 0x00000100,
+       0x480b4409, 0x8c000502, 0x0400001f, 0x8c000506,
+       0x04000009, 0x82000d00, 0x0000000a, 0x82040d80,
+       0x0000000a, 0x04020004, 0x4a034209, 0x00000001,
+       0x0401f022, 0x8c00050a, 0x04000009, 0x82000d00,
+       0x00000022, 0x82040d80, 0x00000022, 0x04020004,
+       0x4a034209, 0x00000003, 0x0401f018, 0x8c000508,
+       0x04000009, 0x82000d00, 0x00000012, 0x82040d80,
+       0x00000012, 0x04020004, 0x4a034209, 0x00000002,
+       0x0401f00e, 0x0201f800, 0x0010513b, 0x04020004,
+       0x4a034209, 0x00000004, 0x0401f5e6, 0x8c000506,
+       0x04000004, 0x4a034406, 0x00000005, 0x0401f62d,
+       0x4a034209, 0x00000000, 0x0401f5de, 0x59a80037,
+       0x48034407, 0x59a80038, 0x48034209, 0x0401f5d9,
+       0x42007800, 0x0010b8ec, 0x59a00406, 0x4803c857,
+       0x82000c80, 0x00000006, 0x04021622, 0x0c01f001,
+       0x001024f6, 0x001024f7, 0x00102505, 0x00102518,
+       0x00102539, 0x001024f6, 0x0401f61a, 0x836c0580,
+       0x00000000, 0x04000613, 0x59a00a07, 0x59a00407,
+       0x900001c0, 0x80040d40, 0x4807c857, 0x59a00a08,
+       0x59a00408, 0x900001c0, 0x80040d40, 0x4807c857,
+       0x0401f056, 0x836c0580, 0x00000000, 0x04000605,
+       0x59a00407, 0x59a01207, 0x900001c0, 0x80081540,
+       0x59a00408, 0x59a01a08, 0x900001c0, 0x800c1d40,
+       0x42000000, 0x0010c1bf, 0x480fc857, 0x480bc857,
+       0x42000800, 0x00001000, 0x0201f000, 0x00103a28,
+       0x59a00a07, 0x59a00407, 0x900001c0, 0x80041d40,
+       0x820c0c80, 0x0010ab4a, 0x040215f2, 0x820c0c80,
+       0x00100000, 0x040015ef, 0x480fc857, 0x823c7c00,
+       0x00000009, 0x503c0800, 0x800409c0, 0x04000006,
+       0x823c0580, 0x0000000d, 0x040005e6, 0x803c7800,
+       0x0401f7f9, 0x59e41001, 0x82080d00, 0xfffeffcf,
+       0x4807c801, 0x440c7800, 0x46001800, 0x0201f800,
+       0x800c1800, 0x46001800, 0x001005cb, 0x480bc801,
+       0x0401f022, 0x59a01a07, 0x59a00407, 0x900001c0,
+       0x800c1d40, 0x480c7801, 0x59a02208, 0x59a00408,
+       0x900001c0, 0x80102540, 0x48107802, 0x59a00209,
+       0x80000040, 0x040015cb, 0x48007806, 0x80000000,
+       0x48007805, 0x42000800, 0x00004000, 0x40001000,
+       0x0201f800, 0x00106681, 0x80000540, 0x04000003,
+       0x49787801, 0x0401f5bf, 0x40040000, 0x800c1c00,
+       0x040015bc, 0x480c7803, 0x48107804, 0x49787808,
+       0x59a00409, 0x48007807, 0x59e40001, 0x4803c857,
+       0x82000540, 0x00040000, 0x4803c801, 0x0401f561,
+       0x59a80006, 0x48034406, 0x59a80007, 0x48034207,
+       0x59a80008, 0x48034407, 0x0401f55a, 0x0201f800,
+       0x001005d8, 0x4803c856, 0x4a03c013, 0x03800300,
+       0x4a03c014, 0x03800380, 0x59a00c06, 0x82040580,
+       0x000000a0, 0x04000004, 0x82040580, 0x000000a2,
+       0x0402002b, 0x59a0140a, 0x82080480, 0x00000100,
+       0x04021027, 0x59a0020b, 0x8c000500, 0x0402002e,
+       0x59a00a0a, 0x800409c0, 0x04000021, 0x82040480,
+       0x00000041, 0x0402101e, 0x82040c00, 0x00000003,
+       0x82040d00, 0x000000fc, 0x80040904, 0x59a00407,
+       0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+       0x59a01a09, 0x900c19c0, 0x800c1d40, 0x0201f800,
+       0x00103a00, 0x04020006, 0x4a034406, 0x00000002,
+       0x4a03c014, 0x03800000, 0x0401f576, 0x832e5c00,
+       0x00000004, 0x412c0000, 0x0201f800, 0x00103a25,
+       0x4a01d809, 0x001025a2, 0x1c01f000, 0x4a03c014,
+       0x03800000, 0x0401f56f, 0x4031d800, 0x58ef400b,
+       0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+       0x0400055c, 0x59a00c06, 0x59a0140a, 0x59a0020b,
+       0x8c000500, 0x04020031, 0x832e5c00, 0x00000004,
+       0x41783800, 0x59a04a0a, 0x401c0000, 0x812c0400,
+       0x50004000, 0x82201d00, 0x000000ff, 0x4c040000,
+       0x0401f8ac, 0x5c000800, 0x0400002d, 0x80244840,
+       0x04000028, 0x80081000, 0x82201d00, 0x0000ff00,
+       0x800c1910, 0x4c040000, 0x0401f8a2, 0x5c000800,
+       0x04000023, 0x80244840, 0x0400001e, 0x80081000,
+       0x82201d00, 0x00ff0000, 0x800c1920, 0x4c040000,
+       0x0401f898, 0x5c000800, 0x04000019, 0x80244840,
+       0x04000014, 0x80081000, 0x82201d00, 0xff000000,
+       0x800c1930, 0x4c040000, 0x0401f88e, 0x5c000800,
+       0x0400000f, 0x80244840, 0x0400000a, 0x80081000,
+       0x801c3800, 0x0401f7d5, 0x59a0020a, 0x82000500,
+       0x000000ff, 0x40001800, 0x0401f882, 0x04000004,
+       0x4a03c014, 0x03800000, 0x0401f4da, 0x4a03c014,
+       0x03800000, 0x0401f523, 0x4803c856, 0x4a03c013,
+       0x03800300, 0x4a03c014, 0x03800380, 0x59a00c06,
+       0x82040580, 0x000000a0, 0x04000004, 0x82040580,
+       0x000000a2, 0x0402006c, 0x59a0140a, 0x82080480,
+       0x00000100, 0x04021068, 0x59a0020b, 0x8c000500,
+       0x0402005c, 0x59a01a0a, 0x800c19c0, 0x04000062,
+       0x820c0480, 0x00000041, 0x0402105f, 0x0201f800,
+       0x00103a00, 0x04020006, 0x4a034406, 0x00000002,
+       0x4a03c014, 0x03800000, 0x0401f502, 0x832e5c00,
+       0x00000004, 0x41783800, 0x59a04a0a, 0x401c0000,
+       0x812c0400, 0x40004000, 0x4c040000, 0x4c080000,
+       0x0401f874, 0x5c001000, 0x5c000800, 0x04000047,
+       0x44144000, 0x80244840, 0x0400002b, 0x80081000,
+       0x4c040000, 0x4c080000, 0x0401f86a, 0x5c001000,
+       0x5c000800, 0x0400003d, 0x50200000, 0x801428d0,
+       0x80140540, 0x44004000, 0x80244840, 0x0400001e,
+       0x80081000, 0x4c040000, 0x4c080000, 0x0401f85d,
+       0x5c001000, 0x5c000800, 0x04000030, 0x50200000,
+       0x801428e0, 0x80140540, 0x44004000, 0x80244840,
+       0x04000011, 0x80081000, 0x4c040000, 0x4c080000,
+       0x0401f850, 0x5c001000, 0x5c000800, 0x04000023,
+       0x50200000, 0x801428f0, 0x80140540, 0x44004000,
+       0x80244840, 0x04000004, 0x80081000, 0x801c3800,
+       0x0401f7cb, 0x59a00a0a, 0x82040c00, 0x00000003,
+       0x82040d00, 0x000000fc, 0x80040904, 0x59a00407,
+       0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+       0x59a01a09, 0x900c19c0, 0x800c1d40, 0x4a03c014,
+       0x03800000, 0x412c0000, 0x0201f000, 0x00103a28,
+       0x0401f830, 0x04000005, 0x48174406, 0x4a03c014,
+       0x03800000, 0x0401f463, 0x4a03c014, 0x03800000,
+       0x0401f4ac, 0x4a03c014, 0x03800000, 0x0401f4ad,
+       0x0401f836, 0x04000010, 0x0401f862, 0x0402000f,
+       0x40080800, 0x0401f85f, 0x0402000c, 0x400c0800,
+       0x0401f85c, 0x04020009, 0x0401f84b, 0x42000000,
+       0x00030d40, 0x80000040, 0x040207ff, 0x82000540,
+       0x00000001, 0x1c01f000, 0x0401f843, 0x80000580,
+       0x0401f7fd, 0x0401f821, 0x0400000a, 0x82040d40,
+       0x00000001, 0x0401f84b, 0x04020007, 0x0401f87e,
+       0x0401f898, 0x0401f838, 0x82000540, 0x00000001,
+       0x1c01f000, 0x0401f834, 0x80000580, 0x0401f7fd,
+       0x40041800, 0x0401f811, 0x0400000c, 0x0401f83d,
+       0x0402000b, 0x40080800, 0x0401f83a, 0x04020008,
+       0x400c0800, 0x0401ffe8, 0x04000004, 0x0401f826,
+       0x82000540, 0x00000001, 0x1c01f000, 0x0401f822,
+       0x80000580, 0x0401f7fd, 0x4c040000, 0x42000800,
+       0x00000064, 0x4a03c013, 0x03800300, 0x80040840,
+       0x04000016, 0x59e00013, 0x82000500, 0x00000300,
+       0x82000580, 0x00000300, 0x040207f7, 0x42000000,
+       0x00000064, 0x80000040, 0x040207ff, 0x4a03c013,
+       0x01000000, 0x42000000, 0x00000064, 0x80000040,
+       0x040207ff, 0x4a03c013, 0x02000000, 0x82000540,
+       0x00000001, 0x0401f002, 0x80000580, 0x5c000800,
+       0x1c01f000, 0x4a03c013, 0x01000000, 0x42000000,
+       0x00000064, 0x80000040, 0x040207ff, 0x4a03c013,
+       0x02000200, 0x42000000, 0x00000064, 0x80000040,
+       0x040207ff, 0x4a03c013, 0x01000100, 0x1c01f000,
+       0x42002000, 0x00000008, 0x82040500, 0x00000080,
+       0x800000c2, 0x82000540, 0x01000000, 0x4803c013,
+       0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+       0x4a03c013, 0x02000200, 0x42000000, 0x00000064,
+       0x80000040, 0x040207ff, 0x4a03c013, 0x02000000,
+       0x800408c2, 0x80102040, 0x040207ec, 0x4a03c013,
+       0x01000100, 0x42000000, 0x00000064, 0x80000040,
+       0x040207ff, 0x4a03c013, 0x02000200, 0x42000000,
+       0x00000064, 0x80000040, 0x040207ff, 0x59e00013,
+       0x82000500, 0x00000100, 0x4a03c013, 0x02000000,
+       0x4c040000, 0x42000800, 0x00000064, 0x59e00013,
+       0x82000500, 0x00000100, 0x80040840, 0x04000003,
+       0x80000540, 0x040207fa, 0x80000540, 0x5c000800,
+       0x1c01f000, 0x4a03c013, 0x01000100, 0x42001000,
+       0x00000008, 0x80000d80, 0x42000000, 0x00000064,
+       0x80000040, 0x040207ff, 0x4a03c013, 0x02000200,
+       0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+       0x59e00013, 0x82000500, 0x00000100, 0x80000110,
+       0x800408c2, 0x80040d40, 0x4a03c013, 0x02000000,
+       0x80081040, 0x040207ed, 0x40042800, 0x1c01f000,
+       0x4a03c013, 0x01000100, 0x42000000, 0x00000064,
+       0x80000040, 0x040207ff, 0x4a03c013, 0x02000200,
+       0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+       0x4a03c013, 0x02000000, 0x1c01f000, 0x59a00407,
+       0x59a80837, 0x48035037, 0x48074407, 0x59a00a09,
+       0x82040480, 0x00000014, 0x04021003, 0x42000800,
+       0x000007d0, 0x59a80038, 0x48075038, 0x48034209,
+       0x0201f000, 0x001022c0, 0x836c0580, 0x00000000,
+       0x0400000e, 0x59a80006, 0x59a00c06, 0x80041580,
+       0x82081500, 0x00000040, 0x02000000, 0x001022c0,
+       0x80080580, 0x48035006, 0x0201f800, 0x00100699,
+       0x0201f000, 0x001022c0, 0x59a00406, 0x59a80806,
+       0x48035006, 0x80040d80, 0x8c040d0c, 0x02020800,
+       0x00100699, 0x59a00207, 0x48035007, 0x59a00407,
+       0x48035008, 0x0201f000, 0x001022c0, 0x800409c0,
+       0x04000005, 0x4a034406, 0x00000001, 0x0201f000,
+       0x0010230c, 0x0201f800, 0x0010513b, 0x04020005,
+       0x4a034406, 0x00000016, 0x0201f000, 0x0010230c,
+       0x836c0580, 0x00000003, 0x04000005, 0x4a034406,
+       0x00000007, 0x0201f000, 0x0010230c, 0x59a00c06,
+       0x82040500, 0xffffff00, 0x02020000, 0x00102310,
+       0x82041580, 0x000000ff, 0x04020007, 0x59a80010,
+       0x82000500, 0x000000ff, 0x82001540, 0x0000ff00,
+       0x0401f011, 0x82040400, 0x0010210e, 0x50000000,
+       0x80000110, 0x82000580, 0x00000080, 0x02000000,
+       0x00102310, 0x59a80010, 0x82000500, 0x000000ff,
+       0x80041580, 0x02000000, 0x00102310, 0x840409c0,
+       0x80041540, 0x0201f800, 0x0002075a, 0x04020005,
+       0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+       0x48ee6021, 0x480a621c, 0x4a02641c, 0x0000bc09,
+       0x4a026406, 0x00000001, 0x0201f800, 0x00103a00,
+       0x04020007, 0x0201f800, 0x0002077d, 0x4a034406,
+       0x00000002, 0x0201f000, 0x0010230c, 0x497a5a04,
+       0x497a5805, 0x4a025c04, 0x00008000, 0x4a01d809,
+       0x001027f9, 0x492e6008, 0x42027000, 0x00000032,
+       0x0201f000, 0x000207a1, 0x800409c0, 0x04000005,
+       0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+       0x0201f800, 0x0010513b, 0x04020005, 0x4a034406,
+       0x00000016, 0x0201f000, 0x0010230c, 0x836c0580,
+       0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+       0x0201f000, 0x0010230c, 0x59a00c06, 0x82040500,
+       0xffffff00, 0x02020000, 0x00102310, 0x82041580,
+       0x000000ff, 0x04020007, 0x59a80010, 0x82000500,
+       0x000000ff, 0x82001540, 0x0000ff00, 0x0401f011,
+       0x82040400, 0x0010210e, 0x50000000, 0x80000110,
+       0x82000580, 0x00000080, 0x02000000, 0x00102310,
+       0x59a80010, 0x82000500, 0x000000ff, 0x80041580,
+       0x02000000, 0x00102310, 0x840409c0, 0x80041540,
+       0x0201f800, 0x0002075a, 0x04020005, 0x4a034406,
+       0x00000003, 0x0201f000, 0x0010230c, 0x48ee6021,
+       0x480a621c, 0x4a02641c, 0x0000bc05, 0x4a026406,
+       0x00000001, 0x0201f800, 0x00103a00, 0x04020007,
+       0x0201f800, 0x0002077d, 0x4a034406, 0x00000002,
+       0x0201f000, 0x0010230c, 0x497a5a04, 0x497a5805,
+       0x4a025c04, 0x00008000, 0x4a01d809, 0x001027f9,
+       0x492e6008, 0x42027000, 0x00000032, 0x0201f000,
+       0x000207a1, 0x592c0005, 0x82000580, 0x01000000,
+       0x02020000, 0x001022c0, 0x4a034406, 0x00000004,
+       0x0201f000, 0x0010230c, 0x497b4406, 0x497b4207,
+       0x0201f800, 0x00103b25, 0x04000008, 0x59a80066,
+       0x59a8086a, 0x80040480, 0x59a80867, 0x48074406,
+       0x80041480, 0x480b4207, 0x49674407, 0x59a8000e,
+       0x48034209, 0x495f4409, 0x59a80020, 0x4803420b,
+       0x0201f000, 0x001022c0, 0x800409c0, 0x04000005,
+       0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+       0x59a00406, 0x8c000500, 0x0402000f, 0x59a80069,
+       0x81640480, 0x04001008, 0x59a8000b, 0x81500580,
+       0x04000009, 0x59a8006a, 0x59a81066, 0x80080580,
+       0x04000005, 0x4a034406, 0x00000018, 0x0201f000,
+       0x0010230c, 0x82000540, 0x00000001, 0x0201f800,
+       0x001015fe, 0x0201f800, 0x00103c80, 0x0201f000,
+       0x001022c0, 0x4803c856, 0x800409c0, 0x02020000,
+       0x00102314, 0x59a00406, 0x8c00051e, 0x04000008,
+       0x4803c856, 0x59a0020b, 0x82000480, 0x00000800,
+       0x04001015, 0x0201f000, 0x00102310, 0x4803c856,
+       0x59a0020b, 0x599c0a01, 0x80040480, 0x04021003,
+       0x0201f000, 0x00102310, 0x59a8000e, 0x81640580,
+       0x04000009, 0x4a034406, 0x00000018, 0x0201f000,
+       0x0010230c, 0x4a034406, 0x00000005, 0x0201f000,
+       0x0010230c, 0x59a80026, 0x8c00050a, 0x040007fa,
+       0x59a00406, 0x8c00051e, 0x04000036, 0x0201f800,
+       0x0002075a, 0x040007f4, 0x0201f800, 0x00103a00,
+       0x040007f1, 0x497a5a04, 0x59a00406, 0x4802620a,
+       0x59a00209, 0x4802640a, 0x59a00409, 0x4802620b,
+       0x59a0020d, 0x4802620c, 0x59a0040d, 0x4802640c,
+       0x59a0020e, 0x4802620d, 0x59a0040e, 0x4802640d,
+       0x59a00210, 0x4802620e, 0x59a00410, 0x4802640e,
+       0x59a0020b, 0x82000500, 0x0000fffc, 0x80000104,
+       0x4802640b, 0x0401f9d9, 0x040007d7, 0x48ee6021,
+       0x58ee580d, 0x5930020e, 0x59301c0e, 0x900c19c0,
+       0x800c1d40, 0x5930020c, 0x5930140c, 0x900811c0,
+       0x80081540, 0x592c0a05, 0x832c0400, 0x00000006,
+       0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5,
+       0x4a034000, 0x00000001, 0x49334001, 0x1c01f000,
+       0x0201f800, 0x00106c55, 0x0201f800, 0x00100ae0,
+       0x0401f86d, 0x497b5057, 0x4201d000, 0x00002710,
+       0x0201f800, 0x001060c6, 0x59c40880, 0x4c040000,
+       0x59c408a3, 0x4c040000, 0x497b4002, 0x0401f876,
+       0x0401f893, 0x4a03a005, 0x10000000, 0x0401f8b4,
+       0x0401f901, 0x04000048, 0x59c80001, 0x800001c0,
+       0x040007fc, 0x59c80018, 0x82000500, 0xf0000000,
+       0x59c00808, 0x82040d00, 0x0fffffff, 0x80040540,
+       0x48038008, 0x0201f800, 0x00100ec1, 0x59c00006,
+       0x4a038006, 0x10000000, 0x59c00009, 0x82000d00,
+       0x00e00000, 0x04020024, 0x4a03900d, 0x00000000,
+       0x59c80020, 0x82000500, 0xff000000, 0x82000580,
+       0x32000000, 0x0402001c, 0x4a03900d, 0x00000001,
+       0x59c80020, 0x82000500, 0xff000000, 0x82000580,
+       0xe1000000, 0x04020014, 0x4a03900d, 0x00000000,
+       0x59c80020, 0x82000500, 0x00ffffff, 0x4a03900d,
+       0x00000000, 0x59c80821, 0x82040d00, 0x00ffffff,
+       0x80040580, 0x04020008, 0x59a80010, 0x80040580,
+       0x04020005, 0x59c40005, 0x82000500, 0x000000f0,
+       0x04000006, 0x4803c856, 0x0401f8d7, 0x4a035057,
+       0x00000001, 0x0401f002, 0x0401f8e1, 0x42000000,
+       0x00000064, 0x80000040, 0x02000800, 0x001005d8,
+       0x59c00807, 0x82040d00, 0x0000000c, 0x040007fa,
+       0x0401f003, 0x4a035057, 0x00000001, 0x0401f8da,
+       0x0201f800, 0x00106f36, 0x0401f818, 0x4201d000,
+       0x000186a0, 0x0201f800, 0x001060c6, 0x5c000800,
+       0x480788a3, 0x5c000800, 0x48078880, 0x59a80057,
+       0x800001c0, 0x02000000, 0x001022c0, 0x0201f000,
+       0x00102318, 0x599c0201, 0x48035059, 0x41780800,
+       0x42001000, 0x00003b10, 0x0201f800, 0x001066a0,
+       0x480b505a, 0x1c01f000, 0x0201f800, 0x00106c4b,
+       0x59b800ea, 0x82000500, 0x00000007, 0x82000580,
+       0x00000003, 0x04020003, 0x4a0370e8, 0x00000001,
+       0x1c01f000, 0x42038000, 0x00007700, 0x4a038006,
+       0x30000000, 0x59c00007, 0x8c00050a, 0x040207fe,
+       0x59c00006, 0x59a00209, 0x59a00c09, 0x900409c0,
+       0x80040d40, 0x48078001, 0x59a0020e, 0x59a00c0e,
+       0x900409c0, 0x80040d40, 0x48078000, 0x59a0020b,
+       0x82000500, 0x0000fffc, 0x48038002, 0x48038003,
+       0x48038005, 0x497b9009, 0x59e00003, 0x82000540,
+       0x00008060, 0x4803c003, 0x1c01f000, 0x41780800,
+       0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800,
+       0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a,
+       0x00000001, 0x4a03a005, 0x20000000, 0x59d00006,
+       0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a,
+       0x040207fe, 0x59d00005, 0x59a00210, 0x59a00c10,
+       0x900409c0, 0x80040d40, 0x4807a001, 0x59a0020d,
+       0x59a00c0d, 0x900409c0, 0x80040d40, 0x4807a000,
+       0x59a0020b, 0x82000500, 0x0000fffc, 0x4803a003,
+       0x4803a002, 0x4803a008, 0x1c01f000, 0x59a00002,
+       0x4803c857, 0x800001c0, 0x0402004a, 0x59a8005a,
+       0x48038880, 0x59c400a3, 0x82000540, 0x00002008,
+       0x8400053a, 0x480388a3, 0x59c40008, 0x8400054e,
+       0x82000500, 0xffffffe1, 0x48038808, 0x59c80040,
+       0x84000534, 0x48039040, 0x0401f902, 0x04020013,
+       0x59a80010, 0x800000d0, 0x82000540, 0x00000011,
+       0x48039120, 0x59a80010, 0x82000500, 0x00ffffff,
+       0x82000540, 0x32000000, 0x48039121, 0x4a039123,
+       0xe1290008, 0x59a80010, 0x82000500, 0x00ffffff,
+       0x48039122, 0x0401f016, 0x59a80010, 0x82000500,
+       0x000000ff, 0x900009c0, 0x840001c0, 0x80040540,
+       0x82000540, 0x00000000, 0x48039120, 0x59a80010,
+       0x82000500, 0x000000ff, 0x82000540, 0x01000000,
+       0x48039121, 0x4a039123, 0x08210008, 0x59a80010,
+       0x82000500, 0x000000ff, 0x48039122, 0x497b9124,
+       0x59a80c5b, 0x80040800, 0x4807545b, 0x900409c0,
+       0x82040540, 0x0000aaaa, 0x48039125, 0x497b9126,
+       0x497b9127, 0x0401f8cf, 0x04020004, 0x4a039100,
+       0x0000e980, 0x0401f003, 0x4a039100, 0x0000e9a0,
+       0x1c01f000, 0x82000540, 0x00000001, 0x0402500d,
+       0x4203e000, 0x80000000, 0x40e81000, 0x41780800,
+       0x42000000, 0x00000064, 0x0201f800, 0x001066a0,
+       0x59940024, 0x80080400, 0x48032824, 0x80000580,
+       0x1c01f000, 0x4d900000, 0x4dd00000, 0x4da40000,
+       0x4d140000, 0x417a3000, 0x0201f800, 0x001070d8,
+       0x0201f800, 0x00106dc3, 0x5c022800, 0x5c034800,
+       0x5c03a000, 0x5c032000, 0x1c01f000, 0x59c80007,
+       0x8c000500, 0x04000003, 0x4a03900d, 0x00000030,
+       0x1c01f000, 0x4a038805, 0x00020000, 0x42000800,
+       0x0000003c, 0x0201f800, 0x00101345, 0x4a038891,
+       0x0000ffff, 0x59c80035, 0x48039035, 0x4a03900d,
+       0x00000040, 0x42038000, 0x00007700, 0x0201f800,
+       0x00100ec1, 0x42038000, 0x00007720, 0x0201f800,
+       0x00100ec1, 0x4a03a005, 0x20000000, 0x4a03a005,
+       0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe,
+       0x1c01f000, 0x4d300000, 0x4031d800, 0x58ef400b,
+       0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+       0x5c026000, 0x02000000, 0x00102304, 0x4d300000,
+       0x59a26001, 0x59a00000, 0x4000b000, 0x80000000,
+       0x48034000, 0x592c0001, 0x80000540, 0x0400001e,
+       0x40025800, 0x8058b040, 0x040207fb, 0x58ec1007,
+       0x58ec1808, 0x592c0a05, 0x4d2c0000, 0x58ec000d,
+       0x40025800, 0x592c0204, 0x5c025800, 0x82000580,
+       0x00000103, 0x04000008, 0x832c0400, 0x00000006,
+       0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5,
+       0x0401f007, 0x832c0400, 0x00000006, 0x0201f800,
+       0x00103a28, 0x4a01d809, 0x001029e5, 0x5c026000,
+       0x1c01f000, 0x58ec000d, 0x40025800, 0x592c0204,
+       0x82000580, 0x00000103, 0x04020006, 0x0201f800,
+       0x0002077d, 0x5c026000, 0x0201f000, 0x001022c0,
+       0x58ec000d, 0x40025800, 0x592c0404, 0x8400055e,
+       0x48025c04, 0x42028800, 0x000007fd, 0x42003000,
+       0x00fffffd, 0x0201f800, 0x001045a6, 0x04000003,
+       0x80000580, 0x0401f004, 0x59a26001, 0x0201f800,
+       0x0010937d, 0x5c026000, 0x02000000, 0x0010230c,
+       0x4d300000, 0x4a01d809, 0x00102a38, 0x0401f7dc,
+       0x592c0005, 0x82000580, 0x01000000, 0x02000000,
+       0x00102318, 0x4d300000, 0x59a26001, 0x5930020b,
+       0x59301c0a, 0x900001c0, 0x800c1d40, 0x5930040d,
+       0x5930120d, 0x900001c0, 0x80081540, 0x592c0a05,
+       0x832c0400, 0x00000006, 0x0201f800, 0x00103a28,
+       0x4a01d809, 0x001029e5, 0x4a034000, 0x00000001,
+       0x5c026000, 0x1c01f000, 0x4933c857, 0x4c300000,
+       0x5930040b, 0x82000c80, 0x0000000e, 0x04001004,
+       0x4a025a05, 0x0000000e, 0x0401f003, 0x48025a05,
+       0x0401f00c, 0x800409c0, 0x0400000a, 0x4c040000,
+       0x0201f800, 0x00103a00, 0x5c000800, 0x04000003,
+       0x40040000, 0x0401f7f0, 0x80000580, 0x0401f003,
+       0x82000540, 0x00000001, 0x5c006000, 0x1c01f000,
+       0x59a00206, 0x82000580, 0x00000044, 0x1c01f000,
+       0x4807c857, 0x800409c0, 0x0400000c, 0x0201f800,
+       0x00101650, 0x04020009, 0x42000000, 0x00000002,
+       0x0201f800, 0x0010188c, 0x42000000, 0x00000002,
+       0x0201f800, 0x00101821, 0x59a00406, 0x82000500,
+       0x00000007, 0x0c01f001, 0x00102a8c, 0x00102aa1,
+       0x00102ab7, 0x00102a8a, 0x00102a8a, 0x00102a8a,
+       0x00102a8a, 0x00102a8a, 0x0201f000, 0x00102310,
+       0x42000800, 0x000000c0, 0x0201f800, 0x0010193f,
+       0x82040540, 0x00000002, 0x42000800, 0x000000c0,
+       0x0201f800, 0x00101944, 0x42000800, 0x00000000,
+       0x0201f800, 0x0010193f, 0x82040540, 0x00000008,
+       0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+       0x0401f00b, 0x42000800, 0x000000c0, 0x0201f800,
+       0x0010193f, 0x82040540, 0x00000001, 0x42000800,
+       0x000000c0, 0x0201f800, 0x00101944, 0x59c80040,
+       0x4c000000, 0x59a80010, 0x4c000000, 0x59c400a3,
+       0x4c000000, 0x59c40008, 0x4c000000, 0x0401f911,
+       0x04000021, 0x0201f800, 0x001005d8, 0x59a80821,
+       0x800409c0, 0x02020000, 0x00102314, 0x0201f800,
+       0x0010513b, 0x04020005, 0x4a034406, 0x00000016,
+       0x0201f000, 0x0010230c, 0x836c0580, 0x00000003,
+       0x02020000, 0x00102314, 0x59c408a4, 0x82040d00,
+       0x0000000f, 0x82040580, 0x00000000, 0x02020000,
+       0x00102314, 0x59c80040, 0x4c000000, 0x59a80010,
+       0x4c000000, 0x59c400a3, 0x4c000000, 0x59c40008,
+       0x4c000000, 0x59c40080, 0x4c000000, 0x59a0020f,
+       0x59a0bc0f, 0x905cb9c0, 0x805cbd40, 0x41784800,
+       0x41785000, 0x41785800, 0x41789000, 0x41789800,
+       0x0401fe21, 0x0201f800, 0x00106c55, 0x0201f800,
+       0x00100ae0, 0x4178c000, 0x497b4002, 0x0401f95c,
+       0x0401f9aa, 0x59a0020c, 0x59a00c0c, 0x80040d40,
+       0x04000002, 0x0401f9fb, 0x0401f9fa, 0x0401fe68,
+       0x8060c1c0, 0x04020014, 0x0401fa98, 0x0401feb2,
+       0x0402000e, 0x0201f800, 0x001018d3, 0x04020008,
+       0x4a034406, 0x00000017, 0x0201f800, 0x0010230c,
+       0x4203e000, 0x50000000, 0x0401f000, 0x42005800,
+       0x0000aaaa, 0x0401f058, 0x59c80001, 0x800001c0,
+       0x040007ee, 0x59c80801, 0x800409c0, 0x04000006,
+       0x0401fa70, 0x40240000, 0x80280540, 0x802c0540,
+       0x0402004d, 0x59a00002, 0x82000580, 0xfeedbeef,
+       0x04000004, 0x42008800, 0x10000000, 0x0401f003,
+       0x42008800, 0x10000004, 0x0401fa19, 0x4a034002,
+       0xfeedbeef, 0x0401fa71, 0x0401fa97, 0x0401fea8,
+       0x59c40005, 0x8c000534, 0x04000004, 0x42005800,
+       0x0000bbbb, 0x0401f038, 0x0401fe83, 0x04020007,
+       0x42005800, 0x0000cccc, 0x485f420f, 0x905cb9c0,
+       0x485f440f, 0x0401f030, 0x59a0040c, 0x800001c0,
+       0x0400000e, 0x59a26000, 0x5930000d, 0x800001c0,
+       0x040207be, 0x59a26001, 0x5930080d, 0x800409c0,
+       0x040207ba, 0x804891c0, 0x040207b8, 0x804c99c0,
+       0x040207b6, 0x0401f87a, 0x805cb840, 0x04000005,
+       0x40240000, 0x80280540, 0x802c0540, 0x0402001a,
+       0x42000000, 0x00030d40, 0x80000040, 0x04020012,
+       0x59c00007, 0x82000500, 0x000501c0, 0x0402000b,
+       0x0201f800, 0x001018d3, 0x04020008, 0x4a034406,
+       0x00000017, 0x0201f800, 0x0010230c, 0x4203e000,
+       0x50000000, 0x0401f000, 0x42005800, 0x0000dddd,
+       0x0401f005, 0x59c00807, 0x82040d00, 0x0000000c,
+       0x040007ea, 0x0401fe5c, 0x59a0040c, 0x800001c0,
+       0x04000002, 0x0401f856, 0x0401fe6b, 0x40240000,
+       0x80280540, 0x802c0540, 0x04020003, 0x805cb9c0,
+       0x04020781, 0x0201f800, 0x00106f36, 0x0401fda3,
+       0x4201d000, 0x000186a0, 0x0201f800, 0x001060c6,
+       0x5c000800, 0x48078880, 0x5c000800, 0x48078808,
+       0x5c000800, 0x480788a3, 0x5c000800, 0x48075010,
+       0x5c000800, 0x48079040, 0x0201f800, 0x00100969,
+       0x59a00406, 0x82000500, 0x00000003, 0x82000580,
+       0x00000002, 0x0400002c, 0x42000800, 0x000000c0,
+       0x0201f800, 0x0010193f, 0x82040500, 0xfffffffc,
+       0x42000800, 0x000000c0, 0x0201f800, 0x00101944,
+       0x42000800, 0x00000000, 0x0201f800, 0x0010193f,
+       0x82040500, 0xfffffff7, 0x42000800, 0x00000000,
+       0x0201f800, 0x00101944, 0x42000800, 0x00000000,
+       0x0201f800, 0x0010193f, 0x82040500, 0xfffffffb,
+       0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+       0x4a0388a7, 0x0000f7f7, 0x42006000, 0xbeffffff,
+       0x42006800, 0x80018000, 0x0201f800, 0x0010427d,
+       0x42006000, 0xfffeffff, 0x41786800, 0x0201f800,
+       0x0010427d, 0x402c0000, 0x80280540, 0x80240540,
+       0x02000000, 0x001022c0, 0x48274406, 0x482b4207,
+       0x482f4407, 0x0201f000, 0x0010231c, 0x59a26000,
+       0x813261c0, 0x0400000e, 0x59325808, 0x812e59c0,
+       0x0400000b, 0x0201f800, 0x0002077d, 0x0201f800,
+       0x001007fd, 0x59a26001, 0x59325808, 0x0201f800,
+       0x0002077d, 0x0201f800, 0x001007fd, 0x1c01f000,
+       0x42000800, 0x000000ef, 0x0201f800, 0x001015eb,
+       0x59c400a3, 0x8400055a, 0x8400053a, 0x480388a3,
+       0x0201f800, 0x0010163b, 0x0402000a, 0x42000000,
+       0x00000001, 0x0201f800, 0x0010188c, 0x42000000,
+       0x00000001, 0x0201f800, 0x00101821, 0x0401f013,
+       0x0201f800, 0x00101642, 0x04020008, 0x41780000,
+       0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+       0x00101821, 0x0401f009, 0x42000000, 0x00000002,
+       0x0201f800, 0x0010188c, 0x42000000, 0x00000002,
+       0x0201f800, 0x00101821, 0x42000800, 0x00000000,
+       0x0201f800, 0x0010193f, 0x82040540, 0x00000004,
+       0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+       0x4201d000, 0x00000014, 0x0201f800, 0x0010608e,
+       0x59c40008, 0x8400054e, 0x82000500, 0xffffffe1,
+       0x48038808, 0x4a0388a7, 0x0000f7f7, 0x42001000,
+       0x04000001, 0x0201f800, 0x0010193d, 0x42006000,
+       0xbe20bfff, 0x42006800, 0x80018000, 0x0201f800,
+       0x0010427d, 0x42006000, 0xfffeffff, 0x41786800,
+       0x0201f800, 0x0010427d, 0x4200b000, 0x00001388,
+       0x4201d000, 0x00000014, 0x4c580000, 0x0201f800,
+       0x0010608e, 0x0201f800, 0x001018d3, 0x5c00b000,
+       0x04000004, 0x8058b040, 0x040207f6, 0x0401f025,
+       0x59c40005, 0x8c000534, 0x04020007, 0x59c400a4,
+       0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+       0x0402001c, 0x42006000, 0x00020000, 0x0201f800,
+       0x00104282, 0x4201d000, 0x00000064, 0x0201f800,
+       0x0010608e, 0x42006000, 0xfeffffff, 0x42006800,
+       0x02000000, 0x0201f800, 0x0010427d, 0x42006000,
+       0xfdffffff, 0x41786800, 0x0201f800, 0x0010427d,
+       0x4a038805, 0x04000001, 0x59c400a4, 0x82000500,
+       0x0000000f, 0x82000580, 0x00000000, 0x04000003,
+       0x82000540, 0x00000001, 0x1c01f000, 0x4803c856,
+       0x42038000, 0x00007700, 0x0201f800, 0x00100ec1,
+       0x59c00006, 0x59a0040c, 0x800001c0, 0x0400003f,
+       0x59a03c0c, 0x59a00209, 0x59a01c09, 0x900c19c0,
+       0x800c1d40, 0x59a0020e, 0x59a0240e, 0x901021c0,
+       0x80102540, 0x59a0020b, 0x82000500, 0x0000fffc,
+       0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003,
+       0x0201f800, 0x0002075a, 0x02000800, 0x001005d8,
+       0x49334000, 0x0201f800, 0x001007e4, 0x4a025a04,
+       0x00000018, 0x4a025805, 0x00abcdef, 0x492e6008,
+       0x492e600b, 0x481e600d, 0x4a02600c, 0x00000004,
+       0x832c0400, 0x00000011, 0x4802600a, 0x42001000,
+       0x0000000c, 0x821c0d80, 0x00000001, 0x04000004,
+       0x801c3840, 0x0401f963, 0x0401f004, 0x41783800,
+       0x0401f960, 0x0401f011, 0x821c0c80, 0x00000005,
+       0x04001005, 0x40043800, 0x42001000, 0x0000003c,
+       0x0401f006, 0x80001580, 0x82081400, 0x0000000c,
+       0x801c3840, 0x040207fd, 0x832c0400, 0x00000005,
+       0x0401f950, 0x040207f1, 0x497b9009, 0x59e00003,
+       0x82000540, 0x00008060, 0x4803c003, 0x4a038009,
+       0x00e00000, 0x1c01f000, 0x4803c856, 0x41780800,
+       0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800,
+       0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a,
+       0x00000001, 0x4a03a005, 0x20000000, 0x59d00006,
+       0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a,
+       0x040207fe, 0x59d00005, 0x59a0020c, 0x800001c0,
+       0x0400003f, 0x59a03a0c, 0x59a00210, 0x59a01c10,
+       0x900c19c0, 0x800c1d40, 0x59a0020d, 0x59a0240d,
+       0x901021c0, 0x80102540, 0x59a0120b, 0x82081500,
+       0x0000fffc, 0x59a0040b, 0x900001c0, 0x80081540,
+       0x480ba003, 0x0201f800, 0x0002075a, 0x02000800,
+       0x001005d8, 0x49334001, 0x0201f800, 0x001007e4,
+       0x4a025a04, 0x00000018, 0x4a025805, 0x00abcdef,
+       0x492e6008, 0x492e600b, 0x481e600d, 0x4a02600c,
+       0x00000004, 0x832c0400, 0x00000011, 0x4802600a,
+       0x42001000, 0x0000000c, 0x821c0d80, 0x00000001,
+       0x04000004, 0x801c3840, 0x0401f906, 0x0401f004,
+       0x41783800, 0x0401f903, 0x0401f011, 0x821c0c80,
+       0x00000005, 0x04001005, 0x40043800, 0x42001000,
+       0x0000003c, 0x0401f006, 0x80001580, 0x82081400,
+       0x0000000c, 0x801c3840, 0x040207fd, 0x832c0400,
+       0x00000005, 0x0401f8f3, 0x040207f1, 0x1c01f000,
+       0x4803c856, 0x59a0020c, 0x800001c0, 0x04000024,
+       0x824c0580, 0x00000002, 0x04000040, 0x59a26001,
+       0x5930380d, 0x801c39c0, 0x0400003c, 0x801c3840,
+       0x481e600d, 0x5932580b, 0x5930080a, 0x50042000,
+       0x58041801, 0x58041002, 0x82081500, 0xfffffffc,
+       0x5930000c, 0x80000000, 0x82000d80, 0x00000005,
+       0x04020009, 0x497a600c, 0x592e5801, 0x812e59c0,
+       0x0400001a, 0x492e600b, 0x832c0c00, 0x00000005,
+       0x0401f005, 0x4802600c, 0x5930080a, 0x82040c00,
+       0x00000003, 0x4806600a, 0x0401f010, 0x59a0120b,
+       0x82081500, 0x0000fffc, 0x59a0040b, 0x900001c0,
+       0x80081540, 0x480ba003, 0x59a0020d, 0x59a0240d,
+       0x901021c0, 0x80102540, 0x59a00210, 0x59a01c10,
+       0x900c19c0, 0x800c1d40, 0x4201d000, 0x00003a98,
+       0x0201f800, 0x001060c6, 0x480ba002, 0x59a80059,
+       0x4803a008, 0x4813a000, 0x480fa001, 0x4a03a005,
+       0x10000000, 0x02005800, 0x001005d8, 0x804c9800,
+       0x82000540, 0x00000001, 0x1c01f000, 0x4847c857,
+       0x59a0040c, 0x800001c0, 0x04000024, 0x82480580,
+       0x00000002, 0x04000042, 0x59a26000, 0x5930380d,
+       0x801c39c0, 0x0400003e, 0x801c3840, 0x481e600d,
+       0x5932580b, 0x5930080a, 0x50042000, 0x58041801,
+       0x58041002, 0x82081500, 0xfffffffc, 0x5930000c,
+       0x80000000, 0x82000d80, 0x00000005, 0x04020009,
+       0x497a600c, 0x592e5801, 0x812e59c0, 0x0400001d,
+       0x492e600b, 0x832c0c00, 0x00000005, 0x0401f005,
+       0x4802600c, 0x5930080a, 0x82040c00, 0x00000003,
+       0x4806600a, 0x0401f013, 0x82440580, 0x10000000,
+       0x0402001f, 0x59a0020e, 0x59a0240e, 0x901021c0,
+       0x80102540, 0x59a00209, 0x59a01c09, 0x900c19c0,
+       0x800c1d40, 0x59a0020b, 0x82000500, 0x0000fffc,
+       0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003,
+       0x48138000, 0x480f8001, 0x480b8002, 0x59c80018,
+       0x82000500, 0xf0000000, 0x59c02008, 0x82102500,
+       0x0fffffff, 0x80100540, 0x48038008, 0x48478006,
+       0x80489000, 0x8260c540, 0x00000001, 0x1c01f000,
+       0x59c00009, 0x4803c857, 0x82000d00, 0x00e00000,
+       0x0400000d, 0x485f420f, 0x905cb9c0, 0x485f440f,
+       0x8c00052e, 0x04000002, 0x80285000, 0x8c00052c,
+       0x04000002, 0x80244800, 0x8c00052a, 0x04000002,
+       0x802c5800, 0x1c01f000, 0x59a0020c, 0x800001c0,
+       0x04000024, 0x59d00806, 0x4807c857, 0x8c040d3e,
+       0x04000020, 0x4a03a005, 0x20000000, 0x4a03a005,
+       0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe,
+       0x824c0480, 0x00000003, 0x02021800, 0x001005d8,
+       0x404c0000, 0x0c01f001, 0x00102da1, 0x00102da3,
+       0x00102da9, 0x0201f800, 0x001005d8, 0x80000040,
+       0x40009800, 0x0401ff43, 0x0400000a, 0x0401ff41,
+       0x0401f008, 0x80000040, 0x40009800, 0x59d00806,
+       0x4807c857, 0x8c040d3e, 0x040207e3, 0x0401ff39,
+       0x1c01f000, 0x59a0040c, 0x800001c0, 0x04000024,
+       0x59c00807, 0x4807c857, 0x8c040d3e, 0x04000020,
+       0x59c00807, 0x4a038006, 0x20000000, 0x82480480,
+       0x00000003, 0x02021800, 0x001005d8, 0x40480000,
+       0x0c01f001, 0x00102dc4, 0x00102dc6, 0x00102dce,
+       0x0201f800, 0x001005d8, 0x80000040, 0x40009000,
+       0x42008800, 0x10000004, 0x0401ff65, 0x0400000c,
+       0x0401ff63, 0x0401f00a, 0x80000040, 0x40009000,
+       0x59c00807, 0x4807c857, 0x8c040d3e, 0x040207e5,
+       0x42008800, 0x10000004, 0x0401ff59, 0x1c01f000,
+       0x492fc857, 0x4000a800, 0x4a03b805, 0x20000000,
+       0x59dc0006, 0x4a03b805, 0x30000000, 0x4813b800,
+       0x480fb801, 0x480bb802, 0x4857b803, 0x4a03b805,
+       0x30000002, 0x59dc0006, 0x4a03b805, 0x70000001,
+       0x59dc0006, 0x4a03b805, 0x10000000, 0x59dc0006,
+       0x8c00053e, 0x040007fe, 0x4a03b805, 0x20000000,
+       0x59dc0006, 0x59dc2000, 0x59dc1801, 0x801c39c0,
+       0x0400000a, 0x4d2c0000, 0x0201f800, 0x001007e4,
+       0x5c000800, 0x02000800, 0x001005d8, 0x4a025a04,
+       0x0000000a, 0x492c0801, 0x1c01f000, 0x42006000,
+       0x00102fb2, 0x0201f800, 0x00101345, 0x4a03902c,
+       0x00200000, 0x4200b000, 0x000001f4, 0x59c8002c,
+       0x8c00052c, 0x04000007, 0x8058b040, 0x040207fc,
+       0x42000000, 0x00004003, 0x41781000, 0x0401f196,
+       0x50301000, 0x41784800, 0x4a03902d, 0x00008000,
+       0x4200b000, 0x000001f4, 0x59c8002c, 0x8c000534,
+       0x04000007, 0x8058b040, 0x040207fc, 0x42000000,
+       0x00004003, 0x41781000, 0x0401f187, 0x0401f8f8,
+       0x80244800, 0x40240000, 0x82000580, 0x000003b1,
+       0x040207fb, 0x0401f988, 0x41784800, 0x0401f920,
+       0x80244800, 0x40240000, 0x82000580, 0x000003b1,
+       0x040207fb, 0x80306000, 0x82300580, 0x00102fb4,
+       0x040207e0, 0x59a80863, 0x800409c0, 0x04000007,
+       0x42000000, 0x00004004, 0x42001000, 0x00000002,
+       0x59a81862, 0x0401f16c, 0x42006000, 0x00102fb2,
+       0x4a035064, 0x00000004, 0x50301000, 0x41784800,
+       0x4a03902d, 0x00004000, 0x4200b000, 0x000001f4,
+       0x59c8002c, 0x8c000532, 0x04000007, 0x8058b040,
+       0x040207fc, 0x42000000, 0x00004003, 0x41781000,
+       0x0401f159, 0x0401f8ca, 0x80244800, 0x40240000,
+       0x82000580, 0x00000154, 0x040207fb, 0x0401f95a,
+       0x41784800, 0x0401f8f2, 0x80244800, 0x40240000,
+       0x82000580, 0x00000154, 0x040207fb, 0x80306000,
+       0x82300580, 0x00102fb4, 0x040207e0, 0x59a80863,
+       0x800409c0, 0x04000007, 0x42000000, 0x00004004,
+       0x42001000, 0x00000004, 0x59a81862, 0x0401f13e,
+       0x42006000, 0x00102fb2, 0x497b5064, 0x50301000,
+       0x41784800, 0x4a03902d, 0x00001000, 0x4200b000,
+       0x000001f4, 0x59c8002c, 0x8c00052e, 0x04000007,
+       0x8058b040, 0x040207fc, 0x42000000, 0x00004003,
+       0x41781000, 0x0401f12c, 0x0401f89d, 0x80244800,
+       0x40240000, 0x82000580, 0x00000088, 0x040207fb,
+       0x0401f92d, 0x41784800, 0x0401f8c5, 0x80244800,
+       0x40240000, 0x82000580, 0x00000088, 0x040207fb,
+       0x80306000, 0x82300580, 0x00102fb4, 0x040207e0,
+       0x59a80863, 0x800409c0, 0x04000007, 0x42000000,
+       0x00004004, 0x42001000, 0x00000001, 0x59a81862,
+       0x0401f111, 0x42006000, 0x00102fb2, 0x50301000,
+       0x41784800, 0x4a03902d, 0x00000800, 0x0401f87c,
+       0x80244800, 0x40240000, 0x82000580, 0x00000018,
+       0x040207fb, 0x0401f90c, 0x41784800, 0x0401f8a4,
+       0x80244800, 0x40240000, 0x82000580, 0x00000018,
+       0x040207fb, 0x80306000, 0x82300580, 0x00102fb4,
+       0x040207eb, 0x59a80863, 0x800409c0, 0x04000007,
+       0x42000000, 0x00004004, 0x42001000, 0x00000010,
+       0x59a81862, 0x0401f0f0, 0x42006000, 0x00102fb2,
+       0x50301000, 0x41784800, 0x4a03902d, 0x00000400,
+       0x0401f85b, 0x80244800, 0x40240000, 0x82000580,
+       0x00000088, 0x040207fb, 0x0401f8eb, 0x41784800,
+       0x0401f883, 0x80244800, 0x40240000, 0x82000580,
+       0x00000088, 0x040207fb, 0x80306000, 0x82300580,
+       0x00102fb4, 0x040207eb, 0x59a80863, 0x800409c0,
+       0x04000007, 0x42000000, 0x00004004, 0x42001000,
+       0x00000008, 0x59a81862, 0x0401f0cf, 0x42006000,
+       0x00102fb2, 0x50301000, 0x41784800, 0x4a03902d,
+       0x00002000, 0x4200b000, 0x000001f4, 0x59c8002c,
+       0x8c000530, 0x04000007, 0x8058b040, 0x040207fc,
+       0x42000000, 0x00004003, 0x41781000, 0x0401f0be,
+       0x59c8002c, 0x82000500, 0xffe0ffff, 0x82080d00,
+       0x001f0000, 0x80040540, 0x4803902c, 0x0401f828,
+       0x80244800, 0x40240000, 0x82000580, 0x00000110,
+       0x040207fb, 0x0401f8b8, 0x41784800, 0x0401f850,
+       0x59c80034, 0x82080d00, 0x001f0000, 0x82000500,
+       0x001f0000, 0x80040580, 0x04000006, 0x59a80063,
+       0x80000000, 0x48035063, 0x40240000, 0x48035062,
+       0x80244800, 0x40240000, 0x82000580, 0x00000110,
+       0x040207ef, 0x80306000, 0x82300580, 0x00102fb4,
+       0x040207cd, 0x59a80863, 0x800409c0, 0x04000006,
+       0x42000000, 0x00004004, 0x42001000, 0x00000020,
+       0x59a81862, 0x0201f000, 0x001022c0, 0x59c8002c,
+       0x82000500, 0xffff0000, 0x82080d00, 0x0000ffff,
+       0x80040540, 0x4803902c, 0x40080000, 0x48039028,
+       0x48039029, 0x59a80064, 0x82000580, 0x00000004,
+       0x04000004, 0x40080000, 0x4803902a, 0x4803902b,
+       0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000,
+       0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4,
+       0x59c8002c, 0x82000500, 0x18000000, 0x04000007,
+       0x8058b040, 0x040207fb, 0x42000000, 0x00004003,
+       0x41781000, 0x0401f06c, 0x4a03902e, 0x00000001,
+       0x4200b000, 0x000001f4, 0x59c8002e, 0x8c000500,
+       0x04000006, 0x8058b040, 0x040207fc, 0x42000000,
+       0x00004003, 0x0401f060, 0x1c01f000, 0x41783800,
+       0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000,
+       0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4,
+       0x59c8002c, 0x82000500, 0x18000000, 0x04000007,
+       0x8058b040, 0x040207fb, 0x42000000, 0x00004003,
+       0x41781000, 0x0401f04c, 0x59c80030, 0x59c80830,
+       0x80040580, 0x040207fd, 0x40041800, 0x59c80031,
+       0x59c80831, 0x80040580, 0x040207fd, 0x40042000,
+       0x59c80032, 0x59c80832, 0x80040580, 0x040207fd,
+       0x40042800, 0x59c80033, 0x59c80833, 0x80040580,
+       0x040207fd, 0x40043000, 0x400c0000, 0x80080580,
+       0x04000002, 0x801c3800, 0x40100000, 0x80080580,
+       0x04000002, 0x801c3800, 0x59a80064, 0x82000580,
+       0x00000004, 0x04000009, 0x40140000, 0x80080580,
+       0x04000002, 0x801c3800, 0x40180000, 0x80080580,
+       0x04000002, 0x801c3800, 0x59a80064, 0x82000580,
+       0x00000004, 0x0400000d, 0x59c80034, 0x59c80834,
+       0x80040580, 0x040207fd, 0x82040500, 0x0000ffff,
+       0x82080d00, 0x0000ffff, 0x80040580, 0x0400000e,
+       0x801c3800, 0x0401f00c, 0x59c80034, 0x59c80834,
+       0x80040580, 0x040207fd, 0x82040500, 0x000000ff,
+       0x82080d00, 0x000000ff, 0x80040580, 0x04000002,
+       0x801c3800, 0x801c39c0, 0x04000006, 0x59a80063,
+       0x801c0400, 0x48035063, 0x40240000, 0x48035062,
+       0x1c01f000, 0x48034206, 0x48074406, 0x480b4207,
+       0x480f4407, 0x48134208, 0x48174408, 0x0201f000,
+       0x001022c3, 0x42000000, 0x00600000, 0x80000040,
+       0x040207ff, 0x1c01f000, 0x5a5a5a5a, 0xa5a5a5a5,
+       0x59a00c0a, 0x800409c0, 0x02000000, 0x00102310,
+       0x82040480, 0x00000021, 0x02021000, 0x00102310,
+       0x82040480, 0x00000011, 0x04001003, 0x42000800,
+       0x00000010, 0x59a00208, 0x59a01407, 0x900811c0,
+       0x80081540, 0x59a00207, 0x59a01c06, 0x900c19c0,
+       0x800c1d40, 0x0201f800, 0x00103a00, 0x04000006,
+       0x0201f800, 0x00103a25, 0x4a01d809, 0x00102fd5,
+       0x1c01f000, 0x4a034406, 0x00000002, 0x0201f000,
+       0x0010230c, 0x4031d800, 0x58ef400b, 0x58ec0002,
+       0x82000580, 0x00000200, 0x02000000, 0x00102304,
+       0x59a00c0a, 0x82040480, 0x00000011, 0x04001003,
+       0x42000800, 0x00000010, 0x59a0040b, 0x59a0120b,
+       0x900811c0, 0x80081540, 0x59a00209, 0x59a01c08,
+       0x900c19c0, 0x800c1d40, 0x58ec0003, 0x0201f800,
+       0x00103a28, 0x4a01d809, 0x00102ff0, 0x1c01f000,
+       0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580,
+       0x00000200, 0x02000000, 0x00102304, 0x59a00c0a,
+       0x82040480, 0x00000011, 0x02001000, 0x001022c0,
+       0x82040c80, 0x00000010, 0x59a00208, 0x59a01407,
+       0x900811c0, 0x80081540, 0x59a00207, 0x59a01c06,
+       0x900c19c0, 0x800c1d40, 0x82081400, 0x00000040,
+       0x58ec0003, 0x0201f800, 0x00103a25, 0x4a01d809,
+       0x0010300e, 0x1c01f000, 0x4031d800, 0x58ef400b,
+       0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+       0x00102304, 0x59a0040a, 0x82000c80, 0x00000010,
+       0x59a0040b, 0x59a0120b, 0x900811c0, 0x80081540,
+       0x59a00209, 0x59a01c08, 0x900c19c0, 0x800c1d40,
+       0x82081400, 0x00000040, 0x58ec0003, 0x0201f800,
+       0x00103a28, 0x4a01d809, 0x001022b9, 0x1c01f000,
+       0x48efc857, 0x59a00207, 0x59a01407, 0x900001c0,
+       0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+       0x800c1d40, 0x59a00406, 0x48034000, 0x480b4001,
+       0x480f4002, 0x0201f800, 0x00103a00, 0x04020005,
+       0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+       0x42000800, 0x00000010, 0x0201f800, 0x00103a25,
+       0x4a01d809, 0x00103043, 0x1c01f000, 0x4031d800,
+       0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+       0x00000200, 0x02000000, 0x00102304, 0x48efc857,
+       0x49a3c857, 0x492fc857, 0x592c0a04, 0x80040910,
+       0x04020005, 0x4a034406, 0x00000019, 0x0201f000,
+       0x0010230c, 0x4805d80c, 0x0401f00a, 0x4031d800,
+       0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+       0x02000000, 0x00102304, 0x48efc857, 0x49a3c857,
+       0x48efc857, 0x49a3c857, 0x58ec000c, 0x80000040,
+       0x04000012, 0x4801d80c, 0x0201f800, 0x00103a00,
+       0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+       0x0010230c, 0x42000800, 0x00000010, 0x58ec1007,
+       0x58ec1808, 0x0201f800, 0x00103a25, 0x4a01d809,
+       0x00103057, 0x1c01f000, 0x58ee580d, 0x48efc857,
+       0x49a3c857, 0x492fc857, 0x492f3006, 0x592c0404,
+       0x8400055e, 0x48025c04, 0x4a01d809, 0x00103081,
+       0x1c01f000, 0x58ee580d, 0x48efc857, 0x49a3c857,
+       0x492fc857, 0x592c0404, 0x8400051e, 0x48025c04,
+       0x59a00000, 0x59a01001, 0x59a01802, 0x80081400,
+       0x820c1c40, 0x00000000, 0x832c0400, 0x00000004,
+       0x42000800, 0x00000010, 0x0201f000, 0x00103a28,
+       0x800409c0, 0x04000005, 0x4a034406, 0x00000001,
+       0x0201f000, 0x0010230c, 0x836c0580, 0x00000003,
+       0x04000005, 0x4a034406, 0x00000007, 0x0201f000,
+       0x0010230c, 0x59a0320b, 0x82183500, 0x000000ff,
+       0x59a28c06, 0x0201f800, 0x00020245, 0x02020000,
+       0x00102310, 0x83440580, 0x000007fd, 0x04000008,
+       0x0201f800, 0x001049e7, 0x04000005, 0x4a034406,
+       0x00000009, 0x0201f000, 0x0010230c, 0x0201f800,
+       0x00103a00, 0x04020005, 0x4a034406, 0x00000002,
+       0x0201f000, 0x0010230c, 0x801831c0, 0x0400000a,
+       0x412c0800, 0x0201f800, 0x00103a00, 0x04020005,
+       0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+       0x40065800, 0x4a025c04, 0x00008000, 0x497a5a04,
+       0x0201f800, 0x00109100, 0x04020005, 0x4a034406,
+       0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+       0x001030d2, 0x1c01f000, 0x592c0005, 0x82000580,
+       0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+       0x0201f000, 0x0010230c, 0x592c0406, 0x82002d00,
+       0x0000ff00, 0x82000500, 0x000000ff, 0x80000904,
+       0x80040800, 0x82040480, 0x00000006, 0x04001003,
+       0x42000800, 0x00000005, 0x832ca400, 0x00000006,
+       0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28,
+       0x59a00407, 0x59a01207, 0x900811c0, 0x80081540,
+       0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40,
+       0x832c0400, 0x00000006, 0x4c140000, 0x0201f800,
+       0x00103a28, 0x5c002800, 0x801429c0, 0x04000003,
+       0x4a01d809, 0x001030ff, 0x1c01f000, 0x4031d800,
+       0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+       0x00000200, 0x02000000, 0x00102304, 0x812e59c0,
+       0x02000800, 0x001005d8, 0x592c0006, 0x82000500,
+       0xff000000, 0x80000904, 0x800409c0, 0x02000000,
+       0x00102304, 0x82040480, 0x0000000e, 0x04001003,
+       0x42000800, 0x0000000d, 0x592e5801, 0x812e59c0,
+       0x02000800, 0x001005d8, 0x832ca400, 0x00000005,
+       0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28,
+       0x58ec1007, 0x58ec1808, 0x832c0400, 0x00000005,
+       0x0201f000, 0x00103a28, 0x0201f800, 0x00103a00,
+       0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+       0x0010230c, 0x59a00c06, 0x82040500, 0x0000ff00,
+       0x840001c0, 0x82001480, 0x00000007, 0x02021000,
+       0x00102310, 0x0c01f001, 0x0010313d, 0x00103144,
+       0x0010314b, 0x0010314b, 0x0010314b, 0x0010314d,
+       0x00103152, 0x42000800, 0x0000000d, 0x42003800,
+       0x00103166, 0x4a034000, 0x0010b4eb, 0x0401f013,
+       0x42000800, 0x0000000d, 0x42003800, 0x00103166,
+       0x4a034000, 0x0010b4f8, 0x0401f00c, 0x0201f000,
+       0x00102310, 0x42000800, 0x00000008, 0x42003800,
+       0x00103179, 0x0401f005, 0x42000800, 0x00000004,
+       0x42003800, 0x001031c3, 0x59a00207, 0x59a01407,
+       0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09,
+       0x900001c0, 0x800c1d40, 0x832c0400, 0x00000005,
+       0x4c1c0000, 0x0201f800, 0x00103a25, 0x5c003800,
+       0x481dd809, 0x1c01f000, 0x4031d800, 0x58ef400b,
+       0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+       0x02000000, 0x00102304, 0x4a03501f, 0x00000001,
+       0x4200b000, 0x0000000d, 0x59a0a800, 0x832ca400,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x0201f000,
+       0x001022c0, 0x4031d800, 0x58ef400b, 0x58ee580d,
+       0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+       0x00102304, 0x832ca400, 0x00000005, 0x50500000,
+       0x82001500, 0x000c0016, 0x02020000, 0x00102310,
+       0x82500c00, 0x00000003, 0x50040000, 0x82001500,
+       0x00000001, 0x02020000, 0x00102310, 0x50500000,
+       0x82001500, 0x00000028, 0x0400001d, 0x82081580,
+       0x00000028, 0x02020000, 0x00102310, 0x80500800,
+       0x50040000, 0x82001500, 0x00000013, 0x82081580,
+       0x00000013, 0x02020000, 0x00102310, 0x80040800,
+       0x50040000, 0x82001500, 0x00010000, 0x82081580,
+       0x00010000, 0x02020000, 0x00102310, 0x836c0580,
+       0x00000000, 0x04000012, 0x599c0019, 0x8c00050e,
+       0x0402000f, 0x0201f000, 0x00102310, 0x80500800,
+       0x50040000, 0x82001500, 0x00000013, 0x02020000,
+       0x00102310, 0x80040800, 0x50040000, 0x82001500,
+       0x00010000, 0x02020000, 0x00102310, 0x4200b000,
+       0x00000008, 0x4200a800, 0x0010b4e3, 0x0201f800,
+       0x0010ab17, 0x0201f000, 0x001022c0, 0x4031d800,
+       0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+       0x00000200, 0x02000000, 0x00102304, 0x4200b000,
+       0x00000004, 0x4200a800, 0x0010b8fa, 0x832ca400,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x59a80005,
+       0x84000550, 0x48035005, 0x0201f000, 0x001022c0,
+       0x0201f800, 0x00103a00, 0x04020005, 0x4a034406,
+       0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06,
+       0x82040500, 0x0000ff00, 0x840001c0, 0x82001480,
+       0x00000006, 0x02021000, 0x00102310, 0x0c01f001,
+       0x001031ee, 0x001031f3, 0x001031f8, 0x001031f8,
+       0x001031f8, 0x001031fa, 0x42000800, 0x0000000d,
+       0x4200a000, 0x0010b4eb, 0x0401f00c, 0x42000800,
+       0x0000000d, 0x4200a000, 0x0010b4f8, 0x0401f007,
+       0x0201f000, 0x00102310, 0x42000800, 0x00000008,
+       0x4200a000, 0x0010b4e3, 0x4004b000, 0x832cac00,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x59a00207,
+       0x59a01407, 0x900001c0, 0x80081540, 0x59a00209,
+       0x59a01c09, 0x900001c0, 0x800c1d40, 0x832c0400,
+       0x00000005, 0x0201f000, 0x00103a28, 0x836c0580,
+       0x00000000, 0x04020005, 0x4a034406, 0x00000007,
+       0x0201f000, 0x0010230c, 0x59a00406, 0x800001c0,
+       0x0400001a, 0x59a80005, 0x8c000514, 0x04000005,
+       0x42000000, 0x00000001, 0x40000800, 0x0401f003,
+       0x59a00207, 0x59a80853, 0x48035053, 0x0201f800,
+       0x0010163b, 0x04000022, 0x0201f800, 0x00101642,
+       0x0400001f, 0x0201f800, 0x00101649, 0x0400001c,
+       0x0201f800, 0x00101650, 0x04000019, 0x48075053,
+       0x0201f000, 0x00102310, 0x59c40801, 0x82040d00,
+       0x00018000, 0x82040580, 0x00000000, 0x04020004,
+       0x4a034406, 0x00000000, 0x0401f00d, 0x82040580,
+       0x00008000, 0x04020004, 0x4a034406, 0x00000001,
+       0x0401f007, 0x82040580, 0x00010000, 0x02020800,
+       0x001005d8, 0x4a034406, 0x00000003, 0x59a00406,
+       0x82000580, 0x00000002, 0x0402001f, 0x59c40006,
+       0x84000500, 0x48038806, 0x0201f800, 0x00106ede,
+       0x497b8880, 0x0201f800, 0x0010a9c0, 0x0201f800,
+       0x0010a9ce, 0x42000000, 0x0010b8ca, 0x0201f800,
+       0x0010aa47, 0x82000540, 0x00000001, 0x0201f800,
+       0x0010518c, 0x4a038808, 0x00000000, 0x4202d800,
+       0x00000004, 0x42001000, 0x00000001, 0x0201f800,
+       0x0010193d, 0x4a035049, 0x00000001, 0x0201f800,
+       0x001006d4, 0x0201f000, 0x001022c0, 0x800409c0,
+       0x04000005, 0x4a034406, 0x00000001, 0x0201f000,
+       0x0010230c, 0x836c0580, 0x00000003, 0x04000005,
+       0x4a034406, 0x00000007, 0x0201f000, 0x0010230c,
+       0x59a28c06, 0x59a0320b, 0x82183500, 0x000000ff,
+       0x0201f800, 0x00020245, 0x02020000, 0x00102310,
+       0x83440580, 0x000007fd, 0x04000008, 0x0201f800,
+       0x001049e7, 0x04000005, 0x42000800, 0x00000009,
+       0x0201f000, 0x0010230c, 0x0201f800, 0x00103a00,
+       0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+       0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000,
+       0x0201f800, 0x00109115, 0x04020005, 0x4a034406,
+       0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+       0x0010329e, 0x1c01f000, 0x592c0005, 0x82000d00,
+       0x0000ffff, 0x82000500, 0xffff0000, 0x82000580,
+       0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+       0x0201f000, 0x0010230c, 0x80040904, 0x832ca400,
+       0x00000005, 0x4050a800, 0x4004b000, 0x0201f800,
+       0x0010ab28, 0x59a00207, 0x59a01407, 0x900001c0,
+       0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+       0x800c1d40, 0x832c0400, 0x00000005, 0x0201f000,
+       0x00103a28, 0x496fc857, 0x836c0580, 0x00000000,
+       0x04000005, 0x4a034406, 0x0000001a, 0x0201f000,
+       0x0010230c, 0x0201f800, 0x0010513b, 0x02020800,
+       0x00104142, 0x42000800, 0x00000020, 0x59a00407,
+       0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+       0x59a01a09, 0x900c19c0, 0x800c1d40, 0x419c0000,
+       0x49a3c857, 0x0201f800, 0x00103a25, 0x4a01d809,
+       0x001032da, 0x1c01f000, 0x4833c857, 0x4031d800,
+       0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+       0x02000000, 0x00102304, 0x599c0200, 0x800001c0,
+       0x02000000, 0x00102310, 0x59a80005, 0x8c000512,
+       0x04000004, 0x599c0019, 0x8400050c, 0x48033819,
+       0x0201f800, 0x001097d7, 0x59a80005, 0x8c000514,
+       0x04000004, 0x599c0017, 0x84000508, 0x48033817,
+       0x0201f800, 0x00103b25, 0x04020004, 0x8c00050a,
+       0x02020000, 0x00102310, 0x4803c857, 0x8c000504,
+       0x04020004, 0x59c408a3, 0x84040d7a, 0x480788a3,
+       0x8c000502, 0x04020004, 0x59c408a3, 0x84040d08,
+       0x480788a3, 0x599c0c02, 0x8c000500, 0x04020004,
+       0x8c000516, 0x04000012, 0x0401f001, 0x82041480,
+       0x0000007f, 0x02021000, 0x00102310, 0x82041400,
+       0x0010210e, 0x50081000, 0x82081500, 0x000000ff,
+       0x8c000500, 0x04020006, 0x480b5010, 0x42000800,
+       0x00000003, 0x0201f800, 0x00106c78, 0x599c0019,
+       0x8c00050e, 0x0402000b, 0x59a80806, 0x8c040d14,
+       0x04000008, 0x42000800, 0x0010b4e3, 0x50040800,
+       0x82040d00, 0x00000028, 0x02020000, 0x00102310,
+       0x82000500, 0x00000030, 0x04000003, 0x80000108,
+       0x0401f003, 0x42000000, 0x00000002, 0x48039040,
+       0x42000800, 0x00000002, 0x82000400, 0x00103415,
+       0x50001000, 0x0201f800, 0x00106c78, 0x599c0201,
+       0x82000c80, 0x00000100, 0x02001000, 0x00102310,
+       0x82000c80, 0x00000841, 0x02021000, 0x00102310,
+       0x82000500, 0x00000007, 0x02020000, 0x00102310,
+       0x599c0401, 0x80000540, 0x02000000, 0x00102310,
+       0x599c0409, 0x599c0c07, 0x80040c80, 0x02021000,
+       0x00102310, 0x80000040, 0x02000000, 0x00102310,
+       0x599c0209, 0x599c0a07, 0x80040c80, 0x02021000,
+       0x00102310, 0x80000040, 0x02000000, 0x00102310,
+       0x0201f800, 0x001053cd, 0x0201f800, 0x00104cb6,
+       0x599c0201, 0x48035004, 0x0201f800, 0x001012ee,
+       0x599c020a, 0x800001c0, 0x04000003, 0x4803504d,
+       0x0401f003, 0x4a03504d, 0x000000c8, 0x0201f800,
+       0x00103b25, 0x04000004, 0x0201f800, 0x001060df,
+       0x417a5000, 0x836c0580, 0x00000000, 0x04020098,
+       0x599c0003, 0x599c0804, 0x9c0001c0, 0x9c0409c0,
+       0x48035002, 0x48075003, 0x599c1017, 0x8c08151c,
+       0x04000006, 0x599c0005, 0x599c0806, 0x9c0001c0,
+       0x9c0409c0, 0x0401f003, 0x82000500, 0xf0ffffff,
+       0x48035000, 0x48075001, 0x42001000, 0x0010b4eb,
+       0x48001000, 0x48041001, 0x42001000, 0x0010b4f8,
+       0x48001000, 0x48041001, 0x59a80005, 0x8c000514,
+       0x04020015, 0x599c1019, 0x82081500, 0x0000e000,
+       0x82080580, 0x00000000, 0x0402000c, 0x4a035053,
+       0x00000000, 0x42000000, 0x00000001, 0x0201f800,
+       0x0010188c, 0x42000000, 0x00000001, 0x0201f800,
+       0x00101821, 0x0401f02b, 0x82080580, 0x00002000,
+       0x0402000a, 0x4a035053, 0x00000001, 0x41780000,
+       0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+       0x00101821, 0x0401f01f, 0x82080580, 0x00004000,
+       0x04020006, 0x4a035053, 0x00000002, 0x4a035049,
+       0x00000001, 0x0401f017, 0x82080580, 0x00006000,
+       0x02020000, 0x00102310, 0x59a80858, 0x82040d80,
+       0x01391077, 0x04020005, 0x59e00813, 0x8c040d00,
+       0x02020000, 0x00102310, 0x4a035053, 0x00000003,
+       0x42000000, 0x00000002, 0x0201f800, 0x0010188c,
+       0x42000000, 0x00000002, 0x0201f800, 0x00101821,
+       0x599c0019, 0x8c000520, 0x0400000d, 0x42000000,
+       0x00000004, 0x42000800, 0x00000040, 0x0201f800,
+       0x00101944, 0x42000000, 0x00000010, 0x42000800,
+       0x000000c0, 0x0201f800, 0x00101944, 0x4a035032,
+       0x0000aaaa, 0x599c1018, 0x82081500, 0x00000030,
+       0x59a8006c, 0x80000540, 0x0400000c, 0x82080580,
+       0x00000000, 0x02000000, 0x00102310, 0x599c1018,
+       0x82081500, 0xffffffcf, 0x82081540, 0x00000010,
+       0x480b3818, 0x0401f010, 0x82080d80, 0x00000000,
+       0x04000007, 0x82080d80, 0x00000010, 0x0400000a,
+       0x82080d80, 0x00000020, 0x04020002, 0x48075032,
+       0x0201f800, 0x00103aba, 0x04000008, 0x0201f800,
+       0x001015fe, 0x0201f800, 0x0010162a, 0x59a8002a,
+       0x80040540, 0x4803502a, 0x49f3c857, 0x42001000,
+       0x00105065, 0x0201f800, 0x00105f90, 0x42001000,
+       0x00105058, 0x0201f800, 0x00106084, 0x4a038805,
+       0xffffffff, 0x4a03c014, 0x00400040, 0x4a03c013,
+       0x00400000, 0x0201f800, 0x001048c7, 0x59a0001d,
+       0x84000540, 0x4803401d, 0x49f3c857, 0x0201f000,
+       0x001022c0, 0x00000018, 0x0000000c, 0x00000018,
+       0x00000020, 0x836c0580, 0x00000000, 0x04020005,
+       0x42000800, 0x00000007, 0x0201f000, 0x0010230c,
+       0x42000800, 0x00000020, 0x59a00407, 0x59a01207,
+       0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09,
+       0x900c19c0, 0x800c1d40, 0x419c0000, 0x0201f000,
+       0x00103a28, 0x800409c0, 0x04000005, 0x4a034406,
+       0x00000001, 0x0201f000, 0x0010230c, 0x0201f800,
+       0x0010513b, 0x04020005, 0x4a034406, 0x00000016,
+       0x0201f000, 0x0010230c, 0x59a80013, 0x8c000500,
+       0x04000011, 0x4a034406, 0x00000000, 0x42000800,
+       0x00000020, 0x59a00407, 0x59a01207, 0x900811c0,
+       0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+       0x800c1d40, 0x42000000, 0x0010be21, 0x0201f000,
+       0x00103a28, 0x4a034406, 0x00000001, 0x4200b000,
+       0x00000020, 0x4200a800, 0x0010be21, 0x4200a000,
+       0xffffffff, 0x4450a800, 0x8054a800, 0x8058b040,
+       0x040207fd, 0x4d440000, 0x4d340000, 0x42028800,
+       0xffffffff, 0x42002000, 0xffffffff, 0x42003000,
+       0x00000001, 0x42003800, 0x00000001, 0x42001800,
+       0x0010be21, 0x59a81010, 0x82081500, 0x000000ff,
+       0x40180000, 0x0c01f001, 0x0010346e, 0x00103471,
+       0x00103475, 0x00103479, 0x82102500, 0xffffff00,
+       0x0401f014, 0x82102500, 0xffff00ff, 0x840811c0,
+       0x0401f010, 0x82102500, 0xff00ffff, 0x900811c0,
+       0x0401f00c, 0x82102500, 0x00ffffff, 0x9c0801c0,
+       0x80102540, 0x44101800, 0x42003000, 0xffffffff,
+       0x42002000, 0xffffffff, 0x800c1800, 0x0401f003,
+       0x40080000, 0x80102540, 0x81468800, 0x83442c80,
+       0x0000007f, 0x04021014, 0x4c080000, 0x4c0c0000,
+       0x4c180000, 0x4c1c0000, 0x0201f800, 0x00020245,
+       0x5c003800, 0x5c003000, 0x5c001800, 0x5c001000,
+       0x040207f2, 0x0201f800, 0x001049f3, 0x040207ef,
+       0x80183000, 0x801c3800, 0x59341202, 0x40180000,
+       0x0c01f7ce, 0x82100580, 0xffffffff, 0x04000002,
+       0x44101800, 0x42001800, 0x0010be21, 0x500c0000,
+       0x82000500, 0xffffff00, 0x801c0540, 0x44001800,
+       0x5c026800, 0x5c028800, 0x42000800, 0x00000020,
+       0x59a00407, 0x59a01207, 0x900811c0, 0x80081540,
+       0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40,
+       0x42000000, 0x0010be21, 0x0201f000, 0x00103a28,
+       0x59a28c06, 0x59a0020b, 0x8c000500, 0x0400000e,
+       0x59a01208, 0x59a00408, 0x82000500, 0x000000ff,
+       0x900001c0, 0x80081540, 0x41784000, 0x0201f800,
+       0x00104919, 0x04000008, 0x48034406, 0x0201f000,
+       0x00102310, 0x0201f800, 0x00020245, 0x02020000,
+       0x00102310, 0x0201f800, 0x00103a00, 0x04020005,
+       0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+       0x59a0020b, 0x8c000500, 0x04000005, 0x0201f800,
+       0x001049f3, 0x02020000, 0x00103ac4, 0x59a0020b,
+       0x8c000502, 0x04000019, 0x83440480, 0x000007f0,
+       0x04021016, 0x0201f800, 0x001049fc, 0x04020013,
+       0x497a5a04, 0x4a025c04, 0x00008000, 0x0201f800,
+       0x001090e6, 0x04020005, 0x4a034406, 0x00000003,
+       0x0201f000, 0x0010230c, 0x4a01d809, 0x001034f1,
+       0x1c01f000, 0x59a28c06, 0x0201f800, 0x00020245,
+       0x02020000, 0x00102310, 0x4200b000, 0x0000000a,
+       0x4134a000, 0x832e5c00, 0x00000002, 0x412ca800,
+       0x0201f800, 0x0010ab17, 0x832cac00, 0x00000006,
+       0x4054a000, 0x4200b000, 0x00000004, 0x0201f800,
+       0x0010ab28, 0x592c0802, 0x82040500, 0x00ff00ff,
+       0x900001c0, 0x82041500, 0xff00ff00, 0x80080540,
+       0x48025802, 0x592c0801, 0x82040500, 0x00ff00ff,
+       0x900001c0, 0x82041500, 0xff00ff00, 0x80080540,
+       0x48025801, 0x42000800, 0x0000000a, 0x59a00407,
+       0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+       0x59a01a09, 0x900c19c0, 0x800c1d40, 0x412c0000,
+       0x0201f000, 0x00103a28, 0x496fc857, 0x496f4406,
+       0x0201f000, 0x001022c0, 0x59a28c06, 0x0201f800,
+       0x00020245, 0x02020000, 0x00102310, 0x836c0580,
+       0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+       0x0201f000, 0x0010230c, 0x83340c00, 0x00000006,
+       0x59a0020b, 0x8c000500, 0x04000003, 0x83340c00,
+       0x00000008, 0x58040001, 0x48034409, 0x900001c0,
+       0x48034209, 0x50040000, 0x48034407, 0x900001c0,
+       0x48034207, 0x59340200, 0x48034406, 0x0201f000,
+       0x001022c0, 0x800409c0, 0x04000005, 0x4a034406,
+       0x00000001, 0x0201f000, 0x0010230c, 0x59a0220b,
+       0x8c102500, 0x0402002e, 0x8c102506, 0x04020006,
+       0x59a03208, 0x82180480, 0x00000003, 0x02021000,
+       0x00102310, 0x59a28c06, 0x0201f800, 0x00020245,
+       0x02020000, 0x00102310, 0x0201f800, 0x001049e7,
+       0x04000005, 0x4a034406, 0x00000009, 0x0201f000,
+       0x0010230c, 0x0201f800, 0x00103a00, 0x04020005,
+       0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+       0x59a0220b, 0x8c102506, 0x04000004, 0x59343002,
+       0x82183500, 0x00ffffff, 0x497a5a04, 0x4a025c04,
+       0x00008000, 0x0201f800, 0x001090a8, 0x04020005,
+       0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+       0x4a01d809, 0x001035d1, 0x1c01f000, 0x59a28c06,
+       0x0201f800, 0x00020245, 0x02020000, 0x00102310,
+       0x0201f800, 0x001049e7, 0x04000005, 0x4a034406,
+       0x00000009, 0x0201f000, 0x0010230c, 0x0201f800,
+       0x00103a00, 0x04020005, 0x4a034406, 0x00000002,
+       0x0201f000, 0x0010230c, 0x497a5a04, 0x4a025c04,
+       0x00008000, 0x0201f800, 0x00103a00, 0x04020005,
+       0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+       0x592e5800, 0x0201f800, 0x001090bd, 0x04020005,
+       0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+       0x4a01d809, 0x001035a3, 0x1c01f000, 0x592c2805,
+       0x82140d80, 0x01000000, 0x04020005, 0x4a034406,
+       0x00000004, 0x0201f000, 0x0010230c, 0x42000800,
+       0x00000008, 0x59a00207, 0x59a01407, 0x900001c0,
+       0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+       0x800c1d40, 0x832c0400, 0x00000005, 0x0201f800,
+       0x00103a28, 0x8c142d00, 0x04000003, 0x4a01d809,
+       0x001035be, 0x1c01f000, 0x4031d800, 0x58ef400b,
+       0x58ee580e, 0x58ec0002, 0x82000580, 0x00000200,
+       0x02000000, 0x00102304, 0x812e59c0, 0x02000800,
+       0x001005d8, 0x42000800, 0x00000008, 0x832c0400,
+       0x00000005, 0x58ec1007, 0x58ec1808, 0x0201f000,
+       0x00103a28, 0x592c0005, 0x82000580, 0x01000000,
+       0x04020005, 0x4a034406, 0x00000004, 0x0201f000,
+       0x0010230c, 0x59a00207, 0x59a01407, 0x900001c0,
+       0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+       0x800c1d40, 0x42000800, 0x00000006, 0x832c0400,
+       0x00000006, 0x0201f000, 0x00103a28, 0x59a00a0a,
+       0x800409c0, 0x02000000, 0x00102310, 0x82040480,
+       0x000000e7, 0x04001003, 0x42000800, 0x000000e6,
+       0x59a00207, 0x59a01407, 0x900001c0, 0x80081540,
+       0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40,
+       0x83880400, 0x00000000, 0x0201f800, 0x00103a28,
+       0x4a01d809, 0x001035ff, 0x1c01f000, 0x4031d800,
+       0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+       0x02000000, 0x00102304, 0x58ef400b, 0x59a0020b,
+       0x8c000500, 0x04000008, 0x83880400, 0x00000000,
+       0x4803c840, 0x4a03c842, 0x00000006, 0x04011000,
+       0x497b8885, 0x4a034207, 0x000000e6, 0x0201f000,
+       0x001022c0, 0x800409c0, 0x04000005, 0x4a034406,
+       0x00000001, 0x0201f000, 0x0010230c, 0x0401fbe5,
+       0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+       0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000,
+       0x59a00406, 0x800001c0, 0x02000000, 0x00102310,
+       0x82001580, 0x000000ff, 0x04000005, 0x82001480,
+       0x00000004, 0x02021000, 0x00102310, 0x40001000,
+       0x0201f800, 0x00101fbf, 0x04020005, 0x4a034406,
+       0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+       0x0010363a, 0x1c01f000, 0x592c0005, 0x82000580,
+       0x01000000, 0x02020000, 0x001022c0, 0x4a034406,
+       0x00000004, 0x0201f000, 0x0010230c, 0x59a01406,
+       0x8c081508, 0x04020007, 0x800409c0, 0x04000005,
+       0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+       0x59a01c07, 0x820c0480, 0x00001000, 0x02021000,
+       0x00102310, 0x497b2804, 0x497b2805, 0x497b281c,
+       0x497b281d, 0x497b281f, 0x497b2820, 0x497b2822,
+       0x497b2823, 0x80000580, 0x0201f800, 0x001015fe,
+       0x59a80805, 0x8c081500, 0x04000004, 0x82040d40,
+       0x00000011, 0x0401f004, 0x8c081506, 0x04000002,
+       0x84040d42, 0x84040d0a, 0x48075005, 0x4202d800,
+       0x00000001, 0x82081500, 0x000000e0, 0x8008010a,
+       0x0c020036, 0x0201f800, 0x0010513b, 0x04020009,
+       0x4a035033, 0x00000001, 0x0201f800, 0x001050a2,
+       0x0401f01f, 0x4a035033, 0x00000000, 0x0401f7fb,
+       0x497b5032, 0x0201f800, 0x00104142, 0x0201f800,
+       0x00106c55, 0x0201f800, 0x00106ede, 0x0201f800,
+       0x00106c4b, 0x59a00a07, 0x480788a7, 0x59c400a3,
+       0x82000500, 0xfeffffff, 0x82000540, 0x80018000,
+       0x40000800, 0x84040d20, 0x480388a3, 0x480788a3,
+       0x497b504e, 0x42000800, 0x0000002d, 0x42001000,
+       0x001041bc, 0x0201f800, 0x00105f69, 0x59a00407,
+       0x800000c2, 0x800008c4, 0x8005d400, 0x42000000,
+       0x0000ffff, 0x0201f800, 0x0010513b, 0x04000003,
+       0x59a00207, 0x80000110, 0x0201f800, 0x00103afc,
+       0x0201f000, 0x001022c0, 0x0010366d, 0x00103670,
+       0x00103678, 0x00102310, 0x00103675, 0x00102310,
+       0x00102310, 0x00102310, 0x836c0580, 0x00000003,
+       0x04000005, 0x4a034406, 0x00000007, 0x0201f000,
+       0x0010230c, 0x59a03c06, 0x59a00407, 0x59a04a07,
+       0x902449c0, 0x80244d40, 0x59a00409, 0x59a05209,
+       0x902851c0, 0x80285540, 0x0401fb46, 0x04020005,
+       0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+       0x417a8800, 0x41783000, 0x497b4001, 0x497b4004,
+       0x832c4400, 0x00000005, 0x48234002, 0x8c1c3d04,
+       0x04020078, 0x0201f800, 0x00020245, 0x0402002a,
+       0x0201f800, 0x001049e7, 0x04000004, 0x0201f800,
+       0x001048e3, 0x04020024, 0x8c1c3d00, 0x04000008,
+       0x59340009, 0x44004000, 0x59340008, 0x80204000,
+       0x44004000, 0x80204000, 0x0401f007, 0x59340007,
+       0x44004000, 0x59340006, 0x80204000, 0x44004000,
+       0x80204000, 0x83440580, 0x000007fe, 0x0400000d,
+       0x83440580, 0x000007fc, 0x0400000a, 0x0201f800,
+       0x001049f3, 0x04000003, 0x85468d5e, 0x0401f005,
+       0x0201f800, 0x00104838, 0x04020002, 0x85468d5e,
+       0x45444000, 0x85468d1e, 0x80204000, 0x82183400,
+       0x00000003, 0x81468800, 0x83440480, 0x000007f0,
+       0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580,
+       0x000007f0, 0x04020004, 0x42028800, 0x000007fe,
+       0x0401f006, 0x83440580, 0x000007ff, 0x04020007,
+       0x42028800, 0x000007fc, 0x82180580, 0x0000000f,
+       0x0400000b, 0x0401f7c0, 0x801831c0, 0x04020006,
+       0x59a00801, 0x800408c4, 0x48074406, 0x0201f000,
+       0x001022c0, 0x4a034004, 0x00000001, 0x49474000,
+       0x59a00001, 0x80180400, 0x48034001, 0x481f4003,
+       0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002,
+       0x4801d803, 0x4825d807, 0x4829d808, 0x4000a800,
+       0x4000a000, 0x4018b000, 0x0201f800, 0x0010ab17,
+       0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809,
+       0x0010372a, 0x1c01f000, 0x4031d800, 0x58ef400b,
+       0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+       0x00102304, 0x59a00004, 0x80000540, 0x04020008,
+       0x59a28800, 0x59a04002, 0x59a03803, 0x41783000,
+       0x58ec4807, 0x58ec5008, 0x0401f78f, 0x59a00801,
+       0x800408c4, 0x48074406, 0x0201f000, 0x001022c0,
+       0x0201f800, 0x00020245, 0x0402002f, 0x0201f800,
+       0x001049e7, 0x04000004, 0x0201f800, 0x001048e3,
+       0x04020029, 0x83440580, 0x000007fe, 0x04000011,
+       0x83440580, 0x000007fc, 0x0400000e, 0x0201f800,
+       0x001049f3, 0x04000005, 0x59340403, 0x8400055e,
+       0x48026c03, 0x0401f007, 0x0201f800, 0x00104838,
+       0x04020004, 0x59340403, 0x8400055e, 0x48026c03,
+       0x4134a000, 0x4020a800, 0x4200b000, 0x00000006,
+       0x0201f800, 0x0010ab17, 0x59340007, 0x4400a800,
+       0x59340006, 0x4800a801, 0x59340009, 0x4800a802,
+       0x59340008, 0x4800a803, 0x59340403, 0x8400051e,
+       0x48026c03, 0x82204400, 0x0000000a, 0x82183400,
+       0x0000000a, 0x81468800, 0x83440480, 0x000007f0,
+       0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580,
+       0x000007f0, 0x04020004, 0x42028800, 0x000007fe,
+       0x0401f006, 0x83440580, 0x000007ff, 0x04020007,
+       0x42028800, 0x000007fc, 0x82180580, 0x0000000a,
+       0x0400000b, 0x0401f7bb, 0x801831c0, 0x04020006,
+       0x59a00801, 0x800408c4, 0x48074406, 0x0201f000,
+       0x001022c0, 0x4a034004, 0x00000001, 0x49474000,
+       0x59a00001, 0x80180400, 0x48034001, 0x481f4003,
+       0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002,
+       0x4801d803, 0x4825d807, 0x4829d808, 0x40ec1000,
+       0x0201f800, 0x00100858, 0x4a01d809, 0x001037a1,
+       0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002,
+       0x82000580, 0x00000200, 0x02000000, 0x00102304,
+       0x59a00004, 0x80000540, 0x04020008, 0x59a28800,
+       0x59a04002, 0x59a03803, 0x41783000, 0x58ec4807,
+       0x58ec5008, 0x0401f78f, 0x59a00801, 0x800408c4,
+       0x48074406, 0x0201f000, 0x001022c0, 0x42002800,
+       0x0000007e, 0x59a00c06, 0x59a01207, 0x59a01c07,
+       0x59a02209, 0x82040500, 0x0000ff00, 0x840001c0,
+       0x82003480, 0x00000020, 0x02001000, 0x00102310,
+       0x80140480, 0x02001000, 0x00102310, 0x82040500,
+       0x000000ff, 0x82003480, 0x00000020, 0x02001000,
+       0x00102310, 0x80140480, 0x02001000, 0x00102310,
+       0x82080500, 0x0000ff00, 0x840001c0, 0x82003480,
+       0x00000020, 0x02001000, 0x00102310, 0x80140480,
+       0x02001000, 0x00102310, 0x82080500, 0x000000ff,
+       0x82003480, 0x00000020, 0x02001000, 0x00102310,
+       0x80140480, 0x02001000, 0x00102310, 0x820c0500,
+       0x0000ff00, 0x840001c0, 0x82003480, 0x00000020,
+       0x02001000, 0x00102310, 0x80140480, 0x02001000,
+       0x00102310, 0x820c0500, 0x000000ff, 0x82003480,
+       0x00000020, 0x02001000, 0x00102310, 0x80140480,
+       0x02001000, 0x00102310, 0x82100500, 0x0000ff00,
+       0x840001c0, 0x82003480, 0x00000020, 0x02001000,
+       0x00102310, 0x80140480, 0x02001000, 0x00102310,
+       0x82100500, 0x000000ff, 0x82003480, 0x00000020,
+       0x02001000, 0x00102310, 0x80140480, 0x02001000,
+       0x00102310, 0x900401c0, 0x80080d40, 0x900c01c0,
+       0x80101d40, 0x83a83400, 0x0000003a, 0x44043000,
+       0x80183000, 0x440c3000, 0x0201f000, 0x001022c0,
+       0x0401f9ec, 0x04020005, 0x4a034406, 0x00000002,
+       0x0201f000, 0x0010230c, 0x42000800, 0x0000000c,
+       0x0401f853, 0x4a01d809, 0x00103820, 0x1c01f000,
+       0x4031d800, 0x58ee580d, 0x58ef400b, 0x58ec0002,
+       0x82000580, 0x00000200, 0x02000000, 0x00102304,
+       0x832ca400, 0x00000004, 0x4200b000, 0x0000000c,
+       0x40c8a800, 0x0201f800, 0x0010ab17, 0x58c80200,
+       0x80000540, 0x04000034, 0x58c80400, 0x82000500,
+       0xfffffffb, 0x04020030, 0x58c80401, 0x80000540,
+       0x0400002d, 0x82000480, 0x0000ff01, 0x0402102a,
+       0x58c80202, 0x82000480, 0x0000005c, 0x04001026,
+       0x0201f800, 0x001063a3, 0x58c80c08, 0x58c80204,
+       0x80040480, 0x04001020, 0x58c80204, 0x82000480,
+       0x00000005, 0x0402101c, 0x58c80205, 0x58c80c08,
+       0x80040902, 0x80040480, 0x04001017, 0x58c80c08,
+       0x0201f800, 0x001062f1, 0x0400001b, 0x0201f800,
+       0x001061b9, 0x04020012, 0x4979940b, 0x59c408a3,
+       0x82040d40, 0x00000002, 0x480788a3, 0x4a038830,
+       0x00000001, 0x4a038832, 0x01ffffff, 0x58c80202,
+       0x48030804, 0x0201f800, 0x0010619b, 0x0201f000,
+       0x001022c0, 0x0201f000, 0x00102310, 0x0201f800,
+       0x001063f5, 0x0201f800, 0x00106402, 0x0201f800,
+       0x001062e4, 0x0201f000, 0x0010230c, 0x4c000000,
+       0x59a01207, 0x59a00407, 0x900811c0, 0x80081540,
+       0x59a01a09, 0x59a00409, 0x900c19c0, 0x800c1d40,
+       0x5c000000, 0x0401f1ac, 0x59840000, 0x82000580,
+       0x00000000, 0x04000054, 0x59840002, 0x8c000504,
+       0x04000051, 0x84000546, 0x48030802, 0x0201f800,
+       0x001062e4, 0x59c408a3, 0x82040d00, 0xfffffffd,
+       0x480788a3, 0x4c5c0000, 0x4200b800, 0x0010ac00,
+       0x505e6800, 0x813669c0, 0x04000008, 0x5936600e,
+       0x813261c0, 0x04000005, 0x0201f800, 0x001062d5,
+       0x02000800, 0x001064ad, 0x805cb800, 0x825c0580,
+       0x0010b3f0, 0x040207f3, 0x59866003, 0x813261c0,
+       0x0400000b, 0x59300406, 0x82000580, 0x00000009,
+       0x02020800, 0x001005d8, 0x5930b800, 0x0201f800,
+       0x001062c1, 0x405e6000, 0x0401f7f5, 0x497b0803,
+       0x4200b800, 0x0010b51b, 0x505e6000, 0x813261c0,
+       0x04000011, 0x59300406, 0x82000580, 0x00000009,
+       0x0402000d, 0x59300203, 0x82000580, 0x00000004,
+       0x04020009, 0x59326809, 0x813669c0, 0x02020800,
+       0x001005d8, 0x0201f800, 0x00100e99, 0x0201f800,
+       0x001062c1, 0x4578b800, 0x805cb800, 0x825c0580,
+       0x0010b523, 0x040207e9, 0x42000800, 0x0010b519,
+       0x49780801, 0x49780800, 0x59a80069, 0x82000400,
+       0x00000007, 0x48035069, 0x0201f800, 0x001063f5,
+       0x0201f800, 0x00106402, 0x5c00b800, 0x0201f800,
+       0x001061b4, 0x0201f000, 0x001022c0, 0x836c0580,
+       0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+       0x0201f000, 0x0010230c, 0x59a00407, 0x59a02207,
+       0x901021c0, 0x80102540, 0x59a00409, 0x59a02a09,
+       0x901429c0, 0x80142d40, 0x0401f91e, 0x04020005,
+       0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+       0x417a8800, 0x41781800, 0x497b4001, 0x497b4003,
+       0x832c3400, 0x00000004, 0x481b4002, 0x41440000,
+       0x81ac0400, 0x50026800, 0x813669c0, 0x0400000b,
+       0x0201f800, 0x001049e7, 0x04020008, 0x59340002,
+       0x48003000, 0x49443001, 0x82183400, 0x00000002,
+       0x820c1c00, 0x00000002, 0x81468800, 0x83440480,
+       0x00000800, 0x04000005, 0x820c0480, 0x00000010,
+       0x0402100b, 0x0401f7ea, 0x800c19c0, 0x04020006,
+       0x59a00801, 0x80040902, 0x48074406, 0x0201f000,
+       0x001022c0, 0x4a034003, 0x00000001, 0x49474000,
+       0x59a00001, 0x800c0400, 0x48034001, 0x40ec1000,
+       0x4a001001, 0x00000000, 0x480c1004, 0x59a00002,
+       0x48001003, 0x48101007, 0x48141008, 0x0201f800,
+       0x00100858, 0x4a01d809, 0x00103920, 0x1c01f000,
+       0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580,
+       0x00000200, 0x02000000, 0x00102304, 0x59a00003,
+       0x80000540, 0x04020008, 0x59a28800, 0x59a03002,
+       0x41781800, 0x40ec1000, 0x58082007, 0x58082808,
+       0x0401f7bf, 0x59a00801, 0x80040902, 0x48074406,
+       0x0201f000, 0x001022c0, 0x800409c0, 0x04000005,
+       0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+       0x59a80026, 0x8c00050a, 0x04020007, 0x8c000506,
+       0x04020005, 0x4a034406, 0x00000016, 0x0201f000,
+       0x0010230c, 0x0401f8bb, 0x04020005, 0x4a034406,
+       0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06,
+       0x80040902, 0x59a00407, 0x59a01207, 0x900811c0,
+       0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+       0x800c1d40, 0x832c0400, 0x00000005, 0x0401f8ce,
+       0x4a01d809, 0x0010395b, 0x1c01f000, 0x4031d800,
+       0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+       0x00000200, 0x02000000, 0x00102304, 0x592c0009,
+       0x0201f800, 0x00105c9a, 0x02000800, 0x001045a6,
+       0x02020000, 0x00102310, 0x49474001, 0x481a6802,
+       0x592c000a, 0x82001d80, 0x70000000, 0x04020007,
+       0x0401f890, 0x04020011, 0x4a034406, 0x00000002,
+       0x0201f000, 0x0010230c, 0x82001d80, 0x72000000,
+       0x02020000, 0x00102310, 0x0401f886, 0x04020885,
+       0x04020884, 0x04020005, 0x4a034406, 0x00000002,
+       0x0201f000, 0x0010230c, 0x58ee580d, 0x4a025c04,
+       0x00008000, 0x497a5a04, 0x592c3208, 0x80183102,
+       0x592c1801, 0x4a001805, 0x01000000, 0x0201f800,
+       0x001090d1, 0x04020005, 0x4a034406, 0x00000003,
+       0x0201f000, 0x0010230c, 0x4a01d809, 0x00103995,
+       0x1c01f000, 0x592c4000, 0x592c0005, 0x82000580,
+       0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+       0x0201f000, 0x0010230c, 0x832c3c00, 0x00000005,
+       0x401ca000, 0x401ca800, 0x5820280a, 0x4200b000,
+       0x00000002, 0x82143580, 0x70000000, 0x04000003,
+       0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab28,
+       0x401c0000, 0x58201006, 0x58201807, 0x58202205,
+       0x80102102, 0x82143580, 0x70000000, 0x04020008,
+       0x82103480, 0x00000002, 0x02001000, 0x00102310,
+       0x42000800, 0x00000002, 0x0401f06e, 0x82143580,
+       0x72000000, 0x02020000, 0x00102310, 0x82103480,
+       0x0000002a, 0x02001000, 0x00102310, 0x42000800,
+       0x0000000f, 0x0401f863, 0x4a01d809, 0x001039c9,
+       0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e,
+       0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+       0x00102304, 0x592e5800, 0x832c0c00, 0x00000005,
+       0x4004a000, 0x4004a800, 0x4200b000, 0x0000000f,
+       0x0201f800, 0x0010ab28, 0x40ec1000, 0x4a001001,
+       0x00000000, 0x4a001004, 0x0000000f, 0x48041003,
+       0x0201f800, 0x00100858, 0x4a01d809, 0x001039e5,
+       0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e,
+       0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+       0x00102304, 0x832c0c00, 0x00000005, 0x4004a000,
+       0x4004a800, 0x4200b000, 0x0000000c, 0x0201f800,
+       0x0010ab28, 0x40ec1000, 0x4a001001, 0x00000000,
+       0x4a001004, 0x0000000c, 0x48041003, 0x0201f800,
+       0x00100858, 0x4a01d809, 0x001022b9, 0x1c01f000,
+       0x0201f800, 0x001007e4, 0x04000010, 0x497a5800,
+       0x58ec000d, 0x80000540, 0x04020004, 0x492dd80d,
+       0x492dd80e, 0x0401f007, 0x58ec000e, 0x48025800,
+       0x82000400, 0x00000001, 0x452c0000, 0x492dd80e,
+       0x832c0400, 0x00000004, 0x492fc857, 0x4803c857,
+       0x1c01f000, 0x4d2c0000, 0x48efc857, 0x58ec400d,
+       0x4823c857, 0x802041c0, 0x04000007, 0x40225800,
+       0x592c4001, 0x497a5801, 0x0201f800, 0x001007f4,
+       0x0401f7f8, 0x4979d80d, 0x4979d80e, 0x5c025800,
+       0x1c01f000, 0x42003000, 0x00000001, 0x0401f003,
+       0x42003000, 0x00000000, 0x4803c857, 0x4807c857,
+       0x480bc857, 0x480fc857, 0x481bc857, 0x48efc857,
+       0x4819d801, 0x800409c0, 0x02000800, 0x001005d8,
+       0x4805d804, 0x4801d803, 0x4809d807, 0x480dd808,
+       0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809,
+       0x001022b9, 0x1c01f000, 0x80002d80, 0x480bc857,
+       0x480fc857, 0x4813c857, 0x4817c857, 0x4d2c0000,
+       0x4da00000, 0x42034000, 0x0010b4a4, 0x59a00017,
+       0x800001c0, 0x04020013, 0x04006012, 0x480bc020,
+       0x480fc021, 0x4813c022, 0x4817c023, 0x900811c0,
+       0x82081540, 0x00000012, 0x480bc011, 0x59e00017,
+       0x8c000508, 0x04020004, 0x4203e000, 0x30000001,
+       0x0401f053, 0x4a03c017, 0x00000002, 0x0401f7fb,
+       0x4c040000, 0x4c1c0000, 0x80000800, 0x48074017,
+       0x59a0381a, 0x481fc857, 0x801c39c0, 0x04020027,
+       0x82000480, 0x0000000a, 0x04021010, 0x59a00018,
+       0x80000000, 0x48034018, 0x59a00219, 0x82000400,
+       0x00000002, 0x82000c80, 0x00000013, 0x48034219,
+       0x04001003, 0x497b4219, 0x41780000, 0x59a03816,
+       0x801c3c00, 0x0401f030, 0x4803c856, 0x0201f800,
+       0x001007e4, 0x04000007, 0x492f401a, 0x492f401b,
+       0x412c3800, 0x497b421c, 0x497a5813, 0x0401f026,
+       0x59880051, 0x80000000, 0x48031051, 0x59a00017,
+       0x80000040, 0x48034017, 0x59a00219, 0x59a03816,
+       0x801c3c00, 0x0401f01c, 0x59a0021c, 0x82000400,
+       0x00000002, 0x82000c80, 0x00000012, 0x04021004,
+       0x4803421c, 0x801c3c00, 0x0401f013, 0x0201f800,
+       0x001007e4, 0x0402000b, 0x59880051, 0x80000000,
+       0x48031051, 0x59a00017, 0x80000040, 0x48034017,
+       0x4803c856, 0x59a0021c, 0x801c3c00, 0x0401f006,
+       0x492f401a, 0x492c3813, 0x412c3800, 0x497b421c,
+       0x497a5813, 0x48083c00, 0x480c3a00, 0x48103c01,
+       0x48143a01, 0x5c003800, 0x5c000800, 0x5c034000,
+       0x5c025800, 0x1c01f000, 0x480fc857, 0x4813c857,
+       0x481bc857, 0x42000000, 0x0010b813, 0x0201f800,
+       0x0010aa47, 0x801800d0, 0x40002800, 0x42001000,
+       0x00008014, 0x0401f786, 0x4c000000, 0x599c0017,
+       0x8c000512, 0x5c000000, 0x1c01f000, 0x4c000000,
+       0x599c0018, 0x8c00050e, 0x5c000000, 0x1c01f000,
+       0x59a80821, 0x800409c0, 0x04000005, 0x4a034406,
+       0x00000001, 0x0201f000, 0x0010230c, 0x836c0580,
+       0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+       0x0201f000, 0x0010230c, 0x599c0017, 0x8c00050a,
+       0x04000005, 0x4a034406, 0x00000008, 0x0201f000,
+       0x0010230c, 0x59340405, 0x8c000508, 0x04020004,
+       0x8c00050a, 0x02020000, 0x001034db, 0x497a5a04,
+       0x497a5805, 0x4a025c04, 0x00008000, 0x0201f800,
+       0x00109176, 0x04020005, 0x4a034406, 0x00000003,
+       0x0201f000, 0x0010230c, 0x4a01d809, 0x00103aed,
+       0x1c01f000, 0x592c0005, 0x82000580, 0x01000000,
+       0x04020005, 0x4a034406, 0x00000004, 0x0201f000,
+       0x0010230c, 0x59a28c06, 0x0201f800, 0x00020245,
+       0x02020000, 0x00102310, 0x0201f000, 0x001034db,
+       0x82001580, 0x0000ffff, 0x04000009, 0x0201f800,
+       0x00105c9a, 0x02000800, 0x00020245, 0x0402000c,
+       0x0201f800, 0x00105fae, 0x0401f009, 0x42028800,
+       0x000007ef, 0x0201f800, 0x00020245, 0x02000800,
+       0x00105fae, 0x81468840, 0x040217fb, 0x1c01f000,
+       0x4803c856, 0x4c0c0000, 0x4d340000, 0x4d440000,
+       0x42028800, 0x000007fe, 0x0201f800, 0x00020245,
+       0x04020009, 0x5934180a, 0x820c1d00, 0x00000001,
+       0x820c1d80, 0x00000001, 0x42001000, 0x0000801b,
+       0x0401ff1e, 0x5c028800, 0x5c026800, 0x5c001800,
+       0x1c01f000, 0x599c0017, 0x8c000508, 0x1c01f000,
+       0x48efc857, 0x04011000, 0x48efc840, 0x4a03c842,
+       0x00000011, 0x40000000, 0x040117ff, 0x4a01d80f,
+       0xbeefbeef, 0x1c01f000, 0x497b4000, 0x497b4001,
+       0x497b4002, 0x497b4003, 0x497b4004, 0x1c01f000,
+       0x59c400a4, 0x4c580000, 0x4c500000, 0x4c540000,
+       0x82000500, 0x0000000f, 0x82000480, 0x00000007,
+       0x0400100a, 0x82006c80, 0x00000006, 0x02021800,
+       0x001005d8, 0x0c01f807, 0x5c00a800, 0x5c00a000,
+       0x5c00b000, 0x1c01f000, 0x0401f906, 0x0401f7fb,
+       0x00103b51, 0x00103b57, 0x00103b7c, 0x00103b9e,
+       0x00103c59, 0x59c40806, 0x8c040d00, 0x04020003,
+       0x84040d40, 0x48078806, 0x1c01f000, 0x59c40005,
+       0x8c000534, 0x02020000, 0x0010429e, 0x4a038805,
+       0xffffffff, 0x42006000, 0x00020000, 0x0201f800,
+       0x00104282, 0x59a80015, 0x82000500, 0xfffffffa,
+       0x84000542, 0x48035015, 0x497b5026, 0x42000800,
+       0x0010be21, 0x45780800, 0x497b5013, 0x42006000,
+       0xffefffff, 0x42006800, 0x40000000, 0x0201f800,
+       0x0010427d, 0x59c40006, 0x82000500, 0xffffff0f,
+       0x48038806, 0x42000800, 0x00000010, 0x42001000,
+       0x001041f3, 0x0201f800, 0x00105f83, 0x0401f001,
+       0x42006000, 0xffffffff, 0x42006800, 0x00800000,
+       0x0201f800, 0x0010427d, 0x4200b000, 0x000000c8,
+       0x59c400a4, 0x82000500, 0x0000000f, 0x82000580,
+       0x0000000a, 0x0400000f, 0x8058b040, 0x040207f9,
+       0x497b5014, 0x42006000, 0xbf7fffff, 0x42006800,
+       0x00018000, 0x0201f800, 0x0010427d, 0x42006000,
+       0xfffeffff, 0x41786800, 0x0201f000, 0x0010427d,
+       0x497b5014, 0x4a035012, 0x00000000, 0x80000580,
+       0x0201f000, 0x00104289, 0x4a038805, 0xffffffff,
+       0x59a80012, 0x82000c80, 0x00000004, 0x02021800,
+       0x001005d8, 0x0c01f001, 0x00103ba9, 0x00103bd6,
+       0x00103c4f, 0x4803c856, 0x59c400a3, 0x8400051e,
+       0x480388a3, 0x4a035012, 0x00000001, 0x59c40008,
+       0x8400054e, 0x48038808, 0x0201f800, 0x00104263,
+       0x42007800, 0x0010b54c, 0x4a007806, 0x11010000,
+       0x4200a000, 0x0010b402, 0x4200a800, 0x0010b553,
+       0x4200b000, 0x00000002, 0x0201f800, 0x0010ab17,
+       0x497b8802, 0x42000800, 0x00000003, 0x497b504a,
+       0x0201f800, 0x0010416e, 0x4a03504a, 0x00000001,
+       0x497b5016, 0x0201f800, 0x00104290, 0x42006000,
+       0xffffffff, 0x42006800, 0x00080000, 0x0201f800,
+       0x0010427d, 0x42006000, 0xfff7ffff, 0x41786800,
+       0x0201f000, 0x0010427d, 0x59a80016, 0x497b5016,
+       0x80002540, 0x04000066, 0x59c40004, 0x82000500,
+       0x00000003, 0x04020071, 0x59a80815, 0x8c040d02,
+       0x0400004b, 0x82100580, 0x0000000c, 0x0402004f,
+       0x82100400, 0x00000018, 0x8000b104, 0x41cc1000,
+       0x42001800, 0x0010b54c, 0x50080800, 0x500c0000,
+       0x80040580, 0x0402001a, 0x80081000, 0x800c1800,
+       0x8058b040, 0x040207f9, 0x0201f800, 0x00104290,
+       0x42006000, 0xffffffff, 0x42006800, 0x00500000,
+       0x0201f800, 0x0010427d, 0x4a035012, 0x00000002,
+       0x4a035014, 0x00000002, 0x42000800, 0x000007d0,
+       0x42001000, 0x00104148, 0x0201f800, 0x0010606e,
+       0x0201f800, 0x00104263, 0x0401f048, 0x59cc0806,
+       0x82040d80, 0x11010000, 0x04020028, 0x59cc0800,
+       0x82040500, 0x00ffffff, 0x0400001a, 0x82000580,
+       0x000000ef, 0x04020017, 0x59cc0801, 0x82040500,
+       0x00ffffff, 0x82000580, 0x000000ef, 0x04020011,
+       0x83cca400, 0x00000007, 0x4200a800, 0x0010b402,
+       0x4200b000, 0x00000002, 0x50500800, 0x50540000,
+       0x80040480, 0x04001007, 0x04020010, 0x8050a000,
+       0x8054a800, 0x8058b040, 0x040207f8, 0x0401f00b,
+       0x59a80015, 0x84000502, 0x48035015, 0x41cca000,
+       0x4200a800, 0x0010b54c, 0x4200b000, 0x00000009,
+       0x0201f800, 0x0010ab17, 0x0201f800, 0x00104290,
+       0x42006000, 0xffffffff, 0x42006800, 0x00080000,
+       0x0201f800, 0x0010427d, 0x42006000, 0xfff7ffff,
+       0x41786800, 0x0201f800, 0x0010427d, 0x42006000,
+       0xffffffff, 0x42006800, 0x00004000, 0x0201f800,
+       0x0010427d, 0x59c40004, 0x82000500, 0x00000003,
+       0x04020006, 0x497b5016, 0x42000800, 0x00000003,
+       0x0201f000, 0x0010416e, 0x1c01f000, 0x1c01f000,
+       0x59a80014, 0x82006d80, 0x0000000f, 0x04000005,
+       0x82000580, 0x0000001b, 0x02020800, 0x00104139,
+       0x1c01f000, 0x59a80015, 0x84000506, 0x48035015,
+       0x497b504a, 0x59a80014, 0x82000c80, 0x0000001e,
+       0x02021800, 0x001005d8, 0x0c01f001, 0x00103c97,
+       0x00103cac, 0x00103cd5, 0x00103cf0, 0x00103d14,
+       0x00103d45, 0x00103d68, 0x00103d9b, 0x00103dbe,
+       0x00103de4, 0x00103e21, 0x00103e48, 0x00103e5f,
+       0x00103e71, 0x00103e8a, 0x00103ea0, 0x00103ea5,
+       0x00103ecd, 0x00103ef0, 0x00103f16, 0x00103f39,
+       0x00103f6c, 0x00103fae, 0x00103fd8, 0x00103ff0,
+       0x00104030, 0x00104049, 0x0010405c, 0x0010405d,
+       0x4803c856, 0x4202d800, 0x00000007, 0x0201f800,
+       0x0010513b, 0x04000007, 0x42006000, 0xffffffd7,
+       0x41786800, 0x0201f800, 0x0010427d, 0x0401f00b,
+       0x59c40006, 0x82000500, 0xffffff0f, 0x48038806,
+       0x42001000, 0x000000f0, 0x0201f800, 0x0010193d,
+       0x0201f800, 0x00105098, 0x1c01f000, 0x4803c856,
+       0x42006000, 0xbf7fffff, 0x42006800, 0x00400000,
+       0x0201f800, 0x0010427d, 0x4a035014, 0x00000001,
+       0x42001000, 0x001041f3, 0x0201f800, 0x00105fa4,
+       0x0201f800, 0x001041f8, 0x42000800, 0x000007d0,
+       0x42001000, 0x00104148, 0x0201f000, 0x0010606e,
+       0x59a80016, 0x82000580, 0x00000014, 0x04020025,
+       0x4803c857, 0x42006000, 0xffbfffff, 0x41786800,
+       0x0201f800, 0x0010427d, 0x59c40004, 0x82000500,
+       0x00000003, 0x0402001b, 0x59cc1006, 0x82081580,
+       0x11020000, 0x04020016, 0x59cc1007, 0x8c08153e,
+       0x0400000b, 0x59a80015, 0x8c000504, 0x04020008,
+       0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47,
+       0x59a80015, 0x84000544, 0x48035015, 0x42001000,
+       0x00104148, 0x0201f800, 0x00105f90, 0x4a035014,
+       0x00000010, 0x0401f9d4, 0x0401f002, 0x497b5016,
+       0x1c01f000, 0x4803c856, 0x4a035014, 0x00000003,
+       0x42006000, 0xbf3fffff, 0x42006800, 0x00100000,
+       0x0201f800, 0x0010427d, 0x42001000, 0x001041f3,
+       0x0201f800, 0x00105fa4, 0x0201f800, 0x001041f8,
+       0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+       0x42007800, 0x0010b552, 0x46007800, 0x11020000,
+       0x42000800, 0x00000005, 0x0201f000, 0x0010416e,
+       0x59a80016, 0x80000540, 0x04000021, 0x4803c857,
+       0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+       0x59a80016, 0x82000580, 0x00000014, 0x04020016,
+       0x59cc1006, 0x82081580, 0x11020000, 0x04020012,
+       0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015,
+       0x8c000504, 0x04020008, 0x42000000, 0x0010b83f,
+       0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544,
+       0x48035015, 0x4a035014, 0x00000004, 0x0401f805,
+       0x0401f003, 0x0201f800, 0x00104139, 0x1c01f000,
+       0x4803c856, 0x4a035014, 0x00000005, 0x83cca400,
+       0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x42007800,
+       0x0010b552, 0x46007800, 0x11030000, 0x0201f800,
+       0x0010413e, 0x04020014, 0x59a80015, 0x8c000500,
+       0x04020011, 0x59a80810, 0x82040580, 0x00ffffff,
+       0x0400000d, 0x82040d00, 0x000000ff, 0x82040400,
+       0x0010210e, 0x50000800, 0x80040910, 0x42001000,
+       0x00000004, 0x0401fb9b, 0x0400000b, 0x0201f800,
+       0x0010420d, 0x4200b000, 0x00000004, 0x83cca400,
+       0x00000007, 0x4200a800, 0x0010b553, 0x0201f800,
+       0x0010ab17, 0x42000800, 0x00000005, 0x0201f000,
+       0x0010416e, 0x59a80016, 0x80000540, 0x04000020,
+       0x4803c857, 0x42001000, 0x00104148, 0x0201f800,
+       0x00105f90, 0x59a80016, 0x82000580, 0x00000014,
+       0x04020016, 0x59cc1006, 0x82081580, 0x11030000,
+       0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b,
+       0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+       0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+       0x84000544, 0x48035015, 0x4a035014, 0x00000006,
+       0x0401f804, 0x0401f002, 0x0401fbd3, 0x1c01f000,
+       0x4803c856, 0x4a035014, 0x00000007, 0x83cca400,
+       0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x42007800,
+       0x0010b552, 0x46007800, 0x11040000, 0x0401fbc7,
+       0x04020020, 0x59a80015, 0x8c000500, 0x0402001d,
+       0x599c0017, 0x8c000500, 0x0400001a, 0x599c1402,
+       0x82080480, 0x0000007f, 0x02021800, 0x001005d8,
+       0x4c080000, 0x82081400, 0x0010210e, 0x50081000,
+       0x82081500, 0x000000ff, 0x480b5010, 0x42000800,
+       0x00000003, 0x0201f800, 0x00106c78, 0x5c000800,
+       0x42001000, 0x00000004, 0x0401fb3e, 0x04000005,
+       0x0401fd2b, 0x04000003, 0x0201f800, 0x001015fe,
+       0x42000800, 0x00000005, 0x0401f3d4, 0x59a80016,
+       0x80000540, 0x04000020, 0x4803c857, 0x42001000,
+       0x00104148, 0x0201f800, 0x00105f90, 0x59a80016,
+       0x82000580, 0x00000014, 0x04020016, 0x59cc1006,
+       0x82081580, 0x11040000, 0x04020012, 0x59cc1007,
+       0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504,
+       0x04020008, 0x42000000, 0x0010b83f, 0x0201f800,
+       0x0010aa47, 0x59a80015, 0x84000544, 0x48035015,
+       0x4a035014, 0x00000008, 0x0401f804, 0x0401f002,
+       0x0401fb7d, 0x1c01f000, 0x4803c856, 0x4a035014,
+       0x00000009, 0x83cca400, 0x00000006, 0x4200a800,
+       0x0010b552, 0x4200b000, 0x00000005, 0x0201f800,
+       0x0010ab17, 0x42007800, 0x0010b552, 0x46007800,
+       0x11050100, 0x0401fb71, 0x0402000a, 0x59a80015,
+       0x8c000500, 0x04020007, 0x0401fa8c, 0x04020005,
+       0x82000540, 0x00000001, 0x0201f800, 0x001015fe,
+       0x42000800, 0x00000005, 0x0401fb94, 0x0401fb63,
+       0x04020ea4, 0x4d3c0000, 0x42027800, 0x00000001,
+       0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000,
+       0x59a80016, 0x80000540, 0x0400003a, 0x4803c857,
+       0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+       0x59a80016, 0x82000580, 0x00000014, 0x04020030,
+       0x59cc1006, 0x82080500, 0x11050000, 0x82000580,
+       0x11050000, 0x0402002a, 0x8c081510, 0x04000014,
+       0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015,
+       0x8c000504, 0x04020008, 0x42000000, 0x0010b83f,
+       0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544,
+       0x48035015, 0x4a035013, 0x00000001, 0x4a035014,
+       0x0000000a, 0x0401f818, 0x0401f016, 0x80000540,
+       0x04020013, 0x59cc1007, 0x8c08153e, 0x0400000b,
+       0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+       0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+       0x84000544, 0x48035015, 0x497b5013, 0x4a035014,
+       0x0000000e, 0x0401f86d, 0x0401f002, 0x0401fb1a,
+       0x1c01f000, 0x4803c856, 0x4a035014, 0x0000000b,
+       0x42001000, 0x0010b553, 0x4008a800, 0x4200b000,
+       0x00000020, 0x4600a800, 0xffffffff, 0x8054a800,
+       0x8058b040, 0x040207fc, 0x42007800, 0x0010b552,
+       0x46007800, 0x11060000, 0x42001000, 0x0010b553,
+       0x0401fb0a, 0x04000005, 0x50080000, 0x46001000,
+       0x00ffffff, 0x0401f00c, 0x50080800, 0x82040d00,
+       0x0000ffff, 0x59a80010, 0x82000500, 0x000000ff,
+       0x82000540, 0x00000100, 0x800000e0, 0x80040d40,
+       0x44041000, 0x42000800, 0x00000021, 0x0401f327,
+       0x59a80016, 0x80000540, 0x04000014, 0x4803c857,
+       0x59a80016, 0x42001000, 0x00104148, 0x0201f800,
+       0x00105f90, 0x59a80016, 0x82000580, 0x00000084,
+       0x04020009, 0x59cc1006, 0x82081580, 0x11060000,
+       0x04020005, 0x4a035014, 0x0000000c, 0x0401f804,
+       0x0401f002, 0x0401fadc, 0x1c01f000, 0x4803c856,
+       0x4a035014, 0x0000000d, 0x83cca400, 0x00000006,
+       0x4200a800, 0x0010b552, 0x4200b000, 0x00000021,
+       0x0201f800, 0x0010ab17, 0x42007800, 0x0010b552,
+       0x46007800, 0x11070000, 0x42000800, 0x00000021,
+       0x0401f2fe, 0x59a80016, 0x80000540, 0x04000016,
+       0x4803c857, 0x59a80016, 0x42001000, 0x00104148,
+       0x0201f800, 0x00105f90, 0x82000580, 0x00000084,
+       0x0402000c, 0x59cc1006, 0x82081580, 0x11070000,
+       0x04020008, 0x4a035013, 0x00000001, 0x0401fa91,
+       0x4a035014, 0x0000000e, 0x0401f804, 0x0401f002,
+       0x0401fab1, 0x1c01f000, 0x4803c856, 0x82040d40,
+       0x00000001, 0x0401fbfc, 0x4a035014, 0x0000000f,
+       0x497b5016, 0x42006000, 0xffffffff, 0x42006800,
+       0x00300000, 0x0401fbe8, 0x42006000, 0xffdfffff,
+       0x41786800, 0x0401fbe4, 0x42000800, 0x000007d0,
+       0x42001000, 0x00104148, 0x0201f000, 0x00105f69,
+       0x4803c856, 0x59a80016, 0x80000540, 0x04020296,
+       0x1c01f000, 0x4803c856, 0x4a035014, 0x00000011,
+       0x83cca400, 0x00000006, 0x4200a800, 0x0010b552,
+       0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17,
+       0x4200a800, 0x0010b552, 0x4600a800, 0x11020000,
+       0x0401fa8a, 0x04020015, 0x59a80010, 0x82000d00,
+       0xffff0000, 0x04000011, 0x82000500, 0x000000ff,
+       0x0400000e, 0x82000c00, 0x0010210e, 0x50040800,
+       0x80040910, 0x82040580, 0x0000007e, 0x04000007,
+       0x82040580, 0x00000080, 0x04000004, 0x42001000,
+       0x00000004, 0x0401fa07, 0x42000800, 0x00000005,
+       0x0401f2a2, 0x59a80016, 0x80000540, 0x04000020,
+       0x4803c857, 0x42001000, 0x00104148, 0x0201f800,
+       0x00105f90, 0x59a80016, 0x82000580, 0x00000014,
+       0x04020016, 0x59cc1006, 0x82081580, 0x11030000,
+       0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b,
+       0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+       0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+       0x84000544, 0x48035015, 0x4a035014, 0x00000012,
+       0x0401f804, 0x0401f002, 0x0401fa4b, 0x1c01f000,
+       0x4803c856, 0x4a035014, 0x00000013, 0x83cca400,
+       0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x4200a800,
+       0x0010b552, 0x4600a800, 0x11030000, 0x0401fa3f,
+       0x04020013, 0x59a80015, 0x8c000500, 0x04020010,
+       0x59a80810, 0x82040580, 0x00ffffff, 0x0400000c,
+       0x82040d00, 0x000000ff, 0x82040400, 0x0010210e,
+       0x50000800, 0x80040910, 0x42001000, 0x00000004,
+       0x0401f9c0, 0x04000002, 0x0401fafb, 0x42000800,
+       0x00000005, 0x0401f259, 0x59a80016, 0x80000540,
+       0x04000020, 0x4803c857, 0x42001000, 0x00104148,
+       0x0201f800, 0x00105f90, 0x59a80016, 0x82000580,
+       0x00000014, 0x04020016, 0x59cc1006, 0x82081580,
+       0x11040000, 0x04020012, 0x59cc1007, 0x8c08153e,
+       0x0400000b, 0x59a80015, 0x8c000504, 0x04020008,
+       0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47,
+       0x59a80015, 0x84000544, 0x48035015, 0x4a035014,
+       0x00000014, 0x0401f804, 0x0401f002, 0x0401fa02,
+       0x1c01f000, 0x4803c856, 0x4a035014, 0x00000015,
+       0x83cca400, 0x00000006, 0x4200a800, 0x0010b552,
+       0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17,
+       0x4200a800, 0x0010b552, 0x4600a800, 0x11040000,
+       0x0401f9f6, 0x04020020, 0x59a80015, 0x8c000500,
+       0x0402001d, 0x599c0017, 0x8c000500, 0x0400001a,
+       0x599c1402, 0x82080480, 0x0000007f, 0x02021800,
+       0x001005d8, 0x4c080000, 0x82081400, 0x0010210e,
+       0x50081000, 0x82081500, 0x000000ff, 0x480b5010,
+       0x42000800, 0x00000003, 0x0201f800, 0x00106c78,
+       0x5c000800, 0x42001000, 0x00000004, 0x0401f96d,
+       0x04000005, 0x0201f800, 0x00103abf, 0x02020800,
+       0x001015fe, 0x42000800, 0x00000005, 0x0401f203,
+       0x59a80016, 0x80000540, 0x0400003f, 0x4803c857,
+       0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+       0x59a80016, 0x82000580, 0x00000014, 0x04020035,
+       0x59cc1006, 0x82080500, 0x11050000, 0x82000580,
+       0x11050000, 0x0402002f, 0x8c081510, 0x04000010,
+       0x0401fb09, 0x59cc1007, 0x8c08153e, 0x0400000b,
+       0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+       0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+       0x84000544, 0x48035015, 0x0401f013, 0x59cc1007,
+       0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504,
+       0x04020008, 0x42000000, 0x0010b83f, 0x0201f800,
+       0x0010aa47, 0x59a80015, 0x84000544, 0x48035015,
+       0x82000540, 0x00000001, 0x0401faeb, 0x497b5013,
+       0x0401f003, 0x4a035013, 0x00000001, 0x59cc1007,
+       0x8c08153c, 0x04000003, 0x4a035026, 0x00000008,
+       0x4a035014, 0x00000016, 0x0401f804, 0x0401f002,
+       0x0401f98d, 0x1c01f000, 0x4803c856, 0x83cca400,
+       0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x4a035014,
+       0x00000017, 0x59a80013, 0x8c000500, 0x04000006,
+       0x42001000, 0x0010b552, 0x46001000, 0x11050100,
+       0x0401f003, 0x4a035014, 0x0000001b, 0x0401f97b,
+       0x0402000a, 0x59a80015, 0x8c000500, 0x04020007,
+       0x0401f896, 0x04020005, 0x82000540, 0x00000001,
+       0x0201f800, 0x001015fe, 0x42000800, 0x00000005,
+       0x0401f99e, 0x4d3c0000, 0x42027800, 0x00000001,
+       0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000,
+       0x59a80016, 0x80000540, 0x04000015, 0x4803c857,
+       0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+       0x59a80016, 0x82000580, 0x00000084, 0x0402000b,
+       0x59cc1006, 0x82081580, 0x11060000, 0x04020007,
+       0x80000580, 0x0401faa0, 0x4a035014, 0x00000018,
+       0x0401f804, 0x0401f002, 0x0401f94b, 0x1c01f000,
+       0x4803c856, 0x4a035014, 0x00000019, 0x83cca400,
+       0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+       0x00000021, 0x0201f800, 0x0010ab17, 0x42003800,
+       0x0010b553, 0x0401f941, 0x04020018, 0x401c2800,
+       0x50141000, 0x80080130, 0x80000000, 0x40001800,
+       0x82081500, 0x00ffffff, 0x800000f0, 0x80080540,
+       0x44002800, 0x59a80810, 0x82040d00, 0x000000ff,
+       0x400c1000, 0x80081104, 0x82082400, 0x0010b553,
+       0x50101000, 0x820c0500, 0x00000003, 0x0c01f806,
+       0x80081540, 0x44082000, 0x42000800, 0x00000021,
+       0x0401f156, 0x0010401d, 0x00104022, 0x00104027,
+       0x0010402c, 0x800408f0, 0x40040000, 0x82081500,
+       0x00ffffff, 0x1c01f000, 0x800408e0, 0x40040000,
+       0x82081500, 0xff00ffff, 0x1c01f000, 0x800408d0,
+       0x40040000, 0x82081500, 0xffff00ff, 0x1c01f000,
+       0x40040000, 0x82081500, 0xffffff00, 0x1c01f000,
+       0x59a80016, 0x80000540, 0x04000016, 0x4803c857,
+       0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+       0x59a80016, 0x82000580, 0x00000084, 0x0402000c,
+       0x59cc1006, 0x82081580, 0x11070000, 0x04020008,
+       0x4a035013, 0x00000001, 0x0401f8d2, 0x4a035014,
+       0x0000001a, 0x0401f804, 0x0401f002, 0x0401f8f2,
+       0x1c01f000, 0x82000540, 0x00000001, 0x0401fa3e,
+       0x4a035014, 0x0000001b, 0x83cca400, 0x00000006,
+       0x4200a800, 0x0010b552, 0x59a82016, 0x40100000,
+       0x8000b104, 0x40580800, 0x5450a800, 0x8050a000,
+       0x8054a800, 0x8058b040, 0x040207fc, 0x0401f113,
+       0x1c01f000, 0x1c01f000, 0x4803c856, 0x42003000,
+       0x00000004, 0x42004000, 0x0010b553, 0x599c2817,
+       0x8c142d14, 0x0402001f, 0x42001000, 0x00000003,
+       0x40200000, 0x80080400, 0x50000800, 0x82042580,
+       0xffffffff, 0x04020005, 0x80081040, 0x80183040,
+       0x040207f8, 0x0401f05e, 0x800811c0, 0x04020006,
+       0x82042580, 0x3fffffff, 0x04000058, 0x82040d40,
+       0xc0000000, 0x4200b000, 0x00000020, 0x42001800,
+       0x00000001, 0x40042000, 0x80102102, 0x04021021,
+       0x800c18c2, 0x8058b040, 0x040207fc, 0x0401f04b,
+       0x41781000, 0x40200000, 0x80080400, 0x50000800,
+       0x82042580, 0xffffffff, 0x04020005, 0x80081000,
+       0x80183040, 0x040207f8, 0x0401f040, 0x800811c0,
+       0x04020003, 0x82040d40, 0xc0000000, 0x4200b000,
+       0x00000001, 0x42001800, 0x80000000, 0x40042000,
+       0x801020c2, 0x04021007, 0x800c1902, 0x8058b000,
+       0x82580480, 0x00000021, 0x040017fa, 0x0401f02f,
+       0x40200000, 0x80082400, 0x50100000, 0x800c0540,
+       0x44002000, 0x59a80015, 0x84000540, 0x48035015,
+       0x40580000, 0x42002800, 0x00000020, 0x80142c80,
+       0x40080000, 0x42003800, 0x00000003, 0x801c0480,
+       0x800000ca, 0x80142d40, 0x82144c00, 0x0010210e,
+       0x50242800, 0x82142d00, 0x000000ff, 0x48175010,
+       0x4c040000, 0x40140800, 0x0201f800, 0x001015eb,
+       0x5c000800, 0x40001800, 0x500c0000, 0x80100540,
+       0x44001800, 0x59a80015, 0x84000540, 0x48035015,
+       0x4200a800, 0x0010b553, 0x4020a000, 0x4200b000,
+       0x00000004, 0x0201f800, 0x0010ab17, 0x82000540,
+       0x00000001, 0x0401f002, 0x80000580, 0x1c01f000,
+       0x4807c857, 0x480bc857, 0x4008b000, 0x83cca400,
+       0x00000007, 0x4200a800, 0x0010b553, 0x40541000,
+       0x0201f800, 0x0010ab17, 0x40041800, 0x41782000,
+       0x42000000, 0x00000003, 0x820c1c80, 0x00000020,
+       0x04001004, 0x80102000, 0x80000040, 0x0401f7fb,
+       0x40041800, 0x801021c0, 0x04000005, 0x820c1c80,
+       0x00000020, 0x80102040, 0x040207fd, 0x42002000,
+       0x00000001, 0x800c19c0, 0x04000004, 0x801020c2,
+       0x800c1840, 0x040207fe, 0x80083c00, 0x83cc2c00,
+       0x00000007, 0x80142c00, 0x50140000, 0x80102d00,
+       0x04020012, 0x80100540, 0x44003800, 0x82042400,
+       0x0010210e, 0x50102800, 0x82142d00, 0x000000ff,
+       0x48175010, 0x4c040000, 0x40140800, 0x0201f800,
+       0x001015eb, 0x5c000800, 0x59a80015, 0x84000540,
+       0x48035015, 0x80000580, 0x1c01f000, 0x4807c856,
+       0x42001000, 0x00008017, 0x59a8184e, 0x0201f800,
+       0x0010aa4f, 0x0201f800, 0x00103a3e, 0x1c01f000,
+       0x4807c856, 0x4200b000, 0x00000020, 0x83cca400,
+       0x00000007, 0x4200a800, 0x0010be21, 0x0201f000,
+       0x0010ab28, 0x4807c856, 0x0201f800, 0x00106ede,
+       0x42000800, 0x000000f7, 0x0401f8de, 0x497b2804,
+       0x497b2805, 0x497b281c, 0x497b281d, 0x4202d800,
+       0x00000001, 0x42006000, 0xbf7fffff, 0x42006800,
+       0x00018000, 0x0401f950, 0x42006000, 0xfffeffff,
+       0x41786800, 0x0401f94c, 0x497b504e, 0x42000800,
+       0x0000002d, 0x42001000, 0x001041bc, 0x0201f000,
+       0x00105f69, 0x4807c856, 0x0401ffe3, 0x497b5014,
+       0x497b5016, 0x1c01f000, 0x4807c856, 0x59a80005,
+       0x8c000506, 0x1c01f000, 0x4807c856, 0x42006000,
+       0xffffffff, 0x42006800, 0x00000028, 0x0401f136,
+       0x4807c856, 0x0401ffc2, 0x0201f800, 0x00106c55,
+       0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500,
+       0x0000000f, 0x82000580, 0x00000002, 0x0402000a,
+       0x42006000, 0xffffffff, 0x42006800, 0x00200000,
+       0x0401f921, 0x42006000, 0xffdfffff, 0x41786800,
+       0x0401f91d, 0x497b5014, 0x42000800, 0x000000f7,
+       0x0401f89c, 0x59c400a3, 0x82000500, 0xbf20bfff,
+       0x82000540, 0x0001c000, 0x480388a3, 0x84000520,
+       0x480388a3, 0x1c01f000, 0x497b5016, 0x59b400f5,
+       0x8c000500, 0x04020004, 0x82000540, 0x00000001,
+       0x480368f5, 0x800400c4, 0x82000400, 0x00002000,
+       0x4803910a, 0x59b400f6, 0x82000500, 0x00000018,
+       0x040207fd, 0x4a0368f0, 0x0010b54b, 0x42000000,
+       0x0010b552, 0x480368f1, 0x82040400, 0x0000dc00,
+       0x480368f3, 0x59c400a4, 0x82000500, 0x0000000f,
+       0x82000580, 0x00000008, 0x04020017, 0x4c5c0000,
+       0x4c600000, 0x59c4b805, 0x8c5cbd3a, 0x04020005,
+       0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+       0x4a038805, 0x02000000, 0x0201f800, 0x001019fe,
+       0x4000c000, 0x0201f800, 0x00101963, 0x4202d800,
+       0x00000001, 0x497b5014, 0x5c00c000, 0x5c00b800,
+       0x1c01f000, 0x59c8010b, 0x8c000502, 0x040007e2,
+       0x59c408a4, 0x82040d00, 0x0000000f, 0x82040d80,
+       0x0000000b, 0x04020005, 0x59a80814, 0x82040d40,
+       0x00002000, 0x0401f004, 0x59a80812, 0x82040d40,
+       0x00001000, 0x4807504e, 0x59a8084a, 0x800409c0,
+       0x04020007, 0x42000800, 0x000007d0, 0x42001000,
+       0x00104148, 0x0201f800, 0x0010606e, 0x1c01f000,
+       0x4807c856, 0x0401ff4e, 0x0201f800, 0x00106c55,
+       0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500,
+       0x0000000f, 0x82000580, 0x00000002, 0x0402000a,
+       0x42006000, 0xffffffff, 0x42006800, 0x00200000,
+       0x0401f8ad, 0x42006000, 0xffdfffff, 0x41786800,
+       0x0401f8a9, 0x0201f800, 0x00105141, 0x04000014,
+       0x0201f800, 0x00105151, 0x04020011, 0x4a035032,
+       0x0000aaaa, 0x4c040000, 0x0201f800, 0x0010162a,
+       0x59a8002a, 0x82000500, 0xffff0000, 0x80040540,
+       0x4803502a, 0x5c000800, 0x4a035033, 0x00000000,
+       0x0201f800, 0x001050a2, 0x0401f008, 0x4a03504c,
+       0x00000005, 0x42000000, 0x00000001, 0x0201f800,
+       0x00101590, 0x0401ff2c, 0x1c01f000, 0x0401f805,
+       0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f086,
+       0x0201f800, 0x00105151, 0x04020005, 0x59c40006,
+       0x82000540, 0x000000f0, 0x48038806, 0x1c01f000,
+       0x800408d0, 0x59a80015, 0x8c000506, 0x04000006,
+       0x59a80010, 0x82000500, 0x000000ff, 0x80040540,
+       0x0401f003, 0x82040540, 0x000000f7, 0x480388a7,
+       0x1c01f000, 0x4807c856, 0x42000000, 0x0010b83b,
+       0x0201f800, 0x0010aa47, 0x42003000, 0x00000005,
+       0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000d,
+       0x42027800, 0x00000002, 0x0401f038, 0x4807c856,
+       0x42000000, 0x0010b86b, 0x0201f800, 0x0010aa47,
+       0x42003000, 0x00000000, 0x4d3c0000, 0x4c180000,
+       0x42003000, 0x0000000f, 0x42027800, 0x00000002,
+       0x0401f02a, 0x4807c856, 0x42000000, 0x0010b86a,
+       0x0201f800, 0x0010aa47, 0x42003000, 0x00000003,
+       0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000e,
+       0x42027800, 0x00000202, 0x0401f01c, 0x4807c856,
+       0x42000000, 0x0010b869, 0x0201f800, 0x0010aa47,
+       0x42003000, 0x00000004, 0x4d3c0000, 0x4c180000,
+       0x42003000, 0x00000010, 0x42027800, 0x00000202,
+       0x0401f00e, 0x4807c856, 0x42000000, 0x0010b83e,
+       0x0201f800, 0x0010aa47, 0x42003000, 0x00000001,
+       0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000c,
+       0x42027800, 0x00000202, 0x42001800, 0x0000ffff,
+       0x42002000, 0x00000007, 0x0201f800, 0x00103aae,
+       0x5c003000, 0x4d400000, 0x0201f800, 0x0010a95d,
+       0x42028000, 0x0000002a, 0x0201f800, 0x00101fe5,
+       0x5c028000, 0x5c027800, 0x1c01f000, 0x4807c856,
+       0x04011000, 0x4a03c840, 0x0010b54b, 0x4a03c842,
+       0x00000040, 0x40000000, 0x040117ff, 0x42007800,
+       0x0010b54b, 0x46007800, 0x00000011, 0x803c7800,
+       0x4a007800, 0x220000ef, 0x4a007801, 0x000000ef,
+       0x4a007802, 0x01380000, 0x4a007803, 0x00000000,
+       0x4a007804, 0xffffffff, 0x4a007805, 0x00000000,
+       0x1c01f000, 0x59c400a3, 0x80300500, 0x80340540,
+       0x480388a3, 0x1c01f000, 0x4833c857, 0x59c400a3,
+       0x80300540, 0x480388a3, 0x80300580, 0x480388a3,
+       0x1c01f000, 0x4803c856, 0x04000004, 0x4a03504b,
+       0x00000001, 0x0401f002, 0x497b504b, 0x1c01f000,
+       0x4803c856, 0x59c80002, 0x80000540, 0x0400000a,
+       0x80000040, 0x04000008, 0x4a039005, 0x00000140,
+       0x42000000, 0x00000006, 0x80000040, 0x040207ff,
+       0x0401f7f4, 0x1c01f000, 0x4c5c0000, 0x4c600000,
+       0x59c4b805, 0x485fc856, 0x8c5cbd3a, 0x04020005,
+       0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+       0x4a038805, 0x02000000, 0x0201f800, 0x001019fe,
+       0x4000c000, 0x0201f800, 0x00101963, 0x4a038805,
+       0x04000000, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+       0x497a6a00, 0x4937c857, 0x4a026c00, 0x00000707,
+       0x497a6801, 0x497a6808, 0x497a6809, 0x497a6806,
+       0x497a6807, 0x497a6c0b, 0x497a680c, 0x0201f800,
+       0x00103b25, 0x04020006, 0x5934080f, 0x59340010,
+       0x80040540, 0x02020800, 0x001005d8, 0x4a026a04,
+       0x00000100, 0x497a6a03, 0x59340402, 0x82000500,
+       0x000000ff, 0x48026c02, 0x497a6c04, 0x497a6a05,
+       0x497a6c05, 0x497a6811, 0x4d2c0000, 0x5934000d,
+       0x49466c03, 0x80025d40, 0x04000004, 0x0201f800,
+       0x001007fd, 0x497a680d, 0x5c025800, 0x599c0401,
+       0x48026a0b, 0x599c0208, 0x48026c12, 0x497a680a,
+       0x0201f000, 0x00104c62, 0x42000000, 0x00000005,
+       0x80000d80, 0x0401f02d, 0x0201f800, 0x00104a09,
+       0x04020017, 0x59a80026, 0x8c00050a, 0x04020010,
+       0x59340212, 0x82000500, 0x0000ff00, 0x4803c857,
+       0x0400000b, 0x59340a00, 0x8c040d1e, 0x02000000,
+       0x000201c4, 0x42000000, 0x00000029, 0x42000800,
+       0x00001000, 0x492fc857, 0x0401f018, 0x492fc857,
+       0x42000000, 0x00000028, 0x0401f012, 0x59a80805,
+       0x8c040d02, 0x04020003, 0x8c040d00, 0x04000004,
+       0x42000000, 0x00000004, 0x0401f00a, 0x42000000,
+       0x00000029, 0x59340a00, 0x8c040d1e, 0x04000005,
+       0x492fc857, 0x42000800, 0x00001000, 0x0401f003,
+       0x492fc857, 0x80000d80, 0x4803c857, 0x80028540,
+       0x1c01f000, 0x4803c857, 0x59a80005, 0x8c000500,
+       0x040207ec, 0x0201f800, 0x001049e7, 0x040207e4,
+       0x59340200, 0x8c00050e, 0x040007e1, 0x0201f000,
+       0x000201c4, 0x0201f800, 0x001047eb, 0x040007bf,
+       0x0201f000, 0x000201c8, 0x592c0206, 0x492fc857,
+       0x82000d80, 0x000007ff, 0x04020006, 0x4a025c0a,
+       0x00000030, 0x42026800, 0x0010b524, 0x0401f021,
+       0x82000c80, 0x000007f0, 0x04021046, 0x81ac0400,
+       0x50000000, 0x80026d40, 0x04000038, 0x0201f800,
+       0x001048e3, 0x04020038, 0x592c040a, 0x8c00050a,
+       0x04020014, 0x592e6009, 0x83300480, 0x0010d1c0,
+       0x0400103b, 0x41580000, 0x81300480, 0x04021038,
+       0x59300c06, 0x82040580, 0x00000009, 0x04020037,
+       0x4a025a06, 0x00000000, 0x497a5800, 0x59300008,
+       0x80000540, 0x04020018, 0x492e6008, 0x0401f010,
+       0x0201f800, 0x0002075a, 0x04000019, 0x592c0206,
+       0x49366009, 0x492e6008, 0x4a026406, 0x00000009,
+       0x497a6015, 0x49325809, 0x82000d80, 0x000007ff,
+       0x04020003, 0x4a026015, 0x00008000, 0x42027000,
+       0x00000043, 0x0201f800, 0x000207a1, 0x80000580,
+       0x0401f020, 0x40000800, 0x58040000, 0x80000d40,
+       0x040207fd, 0x492c0800, 0x0401f01a, 0x42000000,
+       0x0000002c, 0x0401f016, 0x42000000, 0x00000028,
+       0x0401f013, 0x59a80805, 0x82040500, 0x00000003,
+       0x04000004, 0x42000000, 0x00000004, 0x0401f00c,
+       0x42000000, 0x00000029, 0x0401f009, 0x42000000,
+       0x00000008, 0x0401f006, 0x82040580, 0x00000007,
+       0x040207fb, 0x42000000, 0x00000005, 0x80000540,
+       0x1c01f000, 0x492fc857, 0x592e8c06, 0x83440d80,
+       0x000007fc, 0x04000004, 0x83440480, 0x000007f0,
+       0x04021014, 0x0201f800, 0x00020245, 0x04020011,
+       0x0201f800, 0x001049f3, 0x04020011, 0x0201f800,
+       0x0002075a, 0x0400001c, 0x49366009, 0x492e6008,
+       0x4a026406, 0x0000000a, 0x42027000, 0x00000040,
+       0x0201f800, 0x000207a1, 0x80000580, 0x0401f011,
+       0x42000000, 0x00000028, 0x0401f00d, 0x0201f800,
+       0x00104a09, 0x040007fb, 0x59a80805, 0x82040d00,
+       0x00000003, 0x04000004, 0x42000000, 0x00000004,
+       0x0401f003, 0x42000000, 0x00000029, 0x80000540,
+       0x1c01f000, 0x42000000, 0x0000002c, 0x0401f7fc,
+       0x492fc857, 0x592e8c06, 0x4947c857, 0x83440c80,
+       0x00000800, 0x42000000, 0x0000000a, 0x04021176,
+       0x592c4207, 0x4823c857, 0x82200500, 0x0000000f,
+       0x0c01f001, 0x001043d5, 0x0010445d, 0x001044a9,
+       0x001044b4, 0x001044bf, 0x001043d1, 0x001043d1,
+       0x001043d1, 0x001044cf, 0x00104513, 0x00104530,
+       0x001043d1, 0x001043d1, 0x001043d1, 0x001043d1,
+       0x001043d1, 0x4803c857, 0x42000000, 0x0000000c,
+       0x0401f15d, 0x592c1008, 0x82081500, 0x00ffffff,
+       0x59a80010, 0x80084d80, 0x42000000, 0x00000010,
+       0x04000155, 0x0201f800, 0x00104919, 0x04000036,
+       0x4803c857, 0x82004d80, 0x0000001d, 0x0402001a,
+       0x0201f800, 0x00105755, 0x59340405, 0x4c000000,
+       0x0201f800, 0x001049e7, 0x5c000000, 0x04000004,
+       0x8c20450a, 0x04000028, 0x80000580, 0x44002800,
+       0x59340008, 0x48002802, 0x59340009, 0x48002801,
+       0x59340006, 0x48002804, 0x59340007, 0x48002803,
+       0x4200b000, 0x00000005, 0x0201f800, 0x0010955f,
+       0x0401f166, 0x4803c857, 0x82004d80, 0x0000001a,
+       0x04020003, 0x40101000, 0x0401f136, 0x4803c857,
+       0x82004d80, 0x0000001b, 0x04020003, 0x40181000,
+       0x0401f130, 0x4803c857, 0x82004d80, 0x0000001c,
+       0x04000131, 0x82004d80, 0x00000019, 0x42000000,
+       0x0000000a, 0x04000120, 0x42000000, 0x0000000a,
+       0x04020137, 0x59a80005, 0x8c000514, 0x0400001b,
+       0x0201f800, 0x001049e7, 0x04000018, 0x59340212,
+       0x82000500, 0x0000ff00, 0x42001000, 0x00000010,
+       0x0402000c, 0x42001000, 0x00000008, 0x59a80026,
+       0x8c000506, 0x04020009, 0x59340002, 0x82000500,
+       0x00ff0000, 0x82000580, 0x00ff0000, 0x04000007,
+       0x0201f800, 0x00104c6d, 0x42000000, 0x0000001c,
+       0x40181000, 0x04020107, 0x0201f800, 0x0002075a,
+       0x04000111, 0x49366009, 0x492e6008, 0x4a026406,
+       0x00000001, 0x8c20450a, 0x04000004, 0x592c0404,
+       0x8400055c, 0x48025c04, 0x4c200000, 0x4d3c0000,
+       0x42027800, 0x00001000, 0x0201f800, 0x0010203c,
+       0x5c027800, 0x5c004000, 0x8c204512, 0x0400000b,
+       0x599c0018, 0x8c000518, 0x04000008, 0x592c0009,
+       0x82000500, 0x00000380, 0x5934080a, 0x80040d40,
+       0x84040d54, 0x4806680a, 0x417a7800, 0x0401f914,
+       0x42000800, 0x00000003, 0x0401f91b, 0x42027000,
+       0x00000002, 0x0201f800, 0x000207a1, 0x80000580,
+       0x0401f10a, 0x0201f800, 0x00020245, 0x040200ec,
+       0x0201f800, 0x001049ed, 0x04000008, 0x0201f800,
+       0x001049e7, 0x040200ec, 0x417a7800, 0x417a6000,
+       0x0201f800, 0x001020a1, 0x59a80005, 0x8c000514,
+       0x0400001b, 0x0201f800, 0x001049e7, 0x04000018,
+       0x59340212, 0x82000500, 0x0000ff00, 0x42001000,
+       0x00000010, 0x0402000c, 0x42001000, 0x00000008,
+       0x59a80026, 0x8c000506, 0x04020009, 0x59340002,
+       0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+       0x04000007, 0x0201f800, 0x00104c6d, 0x42000000,
+       0x0000001c, 0x40181000, 0x040200b2, 0x0201f800,
+       0x0002075a, 0x040000bc, 0x5934080a, 0x8c204512,
+       0x0400000c, 0x599c0018, 0x8c000518, 0x04000009,
+       0x592c0009, 0x82000500, 0x00000380, 0x82041500,
+       0xfffffc7f, 0x80080d40, 0x84040d54, 0x0401f002,
+       0x84040d14, 0x4806680a, 0x49366009, 0x492e6008,
+       0x4a026406, 0x00000001, 0x417a7800, 0x0401f8c8,
+       0x42000800, 0x00000005, 0x0401f8cf, 0x42027000,
+       0x00000003, 0x0201f800, 0x000207a1, 0x80000580,
+       0x0401f0be, 0x0201f800, 0x00020245, 0x040200a0,
+       0x0201f800, 0x001049fc, 0x040200a3, 0x0201f800,
+       0x00109517, 0x04000094, 0x80000580, 0x0401f0b3,
+       0x0201f800, 0x00020245, 0x04020095, 0x0201f800,
+       0x001049fc, 0x04020098, 0x0201f800, 0x001090e6,
+       0x04000089, 0x80000580, 0x0401f0a8, 0x0201f800,
+       0x00020245, 0x0402008a, 0x83444d80, 0x000007fe,
+       0x42000000, 0x0000000a, 0x0402006b, 0x0201f800,
+       0x001049e7, 0x04020088, 0x0201f800, 0x0010952f,
+       0x04000079, 0x80000580, 0x0401f098, 0x82200500,
+       0x00000070, 0x04020005, 0x8c20450e, 0x42000000,
+       0x0000000c, 0x0402005c, 0x8c20450a, 0x0400000d,
+       0x4d3c0000, 0x42027800, 0x00001000, 0x8c20450e,
+       0x04020002, 0x853e7d56, 0x82200500, 0x000000a0,
+       0x0201f800, 0x001049d3, 0x5c027800, 0x0401f07f,
+       0x0201f800, 0x00020245, 0x04020065, 0x8c204508,
+       0x04000010, 0x4d3c0000, 0x42027800, 0x00001000,
+       0x8c20450e, 0x04020002, 0x853e7d56, 0x82200500,
+       0x00000090, 0x0201f800, 0x001049bb, 0x5c027800,
+       0x42000000, 0x0000000a, 0x0402003b, 0x0401f06b,
+       0x836c0580, 0x00000003, 0x42000800, 0x00000007,
+       0x0402000f, 0x0201f800, 0x001049f3, 0x04000007,
+       0x4c000000, 0x0201f800, 0x00104a1f, 0x5c000000,
+       0x0400004d, 0x0401f05d, 0x0201f800, 0x001094c5,
+       0x04000007, 0x80000580, 0x0401f05c, 0x0201f800,
+       0x00104a1f, 0x04000051, 0x0401f054, 0x0201f800,
+       0x00104a1f, 0x04000034, 0x0401f050, 0x0201f800,
+       0x00020245, 0x04020036, 0x836c0580, 0x00000003,
+       0x04020040, 0x8c204508, 0x04000006, 0x417a7800,
+       0x417a6000, 0x0201f800, 0x001020a1, 0x0401f043,
+       0x0201f800, 0x001049ed, 0x04000008, 0x0201f800,
+       0x001049e7, 0x0402002c, 0x417a7800, 0x417a6000,
+       0x0201f800, 0x001020a1, 0x480bc856, 0x0201f800,
+       0x00109332, 0x04000018, 0x80000580, 0x0401f037,
+       0x0401f7e3, 0x480bc857, 0x42000800, 0x00000019,
+       0x40001000, 0x4200b000, 0x00000002, 0x0401f00a,
+       0x480bc857, 0x40000800, 0x4200b000, 0x00000002,
+       0x0401f005, 0x480bc857, 0x40000800, 0x4200b000,
+       0x00000001, 0x480bc857, 0x42028000, 0x00000031,
+       0x0401f020, 0x480bc857, 0x42000800, 0x00000003,
+       0x4200b000, 0x00000001, 0x0401f7f7, 0x480bc857,
+       0x42000800, 0x0000000a, 0x4200b000, 0x00000001,
+       0x0401f7f1, 0x480bc857, 0x42000800, 0x00000009,
+       0x40001000, 0x4200b000, 0x00000002, 0x0401f7ea,
+       0x480bc857, 0x42000800, 0x00000007, 0x4200b000,
+       0x00000001, 0x0401f7e4, 0x480bc857, 0x4200b000,
+       0x00000001, 0x0401f7e0, 0x80028580, 0x4178b000,
+       0x82000540, 0x00000001, 0x1c01f000, 0x4937c857,
+       0x59326809, 0x59341200, 0x813e79c0, 0x04000003,
+       0x84081540, 0x0401f002, 0x84081500, 0x480a6a00,
+       0x1c01f000, 0x59326809, 0x5c000000, 0x4c000000,
+       0x4803c857, 0x4937c857, 0x82040580, 0x00000006,
+       0x04020004, 0x42000000, 0x00000606, 0x0401f021,
+       0x82040580, 0x00000004, 0x04020004, 0x42000000,
+       0x00000404, 0x0401f01b, 0x82040580, 0x00000007,
+       0x42000000, 0x00000707, 0x04000016, 0x82040580,
+       0x00000003, 0x42000000, 0x00000703, 0x04000011,
+       0x82040580, 0x00000005, 0x42000000, 0x00000405,
+       0x0400000c, 0x82040580, 0x00000009, 0x42000000,
+       0x00000409, 0x04000007, 0x82040580, 0x0000000b,
+       0x42000000, 0x0000070b, 0x02020800, 0x001005d8,
+       0x4803c857, 0x48026c00, 0x82040d80, 0x00000006,
+       0x04020005, 0x59341404, 0x800811c0, 0x02000800,
+       0x001005d8, 0x1c01f000, 0x5c000000, 0x4c000000,
+       0x4803c857, 0x4947c857, 0x481bc857, 0x83440480,
+       0x00000800, 0x04021034, 0x83441400, 0x0010ac00,
+       0x50080000, 0x80026d40, 0x04020011, 0x4c180000,
+       0x4d2c0000, 0x0201f800, 0x001007d3, 0x412e6800,
+       0x5c025800, 0x5c003000, 0x04000027, 0x45341000,
+       0x497a680d, 0x497a6810, 0x497a680f, 0x497a680e,
+       0x4c180000, 0x0401fcf3, 0x5c003000, 0x59340a12,
+       0x4c040000, 0x0201f800, 0x0010513b, 0x5c000800,
+       0x04000009, 0x82180500, 0x00ffff00, 0x04000008,
+       0x59a81010, 0x82081500, 0x00ffff00, 0x80080580,
+       0x04000003, 0x80000580, 0x0401f004, 0x82180500,
+       0x000000ff, 0x800000d0, 0x80040d80, 0x04000003,
+       0x4803c857, 0x48026a12, 0x59340002, 0x80180580,
+       0x04000003, 0x481bc857, 0x481a6802, 0x80000580,
+       0x1c01f000, 0x4803c856, 0x82000540, 0x00000001,
+       0x0401f7fc, 0x4947c857, 0x83440480, 0x00000800,
+       0x04021011, 0x83441400, 0x0010ac00, 0x50080000,
+       0x80026d40, 0x0400000b, 0x0401fbf9, 0x0402000a,
+       0x59a80005, 0x8c000502, 0x04000004, 0x59340200,
+       0x8c00050e, 0x04000004, 0x82000540, 0x00000001,
+       0x1c01f000, 0x80000580, 0x0401f7fe, 0x5c000000,
+       0x4c000000, 0x4803c857, 0x4947c857, 0x4d2c0000,
+       0x4d300000, 0x83440480, 0x00000800, 0x04021024,
+       0x83441400, 0x0010ac00, 0x50080000, 0x80026d40,
+       0x0400001b, 0x45781000, 0x5934000d, 0x80025d40,
+       0x02020800, 0x001007fd, 0x59366011, 0x813261c0,
+       0x0400000e, 0x4c640000, 0x5930c800, 0x59325808,
+       0x0201f800, 0x00109037, 0x02020800, 0x001007fd,
+       0x0201f800, 0x0002077d, 0x82666540, 0x00000000,
+       0x040207f6, 0x5c00c800, 0x0201f800, 0x00104c62,
+       0x41365800, 0x0201f800, 0x001007f5, 0x80000580,
+       0x5c026000, 0x5c025800, 0x1c01f000, 0x82000540,
+       0x00000001, 0x0401f7fb, 0x4937c857, 0x4c580000,
+       0x59cc0001, 0x82000500, 0x00ffffff, 0x48026802,
+       0x497a6c01, 0x497a6a01, 0x59340200, 0x84000502,
+       0x48026a00, 0x0201f800, 0x0010513b, 0x04020017,
+       0x59340403, 0x82000580, 0x000007fe, 0x04000005,
+       0x59a80026, 0x8c00050a, 0x04020010, 0x0401f008,
+       0x59cc0408, 0x8c000518, 0x0400000c, 0x59cc0009,
+       0x48035035, 0x59cc000a, 0x48035036, 0x59cc0207,
+       0x80000540, 0x04020003, 0x42000000, 0x00000001,
+       0x48038893, 0x4803501e, 0x59cc0a09, 0x82040d00,
+       0x00000010, 0x59cc0408, 0x82000500, 0x00000020,
+       0x04000002, 0x84040d40, 0x5934000a, 0x82000500,
+       0xffffffee, 0x80040540, 0x4802680a, 0x83cca400,
+       0x0000000b, 0x8334ac00, 0x00000006, 0x4200b000,
+       0x00000002, 0x0201f800, 0x0010ab17, 0x83cca400,
+       0x0000000d, 0x8334ac00, 0x00000008, 0x4200b000,
+       0x00000002, 0x0201f800, 0x0010ab17, 0x59cc0a18,
+       0x82040480, 0x00000800, 0x0402100c, 0x82040480,
+       0x00000400, 0x04001004, 0x42000800, 0x00000400,
+       0x0401f006, 0x82040480, 0x00000200, 0x04001003,
+       0x42000800, 0x00000200, 0x48066a04, 0x59340403,
+       0x82000580, 0x000007fe, 0x04020003, 0x59cc0a08,
+       0x48066a04, 0x42000800, 0x00000004, 0x59cc1207,
+       0x800811c0, 0x04000005, 0x82080480, 0x00000004,
+       0x04021002, 0x40080800, 0x48066c04, 0x5c00b000,
+       0x1c01f000, 0x4937c857, 0x59a80026, 0x8c000508,
+       0x04000004, 0x84000556, 0x4803c857, 0x48035026,
+       0x59cc0207, 0x4803c857, 0x48026a05, 0x59cc020a,
+       0x4803c857, 0x48026c05, 0x59341200, 0x599c0818,
+       0x5934180a, 0x4807c857, 0x480bc857, 0x480fc857,
+       0x59cc2006, 0x82102500, 0xff000000, 0x82102580,
+       0x02000000, 0x04000007, 0x8c00050e, 0x04000009,
+       0x8c0c1d14, 0x04000003, 0x8c0c1d0e, 0x04000005,
+       0x8c040d18, 0x04000003, 0x8408154a, 0x0401f002,
+       0x8408150a, 0x8c000510, 0x04000009, 0x8c0c1d14,
+       0x04000003, 0x8c0c1d10, 0x04000005, 0x8c040d18,
+       0x04000003, 0x8408154e, 0x0401f002, 0x8408150e,
+       0x8c000512, 0x04000009, 0x8c0c1d14, 0x04000003,
+       0x8c0c1d12, 0x04000005, 0x8c040d18, 0x04000003,
+       0x8408155c, 0x0401f002, 0x8408151c, 0x480a6a00,
+       0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000,
+       0x4c580000, 0x5934000d, 0x80025d40, 0x04000029,
+       0x592c0003, 0x82000480, 0x00000008, 0x0400100b,
+       0x412cb800, 0x592c0001, 0x80025d40, 0x040207f9,
+       0x0201f800, 0x001007e4, 0x04000037, 0x492fc857,
+       0x492cb801, 0x0401f020, 0x832c0c00, 0x00000004,
+       0x4200b000, 0x00000008, 0x50040000, 0x82000580,
+       0xffffffff, 0x04020006, 0x80041000, 0x50080000,
+       0x82000580, 0xffffffff, 0x04000007, 0x82040c00,
+       0x00000002, 0x8058b040, 0x040207f4, 0x0201f800,
+       0x001005d8, 0x45480800, 0x454c1000, 0x592c1803,
+       0x800c1800, 0x480e5803, 0x480fc857, 0x0401f014,
+       0x0201f800, 0x001007e4, 0x04000017, 0x492fc857,
+       0x492e680d, 0x497a5802, 0x4a025803, 0x00000001,
+       0x494a5804, 0x494e5805, 0x832c0c00, 0x00000006,
+       0x4200b000, 0x0000000e, 0x46000800, 0xffffffff,
+       0x80040800, 0x8058b040, 0x040207fc, 0x82000540,
+       0x00000001, 0x5c00b000, 0x5c025800, 0x5c00b800,
+       0x1c01f000, 0x80000580, 0x0401f7fb, 0x4803c856,
+       0x4d3c0000, 0x4d2c0000, 0x5934000d, 0x80025d40,
+       0x0400001f, 0x592c0002, 0x80000540, 0x0402001f,
+       0x412e7800, 0x0401f8ce, 0x0402001c, 0x46000800,
+       0xffffffff, 0x46001000, 0xffffffff, 0x4813c857,
+       0x480fc857, 0x580c0003, 0x82000c80, 0x00000002,
+       0x04021014, 0x480fc857, 0x400c0000, 0x812c0580,
+       0x04020004, 0x580c0001, 0x4802680d, 0x0401f003,
+       0x580c0001, 0x48002001, 0x400e5800, 0x0201f800,
+       0x001007f4, 0x82000540, 0x00000001, 0x5c025800,
+       0x5c027800, 0x1c01f000, 0x80000580, 0x0401f7fc,
+       0x80000040, 0x48001803, 0x4803c857, 0x0401f7f6,
+       0x0201f800, 0x00020086, 0x59300007, 0x8400054e,
+       0x48026007, 0x592c1a04, 0x820c1d00, 0x000000ff,
+       0x820c0580, 0x00000048, 0x04000013, 0x0201f000,
+       0x0002028e, 0x8c000500, 0x02020800, 0x000200e5,
+       0x4a026203, 0x00000002, 0x592c1a04, 0x820c1d00,
+       0x000000ff, 0x820c0580, 0x00000018, 0x02000000,
+       0x0002028e, 0x820c0580, 0x00000048, 0x02020000,
+       0x0002028e, 0x42000800, 0x80000804, 0x0201f800,
+       0x00106721, 0x0201f000, 0x00020297, 0x4a025a06,
+       0x00000008, 0x0201f000, 0x000202da, 0x4a025a06,
+       0x00000029, 0x0201f000, 0x000202da, 0x4a025a06,
+       0x0000002a, 0x0201f000, 0x000202da, 0x4a025a06,
+       0x00000028, 0x0201f000, 0x000202da, 0x4943c857,
+       0x4d440000, 0x4d340000, 0x4d2c0000, 0x4c580000,
+       0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800,
+       0x00020245, 0x0402000d, 0x8d3e7d14, 0x04000005,
+       0x59340212, 0x82000500, 0x0000ff00, 0x04000007,
+       0x8d3e7d06, 0x04000004, 0x59340200, 0x8c00050e,
+       0x04020002, 0x0401f813, 0x81468800, 0x8058b040,
+       0x040207ef, 0x83440480, 0x00000800, 0x04021008,
+       0x8d3e7d02, 0x04000006, 0x42028800, 0x000007f0,
+       0x4200b000, 0x00000010, 0x0401f7e5, 0x5c00b000,
+       0x5c025800, 0x5c026800, 0x5c028800, 0x1c01f000,
+       0x4d2c0000, 0x41783000, 0x5936580f, 0x812e59c0,
+       0x04000029, 0x592c0204, 0x82000500, 0x000000ff,
+       0x82000580, 0x00000012, 0x04000020, 0x8d3e7d00,
+       0x04000003, 0x0401f83c, 0x0402001c, 0x592c2000,
+       0x497a5800, 0x801831c0, 0x04020009, 0x59340010,
+       0x812c0580, 0x04020004, 0x497a680f, 0x497a6810,
+       0x0401f008, 0x4812680f, 0x0401f006, 0x48103000,
+       0x59340010, 0x812c0580, 0x04020002, 0x481a6810,
+       0x4a025a04, 0x00000103, 0x49425a06, 0x497a5c09,
+       0x0201f800, 0x001091c6, 0x0201f800, 0x000202da,
+       0x40125800, 0x0401f7da, 0x412c3000, 0x592e5800,
+       0x0401f7d7, 0x5c025800, 0x1c01f000, 0x4803c856,
+       0x41781800, 0x5934000f, 0x80025d40, 0x04000010,
+       0x592c0005, 0x80200580, 0x592c0000, 0x04000003,
+       0x412c1800, 0x0401f7f9, 0x497a5800, 0x800c19c0,
+       0x04000008, 0x48001800, 0x80000540, 0x04020004,
+       0x480e6810, 0x82000540, 0x00000001, 0x1c01f000,
+       0x4802680f, 0x80000540, 0x040207fd, 0x497a6810,
+       0x0401f7f9, 0x592c0008, 0x81480580, 0x04020003,
+       0x592c0009, 0x814c0580, 0x1c01f000, 0x4803c856,
+       0x4c580000, 0x413c1800, 0x400c2000, 0x593c0002,
+       0x80000540, 0x04020018, 0x4200b000, 0x00000008,
+       0x820c0c00, 0x00000004, 0x50040000, 0x81480580,
+       0x04020005, 0x80041000, 0x50080000, 0x814c0580,
+       0x0400000d, 0x82040c00, 0x00000002, 0x8058b040,
+       0x040207f6, 0x400c2000, 0x580c0001, 0x80001d40,
+       0x040207ee, 0x82000540, 0x00000001, 0x5c00b000,
+       0x1c01f000, 0x80000580, 0x0401f7fd, 0x4937c857,
+       0x4c580000, 0x4d2c0000, 0x5934000d, 0x80025d40,
+       0x04020016, 0x0201f800, 0x001007e4, 0x04000010,
+       0x492e680d, 0x4a025802, 0x00000001, 0x497a5803,
+       0x832c0c00, 0x00000004, 0x4200b000, 0x00000010,
+       0x46000800, 0xffffffff, 0x80040800, 0x8058b040,
+       0x040207fc, 0x82000540, 0x00000001, 0x5c025800,
+       0x5c00b000, 0x1c01f000, 0x4d2c0000, 0x592e5801,
+       0x0201f800, 0x001007fd, 0x5c025800, 0x0401f7ea,
+       0x4d2c0000, 0x5936580d, 0x812e59c0, 0x04000007,
+       0x4937c857, 0x497a680d, 0x0201f800, 0x001007fd,
+       0x82000540, 0x00000001, 0x5c025800, 0x1c01f000,
+       0x59340405, 0x4937c857, 0x4803c857, 0x8c000508,
+       0x1c01f000, 0x4803c856, 0x0201f800, 0x0010513b,
+       0x04000011, 0x59a80815, 0x8c040d04, 0x0402000e,
+       0x59a80826, 0x8c040d06, 0x0400000b, 0x83ac0400,
+       0x000007fe, 0x50000000, 0x80026d40, 0x04000006,
+       0x0401f9a7, 0x04020004, 0x59340200, 0x8400055a,
+       0x48026a00, 0x599c0017, 0x8c000508, 0x04000015,
+       0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800,
+       0x00020245, 0x0402000c, 0x0401f999, 0x0402000a,
+       0x59a80010, 0x59340802, 0x80040580, 0x82000500,
+       0x00ffff00, 0x04020004, 0x59340200, 0x8400055a,
+       0x48026a00, 0x81468800, 0x8058b040, 0x040207f0,
+       0x0401f884, 0x04000003, 0x59a80836, 0x0401f006,
+       0x599c0017, 0x8c000508, 0x04000007, 0x42000800,
+       0x000007d0, 0x42001000, 0x00104876, 0x0201f800,
+       0x0010606e, 0x1c01f000, 0x4803c856, 0x4d340000,
+       0x4d440000, 0x4d3c0000, 0x4c580000, 0x42001000,
+       0x00104876, 0x0201f800, 0x00105f90, 0x59a80826,
+       0x8c040d06, 0x04000015, 0x0401f86a, 0x04000013,
+       0x83ae6c00, 0x000007fe, 0x51366800, 0x59340200,
+       0x8400051a, 0x48026a00, 0x599c0017, 0x8c000508,
+       0x04000007, 0x42000800, 0x000007d0, 0x42001000,
+       0x00104876, 0x0201f800, 0x0010606e, 0x0201f800,
+       0x00101e45, 0x0401f027, 0x4200b000, 0x000007f0,
+       0x80028d80, 0x0201f800, 0x00020245, 0x0402001e,
+       0x59340200, 0x8c00051a, 0x0400001b, 0x59368c03,
+       0x417a7800, 0x42028000, 0x00000029, 0x41783000,
+       0x0201f800, 0x0010a446, 0x59340200, 0x84000558,
+       0x8400051a, 0x48026a00, 0x4937c857, 0x4a026c00,
+       0x00000707, 0x42028000, 0x00000029, 0x0201f800,
+       0x00106ab4, 0x417a7800, 0x0201f800, 0x001067fd,
+       0x80000d80, 0x0201f800, 0x0010a2ff, 0x0201f800,
+       0x00106c4b, 0x81468800, 0x8058b040, 0x040207de,
+       0x5c00b000, 0x5c027800, 0x5c028800, 0x5c026800,
+       0x1c01f000, 0x4933c857, 0x59303809, 0x581c0200,
+       0x8400051a, 0x48003a00, 0x1c01f000, 0x4803c856,
+       0x42026800, 0x0010b524, 0x497a680e, 0x42028800,
+       0x000007ff, 0x0201f800, 0x001042b4, 0x4937c857,
+       0x4a026c00, 0x00000606, 0x4a026802, 0x00ffffff,
+       0x4a026a04, 0x00000200, 0x4a026c04, 0x00000002,
+       0x1c01f000, 0x59300009, 0x50000000, 0x4933c857,
+       0x4803c857, 0x8c00050e, 0x1c01f000, 0x59300009,
+       0x50000000, 0x8c00050a, 0x1c01f000, 0x4933c856,
+       0x0401f90f, 0x04000006, 0x59340400, 0x82000d00,
+       0x000000ff, 0x82041580, 0x00000005, 0x1c01f000,
+       0x4d340000, 0x83ac0400, 0x000007fe, 0x50000000,
+       0x80026d40, 0x04000003, 0x59340200, 0x8c00051a,
+       0x5c026800, 0x1c01f000, 0x4937c857, 0x493fc857,
+       0x59340403, 0x81ac0400, 0x50000000, 0x81340580,
+       0x02020800, 0x001005d8, 0x59341200, 0x813e79c0,
+       0x04000003, 0x8408155e, 0x0401f002, 0x8408151e,
+       0x480a6a00, 0x1c01f000, 0x4937c857, 0x0201f800,
+       0x0010210a, 0x04000006, 0x59a80835, 0x42001000,
+       0x00104910, 0x0201f800, 0x0010606e, 0x1c01f000,
+       0x4937c857, 0x42001000, 0x00104910, 0x0201f800,
+       0x00105f90, 0x59a81026, 0x84081512, 0x480b5026,
+       0x1c01f000, 0x4c380000, 0x4c340000, 0x4c240000,
+       0x4c600000, 0x4008c000, 0x83440480, 0x00000800,
+       0x04021045, 0x80002d80, 0x41442000, 0x83447400,
+       0x0010ac00, 0x4200b000, 0x000007f0, 0x83444c80,
+       0x000007f0, 0x04001003, 0x4200b000, 0x00000010,
+       0x50380000, 0x80000540, 0x0402001e, 0x41440000,
+       0x80100580, 0x04020043, 0x40102800, 0x82104c80,
+       0x000007f0, 0x04001015, 0x82104d80, 0x000007fc,
+       0x04020005, 0x82604d80, 0x00fffffc, 0x0402002a,
+       0x0401f00e, 0x82104d80, 0x000007fd, 0x04020005,
+       0x82604d80, 0x00fffffd, 0x04020023, 0x0401f007,
+       0x82104d80, 0x000007ff, 0x0402001f, 0x82604d80,
+       0x00ffffff, 0x0402001c, 0x84142d5e, 0x0401f029,
+       0x40006800, 0x58343002, 0x82183500, 0x00ffffff,
+       0x40180000, 0x80600580, 0x04020019, 0x40100000,
+       0x81440580, 0x0402000a, 0x40366800, 0x8c204508,
+       0x04000053, 0x0401ff8a, 0x04020051, 0x4947c857,
+       0x42000000, 0x0000001d, 0x0401f04e, 0x4947c857,
+       0x480bc857, 0x4823c857, 0x42000000, 0x0000001a,
+       0x0401f048, 0x4947c857, 0x4863c857, 0x4813c857,
+       0x42000000, 0x00000019, 0x0401f042, 0x40100000,
+       0x81440580, 0x04020007, 0x58343002, 0x4947c857,
+       0x481bc857, 0x42000000, 0x0000001b, 0x0401f039,
+       0x80102000, 0x80387000, 0x83444c80, 0x000007f0,
+       0x04001009, 0x82104d80, 0x00000800, 0x0402000c,
+       0x42002000, 0x000007f0, 0x42007000, 0x0010b3f0,
+       0x0401f007, 0x82104d80, 0x000007f0, 0x04020004,
+       0x41782000, 0x42007000, 0x0010ac00, 0x8058b040,
+       0x040207a4, 0x801429c0, 0x04020007, 0x0201f800,
+       0x001005d8, 0x4947c857, 0x42000000, 0x0000000a,
+       0x0401f01c, 0x4d2c0000, 0x4c180000, 0x40603000,
+       0x0401fc12, 0x4947c857, 0x4937c857, 0x5c003000,
+       0x5c025800, 0x040207f4, 0x497a6a12, 0x59a80026,
+       0x8c00050a, 0x0402000d, 0x82600500, 0x00ffff00,
+       0x04000006, 0x59a84810, 0x82244d00, 0x00ffff00,
+       0x80240580, 0x04020005, 0x82600500, 0x000000ff,
+       0x800000d0, 0x48026a12, 0x48626802, 0x80000580,
+       0x80000540, 0x5c00c000, 0x5c004800, 0x5c006800,
+       0x5c007000, 0x1c01f000, 0x5934000f, 0x5934140b,
+       0x80081040, 0x04001002, 0x480a6c0b, 0x80000540,
+       0x02020800, 0x00020253, 0x1c01f000, 0x4803c857,
+       0x4947c857, 0x4c300000, 0x82006500, 0x00000030,
+       0x04000006, 0x4c000000, 0x0201f800, 0x0010942a,
+       0x5c000000, 0x0402000b, 0x8c00050e, 0x04000006,
+       0x0201f800, 0x00020245, 0x04020006, 0x4937c857,
+       0x0401fc2f, 0x80000580, 0x5c006000, 0x1c01f000,
+       0x82000540, 0x00000001, 0x0401f7fc, 0x4803c857,
+       0x4c580000, 0x4d440000, 0x40001000, 0x80000d80,
+       0x4200b000, 0x000007f0, 0x4c040000, 0x40068800,
+       0x4c080000, 0x40080000, 0x0401ffdd, 0x5c001000,
+       0x5c000800, 0x80040800, 0x8058b040, 0x040207f7,
+       0x5c028800, 0x5c00b000, 0x1c01f000, 0x4c5c0000,
+       0x59340400, 0x8200bd80, 0x00000606, 0x5c00b800,
+       0x1c01f000, 0x4c5c0000, 0x59340400, 0x8200bd80,
+       0x00000404, 0x5c00b800, 0x1c01f000, 0x4c5c0000,
+       0x59340400, 0x8200bd80, 0x00000404, 0x04000003,
+       0x8200bd80, 0x00000606, 0x5c00b800, 0x1c01f000,
+       0x4c5c0000, 0x4c600000, 0x59340400, 0x8200bd00,
+       0x0000ff00, 0x825cc580, 0x00000400, 0x04000003,
+       0x825cc580, 0x00000600, 0x5c00c000, 0x5c00b800,
+       0x1c01f000, 0x4c5c0000, 0x59340400, 0x82000500,
+       0x000000ff, 0x8200bd80, 0x00000003, 0x04000003,
+       0x8200bd80, 0x00000005, 0x5c00b800, 0x1c01f000,
+       0x4c5c0000, 0x59340400, 0x82000500, 0x0000ff00,
+       0x8400b9c0, 0x805c0580, 0x4937c857, 0x4803c857,
+       0x48026c00, 0x5c00b800, 0x1c01f000, 0x4c040000,
+       0x4c080000, 0x592c0207, 0x8c00050c, 0x0400000f,
+       0x592e8c06, 0x82000500, 0x00000080, 0x84000548,
+       0x4d3c0000, 0x42027800, 0x00001000, 0x0401ff90,
+       0x5c027800, 0x82000540, 0x00000001, 0x5c001000,
+       0x5c000800, 0x1c01f000, 0x80000580, 0x0401f7fc,
+       0x592c040b, 0x82000500, 0x0000e000, 0x82000580,
+       0x00006000, 0x04000019, 0x836c0580, 0x00000003,
+       0x04000016, 0x836c0580, 0x00000002, 0x040200ff,
+       0x59a80026, 0x82000d00, 0x00000038, 0x04020005,
+       0x59a80832, 0x800409c0, 0x0400000c, 0x0401f0f7,
+       0x82000d00, 0x00000003, 0x82040d80, 0x00000003,
+       0x040200f2, 0x82000d00, 0x00000028, 0x04020003,
+       0x8c00050c, 0x040000ed, 0x592c100a, 0x82080500,
+       0xff000000, 0x040200ce, 0x59a80010, 0x80080580,
+       0x040000c8, 0x592c0c0b, 0x82040d00, 0x0000e000,
+       0x82040480, 0x00008000, 0x040210c8, 0x592e8c06,
+       0x83440480, 0x00000800, 0x04001007, 0x83440580,
+       0x0000ffff, 0x040200af, 0x800409c0, 0x040200f7,
+       0x0401f0ac, 0x800409c0, 0x040200f4, 0x41784000,
+       0x0401fead, 0x040200db, 0x42027000, 0x00000053,
+       0x592c2409, 0x82100500, 0xffffff00, 0x040200aa,
+       0x4813c857, 0x592c000c, 0x800001c0, 0x04000083,
+       0x82100580, 0x00000004, 0x040000a0, 0x82100580,
+       0x00000051, 0x0400009d, 0x82100580, 0x00000003,
+       0x04000016, 0x82100580, 0x00000020, 0x0400004b,
+       0x82100580, 0x00000024, 0x04000042, 0x82100580,
+       0x00000021, 0x04000042, 0x82100580, 0x00000050,
+       0x04000037, 0x82100580, 0x00000052, 0x04000031,
+       0x82100580, 0x00000005, 0x0402006b, 0x42027000,
+       0x00000001, 0x0401f01b, 0x42027000, 0x00000002,
+       0x59a80005, 0x8c000514, 0x04000016, 0x0401ff4c,
+       0x04000014, 0x59340212, 0x82000500, 0x0000ff00,
+       0x42001000, 0x00000010, 0x0402000c, 0x59a80026,
+       0x8c000506, 0x0402006f, 0x42001000, 0x00000008,
+       0x59340002, 0x82000500, 0x00ff0000, 0x82000580,
+       0x00ff0000, 0x04000003, 0x0401f9bf, 0x04020065,
+       0x0201f800, 0x0002075a, 0x0400007e, 0x4a026406,
+       0x00000010, 0x49366009, 0x42000800, 0x00000003,
+       0x83380580, 0x00000002, 0x04000003, 0x42000800,
+       0x0000000b, 0x0201f800, 0x00104571, 0x0401f044,
+       0x42027000, 0x00000000, 0x0401f003, 0x42027000,
+       0x00000004, 0x0401ff37, 0x04020071, 0x0401f036,
+       0x42027000, 0x00000033, 0x0401f006, 0x42027000,
+       0x00000005, 0x0401f003, 0x42027000, 0x00000003,
+       0x0401ff23, 0x04020066, 0x59a80005, 0x8c000514,
+       0x04000016, 0x0401ff12, 0x04000014, 0x59340212,
+       0x82000500, 0x0000ff00, 0x42001000, 0x00000010,
+       0x0402000c, 0x59a80026, 0x8c000506, 0x04020035,
+       0x42001000, 0x00000008, 0x59340002, 0x82000500,
+       0x00ff0000, 0x82000580, 0x00ff0000, 0x04000003,
+       0x0401f985, 0x0402002b, 0x0201f800, 0x0002075a,
+       0x04000044, 0x4a026406, 0x00000010, 0x49366009,
+       0x42000800, 0x00000005, 0x83380580, 0x00000003,
+       0x04000003, 0x42000800, 0x00000009, 0x0201f800,
+       0x00104571, 0x0401f00a, 0x82102580, 0x00000011,
+       0x0402002d, 0x0201f800, 0x0002075a, 0x04000031,
+       0x4a026406, 0x00000010, 0x49366009, 0x492e6008,
+       0x49325808, 0x813669c0, 0x04000007, 0x592c0c0b,
+       0x8c040d18, 0x04000004, 0x59340200, 0x84000514,
+       0x48026a00, 0x0201f800, 0x000207a1, 0x80000580,
+       0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fd,
+       0x42001000, 0x0000000a, 0x0401f015, 0x42001000,
+       0x00000010, 0x0401f012, 0x42001000, 0x00000016,
+       0x0401f00f, 0x42001000, 0x00000017, 0x0401f00c,
+       0x42001000, 0x00000018, 0x0401f009, 0x42001000,
+       0x0000001b, 0x0401f006, 0x42001000, 0x0000001e,
+       0x0401f003, 0x42001000, 0x00000020, 0x42000800,
+       0x00000019, 0x42028000, 0x00000031, 0x0401f7e2,
+       0x42000800, 0x00000003, 0x0401f003, 0x42000800,
+       0x0000000a, 0x41781000, 0x0401f7f7, 0x42000800,
+       0x00000009, 0x59341400, 0x0401f7f3, 0x42028000,
+       0x00000008, 0x0401f005, 0x42000800, 0x00000007,
+       0x416c1000, 0x0401f7ec, 0x41780800, 0x41781000,
+       0x0401f7cd, 0x42028000, 0x00000000, 0x0401f7fb,
+       0x82004d80, 0x0000001d, 0x02000800, 0x001005d8,
+       0x82004d80, 0x0000001a, 0x04020004, 0x40101000,
+       0x40000800, 0x0401f7dc, 0x82004d80, 0x0000001b,
+       0x04020003, 0x40181000, 0x0401f7fa, 0x82004d80,
+       0x0000001c, 0x040007f7, 0x82004d80, 0x00000019,
+       0x040007b8, 0x0401f7d6, 0x592e6008, 0x0201f800,
+       0x0010941a, 0x040007b6, 0x59300c06, 0x82040580,
+       0x00000011, 0x040207d6, 0x83440580, 0x0000ffff,
+       0x04020005, 0x59326809, 0x813669c0, 0x0400000e,
+       0x0401f7cf, 0x592c100a, 0x82081500, 0x00ffffff,
+       0x41784000, 0x0401fda8, 0x040207d6, 0x59300009,
+       0x800001c0, 0x04000003, 0x81340580, 0x040207c4,
+       0x49366009, 0x592c0c0b, 0x82041500, 0x0000e000,
+       0x82080580, 0x00006000, 0x04000009, 0x59300a03,
+       0x82040580, 0x00000007, 0x040207b9, 0x492e6008,
+       0x42027000, 0x00000054, 0x0401f77f, 0x0201f800,
+       0x0010a8d4, 0x040007bc, 0x0401f7b1, 0x492fc857,
+       0x59a80021, 0x800001c0, 0x04020073, 0x592e6008,
+       0x4933c857, 0x0201f800, 0x0010941a, 0x04000041,
+       0x59301406, 0x82080580, 0x00000005, 0x0402005b,
+       0x59301203, 0x82080580, 0x00000007, 0x04020057,
+       0x592e8c06, 0x83440480, 0x00000800, 0x04021032,
+       0x41784000, 0x592c1009, 0x82081500, 0x00ffffff,
+       0x0401fd75, 0x0402005f, 0x59300009, 0x800001c0,
+       0x04000003, 0x81340580, 0x04020048, 0x4d300000,
+       0x592e6013, 0x4933c857, 0x83300580, 0xffffffff,
+       0x0400000d, 0x0201f800, 0x0010941a, 0x5c026000,
+       0x04000029, 0x591c1406, 0x82080580, 0x00000006,
+       0x04000046, 0x82080580, 0x00000011, 0x04000043,
+       0x0401f002, 0x5c026000, 0x59a80010, 0x592c100a,
+       0x82081500, 0x00ffffff, 0x80081580, 0x04020017,
+       0x592c1009, 0x82081500, 0x00ffffff, 0x80081580,
+       0x0400000f, 0x49366009, 0x492e6008, 0x42027000,
+       0x00000092, 0x0201f800, 0x000207a1, 0x80000580,
+       0x1c01f000, 0x42001000, 0x0000000a, 0x0401f00c,
+       0x42001000, 0x00000010, 0x0401f009, 0x42001000,
+       0x00000014, 0x0401f006, 0x42001000, 0x00000018,
+       0x0401f003, 0x42001000, 0x0000003c, 0x492fc857,
+       0x480bc857, 0x42000800, 0x00000019, 0x42028000,
+       0x00000031, 0x82000540, 0x00000001, 0x0401f7e9,
+       0x492fc857, 0x4803c857, 0x480bc857, 0x40000800,
+       0x0401f7f7, 0x492fc857, 0x42000800, 0x0000000a,
+       0x41781000, 0x0401f7f2, 0x4933c857, 0x59300406,
+       0x4803c857, 0x59300203, 0x4803c857, 0x59300009,
+       0x4803c857, 0x42028000, 0x00000008, 0x41780800,
+       0x41781000, 0x0401f7e8, 0x42000800, 0x0000001e,
+       0x0401f7f0, 0x42000800, 0x00000001, 0x0401f7ed,
+       0x82004d80, 0x0000001d, 0x02000800, 0x001005d8,
+       0x82004d80, 0x0000001a, 0x04020003, 0x40101000,
+       0x0401f7dc, 0x82004d80, 0x0000001b, 0x04020003,
+       0x40181000, 0x0401f7d7, 0x82004d80, 0x0000001c,
+       0x040007d4, 0x82004d80, 0x00000019, 0x040007d1,
+       0x0401f7d5, 0x59302009, 0x801021c0, 0x04000035,
+       0x58101400, 0x82081d00, 0x000000ff, 0x59300c03,
+       0x82040580, 0x00000008, 0x04000022, 0x82040580,
+       0x0000000a, 0x04000017, 0x82040580, 0x0000000c,
+       0x04000010, 0x82040580, 0x00000002, 0x04000019,
+       0x82040580, 0x00000001, 0x04000012, 0x82040580,
+       0x00000003, 0x0400000b, 0x82040580, 0x00000005,
+       0x04000004, 0x82040580, 0x00000033, 0x04020019,
+       0x820c0580, 0x00000009, 0x0400000d, 0x0401f015,
+       0x820c0580, 0x00000005, 0x04000009, 0x0401f011,
+       0x820c0580, 0x0000000b, 0x04000005, 0x0401f00d,
+       0x820c0580, 0x00000003, 0x0402000a, 0x82081d00,
+       0xffffff00, 0x840c01c0, 0x800c0540, 0x4813c857,
+       0x480bc857, 0x4807c857, 0x4803c857, 0x48002400,
+       0x1c01f000, 0x599c0017, 0x8c00050a, 0x04000003,
+       0x80000580, 0x1c01f000, 0x59a80026, 0x82000500,
+       0x00000028, 0x04000008, 0x42028800, 0x000007fd,
+       0x0201f800, 0x00020245, 0x04020003, 0x5934000a,
+       0x8c000504, 0x1c01f000, 0x4d300000, 0x5934000e,
+       0x80026540, 0x04000006, 0x0201f800, 0x001062d5,
+       0x02000800, 0x001064ad, 0x497a680e, 0x5c026000,
+       0x1c01f000, 0x4d440000, 0x4d340000, 0x80000580,
+       0x40001800, 0x40028800, 0x82080580, 0x00000008,
+       0x04020003, 0x42001800, 0x00000001, 0x0201f800,
+       0x00020245, 0x0402000a, 0x0401fd6d, 0x04020008,
+       0x800c19c0, 0x04000004, 0x59340405, 0x8c000508,
+       0x04000003, 0x80081040, 0x04000009, 0x81468800,
+       0x83440480, 0x00000800, 0x040017f1, 0x80000580,
+       0x5c026800, 0x5c028800, 0x1c01f000, 0x82000540,
+       0x00000001, 0x5c026800, 0x5c028800, 0x1c01f000,
+       0x4a033020, 0x00000000, 0x497b3026, 0x497b3027,
+       0x497b3028, 0x497b3029, 0x497b302b, 0x497b3021,
+       0x4a03b104, 0x60000001, 0x1c01f000, 0x4803c856,
+       0x599c0018, 0x497b3024, 0x497b3025, 0x82000500,
+       0x0000000f, 0x82000d80, 0x00000005, 0x04000006,
+       0x82000580, 0x00000006, 0x0400000d, 0x497b3022,
+       0x1c01f000, 0x4a033022, 0x00000005, 0x599c0216,
+       0x82000500, 0x0000ffff, 0x04020003, 0x42000000,
+       0x00000002, 0x48033023, 0x1c01f000, 0x4a033022,
+       0x00000006, 0x0401f7f6, 0x0401ffe5, 0x4a03c826,
+       0x00000004, 0x599c0209, 0x80000540, 0x0400001f,
+       0x599c0207, 0x80000540, 0x04000007, 0x800000cc,
+       0x599c080d, 0x80040400, 0x4803b100, 0x497bb102,
+       0x59d80101, 0x599c000d, 0x4803b100, 0x599c000e,
+       0x4803b101, 0x599c0207, 0x80000540, 0x04020002,
+       0x497bb102, 0x599c0a09, 0x82040540, 0x00400000,
+       0x59980822, 0x4803b103, 0x4a03b109, 0x00000004,
+       0x4a03b104, 0x10000001, 0x800409c0, 0x04020004,
+       0x4a033020, 0x00000001, 0x1c01f000, 0x4a033020,
+       0x00000002, 0x0401f7fd, 0x59980022, 0x4803c856,
+       0x80000540, 0x02000000, 0x000202de, 0x0401f017,
+       0x42034000, 0x0010b4a4, 0x59a1d81e, 0x80edd9c0,
+       0x02000800, 0x001005d8, 0x58ec0009, 0x48efc857,
+       0x49a3c857, 0x492fc857, 0x4803c857, 0x800001c0,
+       0x08020000, 0x0201f800, 0x001005d8, 0x5931d821,
+       0x58ef400b, 0x58ec0009, 0x800001c0, 0x08020000,
+       0x0201f800, 0x001005d8, 0x497a5800, 0x59980026,
+       0x80000540, 0x0402008c, 0x59d80105, 0x82000d00,
+       0x00018780, 0x040201da, 0x80000106, 0x82000500,
+       0x00000003, 0x0c01f001, 0x00104d0a, 0x00104d89,
+       0x00104d22, 0x00104d50, 0x592c0001, 0x492fc857,
+       0x492fb107, 0x80000d40, 0x04020007, 0x59940019,
+       0x80000540, 0x04022003, 0x59980023, 0x48032819,
+       0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001,
+       0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40,
+       0x040207f9, 0x59c80000, 0x82000540, 0x00001200,
+       0x48039000, 0x0401f7ee, 0x492fc857, 0x492fb107,
+       0x592c0001, 0x80000d40, 0x04020012, 0x59da5908,
+       0x835c0480, 0x00000020, 0x0400101c, 0x0402b01a,
+       0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500,
+       0x00018780, 0x040201aa, 0x59940019, 0x80000540,
+       0x04022003, 0x59980023, 0x48032819, 0x1c01f000,
+       0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+       0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9,
+       0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+       0x0401f7e3, 0x0400f009, 0x496a5800, 0x412ed000,
+       0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+       0x48039000, 0x0401f7e0, 0x492fa807, 0x0401f7de,
+       0x492fc857, 0x59d81108, 0x45681000, 0x400ad000,
+       0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540,
+       0x00001200, 0x48039000, 0x0402d00c, 0x592c0001,
+       0x492fc857, 0x492fb107, 0x80000d40, 0x0402001d,
+       0x59940019, 0x80000540, 0x04022003, 0x59980023,
+       0x48032819, 0x1c01f000, 0x59d80105, 0x82000500,
+       0x00018780, 0x04020172, 0x42000000, 0x0010b855,
+       0x0201f800, 0x0010aa47, 0x59980026, 0x59980828,
+       0x80000000, 0x48033026, 0x492fc857, 0x800409c0,
+       0x492f3028, 0x04000003, 0x492c0800, 0x0401f002,
+       0x492f3029, 0x592c0001, 0x80000d40, 0x040007e5,
+       0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+       0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9,
+       0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+       0x0401f7d8, 0x59980026, 0x59980828, 0x80000000,
+       0x48033026, 0x492fc857, 0x800409c0, 0x492f3028,
+       0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+       0x592c0001, 0x80000d40, 0x04020027, 0x0402d00e,
+       0x59980029, 0x80025d40, 0x0400000f, 0x59980026,
+       0x80000040, 0x48033026, 0x04020002, 0x48033028,
+       0x592c0000, 0x48033029, 0x492fc857, 0x492fb107,
+       0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800,
+       0x0010aa47, 0x0402e00a, 0x59da5908, 0x496a5800,
+       0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000,
+       0x82000540, 0x00001200, 0x48039000, 0x59d80105,
+       0x82000500, 0x00018780, 0x04020125, 0x59940019,
+       0x80000540, 0x04022003, 0x59980023, 0x48032819,
+       0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001,
+       0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40,
+       0x040207f9, 0x59c80000, 0x82000540, 0x00001200,
+       0x48039000, 0x0401f7ce, 0x592c0204, 0x4803c856,
+       0x04000008, 0x42034000, 0x0010b4a4, 0x59a1d81e,
+       0x80edd9c0, 0x02000800, 0x001005d8, 0x0401f003,
+       0x5931d821, 0x58ef400b, 0x58ec0009, 0x800001c0,
+       0x08020000, 0x0201f800, 0x001005d8, 0x497a5801,
+       0x40065800, 0x592c0001, 0x496a5800, 0x412ed000,
+       0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000,
+       0x82000540, 0x00001200, 0x48039000, 0x1c01f000,
+       0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+       0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9,
+       0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+       0x0200e000, 0x000202fb, 0x0201f000, 0x00020302,
+       0x5998002b, 0x84000540, 0x4803302b, 0x0201f000,
+       0x0002035e, 0x42000000, 0x0010b855, 0x0201f800,
+       0x0010aa47, 0x492fc857, 0x59980026, 0x59980828,
+       0x80000000, 0x48033026, 0x800409c0, 0x492f3028,
+       0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+       0x592c0001, 0x80000d40, 0x04020002, 0x1c01f000,
+       0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+       0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9,
+       0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+       0x1c01f000, 0x59980026, 0x59980828, 0x80000000,
+       0x48033026, 0x492fc857, 0x800409c0, 0x492f3028,
+       0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+       0x592c0001, 0x80000d40, 0x04020039, 0x0402d00e,
+       0x59980029, 0x80025d40, 0x0400000f, 0x59980026,
+       0x80000040, 0x48033026, 0x04020002, 0x48033028,
+       0x592c0000, 0x48033029, 0x492fc857, 0x492fb107,
+       0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800,
+       0x0010aa47, 0x0402e01d, 0x59da5908, 0x496a5800,
+       0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000,
+       0x82000540, 0x00001200, 0x48039000, 0x04006018,
+       0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd,
+       0x900001c0, 0x82000540, 0x00000013, 0x4803c011,
+       0x5998002b, 0x84000500, 0x4803302b, 0x59e00017,
+       0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+       0x4203e000, 0x30000001, 0x59d80105, 0x82000500,
+       0x00018780, 0x0402007e, 0x1c01f000, 0x5998002b,
+       0x84000540, 0x4803302b, 0x0401f7f8, 0x497a5801,
+       0x40065800, 0x592c0001, 0x496a5800, 0x412ed000,
+       0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000,
+       0x82000540, 0x00001200, 0x48039000, 0x0401f7bc,
+       0x5c000000, 0x4c000000, 0x4803c857, 0x492fc857,
+       0x4943c857, 0x4807c857, 0x4a025a04, 0x00000103,
+       0x49425a06, 0x48065a08, 0x4a025c06, 0x0000ffff,
+       0x813261c0, 0x04000003, 0x59300402, 0x48025c06,
+       0x832c0400, 0x00000009, 0x04011000, 0x4803c840,
+       0x4a03c842, 0x0000000b, 0x04011000, 0x1c01f000,
+       0x4df00000, 0x4203e000, 0x50000000, 0x599cb817,
+       0x59940019, 0x80000540, 0x04002023, 0x0400000e,
+       0x59980022, 0x82000580, 0x00000005, 0x0400001e,
+       0x59a80069, 0x81640580, 0x0402001b, 0x8c5cbd08,
+       0x04000005, 0x59a8006a, 0x59a80866, 0x80040580,
+       0x04020015, 0x8c5cbd08, 0x04020030, 0x59d8090b,
+       0x59d8010a, 0x80040580, 0x0400000d, 0x0400600e,
+       0x4a03c011, 0x80400012, 0x4a03c020, 0x00008040,
+       0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017,
+       0x00000002, 0x4203e000, 0x30000001, 0x4a032819,
+       0xffff0000, 0x04026835, 0x04006003, 0x8c5cbd08,
+       0x04020860, 0x59980029, 0x80025d40, 0x04000010,
+       0x59d80105, 0x82000500, 0x00018780, 0x04020020,
+       0x0402d00d, 0x59980026, 0x492fc857, 0x80000040,
+       0x48033026, 0x592c0000, 0x492fb107, 0x48033029,
+       0x04020003, 0x4803c856, 0x48033028, 0x5c03e000,
+       0x1c01f000, 0x42000000, 0x0010b855, 0x0201f800,
+       0x0010aa47, 0x0401f7fa, 0x59e0000f, 0x59e0080f,
+       0x80040580, 0x040207fd, 0x59e00010, 0x59e01010,
+       0x80081580, 0x040207fd, 0x40065000, 0x80041580,
+       0x040007c7, 0x040067dc, 0x0401f7ca, 0x4803c857,
+       0x485fc857, 0x8c00050e, 0x02020800, 0x001005d0,
+       0x4203e000, 0x50000000, 0x4200b800, 0x00008004,
+       0x0201f000, 0x001005dd, 0x5998002b, 0x8c000500,
+       0x04000013, 0x84000500, 0x4803302b, 0x59d8010a,
+       0x59d8090a, 0x80040580, 0x040207fd, 0x800408e0,
+       0x82040d40, 0x00000013, 0x4807c011, 0x59e00017,
+       0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+       0x4203e000, 0x30000001, 0x1c01f000, 0x0402e014,
+       0x59da5908, 0x496a5800, 0x412ed000, 0x815eb800,
+       0x0400e7fc, 0x59c80000, 0x82000540, 0x00001200,
+       0x48039000, 0x59d8090b, 0x59980024, 0x48073024,
+       0x80040480, 0x04020004, 0x59940019, 0x80000540,
+       0x04022003, 0x59980823, 0x48072819, 0x59d80105,
+       0x82000500, 0x00018780, 0x040207c9, 0x1c01f000,
+       0x59981025, 0x59e00010, 0x59e00810, 0x80041d80,
+       0x040207fd, 0x80080580, 0x04000013, 0x48073025,
+       0x59e0000f, 0x59e0100f, 0x80081d80, 0x040207fd,
+       0x81280580, 0x04000008, 0x400a5000, 0x40080000,
+       0x80040580, 0x04000003, 0x59980823, 0x48072819,
+       0x1c01f000, 0x59940019, 0x80000540, 0x040227f8,
+       0x0401f7fc, 0x59e0000f, 0x59e0100f, 0x80081d80,
+       0x040207fd, 0x81280580, 0x040007f6, 0x400a5000,
+       0x59940019, 0x80000540, 0x040027ed, 0x0401f7f1,
+       0x59a80017, 0x82000c80, 0x0000000a, 0x02021800,
+       0x001005d8, 0x0c01f809, 0x4a038805, 0x000000f0,
+       0x59c400a3, 0x82000500, 0x02870000, 0x02020800,
+       0x001005d8, 0x1c01f000, 0x00104fc5, 0x00104f51,
+       0x00104f6c, 0x00104f95, 0x00104fb8, 0x00104ff2,
+       0x00105004, 0x00104f6c, 0x00104fd6, 0x00104f50,
+       0x1c01f000, 0x4a038808, 0x00000004, 0x0401f8f9,
+       0x0201f800, 0x001053ab, 0x59c40805, 0x8c040d0e,
+       0x04020013, 0x8c040d0a, 0x0402000b, 0x8c040d0c,
+       0x04020006, 0x8c040d08, 0x0400000d, 0x4a035017,
+       0x00000003, 0x0401f00a, 0x4a035017, 0x00000000,
+       0x0401f007, 0x42000000, 0x0010b844, 0x0201f800,
+       0x0010aa47, 0x4a035017, 0x00000002, 0x1c01f000,
+       0x4a038808, 0x00000002, 0x0401f8de, 0x59c40805,
+       0x8c040d08, 0x04020021, 0x8c040d0c, 0x0402001c,
+       0x8c040d0e, 0x04020017, 0x82040500, 0x000000f0,
+       0x0402001c, 0x0201f800, 0x001053ab, 0x4a038808,
+       0x00000080, 0x59c40002, 0x8400050c, 0x48038802,
+       0x0401f9d9, 0x4d3c0000, 0x42027800, 0x00000001,
+       0x0201f800, 0x00109874, 0x5c027800, 0x4a038808,
+       0x00000080, 0x4a035017, 0x00000009, 0x0401f009,
+       0x4a035017, 0x00000001, 0x0401f006, 0x4a035017,
+       0x00000000, 0x0401f003, 0x4a035017, 0x00000003,
+       0x1c01f000, 0x0401f8b7, 0x4a038808, 0x00000080,
+       0x59c40805, 0x8c040d0a, 0x0402001b, 0x8c040d0c,
+       0x04020016, 0x8c040d0e, 0x04020011, 0x82040500,
+       0x000000f0, 0x04020016, 0x59c40002, 0x8400050c,
+       0x48038802, 0x0401f9b4, 0x4d3c0000, 0x42027800,
+       0x00000001, 0x0201f800, 0x00109874, 0x5c027800,
+       0x4a035017, 0x00000009, 0x0401f009, 0x4a035017,
+       0x00000001, 0x0401f006, 0x4a035017, 0x00000000,
+       0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+       0x4a038808, 0x00000008, 0x59c40805, 0x8c040d0c,
+       0x04020006, 0x8c040d0e, 0x04000006, 0x4a035017,
+       0x00000001, 0x0401f003, 0x4a035017, 0x00000000,
+       0x1c01f000, 0x0401f8d3, 0x59c40805, 0x8c040d0c,
+       0x0402000d, 0x4c040000, 0x0401f882, 0x5c000800,
+       0x8c040d0a, 0x04020006, 0x8c040d0e, 0x04000006,
+       0x4a035017, 0x00000001, 0x0401f003, 0x4a035017,
+       0x00000002, 0x1c01f000, 0x4a038808, 0x00000008,
+       0x42001000, 0x00105058, 0x0201f800, 0x00106084,
+       0x59c40805, 0x8c040d0a, 0x0402000d, 0x8c040d08,
+       0x0402000b, 0x8c040d0c, 0x04020006, 0x8c040d0e,
+       0x0400000d, 0x4a035017, 0x00000001, 0x0401f00a,
+       0x4a035017, 0x00000000, 0x0401f007, 0x42000000,
+       0x0010b844, 0x0201f800, 0x0010aa47, 0x4a035017,
+       0x00000004, 0x1c01f000, 0x0401f8a6, 0x0401f859,
+       0x59c40805, 0x8c040d0a, 0x0402000b, 0x8c040d0c,
+       0x04020006, 0x8c040d0e, 0x04000009, 0x4a035017,
+       0x00000001, 0x0401f006, 0x4a035017, 0x00000000,
+       0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+       0x4a038808, 0x00000004, 0x0401f846, 0x59c40805,
+       0x8c040d0a, 0x04020010, 0x8c040d08, 0x0402000b,
+       0x8c040d0c, 0x04020006, 0x8c040d0e, 0x0400000c,
+       0x4a035017, 0x00000001, 0x0401f009, 0x4a035017,
+       0x00000000, 0x0401f006, 0x4a035017, 0x00000003,
+       0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+       0x0401f91f, 0x02020800, 0x001005d8, 0x59a80805,
+       0x8c040d0c, 0x04000015, 0x84040d0c, 0x48075005,
+       0x4a038805, 0x00000010, 0x0201f800, 0x00101937,
+       0x59c40005, 0x8c000508, 0x04000008, 0x4a038808,
+       0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+       0x00000001, 0x0401f01a, 0x59c40006, 0x84000548,
+       0x48038806, 0x0401f016, 0x59a80017, 0x82000580,
+       0x00000001, 0x0400000c, 0x59a80017, 0x82000580,
+       0x00000005, 0x0402000c, 0x42000000, 0x0010b844,
+       0x0201f800, 0x0010aa47, 0x4a035017, 0x00000008,
+       0x0401f007, 0x42000000, 0x0010b844, 0x0201f800,
+       0x0010aa47, 0x4a035017, 0x00000004, 0x1c01f000,
+       0x4803c856, 0x4c040000, 0x4c080000, 0x42000800,
+       0x00000064, 0x42001000, 0x00105058, 0x0201f800,
+       0x00106079, 0x5c001000, 0x5c000800, 0x1c01f000,
+       0x4803c856, 0x4c040000, 0x0201f800, 0x00106c55,
+       0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x0401ffba, 0x5c000800,
+       0x1c01f000, 0x4803c856, 0x4c040000, 0x4c080000,
+       0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800,
+       0x00106e21, 0x5c03e000, 0x02000800, 0x00106c4b,
+       0x59c40006, 0x84000500, 0x48038806, 0x0201f800,
+       0x00106ede, 0x497b8880, 0x0201f800, 0x0010a9c0,
+       0x0201f800, 0x0010a9ce, 0x0201f800, 0x00101815,
+       0x4a03504c, 0x00000004, 0x4202d800, 0x00000004,
+       0x4a038805, 0x00000001, 0x42001000, 0x00105058,
+       0x0201f800, 0x00106084, 0x0201f800, 0x001006d4,
+       0x0401f8c1, 0x04000006, 0x42006000, 0xfeffffff,
+       0x41786800, 0x0201f800, 0x0010427d, 0x0201f800,
+       0x00100452, 0x42000000, 0x00000001, 0x0201f800,
+       0x00101590, 0x5c001000, 0x5c000800, 0x1c01f000,
+       0x59c40008, 0x8c000508, 0x04020007, 0x4a038808,
+       0x00000010, 0x4201d000, 0x00001388, 0x0201f800,
+       0x0010608e, 0x1c01f000, 0x4c040000, 0x59a80833,
+       0x82040580, 0x00000000, 0x0400000b, 0x82040580,
+       0x00000001, 0x0400000b, 0x82040580, 0x00000002,
+       0x0400000b, 0x82040580, 0x00000003, 0x0400000b,
+       0x0401f057, 0x4a035017, 0x00000000, 0x0401f009,
+       0x4a035017, 0x00000004, 0x0401f006, 0x4a035017,
+       0x00000001, 0x0401f003, 0x4a035017, 0x00000007,
+       0x497b8880, 0x4a038893, 0x00000001, 0x41780000,
+       0x0201f800, 0x00101606, 0x0201f800, 0x00106ede,
+       0x836c0d80, 0x00000004, 0x04000008, 0x59c40006,
+       0x82000500, 0xffffff0f, 0x82000540, 0x04000001,
+       0x48038806, 0x0401f007, 0x59c40006, 0x82000500,
+       0xffffff0f, 0x82000540, 0x04000000, 0x48038806,
+       0x0401f875, 0x04020005, 0x59c40806, 0x82040d00,
+       0xfbffff0f, 0x48078806, 0x4200b000, 0x00000005,
+       0x59c40005, 0x8c000534, 0x04020033, 0x42006000,
+       0xfc18ffff, 0x42006800, 0x01000000, 0x0201f800,
+       0x0010427d, 0x0201f800, 0x00101937, 0x59c408a4,
+       0x82040d00, 0x0000000f, 0x82040d80, 0x0000000c,
+       0x0400000a, 0x42006000, 0xfeffffff, 0x42006800,
+       0x02000000, 0x0201f800, 0x0010427d, 0x8058b040,
+       0x040207e8, 0x0401f8a1, 0x0401f853, 0x04000006,
+       0x42006000, 0xfeffffff, 0x41786800, 0x0201f800,
+       0x0010427d, 0x836c0d80, 0x00000004, 0x04000006,
+       0x59a8084d, 0x42001000, 0x00105065, 0x0201f800,
+       0x0010606e, 0x4a035033, 0x00000004, 0x0401fe31,
+       0x0401f841, 0x04020008, 0x59c408a4, 0x82040d00,
+       0x0000000f, 0x82040580, 0x0000000c, 0x02020800,
+       0x001005d8, 0x5c000800, 0x1c01f000, 0x4803c856,
+       0x4c000000, 0x0201f800, 0x0010609e, 0x4a035010,
+       0x00ffffff, 0x497b5032, 0x59a8002a, 0x82000500,
+       0xffff0000, 0x4803502a, 0x497b8880, 0x497b8893,
+       0x41780000, 0x0201f800, 0x00101606, 0x59c40001,
+       0x82000500, 0xfffffcff, 0x48038801, 0x42006000,
+       0xfc18ffff, 0x41786800, 0x0201f800, 0x0010427d,
+       0x4a038808, 0x00000000, 0x5c000000, 0x800001c0,
+       0x02020800, 0x0010411d, 0x4a038805, 0x040000f0,
+       0x59c40006, 0x82000500, 0xffffffcf, 0x82000540,
+       0x440000c1, 0x48038806, 0x1c01f000, 0x4c5c0000,
+       0x59a8b832, 0x825cbd80, 0x0000aaaa, 0x5c00b800,
+       0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+       0x00000030, 0x825cbd80, 0x00000000, 0x5c00b800,
+       0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+       0x00000030, 0x825cbd80, 0x00000010, 0x5c00b800,
+       0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+       0x00000030, 0x825cbd80, 0x00000020, 0x5c00b800,
+       0x1c01f000, 0x59a80005, 0x4803c857, 0x82000d00,
+       0x00000013, 0x04000025, 0x599c1017, 0x4d3c0000,
+       0x82000500, 0x00000011, 0x04000007, 0x42027800,
+       0x00000400, 0x0201f800, 0x00103b25, 0x0402000a,
+       0x0401f012, 0x42027800, 0x00000408, 0x0201f800,
+       0x00103b25, 0x0400000d, 0x42003000, 0x00000003,
+       0x0401f003, 0x42003000, 0x00000004, 0x42028000,
+       0x0000000e, 0x0201f800, 0x0010a449, 0x599c1017,
+       0x8c08150a, 0x04020007, 0x42028000, 0x00000004,
+       0x0201f800, 0x00101fe5, 0x80000580, 0x0401f80d,
+       0x5c027800, 0x0401f00a, 0x0201f800, 0x00103b25,
+       0x04000007, 0x42028000, 0x0000000f, 0x42003000,
+       0x00000001, 0x0201f800, 0x0010a449, 0x1c01f000,
+       0x59a80005, 0x04000004, 0x82000540, 0x00000010,
+       0x0401f003, 0x82000500, 0xffffffef, 0x48035005,
+       0x4803c857, 0x1c01f000, 0x4803c856, 0x4c580000,
+       0x42000000, 0x0010b8cb, 0x0201f800, 0x0010aa47,
+       0x42000800, 0x0010c0f1, 0x59c40003, 0x44000800,
+       0x59c40004, 0x48000801, 0x59c4000b, 0x48000802,
+       0x59c4008e, 0x48000803, 0x59c4008f, 0x48000804,
+       0x59c40090, 0x48000805, 0x59c40091, 0x48000806,
+       0x59c40092, 0x48000807, 0x59c40093, 0x48000808,
+       0x59c40099, 0x48000809, 0x59c4009e, 0x4800080a,
+       0x59c400aa, 0x4800080b, 0x59c400af, 0x4800080c,
+       0x59c400b2, 0x4800080d, 0x59c400b1, 0x4800080e,
+       0x82040c00, 0x0000000f, 0x41c41800, 0x4200b000,
+       0x00000030, 0x580c0050, 0x44000800, 0x80040800,
+       0x800c1800, 0x8058b040, 0x040207fb, 0x41c41800,
+       0x4200b000, 0x00000020, 0x580c0010, 0x44000800,
+       0x80040800, 0x800c1800, 0x8058b040, 0x040207fb,
+       0x497b8830, 0x4200b000, 0x00000040, 0x59c40031,
+       0x44000800, 0x80040800, 0x8058b040, 0x040207fc,
+       0x497b88ac, 0x4200b000, 0x00000010, 0x59c400ad,
+       0x44000800, 0x80040800, 0x8058b040, 0x040207fc,
+       0x59c41001, 0x4c080000, 0x8408150c, 0x480b8801,
+       0x4a0370e4, 0x00000300, 0x4a0370e5, 0xb0000000,
+       0x42000800, 0x00000800, 0x80040840, 0x02000800,
+       0x001005d8, 0x59b800e5, 0x8c000538, 0x040207fb,
+       0x4a0370e4, 0x00000200, 0x42006000, 0xffffffff,
+       0x42006800, 0x80000000, 0x0201f800, 0x0010427d,
+       0x4a038807, 0x00000001, 0x497b8807, 0x4a038808,
+       0x00000010, 0x42006000, 0xfcf8ffff, 0x42006800,
+       0x01000000, 0x0201f800, 0x0010427d, 0x5c001000,
+       0x480b8801, 0x42000800, 0x0010c0f1, 0x50040000,
+       0x48038803, 0x58040001, 0x48038804, 0x58040002,
+       0x4803880b, 0x58040003, 0x4803888e, 0x58040004,
+       0x4803888f, 0x58040005, 0x48038890, 0x58040006,
+       0x48038891, 0x58040007, 0x48038892, 0x58040008,
+       0x48038893, 0x58040009, 0x48038899, 0x5804000a,
+       0x4803889e, 0x5804000b, 0x480388aa, 0x5804000c,
+       0x480388af, 0x5804000d, 0x480388b2, 0x5804000e,
+       0x480388b1, 0x82040c00, 0x0000000f, 0x41c41800,
+       0x4200b000, 0x00000030, 0x50040000, 0x48001850,
+       0x80040800, 0x800c1800, 0x8058b040, 0x040207fb,
+       0x41c41800, 0x4200b000, 0x00000020, 0x50040000,
+       0x48001810, 0x80040800, 0x800c1800, 0x8058b040,
+       0x040207fb, 0x497b8830, 0x4200b000, 0x00000040,
+       0x50040000, 0x48038831, 0x80040800, 0x8058b040,
+       0x040207fc, 0x497b88ac, 0x4200b000, 0x00000010,
+       0x50040000, 0x480388ad, 0x80040800, 0x8058b040,
+       0x040207fc, 0x497b8880, 0x41780000, 0x0201f800,
+       0x00101606, 0x59c408a4, 0x82040d00, 0x0000000f,
+       0x82040580, 0x0000000c, 0x02020800, 0x001005d8,
+       0x4a038805, 0x04000000, 0x5c00b000, 0x1c01f000,
+       0x4803c856, 0x4c580000, 0x4ce80000, 0x42000000,
+       0x0010b845, 0x0201f800, 0x0010aa47, 0x59c41008,
+       0x4c080000, 0x82080500, 0xffffff7f, 0x48038808,
+       0x59c40004, 0x82000500, 0x00003e02, 0x04000005,
+       0x4201d000, 0x00000014, 0x0201f800, 0x0010608e,
+       0x59c40006, 0x82000500, 0xffffff0f, 0x48038806,
+       0x4a038805, 0x00000010, 0x4a038808, 0x00000004,
+       0x4200b000, 0x00000065, 0x59c40005, 0x8c000508,
+       0x04020012, 0x4201d000, 0x000003e8, 0x0201f800,
+       0x0010608e, 0x8058b040, 0x040207f8, 0x0201f800,
+       0x00106ede, 0x4a038808, 0x00000008, 0x4a035033,
+       0x00000001, 0x4202d800, 0x00000001, 0x82000540,
+       0x00000001, 0x0401f030, 0x0201f800, 0x00100ae0,
+       0x42000000, 0x0010b8a8, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x00100ef4, 0x497b8880, 0x59a8002a,
+       0x82000500, 0x0000ffff, 0x4c000000, 0x0201f800,
+       0x00101606, 0x5c000000, 0x48038880, 0x4a038808,
+       0x00000000, 0x4200b000, 0x00000065, 0x4a038805,
+       0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+       0x000000f0, 0x59c40005, 0x80040d00, 0x04000008,
+       0x4201d000, 0x000003e8, 0x0201f800, 0x0010608e,
+       0x8058b040, 0x040207f2, 0x0401f7d1, 0x59c40006,
+       0x82000540, 0x000000f0, 0x48038806, 0x59a8001e,
+       0x80000540, 0x04020002, 0x80000000, 0x48038893,
+       0x80000580, 0x5c001000, 0x4df00000, 0x0201f800,
+       0x0010195d, 0x5c03e000, 0x480b8808, 0x5c01d000,
+       0x5c00b000, 0x1c01f000, 0x4803c856, 0x4c580000,
+       0x4ce80000, 0x59c41008, 0x82080500, 0xffffff7f,
+       0x48038808, 0x4c080000, 0x59c40004, 0x82000500,
+       0x00003e02, 0x04000005, 0x4201d000, 0x00000014,
+       0x0201f800, 0x0010608e, 0x0201f800, 0x00100ae0,
+       0x42000000, 0x0010b8a9, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x00100ef4, 0x4a038808, 0x00000002,
+       0x80000580, 0x48038880, 0x48038893, 0x0201f800,
+       0x00101606, 0x4200b000, 0x00000384, 0x4a038805,
+       0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+       0x000000f0, 0x59c40005, 0x80040d00, 0x04000015,
+       0x82000500, 0x000000d0, 0x04020012, 0x4201d000,
+       0x00000067, 0x0201f800, 0x0010608e, 0x8058b040,
+       0x040207ef, 0x0201f800, 0x00106ede, 0x4a038808,
+       0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+       0x00000001, 0x82000540, 0x00000001, 0x0401f010,
+       0x497b8880, 0x59a8001e, 0x80000540, 0x04020002,
+       0x80000000, 0x48038893, 0x59a8002a, 0x82000500,
+       0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606,
+       0x5c000000, 0x48038880, 0x80000580, 0x5c001000,
+       0x4df00000, 0x0201f800, 0x0010195d, 0x5c03e000,
+       0x480b8808, 0x5c01d000, 0x5c00b000, 0x1c01f000,
+       0x4803c856, 0x59c40004, 0x82000500, 0x00003e02,
+       0x0400000a, 0x0201f800, 0x00106ede, 0x4a038808,
+       0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+       0x00000001, 0x0401f052, 0x0201f800, 0x00100ae0,
+       0x42000000, 0x0010b8aa, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x00100ef4, 0x59c40006, 0x84000508,
+       0x48038806, 0x4a038805, 0x00000010, 0x59a80805,
+       0x84040d4c, 0x48075005, 0x42000800, 0x00000064,
+       0x42001000, 0x00105058, 0x0201f800, 0x0010606e,
+       0x4a038808, 0x00000000, 0x497b8880, 0x4a038805,
+       0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+       0x000000f0, 0x59c40005, 0x80040d00, 0x0400000e,
+       0x82000500, 0x000000e0, 0x0402000b, 0x4201d000,
+       0x000003e8, 0x0201f800, 0x0010608e, 0x0201f800,
+       0x00105f48, 0x59940004, 0x80000540, 0x040207ec,
+       0x0401f023, 0x4c080000, 0x42001000, 0x00105065,
+       0x0201f800, 0x00105f90, 0x42001000, 0x00105058,
+       0x0201f800, 0x00106084, 0x5c001000, 0x497b8880,
+       0x59a8001e, 0x80000540, 0x04020002, 0x80000000,
+       0x48038893, 0x59a8002a, 0x82000500, 0x0000ffff,
+       0x4c000000, 0x0201f800, 0x00101606, 0x5c000000,
+       0x48038880, 0x59a80805, 0x84040d0c, 0x48075005,
+       0x59c40006, 0x84000548, 0x48038806, 0x0201f800,
+       0x0010195d, 0x4a038808, 0x00000080, 0x1c01f000,
+       0x4803c856, 0x4d400000, 0x4d3c0000, 0x0201f800,
+       0x00106ede, 0x0201f800, 0x0010ab33, 0x04020025,
+       0x599c1017, 0x59a80805, 0x8c040d00, 0x0402000c,
+       0x8c08151a, 0x0400001f, 0x84040d42, 0x48075005,
+       0x42028000, 0x00000004, 0x42027800, 0x0000000c,
+       0x8c081508, 0x04020008, 0x0401f012, 0x42028000,
+       0x00000004, 0x42027800, 0x00000004, 0x8c081508,
+       0x0400000c, 0x4d400000, 0x42028000, 0x0000000e,
+       0x42028800, 0x0000ffff, 0x0201f800, 0x0010a446,
+       0x5c028000, 0x599c0817, 0x8c040d0a, 0x04020005,
+       0x4943c857, 0x493fc857, 0x0201f800, 0x00101fe5,
+       0x497b8880, 0x4202d800, 0x00000001, 0x0401fcfb,
+       0x5c027800, 0x5c028000, 0x1c01f000, 0x0201f800,
+       0x00100ae0, 0x42000000, 0x0010b8ab, 0x0201f800,
+       0x0010aa47, 0x0201f800, 0x00100ef4, 0x42000000,
+       0x00000001, 0x0201f800, 0x00101606, 0x4a038880,
+       0x00000001, 0x0201f000, 0x0010195d, 0x4202e000,
+       0x00000000, 0x4a033015, 0x00000001, 0x497b301d,
+       0x497b3006, 0x4a03b004, 0x60000001, 0x59d80005,
+       0x4a03b004, 0x90000001, 0x4a03a804, 0x60000001,
+       0x59d40005, 0x4a03a804, 0x90000001, 0x0201f000,
+       0x00105983, 0x4a03c825, 0x00000004, 0x4a03c827,
+       0x00000004, 0x599c0409, 0x80000d40, 0x04000020,
+       0x599c0407, 0x80000540, 0x04000007, 0x800000cc,
+       0x599c100b, 0x80080400, 0x4803b000, 0x497bb002,
+       0x59d80001, 0x599c000b, 0x4803b000, 0x599c000c,
+       0x4803b001, 0x599c0407, 0x80000540, 0x04020002,
+       0x497bb002, 0x599c0c09, 0x82040540, 0x00400000,
+       0x4803b003, 0x4a03b009, 0x00000004, 0x4a03b004,
+       0x10000001, 0x59e00803, 0x82040d00, 0xfffffeff,
+       0x82040d40, 0x00008000, 0x4807c003, 0x599c040a,
+       0x80000540, 0x04000020, 0x599c0408, 0x80000540,
+       0x04000007, 0x800000cc, 0x599c100f, 0x80080400,
+       0x4803a800, 0x497ba802, 0x59d40001, 0x599c000f,
+       0x4803a800, 0x599c0010, 0x4803a801, 0x599c0408,
+       0x80000540, 0x04020002, 0x497ba802, 0x599c0c0a,
+       0x82040540, 0x00400000, 0x4803a803, 0x4a03a809,
+       0x00000004, 0x4a03a804, 0x10000001, 0x59e00803,
+       0x82040d00, 0xfffffbff, 0x82040d40, 0x00008000,
+       0x4807c003, 0x800409c0, 0x04000007, 0x4202e000,
+       0x00000001, 0x0200b800, 0x00020551, 0x0200f000,
+       0x00020566, 0x1c01f000, 0x0201f800, 0x001005d8,
+       0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000,
+       0x59981005, 0x800811c0, 0x0400001e, 0x58080005,
+       0x82000d00, 0x43018780, 0x02020000, 0x00105846,
+       0x8c000508, 0x04000015, 0x580a5808, 0x592c0204,
+       0x497a5800, 0x497a5801, 0x82000500, 0x000000ff,
+       0x82000c80, 0x0000004b, 0x0402100b, 0x0c01f80f,
+       0x5c03e000, 0x83700580, 0x00000003, 0x040007e6,
+       0x0200f800, 0x00020566, 0x0200b000, 0x00020551,
+       0x1c01f000, 0x0401f850, 0x5c03e000, 0x0401f7f9,
+       0x0401f8de, 0x0401f7fd, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x001054a1, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105519, 0x00105491, 0x00105491, 0x001054a1,
+       0x001054a1, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x492fc857, 0x42000000, 0x0010b85e,
+       0x0201f800, 0x0010aa47, 0x42000000, 0x00000400,
+       0x0401f019, 0x492fc857, 0x42000000, 0x0010b85d,
+       0x0201f800, 0x0010aa47, 0x42000000, 0x00001000,
+       0x0401f011, 0x492fc857, 0x42000000, 0x0010b85c,
+       0x0201f800, 0x0010aa47, 0x42000000, 0x00002000,
+       0x0401f009, 0x492fc857, 0x42000000, 0x0010b85f,
+       0x0201f800, 0x0010aa47, 0x42000000, 0x00000800,
+       0x0401f001, 0x4803c857, 0x4202e000, 0x00000001,
+       0x592c0c04, 0x82040d00, 0xffff80ff, 0x80040540,
+       0x48025c04, 0x0201f000, 0x000202da, 0x592c0204,
+       0x492fc857, 0x80000110, 0x040007db, 0x80000040,
+       0x04000025, 0x48033002, 0x492f3003, 0x492f3004,
+       0x4a033008, 0x001054e5, 0x4202e000, 0x00000003,
+       0x1c01f000, 0x592c0204, 0x492fc857, 0x80000110,
+       0x040007cd, 0x80000040, 0x04000033, 0x48033002,
+       0x492f3003, 0x492f3004, 0x4a033008, 0x00105501,
+       0x4202e000, 0x00000003, 0x1c01f000, 0x0201f800,
+       0x0010ab33, 0x02020000, 0x000204d9, 0x42028000,
+       0x00000028, 0x41780800, 0x417a6000, 0x0201f800,
+       0x00104e70, 0x0201f800, 0x001091c6, 0x0201f000,
+       0x000202da, 0x592c0a0a, 0x8c040d02, 0x04020016,
+       0x59a80021, 0x492fc857, 0x80000540, 0x0402000f,
+       0x592c0207, 0x80000540, 0x04000005, 0x0201f800,
+       0x00104326, 0x04020004, 0x1c01f000, 0x42000000,
+       0x00000000, 0x592c0a06, 0x48065c06, 0x48025a06,
+       0x0201f000, 0x000202da, 0x42000000, 0x00000028,
+       0x0401f7f9, 0x42000800, 0x00000009, 0x0201f000,
+       0x0010665b, 0x592c0208, 0x492fc857, 0x82000c80,
+       0x0000199a, 0x040217a4, 0x592c0408, 0x80000540,
+       0x040207a1, 0x59a80821, 0x800409c0, 0x04020009,
+       0x592c0207, 0x80000540, 0x0400079b, 0x497a5a06,
+       0x0201f800, 0x00104385, 0x04020004, 0x1c01f000,
+       0x42000000, 0x00000028, 0x48025a06, 0x0201f000,
+       0x000202da, 0x59980804, 0x59980002, 0x48065800,
+       0x492c0801, 0x492f3004, 0x80000040, 0x48033002,
+       0x04000002, 0x1c01f000, 0x599a5803, 0x59980008,
+       0x4202e000, 0x00000001, 0x0801f000, 0x592e8a06,
+       0x592c0406, 0x4803c856, 0x82000500, 0x000000ff,
+       0x4200b800, 0x00000001, 0x82000d80, 0x00000001,
+       0x04000015, 0x417a8800, 0x4200b800, 0x000007f0,
+       0x82000d80, 0x00000002, 0x0400000f, 0x80000540,
+       0x02020000, 0x000202da, 0x592e8a06, 0x0201f800,
+       0x00020245, 0x02020000, 0x000202da, 0x592e9008,
+       0x592e9809, 0x0201f800, 0x00104713, 0x0201f000,
+       0x000202da, 0x59a80805, 0x84040d00, 0x48075005,
+       0x0201f800, 0x00020245, 0x02000800, 0x0010482c,
+       0x81468800, 0x805cb840, 0x040207fa, 0x0201f000,
+       0x000202da, 0x592c0a08, 0x4807c857, 0x82040580,
+       0x0000000e, 0x04000045, 0x82040580, 0x00000046,
+       0x04000046, 0x82040580, 0x00000045, 0x04000020,
+       0x82040580, 0x00000029, 0x04000010, 0x82040580,
+       0x0000002a, 0x04000009, 0x82040580, 0x0000000f,
+       0x040001fc, 0x82040580, 0x0000002e, 0x040001f9,
+       0x4807c856, 0x0401f1f2, 0x59a80805, 0x84040d04,
+       0x48075005, 0x0401f1f3, 0x592e8a06, 0x0201f800,
+       0x00020245, 0x040201ef, 0x59340200, 0x84000518,
+       0x48026a00, 0x592e6009, 0x4933c857, 0x83300580,
+       0xffffffff, 0x0402002a, 0x0401f1e6, 0x592c1407,
+       0x480bc857, 0x0201f800, 0x00109410, 0x411e6000,
+       0x04020003, 0x4803c856, 0x0401f1d9, 0x592e3809,
+       0x591c1414, 0x84081516, 0x84081554, 0x480a3c14,
+       0x4a026403, 0x0000003a, 0x592c040b, 0x80000540,
+       0x04000007, 0x4a026403, 0x0000003b, 0x592c020c,
+       0x4802641a, 0x592c040c, 0x4802621a, 0x4a026203,
+       0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+       0x00020721, 0x0401f1c7, 0x59a80068, 0x84000510,
+       0x48035068, 0x0401f1c3, 0x592c1207, 0x8c081500,
+       0x040201c0, 0x592e8a06, 0x592e6009, 0x0201f800,
+       0x0010941a, 0x04020003, 0x4803c856, 0x0401f1b4,
+       0x59300c06, 0x82040580, 0x00000004, 0x04000003,
+       0x4803c856, 0x0401f1ae, 0x59300a03, 0x82040580,
+       0x00000007, 0x04000003, 0x4803c856, 0x0401f1a8,
+       0x59300c03, 0x82040580, 0x00000001, 0x04000021,
+       0x82040580, 0x00000003, 0x04000016, 0x82040580,
+       0x00000006, 0x04000020, 0x82040580, 0x00000008,
+       0x04000015, 0x82040580, 0x0000000a, 0x0400000a,
+       0x82040580, 0x0000000c, 0x04000004, 0x82040580,
+       0x0000002e, 0x04020018, 0x42000800, 0x00000009,
+       0x0401f013, 0x42000800, 0x00000005, 0x0401f010,
+       0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406,
+       0x00000001, 0x42000800, 0x00000003, 0x0401f008,
+       0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406,
+       0x00000001, 0x42000800, 0x0000000b, 0x0201f800,
+       0x00104571, 0x4a026203, 0x00000001, 0x0201f800,
+       0x0010672b, 0x0401f17b, 0x40000800, 0x58040000,
+       0x80000540, 0x040207fd, 0x492c0800, 0x1c01f000,
+       0x492fc857, 0x59300c06, 0x82040580, 0x00000006,
+       0x04020094, 0x0201f800, 0x001049e7, 0x04020005,
+       0x59340200, 0x8c00051a, 0x02000000, 0x00020533,
+       0x59340200, 0x8c00050e, 0x0400008a, 0x59300203,
+       0x42027800, 0x00000001, 0x82000580, 0x00000007,
+       0x02020000, 0x00020533, 0x4a026203, 0x00000002,
+       0x0201f000, 0x00020533, 0x42028000, 0x00000002,
+       0x4a026206, 0x00000014, 0x4d2c0000, 0x0201f800,
+       0x0010a1d1, 0x5c025800, 0x59300c06, 0x4807c857,
+       0x82040580, 0x00000007, 0x04020063, 0x492fc857,
+       0x4a025a06, 0x00000001, 0x0201f000, 0x000202da,
+       0x592c240a, 0x492fc857, 0x4813c857, 0x8c10251c,
+       0x04020016, 0x8c10251a, 0x04000003, 0x8c10250a,
+       0x04000069, 0x59340a00, 0x8c040d0e, 0x04000003,
+       0x8c10251e, 0x04000064, 0x0201f800, 0x0002075a,
+       0x0400006b, 0x592c240a, 0x49366009, 0x49325809,
+       0x4a026406, 0x00000006, 0x4a026203, 0x00000007,
+       0x0201f000, 0x0002052f, 0x592c0a0c, 0x5934000f,
+       0x41784000, 0x80001540, 0x0400006d, 0x58080204,
+       0x82000500, 0x000000ff, 0x82000580, 0x00000012,
+       0x04020004, 0x5808020c, 0x80040580, 0x04000004,
+       0x58080000, 0x40084000, 0x0401f7f3, 0x58080000,
+       0x49781000, 0x802041c0, 0x04000006, 0x48004000,
+       0x80000540, 0x04020007, 0x48226810, 0x0401f005,
+       0x4802680f, 0x80000540, 0x04020002, 0x497a6810,
+       0x4d2c0000, 0x400a5800, 0x4a025a06, 0x00000002,
+       0x0201f800, 0x000202da, 0x5c025800, 0x0401f7bc,
+       0x592c040a, 0x8c00051c, 0x04000016, 0x592c0206,
+       0x82000580, 0x0000ffff, 0x04020012, 0x592e6009,
+       0x83300580, 0xffffffff, 0x040007b1, 0x83300480,
+       0x0010d1c0, 0x04001010, 0x59a8000b, 0x81300480,
+       0x0402100d, 0x59300008, 0x800001c0, 0x04020005,
+       0x59300203, 0x82000580, 0x00000007, 0x04000797,
+       0x492fc857, 0x4a025a06, 0x00000029, 0x0201f000,
+       0x000202da, 0x492fc857, 0x4a025a06, 0x00000008,
+       0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06,
+       0x00000045, 0x0201f000, 0x000202da, 0x492fc857,
+       0x4a025a06, 0x0000002a, 0x0201f000, 0x000202da,
+       0x492fc857, 0x4a025a06, 0x00000028, 0x0201f000,
+       0x000202da, 0x492fc857, 0x4a025a06, 0x00000006,
+       0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06,
+       0x0000000e, 0x0201f000, 0x000202da, 0x59340010,
+       0x492e6810, 0x492fc857, 0x80000d40, 0x04000003,
+       0x492c0800, 0x1c01f000, 0x5934040b, 0x492e680f,
+       0x492fc857, 0x4803c857, 0x80000540, 0x04020003,
+       0x4a026a03, 0x00000001, 0x1c01f000, 0x59a8000e,
+       0x81640480, 0x0402176e, 0x42026000, 0x0010d1c0,
+       0x59300009, 0x81340580, 0x04020004, 0x59300202,
+       0x80040580, 0x04000759, 0x83326400, 0x00000024,
+       0x41580000, 0x81300480, 0x040017f6, 0x0401f760,
+       0x492fc857, 0x592c0407, 0x82000c80, 0x0000199a,
+       0x040215f1, 0x592c0204, 0x80000112, 0x040205de,
+       0x592e8a06, 0x0201f800, 0x00020245, 0x04020059,
+       0x0201f800, 0x001049e7, 0x04020059, 0x592e780a,
+       0x493fc857, 0x8d3e7d3e, 0x04020007, 0x59a80021,
+       0x80000540, 0x0402004f, 0x0201f800, 0x00104838,
+       0x040005dd, 0x833c1d00, 0x0000001f, 0x040005da,
+       0x592c0207, 0x82000c80, 0x00001000, 0x040215d6,
+       0x800000c2, 0x800008c4, 0x8005d400, 0x592e9008,
+       0x592e9809, 0x5934080d, 0x800409c0, 0x0402002e,
+       0x833c1d00, 0x0000001f, 0x81780040, 0x80000000,
+       0x800c1902, 0x040217fe, 0x040205c7, 0x0c01f001,
+       0x001056e9, 0x001056ec, 0x001056f9, 0x001056fc,
+       0x001056ff, 0x0201f800, 0x0010903e, 0x0401f01a,
+       0x0201f800, 0x0010480b, 0x04000027, 0x80e9d1c0,
+       0x02020800, 0x00105fae, 0x42028000, 0x00000005,
+       0x417a9000, 0x417a9800, 0x0201f800, 0x0010904e,
+       0x0401f00d, 0x42027000, 0x0000004d, 0x0401f006,
+       0x42027000, 0x0000004e, 0x0401f003, 0x42027000,
+       0x00000052, 0x0201f800, 0x001046c9, 0x02020800,
+       0x0010907e, 0x04000010, 0x8d3e7d3e, 0x04020017,
+       0x1c01f000, 0x58040002, 0x80000540, 0x04020007,
+       0x4d3c0000, 0x40067800, 0x0201f800, 0x001047eb,
+       0x5c027800, 0x040207cb, 0x4a025a06, 0x00000030,
+       0x0401f00d, 0x4a025a06, 0x0000002c, 0x0401f00a,
+       0x4a025a06, 0x00000028, 0x0401f007, 0x4a025a06,
+       0x00000029, 0x0401f004, 0x497a5c09, 0x4a025a06,
+       0x00000000, 0x4a025a04, 0x00000103, 0x0201f000,
+       0x000202da, 0x492fc857, 0x592c0204, 0x80000110,
+       0x80000040, 0x04000002, 0x0401f56f, 0x592c0207,
+       0x82000500, 0x000003ff, 0x48025a07, 0x8c000506,
+       0x04000004, 0x82000500, 0x00000070, 0x04020004,
+       0x59a80821, 0x800409c0, 0x04020018, 0x4a025a06,
+       0x0000dead, 0x592c0408, 0x82000500, 0x0000f0ff,
+       0x48025c08, 0x0201f800, 0x001043b4, 0x04020002,
+       0x1c01f000, 0x49425a06, 0x8058b1c0, 0x04000009,
+       0x0201f800, 0x0010955f, 0x0401f80f, 0x44042800,
+       0x82580580, 0x00000002, 0x04020002, 0x48082801,
+       0x0201f000, 0x000202da, 0x42028000, 0x00000031,
+       0x42000800, 0x00000001, 0x4200b000, 0x00000001,
+       0x0401f7ed, 0x592c0408, 0x80000118, 0x832c2c00,
+       0x00000009, 0x80142c00, 0x1c01f000, 0x492fc857,
+       0x4a025a08, 0x00000006, 0x0201f000, 0x000202da,
+       0x492fc857, 0x4a025a08, 0x00000001, 0x0201f000,
+       0x000202da, 0x492fc857, 0x592c040a, 0x82000500,
+       0x00000003, 0x04000020, 0x0201f800, 0x0002075a,
+       0x04000021, 0x592c0204, 0x492e6008, 0x82000500,
+       0x000000ff, 0x82000580, 0x00000045, 0x0400000e,
+       0x592c000b, 0x0201f800, 0x00105c9a, 0x02000800,
+       0x00020245, 0x04020018, 0x42027000, 0x00000041,
+       0x49366009, 0x4a026406, 0x00000001, 0x0201f000,
+       0x000207a1, 0x59300015, 0x8400055e, 0x48026015,
+       0x42026800, 0x0010b524, 0x42027000, 0x00000040,
+       0x0401f7f4, 0x4a025a06, 0x00000101, 0x0201f000,
+       0x000202da, 0x4a025a06, 0x0000002c, 0x0201f000,
+       0x000202da, 0x4a025a06, 0x00000028, 0x0201f800,
+       0x000202da, 0x0201f000, 0x0002077d, 0x492fc857,
+       0x0201f800, 0x001062e1, 0x0400000b, 0x592c0204,
+       0x80000110, 0x80000040, 0x040204fb, 0x592c0c06,
+       0x800409c0, 0x04000009, 0x42000000, 0x00000102,
+       0x0401f003, 0x42000000, 0x00000104, 0x48025a06,
+       0x0201f000, 0x000202da, 0x592c0c07, 0x800409c0,
+       0x04000024, 0x82040480, 0x00000005, 0x04021021,
+       0x4c040000, 0x80040800, 0x0201f800, 0x00106306,
+       0x5c001000, 0x04020018, 0x832c0400, 0x00000008,
+       0x4000a000, 0x0201f800, 0x0010632f, 0x04020012,
+       0x592c1207, 0x82cc0580, 0x0010b50e, 0x04020009,
+       0x58c80c0b, 0x84040d00, 0x84040d02, 0x8c081500,
+       0x04000002, 0x84040d5e, 0x4805940b, 0x0401f001,
+       0x42000000, 0x00000000, 0x48025a06, 0x0201f000,
+       0x000202da, 0x42000000, 0x00000103, 0x0401f7fb,
+       0x42000000, 0x00000102, 0x0401f7f8, 0x492fc857,
+       0x592e7c06, 0x833c0500, 0xfffffffe, 0x04020043,
+       0x592c4007, 0x42026000, 0x0010d1c0, 0x41581800,
+       0x400c0000, 0x81300480, 0x04021023, 0x59300203,
+       0x82000580, 0x00000000, 0x04000007, 0x59300008,
+       0x80000d40, 0x04000004, 0x58040005, 0x80200580,
+       0x04000004, 0x83326400, 0x00000024, 0x0401f7f1,
+       0x58040204, 0x82000500, 0x000000ff, 0x82000d80,
+       0x00000053, 0x04000007, 0x82000d80, 0x00000048,
+       0x04000004, 0x82000580, 0x00000018, 0x04020023,
+       0x4d2c0000, 0x0201f800, 0x00108be3, 0x5c025800,
+       0x0400001e, 0x4a025a06, 0x00000000, 0x0201f000,
+       0x000202da, 0x592e8a06, 0x83440480, 0x000007f0,
+       0x04021016, 0x83440400, 0x0010ac00, 0x50000000,
+       0x80026d40, 0x04000011, 0x4d2c0000, 0x0201f800,
+       0x001047cb, 0x0400000c, 0x42028000, 0x00000005,
+       0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+       0x001091cc, 0x0201f800, 0x000202da, 0x5c025800,
+       0x0401f7e5, 0x5c025800, 0x4a025a06, 0x00000031,
+       0x0201f000, 0x000202da, 0x492fc857, 0x4d2c0000,
+       0x0201f800, 0x001007e4, 0x04000016, 0x492fc857,
+       0x412f4000, 0x0201f800, 0x001007e4, 0x0400000e,
+       0x492fc857, 0x412dd800, 0x0201f800, 0x00103b28,
+       0x0201f800, 0x00103b32, 0x49a1d80b, 0x5c025800,
+       0x492dd80a, 0x0201f800, 0x00102214, 0x0201f000,
+       0x00102233, 0x41a25800, 0x0201f800, 0x001007f4,
+       0x5c025800, 0x4a025a06, 0x00004005, 0x4a025c06,
+       0x00000002, 0x0201f000, 0x000202da, 0x4807c857,
+       0x485fc857, 0x4200b800, 0x00000001, 0x5c000800,
+       0x4c5c0000, 0x0401f005, 0x4807c857, 0x485fc857,
+       0x5c000800, 0x4d780000, 0x4803c857, 0x492fc857,
+       0x8c00050e, 0x02020800, 0x001005d0, 0x4203e000,
+       0x50000000, 0x4200b800, 0x00008003, 0x0201f000,
+       0x001005dd, 0x592c0204, 0x80000110, 0x80000040,
+       0x04020441, 0x0201f800, 0x00104a34, 0x04020002,
+       0x1c01f000, 0x49425a06, 0x4806580d, 0x480a580e,
+       0x4943c857, 0x4807c857, 0x480bc857, 0x0201f000,
+       0x000202da, 0x592c0204, 0x80000110, 0x80000040,
+       0x04020431, 0x0201f800, 0x00104b8b, 0x04020002,
+       0x1c01f000, 0x49425a06, 0x48065811, 0x480a5812,
+       0x0201f000, 0x000202da, 0x592c0204, 0x80000110,
+       0x04000425, 0x80000040, 0x0402000c, 0x4202e000,
+       0x00000001, 0x592c020a, 0x8c000504, 0x02000000,
+       0x000204d0, 0x592c0207, 0x82000c80, 0x00001001,
+       0x04021429, 0x0401f009, 0x4202e000, 0x00000003,
+       0x48033002, 0x492f3003, 0x492f3004, 0x4a033008,
+       0x000204d0, 0x1c01f000, 0x4202e000, 0x00000002,
+       0x42000000, 0x0010beda, 0x50007000, 0x492c700b,
+       0x4978700e, 0x4978700c, 0x592c0011, 0x592c0812,
+       0x48007007, 0x48047008, 0x592c1013, 0x82080500,
+       0xffff0000, 0x04000003, 0x0201f800, 0x001005d8,
+       0x4978700d, 0x82080480, 0x00000180, 0x4803c857,
+       0x04001007, 0x4800700f, 0x4a007005, 0x00000180,
+       0x4a007004, 0x00000060, 0x0401f005, 0x4978700f,
+       0x48087005, 0x80081104, 0x48087004, 0x5838000a,
+       0x48007003, 0x40381000, 0x0201f000, 0x00100858,
+       0x0201f800, 0x001007d3, 0x04000003, 0x59980007,
+       0x0801f000, 0x1c01f000, 0x40307000, 0x5838000b,
+       0x80025d40, 0x0400001b, 0x58380002, 0x82000580,
+       0x00000100, 0x0400001d, 0x4c380000, 0x592c0204,
+       0x82000500, 0x000000ff, 0x82000580, 0x00000012,
+       0x0400000b, 0x592c0208, 0x8400054e, 0x48025a08,
+       0x4a025a06, 0x00000002, 0x4a025a04, 0x00000103,
+       0x0201f800, 0x000202c1, 0x0401f005, 0x4a025a06,
+       0x00000010, 0x0201f800, 0x000202da, 0x5c007000,
+       0x4202e000, 0x00000001, 0x4a007002, 0x00000100,
+       0x49787010, 0x1c01f000, 0x58380004, 0x82000480,
+       0x00000003, 0x04000087, 0x58380010, 0x8c000500,
+       0x04020019, 0x4200b000, 0x00000003, 0x832cac00,
+       0x00000011, 0x5838000a, 0x5838100d, 0x8008a400,
+       0x4c380000, 0x0201f800, 0x0010ab17, 0x5c007000,
+       0x5838000d, 0x82000400, 0x00000003, 0x4800700d,
+       0x4a007010, 0x00000001, 0x58380004, 0x82000480,
+       0x00000003, 0x48007004, 0x82000580, 0x00000003,
+       0x0400006c, 0x5838000e, 0x80001d40, 0x04020020,
+       0x4c380000, 0x0201f800, 0x001007d3, 0x5c007000,
+       0x04000010, 0x4a025a04, 0x0000010a, 0x42001800,
+       0x00000005, 0x480c700e, 0x5838000c, 0x80000540,
+       0x04020002, 0x5838000b, 0x40000800, 0x492c0801,
+       0x492c700c, 0x42000800, 0x0000000f, 0x0401f011,
+       0x4202e000, 0x00000008, 0x4a033007, 0x00105915,
+       0x1c01f000, 0x4202e000, 0x00000002, 0x42000000,
+       0x0010beda, 0x50007000, 0x0401f7e7, 0x583a580c,
+       0x400c0000, 0x42000800, 0x00000014, 0x80040c80,
+       0x58381004, 0x5838000f, 0x41783000, 0x80000540,
+       0x04020005, 0x84183540, 0x82081480, 0x00000003,
+       0x0400003c, 0x40080000, 0x80040480, 0x04001002,
+       0x40080800, 0x4004b000, 0x412c0000, 0x800c0400,
+       0x4000a800, 0x5838000a, 0x5838100d, 0x8008a400,
+       0x4c080000, 0x4c040000, 0x4c0c0000, 0x4c380000,
+       0x0201f800, 0x0010ab17, 0x5c007000, 0x5c001800,
+       0x5c000800, 0x40040000, 0x58381004, 0x80080480,
+       0x48007004, 0x82000580, 0x00000003, 0x04000002,
+       0x84183500, 0x5c000000, 0x80041400, 0x82080480,
+       0x00000060, 0x04020003, 0x84183542, 0x41781000,
+       0x400c0000, 0x80041c00, 0x820c0480, 0x00000014,
+       0x04020003, 0x84183544, 0x40001800, 0x40080800,
+       0x4804700d, 0x480c700e, 0x40180000, 0x0c01f001,
+       0x00105960, 0x00105964, 0x00105962, 0x00105960,
+       0x001058fc, 0x00105964, 0x00105962, 0x00105960,
+       0x0201f800, 0x001005d8, 0x5838100f, 0x0401f739,
+       0x5838080d, 0x82040400, 0x00000002, 0x5838100a,
+       0x80080400, 0x50001000, 0x800811c0, 0x0402000f,
+       0x4202e000, 0x00000001, 0x583a580b, 0x4978700b,
+       0x49787010, 0x592c0204, 0x82000500, 0x000000ff,
+       0x82000580, 0x00000012, 0x02000000, 0x00020507,
+       0x0201f000, 0x000204d0, 0x5838000a, 0x80040c00,
+       0x82381c00, 0x00000007, 0x54041800, 0x80040800,
+       0x800c1800, 0x54041800, 0x0401f71a, 0x0201f800,
+       0x001007d3, 0x02000800, 0x001005d8, 0x4a02580a,
+       0x0010be79, 0x42000800, 0x0010beda, 0x452c0800,
+       0x497a580b, 0x497a580c, 0x497a580d, 0x497a580e,
+       0x497a580f, 0x4a025809, 0x001058b6, 0x497a5810,
+       0x4a025802, 0x00000100, 0x4a025801, 0x00000001,
+       0x1c01f000, 0x59c80007, 0x8c000502, 0x04000070,
+       0x835c2c80, 0x00000005, 0x02001000, 0x00105f23,
+       0x59c82817, 0x497b9005, 0x82140500, 0x00e00000,
+       0x0402004f, 0x82140500, 0x000003ff, 0x82001c00,
+       0x00000006, 0x41cc2000, 0x42003000, 0x00006080,
+       0x820c0480, 0x00000040, 0x04001006, 0x42001000,
+       0x00000040, 0x820c1c80, 0x00000040, 0x0401f003,
+       0x400c1000, 0x41781800, 0x54182000, 0x80102000,
+       0x80183000, 0x80081040, 0x040207fc, 0x800c19c0,
+       0x04000005, 0x59c80005, 0x80000000, 0x48039005,
+       0x0401f7ea, 0x82140500, 0x01f60000, 0x04020029,
+       0x82140500, 0x0000f000, 0x0400000b, 0x82000c80,
+       0x00002000, 0x0402100f, 0x82140500, 0x0e000000,
+       0x80000132, 0x0c01f840, 0x4a039005, 0x00000140,
+       0x1c01f000, 0x59cc0400, 0x82000500, 0x0000ff00,
+       0x82000580, 0x00008100, 0x040007f4, 0x0401f01c,
+       0x4817c857, 0x82140500, 0x000003ff, 0x04020007,
+       0x59cc0400, 0x82000500, 0x0000ff00, 0x82000580,
+       0x00008100, 0x04020012, 0x42000000, 0x0010b8bd,
+       0x0201f800, 0x0010aa47, 0x0201f800, 0x00105dfa,
+       0x4803c856, 0x4a039005, 0x00000140, 0x0401f020,
+       0x4817c857, 0x82140500, 0x00f60000, 0x04020004,
+       0x0201f800, 0x00105e35, 0x040207d2, 0x0201f800,
+       0x0010513b, 0x04000010, 0x59c400a4, 0x4803c857,
+       0x82000500, 0x0000000f, 0x82000580, 0x0000000a,
+       0x04020009, 0x497b5016, 0x59c400a3, 0x82000540,
+       0x00080000, 0x480388a3, 0x82000500, 0xfff7ffff,
+       0x480388a3, 0x4817c856, 0x0201f800, 0x0010a978,
+       0x4a039005, 0x00000140, 0x0401f842, 0x4803c856,
+       0x1c01f000, 0x00105a1d, 0x00105cf4, 0x00105a15,
+       0x00105a15, 0x00105a15, 0x00105a15, 0x00105a15,
+       0x00105a15, 0x4803c857, 0x42000000, 0x0010b85a,
+       0x0201f800, 0x0010aa47, 0x4a039005, 0x00000140,
+       0x1c01f000, 0x4817c857, 0x59cc0400, 0x4803c857,
+       0x82000d00, 0x0000ff00, 0x82041500, 0x0000f000,
+       0x840409c0, 0x82140500, 0x000003ff, 0x800018c4,
+       0x8c142d14, 0x04000005, 0x59cc0002, 0x82000500,
+       0x00000003, 0x800c1c80, 0x480f5016, 0x82080580,
+       0x00002000, 0x04020011, 0x836c0580, 0x00000001,
+       0x0402000c, 0x59cc0006, 0x82000500, 0xff000000,
+       0x82000580, 0x11000000, 0x04020011, 0x0201f800,
+       0x00103b38, 0x0201f800, 0x00105f48, 0x0401f00c,
+       0x0401f81f, 0x0401f00a, 0x82080580, 0x00003000,
+       0x04020003, 0x0401fa06, 0x0401f005, 0x82080580,
+       0x00008000, 0x04020002, 0x0401fafc, 0x1c01f000,
+       0x4817c857, 0x42000000, 0x0010b859, 0x0201f800,
+       0x0010aa47, 0x836c0580, 0x00000003, 0x0402000b,
+       0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048,
+       0x40141800, 0x80142120, 0x0201f800, 0x00103a3e,
+       0x5c001800, 0x5c001000, 0x1c01f000, 0x4807c857,
+       0x59cc0002, 0x82000500, 0xff000000, 0x82001580,
+       0x01000000, 0x04000004, 0x82001580, 0x23000000,
+       0x04020192, 0x82040580, 0x00000023, 0x0402003f,
+       0x0401fb6a, 0x0400018d, 0x59300c06, 0x82040580,
+       0x00000010, 0x04000013, 0x82040580, 0x00000011,
+       0x04000010, 0x82040580, 0x00000001, 0x0400000d,
+       0x82040580, 0x00000004, 0x0400000a, 0x82040580,
+       0x00000008, 0x04000007, 0x82040580, 0x0000000a,
+       0x04000004, 0x4933c857, 0x4807c857, 0x0401f177,
+       0x59300004, 0x82000500, 0x80010000, 0x04000004,
+       0x0201f800, 0x00106f60, 0x04020170, 0x59cc0a04,
+       0x48066202, 0x59cc0006, 0x82000500, 0xffff0000,
+       0x82000d80, 0x02000000, 0x04020005, 0x42027000,
+       0x00000015, 0x0201f000, 0x000207a1, 0x82000d80,
+       0x02140000, 0x040007fa, 0x82000d80, 0x02100000,
+       0x040007f7, 0x82000d80, 0x02100000, 0x040007f4,
+       0x82000d80, 0x01000000, 0x04020158, 0x59cc0006,
+       0x82000500, 0x0000ffff, 0x04020154, 0x42027000,
+       0x00000016, 0x0401f7ec, 0x82040580, 0x00000022,
+       0x0402014e, 0x59a80806, 0x8c040d14, 0x04000011,
+       0x0401f967, 0x0402000f, 0x0401f97d, 0x0400000d,
+       0x42027000, 0x0000004c, 0x59cc0001, 0x82000500,
+       0x00ffffff, 0x0201f800, 0x00105eec, 0x0400012a,
+       0x42028800, 0x0000ffff, 0x417a6800, 0x0401f126,
+       0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80,
+       0x03000000, 0x04020021, 0x59a80026, 0x8c000508,
+       0x04000017, 0x8400054c, 0x48035026, 0x59cc0800,
+       0x82040d00, 0x00ffffff, 0x48075010, 0x497b8830,
+       0x84040d70, 0x48078832, 0x59c40802, 0x84040d4c,
+       0x48078802, 0x59cc0007, 0x82000500, 0x0000ffff,
+       0x48038893, 0x4803501e, 0x42000800, 0x00000003,
+       0x59a81010, 0x0201f800, 0x00106c78, 0x59cc0006,
+       0x82000500, 0x0000ffff, 0x04020118, 0x42027000,
+       0x00000017, 0x0401f0d9, 0x82000d80, 0x04000000,
+       0x04020011, 0x59cc0006, 0x82000500, 0x0000ffff,
+       0x0402010e, 0x0201f800, 0x0010513b, 0x04000004,
+       0x42027000, 0x0000001d, 0x0401f0cc, 0x59a80026,
+       0x84000548, 0x48035026, 0x42027000, 0x00000030,
+       0x0401f0c6, 0x82000d80, 0x05000000, 0x04020008,
+       0x59cc0006, 0x82000500, 0x0000ffff, 0x040200fb,
+       0x42027000, 0x00000018, 0x0401f0bc, 0x82000d80,
+       0x20100000, 0x04020004, 0x42027000, 0x00000019,
+       0x0401f0b6, 0x82000d80, 0x21100000, 0x04020004,
+       0x42027000, 0x0000001a, 0x0401f0b0, 0x82000d80,
+       0x52000000, 0x04020008, 0x59cc0006, 0x82000500,
+       0x0000ffff, 0x040200e5, 0x42027000, 0x0000001b,
+       0x0401f0a6, 0x82000d80, 0x50000000, 0x04020008,
+       0x59cc0006, 0x82000500, 0x0000ffff, 0x040200db,
+       0x42027000, 0x0000001c, 0x0401f09c, 0x82000d80,
+       0x13000000, 0x04020004, 0x42027000, 0x00000034,
+       0x0401f096, 0x82000d80, 0x12000000, 0x04020008,
+       0x59cc0006, 0x82000500, 0x0000ffff, 0x040200cb,
+       0x42027000, 0x00000024, 0x0401f08c, 0x82000d00,
+       0xff000000, 0x82040d80, 0x24000000, 0x04020004,
+       0x42027000, 0x0000002d, 0x0401f084, 0x82000d00,
+       0xff000000, 0x82040d80, 0x53000000, 0x04020004,
+       0x42027000, 0x0000002a, 0x0401f07c, 0x82000d80,
+       0x0f000000, 0x04020004, 0x42027000, 0x00000020,
+       0x0401f076, 0x82000d80, 0x61040000, 0x04020036,
+       0x83cc1400, 0x00000006, 0x80080800, 0x50080000,
+       0x82000500, 0x0000ffff, 0x82000480, 0x00000004,
+       0x4c580000, 0x8000b104, 0x8058b1c0, 0x04000026,
+       0x4c100000, 0x50041800, 0x820c1500, 0x03000000,
+       0x80081130, 0x42000000, 0x0010b817, 0x82082580,
+       0x00000000, 0x04020004, 0x42000000, 0x0010b814,
+       0x0401f00c, 0x82082580, 0x00000001, 0x04020004,
+       0x42000000, 0x0010b815, 0x0401f006, 0x82082580,
+       0x00000002, 0x04020003, 0x42000000, 0x0010b816,
+       0x0201f800, 0x0010aa47, 0x42001000, 0x00008015,
+       0x820c2500, 0x0000ffff, 0x800c1920, 0x0201f800,
+       0x00103a3e, 0x5c002000, 0x80040800, 0x8058b040,
+       0x040207da, 0x5c00b000, 0x42027000, 0x00000023,
+       0x0401f03e, 0x82000d80, 0x60000000, 0x04020004,
+       0x42027000, 0x0000003f, 0x0401f038, 0x82000d80,
+       0x54000000, 0x04020006, 0x0401fb12, 0x0402006f,
+       0x42027000, 0x00000046, 0x0401f030, 0x82000d80,
+       0x55000000, 0x04020009, 0x0401fb32, 0x04020004,
+       0x42027000, 0x00000041, 0x0401f028, 0x42027000,
+       0x00000042, 0x0401f025, 0x82000d80, 0x78000000,
+       0x04020004, 0x42027000, 0x00000045, 0x0401f01f,
+       0x82000d80, 0x10000000, 0x04020004, 0x42027000,
+       0x0000004e, 0x0401f019, 0x82000d80, 0x63000000,
+       0x04020004, 0x42027000, 0x0000004a, 0x0401f013,
+       0x82000d00, 0xff000000, 0x82040d80, 0x56000000,
+       0x04020004, 0x42027000, 0x0000004f, 0x0401f00b,
+       0x82000d00, 0xff000000, 0x82040d80, 0x57000000,
+       0x04020004, 0x42027000, 0x00000050, 0x0401f003,
+       0x42027000, 0x0000001d, 0x59cc3800, 0x821c3d00,
+       0x00ffffff, 0x821c0580, 0x00fffffe, 0x59cc0001,
+       0x04020005, 0x40003000, 0x42028800, 0x000007fe,
+       0x0401f003, 0x0401f8d1, 0x04020030, 0x0201f800,
+       0x001045a6, 0x0402002d, 0x83380580, 0x00000046,
+       0x04020004, 0x59a80010, 0x80180580, 0x04000027,
+       0x59340200, 0x8c000514, 0x0400000f, 0x83380580,
+       0x00000030, 0x0400000c, 0x83380580, 0x0000003f,
+       0x04000009, 0x83380580, 0x00000034, 0x04000006,
+       0x83380580, 0x00000024, 0x04000003, 0x42027000,
+       0x0000004c, 0x0201f800, 0x0002075a, 0x04000018,
+       0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04,
+       0x48066202, 0x83380580, 0x0000004c, 0x04020009,
+       0x4a026406, 0x00000011, 0x813669c0, 0x04020005,
+       0x59cc0001, 0x82000500, 0x00ffffff, 0x4802601e,
+       0x0201f000, 0x000207a1, 0x59880052, 0x4803c857,
+       0x80000000, 0x48031052, 0x1c01f000, 0x42001000,
+       0x00008049, 0x59cc1806, 0x800c1930, 0x0201f800,
+       0x00103a3e, 0x0201f800, 0x00107942, 0x040007f3,
+       0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04,
+       0x48066202, 0x4a026403, 0x00000009, 0x4a02641a,
+       0x00000009, 0x4a02621a, 0x00002900, 0x4a026203,
+       0x00000001, 0x0201f000, 0x0010672b, 0x59a80026,
+       0x4803c857, 0x8c000508, 0x04000010, 0x59cc0006,
+       0x82000500, 0xff000000, 0x82000d80, 0x03000000,
+       0x0400000c, 0x82000d80, 0x20000000, 0x04000009,
+       0x82000d80, 0x05000000, 0x04000006, 0x82000d80,
+       0x21000000, 0x04000003, 0x80000580, 0x1c01f000,
+       0x82000540, 0x00000001, 0x0401f7fd, 0x59cc2006,
+       0x82102500, 0xff000000, 0x9c1021c0, 0x0401f807,
+       0x820c1c00, 0x0010b4e3, 0x500c1800, 0x800c0500,
+       0x4803c857, 0x1c01f000, 0x40100800, 0x41781800,
+       0x82040480, 0x00000020, 0x04001004, 0x800c1800,
+       0x40000800, 0x0401f7fb, 0x82040500, 0x0000000f,
+       0x82000400, 0x0010ab38, 0x50000000, 0x8c040d08,
+       0x04000002, 0x900001c0, 0x1c01f000, 0x4803c856,
+       0x0401fac3, 0x0402000a, 0x0201f800, 0x0010210a,
+       0x04020007, 0x59cc0002, 0x82000500, 0xff000000,
+       0x82000d80, 0x08000000, 0x04000802, 0x1c01f000,
+       0x4803c856, 0x59cc0400, 0x82000d00, 0x0000ff00,
+       0x840409c0, 0x82040580, 0x00000033, 0x0402001f,
+       0x0401f976, 0x04000038, 0x59cc0a04, 0x48066202,
+       0x59cc0006, 0x4803c857, 0x82000500, 0xffff0000,
+       0x82000d80, 0x02000000, 0x04020009, 0x59cc0006,
+       0x82000500, 0x0000ffff, 0x0402002b, 0x42027000,
+       0x00000015, 0x0201f000, 0x000207a1, 0x82000d80,
+       0x01000000, 0x04020024, 0x59cc0006, 0x82000500,
+       0x0000ffff, 0x04020020, 0x42027000, 0x00000016,
+       0x0201f000, 0x000207a1, 0x82040580, 0x00000032,
+       0x04020019, 0x59cc0006, 0x82000500, 0xffff0000,
+       0x82000d80, 0x14000000, 0x04020013, 0x42027000,
+       0x00000038, 0x59cc0001, 0x0401f810, 0x0402000e,
+       0x0201f800, 0x001045a6, 0x0402000b, 0x0201f800,
+       0x0002075a, 0x04000008, 0x49366009, 0x4a026406,
+       0x00000004, 0x59cc0c04, 0x48066202, 0x0201f000,
+       0x000207a1, 0x1c01f000, 0x4803c857, 0x4c580000,
+       0x4c100000, 0x4c380000, 0x4c340000, 0x82003500,
+       0x00ffffff, 0x82181500, 0x00ff0000, 0x82081580,
+       0x00ff0000, 0x04020016, 0x82181480, 0x00fffffc,
+       0x04001013, 0x82181580, 0x00fffffd, 0x04020004,
+       0x42028800, 0x000007fd, 0x0401f040, 0x82181580,
+       0x00fffffe, 0x04020004, 0x42028800, 0x000007fe,
+       0x0401f03a, 0x82181580, 0x00fffffc, 0x04020004,
+       0x42028800, 0x000007fc, 0x0401f034, 0x41781000,
+       0x42002000, 0x00000000, 0x4200b000, 0x000007f0,
+       0x41ac7000, 0x50380000, 0x80006d40, 0x04020005,
+       0x800811c0, 0x0402001e, 0x8410155e, 0x0401f01c,
+       0x58340212, 0x82000500, 0x0000ff00, 0x04000011,
+       0x59a84010, 0x82204500, 0x00ffff00, 0x82180500,
+       0x00ffff00, 0x04000002, 0x80200580, 0x58340002,
+       0x0402000f, 0x82000500, 0x000000ff, 0x82184500,
+       0x000000ff, 0x80204580, 0x04020009, 0x0401f006,
+       0x58340002, 0x82000500, 0x00ffffff, 0x80184580,
+       0x04020003, 0x40128800, 0x0401f00c, 0x80102000,
+       0x80387000, 0x8058b040, 0x040207db, 0x800811c0,
+       0x04020005, 0x481bc857, 0x82000540, 0x00000001,
+       0x0401f003, 0x840a8d1e, 0x80000580, 0x5c006800,
+       0x5c007000, 0x5c002000, 0x5c00b000, 0x1c01f000,
+       0x59a80026, 0x8c00050e, 0x04000003, 0x8c000502,
+       0x04000006, 0x59cc0c00, 0x80040910, 0x82040500,
+       0x0000000f, 0x0c01f002, 0x1c01f000, 0x00105d0f,
+       0x00105d0f, 0x00105d0f, 0x00105de5, 0x00105d0f,
+       0x00105d11, 0x00105d29, 0x00105d2c, 0x00105d0f,
+       0x00105d0f, 0x00105d0f, 0x00105d0f, 0x00105d0f,
+       0x00105d0f, 0x00105d0f, 0x00105d0f, 0x4803c856,
+       0x1c01f000, 0x0401f8c5, 0x04000014, 0x82140500,
+       0x000003ff, 0x800000c4, 0x82000480, 0x00000008,
+       0x0400100e, 0x59cc0001, 0x59326809, 0x59340802,
+       0x80040580, 0x82000500, 0x00ffffff, 0x04020007,
+       0x59cc0a04, 0x48066202, 0x42027000, 0x00000046,
+       0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857,
+       0x1c01f000, 0x59cc0004, 0x4803c857, 0x1c01f000,
+       0x0401f8aa, 0x04000016, 0x82140500, 0x000003ff,
+       0x800000c4, 0x82000480, 0x0000000c, 0x04001010,
+       0x59cc0001, 0x82000500, 0x00ffffff, 0x59326809,
+       0x59340802, 0x82040d00, 0x00ffffff, 0x80040580,
+       0x04020007, 0x59cc0a04, 0x48066202, 0x42027000,
+       0x00000045, 0x0201f000, 0x000207a1, 0x59cc0004,
+       0x4803c857, 0x1c01f000, 0x4817c857, 0x0401f9c8,
+       0x04020011, 0x0201f800, 0x0010210a, 0x0402000e,
+       0x59cc0002, 0x82000500, 0xff000000, 0x82000580,
+       0x00000000, 0x04020008, 0x82040500, 0x0000000f,
+       0x82000c80, 0x00000006, 0x04021003, 0x4803c857,
+       0x0c01f002, 0x1c01f000, 0x00105d60, 0x00105d64,
+       0x00105d60, 0x00105d60, 0x00105db2, 0x00105dc3,
+       0x4803c857, 0x59cc0004, 0x4803c857, 0x1c01f000,
+       0x59cc0004, 0x4803c857, 0x59a80016, 0x800001c0,
+       0x040207f8, 0x59cc0802, 0x8c040d2e, 0x0402001d,
+       0x0201f800, 0x00107942, 0x02000800, 0x001005d8,
+       0x59cc0001, 0x4803c857, 0x0401ff28, 0x0402000d,
+       0x0201f800, 0x00020245, 0x0402000a, 0x4a026406,
+       0x00000005, 0x49366009, 0x59cc0c04, 0x48066202,
+       0x42027000, 0x00000088, 0x0201f000, 0x000207a1,
+       0x42028800, 0x0000ffff, 0x417a6800, 0x59cc0001,
+       0x82000500, 0x00ffffff, 0x4802601e, 0x0401f7f0,
+       0x59cc0001, 0x4803c857, 0x0401ff10, 0x040207d5,
+       0x0201f800, 0x001045a6, 0x040207d2, 0x59cc0005,
+       0x8c000500, 0x04020004, 0x59340200, 0x8c00050e,
+       0x040207cc, 0x0201f800, 0x001049f3, 0x0402000f,
+       0x0401f83e, 0x040007c7, 0x0201f800, 0x0002075a,
+       0x040007c4, 0x49366009, 0x4a026406, 0x00000002,
+       0x59cc0c04, 0x48066202, 0x42027000, 0x00000088,
+       0x0201f000, 0x000207a1, 0x0201f800, 0x0002075a,
+       0x040007b8, 0x49366009, 0x4a026406, 0x00000004,
+       0x59cc0c04, 0x48066202, 0x42027000, 0x00000001,
+       0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857,
+       0x59cc0802, 0x8c040d2e, 0x0400000b, 0x0401f81f,
+       0x04000009, 0x0401f960, 0x04020007, 0x59cc0a04,
+       0x48066202, 0x42027000, 0x00000089, 0x0201f000,
+       0x000207a1, 0x4933c857, 0x1c01f000, 0x59cc0004,
+       0x4803c857, 0x59cc0802, 0x8c040d2e, 0x0400000b,
+       0x0401f80e, 0x04000009, 0x0401f94f, 0x04020007,
+       0x59cc0a04, 0x48066202, 0x42027000, 0x0000008a,
+       0x0201f000, 0x000207a1, 0x4933c857, 0x1c01f000,
+       0x59cc0a04, 0x0401f002, 0x59cc0c04, 0x59a8000e,
+       0x59a81067, 0x80080400, 0x80040480, 0x04021008,
+       0x40040000, 0x800000c4, 0x800408ca, 0x80040c00,
+       0x82066400, 0x0010d1c0, 0x1c01f000, 0x80000580,
+       0x0401f7fe, 0x59cc0802, 0x8c040d2e, 0x04020010,
+       0x0401ffec, 0x0400000e, 0x59cc0001, 0x82000500,
+       0x00ffffff, 0x59326809, 0x59340802, 0x82040d00,
+       0x00ffffff, 0x80040580, 0x04020005, 0x42027000,
+       0x00000051, 0x0201f000, 0x000207a1, 0x59cc0004,
+       0x4803c857, 0x1c01f000, 0x4803c856, 0x42003000,
+       0x00000105, 0x0401f001, 0x4803c856, 0x4c3c0000,
+       0x41cc7800, 0x0401f803, 0x5c007800, 0x1c01f000,
+       0x4803c856, 0x4c580000, 0x583c0400, 0x82000500,
+       0x0000f000, 0x82000580, 0x0000c000, 0x04000024,
+       0x0201f800, 0x0002075a, 0x04000021, 0x4c180000,
+       0x583c0001, 0x0401fe89, 0x0402001f, 0x0201f800,
+       0x001045a6, 0x0402001c, 0x49366009, 0x0201f800,
+       0x001007e4, 0x04000018, 0x492e6017, 0x497a5800,
+       0x497a5a04, 0x48125c04, 0x832cac00, 0x00000005,
+       0x4200b000, 0x00000007, 0x403ca000, 0x0201f800,
+       0x0010ab17, 0x5c003000, 0x481a641a, 0x4a026403,
+       0x0000003e, 0x4a026406, 0x00000001, 0x4a026203,
+       0x00000001, 0x0201f800, 0x0010672b, 0x5c00b000,
+       0x1c01f000, 0x0201f800, 0x0002077d, 0x5c003000,
+       0x0401f7fb, 0x4803c856, 0x59cc0400, 0x82000d00,
+       0x0000ff00, 0x82040500, 0x0000f000, 0x840409c0,
+       0x82000580, 0x00002000, 0x04020049, 0x82040580,
+       0x00000022, 0x0402003a, 0x59c400a4, 0x82000500,
+       0x0000000f, 0x82000c80, 0x00000007, 0x04001004,
+       0x82000480, 0x0000000c, 0x0400103f, 0x59cc0006,
+       0x82000500, 0xffff0000, 0x82000d80, 0x04000000,
+       0x04000039, 0x82000d80, 0x60000000, 0x04000036,
+       0x82000d80, 0x54000000, 0x04000033, 0x82000d80,
+       0x03000000, 0x04020015, 0x59a80826, 0x8c040d02,
+       0x0402002d, 0x8c040d08, 0x0402002b, 0x0201f800,
+       0x001048ec, 0x0400002b, 0x59a8001d, 0x800000d0,
+       0x59a80810, 0x82040d00, 0x000000ff, 0x80040540,
+       0x59cc0800, 0x82040d00, 0x00ffffff, 0x80040580,
+       0x0402001b, 0x0401f01c, 0x59c40802, 0x8c040d0c,
+       0x04020017, 0x82000d80, 0x52000000, 0x040007ec,
+       0x82000d80, 0x05000000, 0x040007e9, 0x82000d80,
+       0x50000000, 0x040007e6, 0x0401f00d, 0x82040580,
+       0x00000023, 0x0402000a, 0x0401ff58, 0x04000008,
+       0x59300c03, 0x82040580, 0x00000002, 0x04000006,
+       0x82040580, 0x00000051, 0x04000003, 0x80000580,
+       0x0401f003, 0x82000540, 0x00000001, 0x1c01f000,
+       0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80,
+       0x03000000, 0x04000004, 0x82000d80, 0x52000000,
+       0x040207f3, 0x59a80026, 0x82000500, 0x00000009,
+       0x82000580, 0x00000008, 0x040007ef, 0x0401f7ec,
+       0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016,
+       0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807,
+       0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00,
+       0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00,
+       0x00000002, 0x83cc1400, 0x0000000d, 0x0201f800,
+       0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a,
+       0x4200b000, 0x00000002, 0x83a81c00, 0x00000000,
+       0x83cc1400, 0x0000000f, 0x0201f800, 0x0010855a,
+       0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540,
+       0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000,
+       0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016,
+       0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807,
+       0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00,
+       0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00,
+       0x00000002, 0x83cc1400, 0x00000009, 0x0201f800,
+       0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a,
+       0x4200b000, 0x00000002, 0x83a81c00, 0x00000000,
+       0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+       0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540,
+       0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000,
+       0x4803c857, 0x4c580000, 0x40003000, 0x42002000,
+       0x000007f0, 0x4200b000, 0x00000010, 0x83ac7400,
+       0x000007f0, 0x50380000, 0x80026d40, 0x04000006,
+       0x59340002, 0x82000500, 0x00ffffff, 0x80180580,
+       0x04000010, 0x80102000, 0x80387000, 0x8058b040,
+       0x040207f5, 0x82100480, 0x00000800, 0x42002000,
+       0x00000000, 0x4200b000, 0x000007f0, 0x41ac7000,
+       0x040217ed, 0x82000540, 0x00000001, 0x0401f002,
+       0x40128800, 0x5c00b000, 0x1c01f000, 0x59a80026,
+       0x8c00050e, 0x04000004, 0x8c000502, 0x04000003,
+       0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+       0x0401f7fd, 0x59300c06, 0x82040580, 0x00000002,
+       0x04000006, 0x82040580, 0x00000005, 0x04000003,
+       0x82000540, 0x00000001, 0x1c01f000, 0x59c80000,
+       0x84000558, 0x84000512, 0x48039000, 0x1c01f000,
+       0x4a03281a, 0x000003e8, 0x4a032802, 0x0010d1c0,
+       0x4a032800, 0x00000000, 0x4a032808, 0x00107049,
+       0x42000000, 0x00000005, 0x83947c00, 0x00000009,
+       0x49787801, 0x4a007802, 0x00106fff, 0x823c7c00,
+       0x00000003, 0x80000040, 0x040207fa, 0x4a032819,
+       0xffff0000, 0x4201d000, 0x00000064, 0x0401f96e,
+       0x4201d000, 0x000186a0, 0x0401f184, 0x00000000,
+       0x00000003, 0x00000006, 0x00000009, 0x0000000c,
+       0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000,
+       0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000,
+       0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000,
+       0x4c640000, 0x4cc80000, 0x4ccc0000, 0x0201f800,
+       0x0002057b, 0x5c019800, 0x5c019000, 0x5c00c800,
+       0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800,
+       0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800,
+       0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000,
+       0x1c01f000, 0x59940004, 0x80000540, 0x0402000a,
+       0x59940025, 0x80040400, 0x02001800, 0x001005d8,
+       0x48032804, 0x480b2805, 0x4a032803, 0x0000000a,
+       0x80000580, 0x1c01f000, 0x5994001f, 0x80000540,
+       0x0402000a, 0x59940025, 0x80040400, 0x02001800,
+       0x001005d8, 0x4803281f, 0x480b2820, 0x4a03281e,
+       0x00000001, 0x80000580, 0x1c01f000, 0x59940022,
+       0x80000540, 0x0402000a, 0x59940025, 0x80040400,
+       0x02001800, 0x001005d8, 0x48032822, 0x480b2823,
+       0x4a032821, 0x0000000a, 0x80000580, 0x1c01f000,
+       0x4c000000, 0x59940005, 0x4803c857, 0x480bc857,
+       0x80080580, 0x04020003, 0x497b2804, 0x497b2805,
+       0x5c000000, 0x1c01f000, 0x4c000000, 0x59940020,
+       0x4803c857, 0x480bc857, 0x80080580, 0x04020003,
+       0x497b281f, 0x497b2820, 0x5c000000, 0x1c01f000,
+       0x4c000000, 0x59940023, 0x4803c857, 0x480bc857,
+       0x80080580, 0x04020003, 0x497b2822, 0x497b2823,
+       0x5c000000, 0x1c01f000, 0x4937c857, 0x48ebc857,
+       0x59340203, 0x80e80480, 0x04001002, 0x48ea6a03,
+       0x1c01f000, 0x5c03e000, 0x1c01f000, 0x4d440000,
+       0x42007800, 0x00000010, 0x59968801, 0x0201f800,
+       0x00020245, 0x04020012, 0x59341a03, 0x800c1840,
+       0x0400100f, 0x59940027, 0x800c0480, 0x04000003,
+       0x48026a03, 0x0402100a, 0x5934000f, 0x497a6a03,
+       0x80000540, 0x04000006, 0x4c3c0000, 0x5934140b,
+       0x0201f800, 0x00020253, 0x5c007800, 0x81468800,
+       0x83440480, 0x00000800, 0x04021007, 0x803c7840,
+       0x040207e7, 0x49472801, 0x5c028800, 0x5c03e000,
+       0x1c01f000, 0x4a032800, 0x00000002, 0x497b2801,
+       0x0401f7fa, 0x42007800, 0x00000010, 0x59966002,
+       0x59300205, 0x80000d40, 0x04000006, 0x59940027,
+       0x80040480, 0x48026205, 0x0400102d, 0x0400002c,
+       0x59300206, 0x80000d40, 0x04000014, 0x59b800e4,
+       0x8c000524, 0x04020011, 0x4a0370e4, 0x00030000,
+       0x40000000, 0x59b800e4, 0x8c000524, 0x04000004,
+       0x4a0370e4, 0x00020000, 0x0401f008, 0x59940027,
+       0x80040480, 0x48026206, 0x4a0370e4, 0x00020000,
+       0x0400101c, 0x0400001b, 0x83326400, 0x00000024,
+       0x49332802, 0x41540000, 0x81300480, 0x04021005,
+       0x803c7840, 0x040207db, 0x5c03e000, 0x1c01f000,
+       0x59940026, 0x48032827, 0x4a032802, 0x0010d1c0,
+       0x497b2826, 0x80000540, 0x0400000f, 0x4a032800,
+       0x00000001, 0x5c03e000, 0x1c01f000, 0x4c3c0000,
+       0x0201f800, 0x001091db, 0x5c007800, 0x0401f7d1,
+       0x4c3c0000, 0x0201f800, 0x00108d5d, 0x5c007800,
+       0x0401f7e2, 0x4a032800, 0x00000000, 0x5c03e000,
+       0x1c01f000, 0x59a8086b, 0x8c040d30, 0x04020029,
+       0x8c040d32, 0x0400000f, 0x59a80069, 0x81640480,
+       0x04001019, 0x59a8000b, 0x81500580, 0x04000005,
+       0x59a8006a, 0x59a81066, 0x80080580, 0x04020012,
+       0x900411c0, 0x82081500, 0x00007000, 0x0401f012,
+       0x82040500, 0x0000001f, 0x04000016, 0x80040840,
+       0x82040500, 0x0000001f, 0x04000003, 0x4807506b,
+       0x0401f010, 0x900401c0, 0x82000500, 0x0000001f,
+       0x80040d40, 0x900401c0, 0x80040580, 0x82001500,
+       0x00007000, 0x82040500, 0xffff8fff, 0x80080540,
+       0x4803506b, 0x80081114, 0x0201f800, 0x001006e2,
+       0x1c01f000, 0x4a032807, 0x000007d0, 0x4a032806,
+       0x0000000a, 0x1c01f000, 0x42000800, 0x000007d0,
+       0x83180480, 0x00000005, 0x02021800, 0x001005d8,
+       0x83947c00, 0x00000009, 0x83180400, 0x00105f43,
+       0x50000000, 0x803c7c00, 0x48047801, 0x4a007800,
+       0x0000000a, 0x1c01f000, 0x83180480, 0x00000005,
+       0x02021800, 0x001005d8, 0x83947c00, 0x00000009,
+       0x83180400, 0x00105f43, 0x50000000, 0x803c7c00,
+       0x49787801, 0x1c01f000, 0x4807c857, 0x480bc857,
+       0x59940025, 0x80040400, 0x02001800, 0x001005d8,
+       0x48032804, 0x480b2805, 0x4a032803, 0x0000000a,
+       0x1c01f000, 0x4807c857, 0x480bc857, 0x59940025,
+       0x80040400, 0x02001800, 0x001005d8, 0x4803281c,
+       0x480b281d, 0x4a03281b, 0x0000000a, 0x1c01f000,
+       0x4c000000, 0x5994001d, 0x4803c857, 0x480bc857,
+       0x80080580, 0x04020003, 0x4803281c, 0x4803281d,
+       0x5c000000, 0x1c01f000, 0x80e9d1c0, 0x0400000e,
+       0x0401f836, 0x04025000, 0x4203e000, 0x80000000,
+       0x40e81000, 0x41780800, 0x42000000, 0x00000064,
+       0x0201f800, 0x001066a0, 0x59940024, 0x80080400,
+       0x48032824, 0x1c01f000, 0x42001000, 0x00105065,
+       0x0401fef0, 0x42001000, 0x00105058, 0x0401ffe1,
+       0x42001000, 0x00104148, 0x0401feea, 0x42001000,
+       0x001041bc, 0x0401fee7, 0x42001000, 0x001041f3,
+       0x0401f6f8, 0x4203e000, 0x70000000, 0x4203e000,
+       0xb0300000, 0x41fc0000, 0x40ebf800, 0x80e80480,
+       0x04001011, 0x04000004, 0x82000480, 0x00000003,
+       0x0402100d, 0x42000000, 0x0000000f, 0x04004004,
+       0x80000040, 0x040207fe, 0x0401f007, 0x4203e000,
+       0x70000000, 0x42000000, 0x0010b87e, 0x0201f800,
+       0x0010aa47, 0x1c01f000, 0x4203e000, 0x80000000,
+       0x4203e000, 0xb0400000, 0x41fc0000, 0x40ebf800,
+       0x80e80480, 0x04001011, 0x04000004, 0x82000480,
+       0x00000003, 0x0402100d, 0x42000000, 0x0000000f,
+       0x04005004, 0x80000040, 0x040207fe, 0x0401f007,
+       0x4203e000, 0x80000000, 0x42000000, 0x0010b87f,
+       0x0201f800, 0x0010aa47, 0x1c01f000, 0x59a8000e,
+       0x82000480, 0x00000100, 0x599c0a02, 0x800409c0,
+       0x04020002, 0x80040800, 0x80041480, 0x04001002,
+       0x40000800, 0x48075067, 0x59a8100e, 0x40040000,
+       0x800acc80, 0x4967500e, 0x49675069, 0x59aaa80b,
+       0x41640800, 0x42001000, 0x00000024, 0x0201f800,
+       0x00106681, 0x8206a400, 0x0010d1c0, 0x49535065,
+       0x4152b000, 0x42006000, 0x0010be65, 0x4a006004,
+       0x0000012c, 0x4a006005, 0xda10da10, 0x4a006008,
+       0x00000011, 0x4a006009, 0x0010be65, 0x4a00600a,
+       0x001010b8, 0x599c0014, 0x48006011, 0x599c0015,
+       0x48006012, 0x42006000, 0x0010be41, 0x4a006203,
+       0x00000008, 0x4a006406, 0x00000006, 0x4a006002,
+       0xffff0000, 0x4a006008, 0x0010be65, 0x4a006014,
+       0x0010be65, 0x599c0014, 0x48006015, 0x599c0015,
+       0x48006016, 0x599c0413, 0x48006017, 0x49506018,
+       0x49546019, 0x59a80067, 0x4800601a, 0x4a00601b,
+       0x0010b465, 0x4a00601c, 0x0010b466, 0x4a00601d,
+       0x0010b46a, 0x42000000, 0xb0000000, 0x42000800,
+       0x0010be41, 0x0201f800, 0x00100b68, 0x1c01f000,
+       0x82000d00, 0x000000c0, 0x04000004, 0x82040d80,
+       0x000000c0, 0x04020055, 0x82000d00, 0x00002020,
+       0x59300414, 0x84000512, 0x82040d80, 0x00002020,
+       0x0400000b, 0x8c000514, 0x0402000f, 0x48026414,
+       0x813e79c0, 0x02020000, 0x000206d0, 0x42027000,
+       0x00000043, 0x0201f000, 0x000207a1, 0x59326809,
+       0x59340a00, 0x8c040d0a, 0x040007f3, 0x84000552,
+       0x0401f7f1, 0x84000514, 0x592c080d, 0x48066015,
+       0x0401f7ef, 0x59326809, 0x59340a00, 0x8c040d0a,
+       0x02000000, 0x000206e3, 0x59300c14, 0x84040d52,
+       0x48066414, 0x0201f000, 0x000206e3, 0x0201f800,
+       0x00020086, 0x813e79c0, 0x02020000, 0x000206d0,
+       0x0201f000, 0x000206f1, 0x8c00051e, 0x02000000,
+       0x000206fd, 0x82000d00, 0x00002020, 0x82040d80,
+       0x00002020, 0x04000014, 0x82000500, 0x000000c0,
+       0x82000d80, 0x00000080, 0x04000008, 0x813e79c0,
+       0x02020000, 0x000206d0, 0x42027000, 0x00000041,
+       0x0201f000, 0x000207a1, 0x813e79c0, 0x02020000,
+       0x000206d0, 0x42027000, 0x00000043, 0x0201f000,
+       0x000207a1, 0x59326809, 0x59340a00, 0x8c040d0a,
+       0x040007ea, 0x59300c14, 0x84040d52, 0x48066414,
+       0x0401f7e6, 0x492fc857, 0x42000800, 0x00000006,
+       0x0201f000, 0x000206f8, 0x492fc857, 0x42000800,
+       0x00000004, 0x0201f000, 0x000206f8, 0x4807c856,
+       0x59a80068, 0x800409c0, 0x04000003, 0x80080540,
+       0x0401f002, 0x80080500, 0x48035068, 0x1c01f000,
+       0x4a030800, 0x00000000, 0x4a030802, 0x00000001,
+       0x497b0803, 0x497b0804, 0x1c01f000, 0x59840002,
+       0x8c000500, 0x04000004, 0x84000500, 0x4a030800,
+       0x00000001, 0x84000544, 0x84000506, 0x48030802,
+       0x82000d00, 0x0fffffff, 0x42000000, 0x90000000,
+       0x0201f800, 0x00100b94, 0x59a80069, 0x82000480,
+       0x00000007, 0x48035069, 0x80000580, 0x42000800,
+       0x0010b519, 0x48000800, 0x48000801, 0x1c01f000,
+       0x59a80069, 0x82000480, 0x00000007, 0x48035069,
+       0x1c01f000, 0x83640480, 0x00000008, 0x0400101b,
+       0x58c80a03, 0x80000580, 0x82000400, 0x00000008,
+       0x80040840, 0x040207fd, 0x815c0480, 0x04001013,
+       0x4200b000, 0x00000007, 0x0201f800, 0x0002075a,
+       0x4a026203, 0x00000004, 0x4a026406, 0x00000009,
+       0x4a026203, 0x00000004, 0x4a026007, 0x00000101,
+       0x0401f809, 0x0401f880, 0x8058b040, 0x040207f3,
+       0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+       0x0401f7fd, 0x0201f800, 0x001007e4, 0x492e6008,
+       0x58c80a03, 0x4a025a04, 0x0000002c, 0x497a5800,
+       0x497a5801, 0x497a5c04, 0x497a5c06, 0x497a5805,
+       0x4a025a08, 0x00000005, 0x4a025a07, 0x00000002,
+       0x58c80201, 0x48025c04, 0x58c80202, 0x48025c07,
+       0x58c80204, 0x48025c08, 0x4a02580d, 0x0000ffff,
+       0x80040840, 0x0400000c, 0x412c2000, 0x0201f800,
+       0x001007e4, 0x4a025a04, 0x0000000a, 0x497a5c04,
+       0x48125800, 0x492c2001, 0x412c2000, 0x80040840,
+       0x040207f7, 0x1c01f000, 0x4d7c0000, 0x4202f800,
+       0x00000010, 0x4df00000, 0x4203e000, 0x50000000,
+       0x59847803, 0x803c79c0, 0x0400001e, 0x4c5c0000,
+       0x583cb808, 0x585c3408, 0x801831c0, 0x0400000b,
+       0x0401f84a, 0x04000016, 0x42001000, 0x0010b519,
+       0x0401f87f, 0x04000012, 0x0201f800, 0x001007d3,
+       0x0400000f, 0x492cb805, 0x585c0005, 0x80000540,
+       0x02000800, 0x001005d8, 0x0401f830, 0x585c5408,
+       0x0401f80b, 0x5c00b800, 0x5c03e000, 0x817ef840,
+       0x040207e1, 0x5c02f800, 0x1c01f000, 0x5c00b800,
+       0x5c03e000, 0x5c02f800, 0x1c01f000, 0x4803c856,
+       0x405c6000, 0x802851c0, 0x04000018, 0x585c0204,
+       0x82000d00, 0x0000000f, 0x82040c00, 0x001010bd,
+       0x50044000, 0x4cf00000, 0x4d000000, 0x4d040000,
+       0x4021e000, 0x40320800, 0x59860004, 0x4c280000,
+       0x0401f934, 0x5c005000, 0x40f04000, 0x41046000,
+       0x0201f800, 0x0010109b, 0x040207f6, 0x5c020800,
+       0x5c020000, 0x5c01e000, 0x58c80204, 0x4800bc08,
+       0x0201f800, 0x00020086, 0x4a026007, 0x00000101,
+       0x497a6009, 0x0401f055, 0x4803c856, 0x59840003,
+       0x80026540, 0x04000003, 0x59300000, 0x48030803,
+       0x1c01f000, 0x4803c856, 0x59840003, 0x48026000,
+       0x49330803, 0x1c01f000, 0x58cc0805, 0x40180000,
+       0x80040480, 0x0400100d, 0x82cc0580, 0x0010b50e,
+       0x02020800, 0x001005d8, 0x58c80205, 0x80040480,
+       0x0400101d, 0x82000540, 0x00000001, 0x1c01f000,
+       0x80003580, 0x0401f7fe, 0x82cc0580, 0x0010b50e,
+       0x02020800, 0x001005d8, 0x58c80400, 0x8c000504,
+       0x040007f8, 0x58c8040b, 0x8c00051e, 0x040007f5,
+       0x8c000500, 0x040207f3, 0x84000540, 0x4801940b,
+       0x42000000, 0x0010b839, 0x0201f800, 0x0010aa47,
+       0x42001000, 0x00008026, 0x0201f800, 0x00103a3e,
+       0x0401f7e8, 0x58c8040b, 0x8c00051e, 0x040007e2,
+       0x8c000502, 0x040207e0, 0x84000542, 0x4801940b,
+       0x42000000, 0x0010b838, 0x0201f800, 0x0010aa47,
+       0x42001000, 0x00008025, 0x42001800, 0x00000000,
+       0x0201f800, 0x00103a3e, 0x0401f7d3, 0x4803c856,
+       0x58080000, 0x42001800, 0x00000007, 0x58080801,
+       0x80040480, 0x04020004, 0x400c0000, 0x80000540,
+       0x0401f005, 0x04001003, 0x800c0480, 0x0401f002,
+       0x80000080, 0x1c01f000, 0x4803c856, 0x59300008,
+       0x80000d40, 0x02000800, 0x001005d8, 0x58040005,
+       0x80000540, 0x02000800, 0x001005d8, 0x59300007,
+       0x82000500, 0x00000101, 0x82000580, 0x00000101,
+       0x02020800, 0x001005d8, 0x42001000, 0x0010b519,
+       0x58080801, 0x82040400, 0x0010b51b, 0x497a6414,
+       0x4a026015, 0x0000ffff, 0x45300000, 0x80040800,
+       0x82040480, 0x00000008, 0x04001002, 0x80000d80,
+       0x48041001, 0x82040400, 0x0010b51b, 0x45780000,
+       0x1c01f000, 0x4933c857, 0x59300808, 0x800409c0,
+       0x02000800, 0x001005d8, 0x4d2c0000, 0x58065805,
+       0x812e59c0, 0x02020800, 0x001007f4, 0x49780805,
+       0x40065800, 0x0201f800, 0x001007fd, 0x5c025800,
+       0x4d300000, 0x0201f800, 0x0002077d, 0x5c026000,
+       0x1c01f000, 0x59300406, 0x82000580, 0x00000009,
+       0x04020006, 0x59300007, 0x8c000510, 0x04000003,
+       0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+       0x1c01f000, 0x59840802, 0x8c040d04, 0x1c01f000,
+       0x4803c856, 0x59840802, 0x84040d04, 0x84040d40,
+       0x4a030800, 0x00000000, 0x48070802, 0x82040d00,
+       0x0fffffff, 0x42000000, 0x90000000, 0x0201f000,
+       0x00100b94, 0x4807c857, 0x4805980a, 0x49799801,
+       0x49799803, 0x49799806, 0x49799807, 0x49799808,
+       0x49799805, 0x49799809, 0x0401f8c9, 0x0400000a,
+       0x0401f8eb, 0x04000008, 0x48359800, 0x48359802,
+       0x48359806, 0x4a019804, 0x00000001, 0x4a019807,
+       0x00000005, 0x1c01f000, 0x4807c857, 0x58cc1007,
+       0x40040000, 0x80080480, 0x04021020, 0x4c040000,
+       0x4c080000, 0x0401f8da, 0x5c001000, 0x5c000800,
+       0x0400001c, 0x58cc0006, 0x80006540, 0x0402000b,
+       0x48359800, 0x48359802, 0x48359806, 0x49799801,
+       0x49799803, 0x49786801, 0x49786800, 0x49799804,
+       0x49799807, 0x0401f005, 0x48306801, 0x48346000,
+       0x48359806, 0x49786800, 0x58cc0004, 0x58cc1007,
+       0x80000000, 0x82081400, 0x00000005, 0x48019804,
+       0x48099807, 0x0401f7df, 0x80000580, 0x1c01f000,
+       0x82000540, 0x00000001, 0x1c01f000, 0x480bc857,
+       0x4c500000, 0x4c540000, 0x4c580000, 0x40083000,
+       0x58cc0801, 0x82040480, 0x00000005, 0x02021800,
+       0x001005d8, 0x82040400, 0x00106418, 0x50000000,
+       0x58cca800, 0x8054ac00, 0x42001800, 0x00000005,
+       0x40040000, 0x800c0480, 0x80082480, 0x04021002,
+       0x40080000, 0x8000b0c2, 0x8058b400, 0x5450a800,
+       0x8050a000, 0x8054a800, 0x8058b040, 0x040207fc,
+       0x40001000, 0x58cc2805, 0x58cc0807, 0x58cc2001,
+       0x80142c00, 0x80040c80, 0x80102400, 0x48159805,
+       0x48059807, 0x48119801, 0x82100580, 0x00000005,
+       0x0400000c, 0x48119801, 0x40080000, 0x80181480,
+       0x40083000, 0x04000003, 0x040217d6, 0x80000580,
+       0x5c00b000, 0x5c00a800, 0x5c00a000, 0x1c01f000,
+       0x58cc0800, 0x800409c0, 0x02000800, 0x001005d8,
+       0x58040800, 0x48059800, 0x41782000, 0x0401f7ee,
+       0x0401f813, 0x50f00000, 0x81040400, 0x40001800,
+       0x585c0204, 0x4803c857, 0x82000580, 0x0000002c,
+       0x02020800, 0x001005d8, 0x58040202, 0x800000e0,
+       0x81000540, 0x48001802, 0x58040000, 0x48001800,
+       0x58040001, 0x48001801, 0x1c01f000, 0x4807c856,
+       0x58cc0005, 0x80000040, 0x02001800, 0x001005d8,
+       0x48019805, 0x58cc1003, 0x82080480, 0x00000005,
+       0x02021800, 0x001005d8, 0x82080400, 0x00106418,
+       0x50000000, 0x58cc0802, 0x80040c00, 0x80081000,
+       0x82080480, 0x00000005, 0x0402000f, 0x58cc2002,
+       0x58100000, 0x80006d40, 0x04000009, 0x4c340000,
+       0x0401f858, 0x5c006800, 0x49786801, 0x48359802,
+       0x58cc0004, 0x80000040, 0x48019804, 0x49799803,
+       0x0401f002, 0x48099803, 0x1c01f000, 0x4807c856,
+       0x41781800, 0x58c80201, 0x80000540, 0x04000002,
+       0x800c1800, 0x58c80c01, 0x80040c80, 0x0400100a,
+       0x04000009, 0x800c1800, 0x58c80202, 0x80041480,
+       0x04001005, 0x04000004, 0x800c1800, 0x40080800,
+       0x0401f7fb, 0x480d9204, 0x400c0000, 0x42002000,
+       0x00000001, 0x80000040, 0x04000007, 0x04001006,
+       0x80102000, 0x82000480, 0x00000005, 0x04000002,
+       0x040217fc, 0x48119203, 0x1c01f000, 0x4807c856,
+       0x4d2c0000, 0x58cc000a, 0x80000540, 0x02000800,
+       0x001005d8, 0x82002400, 0x00000005, 0x0201f800,
+       0x001007d3, 0x04000012, 0x492d9809, 0x497a5800,
+       0x497a5801, 0x0201f800, 0x001007d3, 0x0400000c,
+       0x58cc0009, 0x48025800, 0x497a5801, 0x492d9809,
+       0x82102480, 0x00000005, 0x040217f7, 0x82000540,
+       0x00000001, 0x5c025800, 0x1c01f000, 0x58cc0009,
+       0x80025d40, 0x040007fc, 0x592c2000, 0x0201f800,
+       0x001007f4, 0x40100000, 0x0401f7fa, 0x58cc0009,
+       0x48cfc857, 0x80006d40, 0x04000005, 0x50340000,
+       0x48019809, 0x49786800, 0x49786801, 0x1c01f000,
+       0x4813c857, 0x58cc0009, 0x48002000, 0x48119809,
+       0x1c01f000, 0x4807c856, 0x4d2c0000, 0x58cc0009,
+       0x80025d40, 0x04000007, 0x592c0000, 0x4c000000,
+       0x0201f800, 0x001007f4, 0x5c000000, 0x0401f7f9,
+       0x5c025800, 0x1c01f000, 0x4807c856, 0x4d2c0000,
+       0x58cc0002, 0x80025d40, 0x04000007, 0x592c0000,
+       0x4c000000, 0x0201f800, 0x001007f4, 0x5c000000,
+       0x0401f7f9, 0x49799800, 0x49799802, 0x49799801,
+       0x49799803, 0x49799806, 0x49799807, 0x49799808,
+       0x49799809, 0x4979980a, 0x5c025800, 0x1c01f000,
+       0x00000003, 0x00000006, 0x00000009, 0x0000000c,
+       0x0000000f, 0x00000012, 0x4803c856, 0x0401f857,
+       0x4a00c204, 0x0000003c, 0x59301009, 0x82080580,
+       0x0010b524, 0x04000013, 0x58080802, 0x82040d00,
+       0x00ffffff, 0x58080403, 0x4804c005, 0x4800c406,
+       0x4a00c207, 0x00000003, 0x59300811, 0x585c0404,
+       0x4978c206, 0x4804c407, 0x80000540, 0x0400000d,
+       0x58600206, 0x84000540, 0x4800c206, 0x0401f009,
+       0x585c080a, 0x82040d00, 0x00ffffff, 0x4804c005,
+       0x4a00c406, 0x000007ff, 0x4978c207, 0x0401f7ef,
+       0x82603c00, 0x00000008, 0x58605404, 0x40282000,
+       0x405c6000, 0x585c0a04, 0x82040d00, 0x0000000f,
+       0x82040c00, 0x001010bd, 0x50044000, 0x80004d80,
+       0x50200000, 0x80307400, 0x58380402, 0x8c244d00,
+       0x04020003, 0x48003a00, 0x0401f003, 0x48003c00,
+       0x801c3800, 0x80244800, 0x80102040, 0x04000006,
+       0x0201f800, 0x0010109b, 0x02000800, 0x001005d8,
+       0x0401f7f0, 0x1c01f000, 0x4803c856, 0x4d340000,
+       0x59300009, 0x80026d40, 0x02000800, 0x001005d8,
+       0x59340401, 0x80000540, 0x0400000e, 0x59840000,
+       0x80000540, 0x0400000b, 0x836c0580, 0x00000003,
+       0x04020008, 0x59341c03, 0x42002000, 0x00000004,
+       0x42003000, 0x00000004, 0x0201f800, 0x00103aae,
+       0x5c026800, 0x1c01f000, 0x4803c856, 0x80001580,
+       0x58c80c01, 0x59300011, 0x80040c80, 0x48066011,
+       0x58c80201, 0x80000540, 0x04000005, 0x80081000,
+       0x80040c80, 0x04001007, 0x04000006, 0x58c80202,
+       0x80081000, 0x80040c80, 0x04001002, 0x040207fd,
+       0x4808bc08, 0x4808c404, 0x1c01f000, 0x4803c856,
+       0x4a0370e5, 0x00020000, 0x59b800e5, 0x8c000524,
+       0x040207fc, 0x4a0370e5, 0x00030000, 0x40000000,
+       0x40000000, 0x59b800e5, 0x8c000524, 0x040207f5,
+       0x5934000e, 0x80006d40, 0x04000010, 0x81300580,
+       0x04020004, 0x58340000, 0x4802680e, 0x0401f00a,
+       0x40347800, 0x58340000, 0x80006d40, 0x02000800,
+       0x001005d8, 0x81300580, 0x040207fa, 0x58340000,
+       0x48007800, 0x497a6000, 0x4a0370e5, 0x00020000,
+       0x1c01f000, 0x4803c856, 0x4d300000, 0x4d2c0000,
+       0x42000800, 0x000003ff, 0x4a0370e5, 0x00020000,
+       0x59b800e5, 0x8c000524, 0x04000005, 0x80040840,
+       0x040207fa, 0x0201f800, 0x001005d8, 0x4a0370e5,
+       0x00030000, 0x40000000, 0x40000000, 0x59b800e5,
+       0x8c000524, 0x040207f1, 0x5934000e, 0x80026540,
+       0x0400000e, 0x4933c857, 0x59300000, 0x4802680e,
+       0x4a026203, 0x00000004, 0x497a6206, 0x497a6009,
+       0x4a026007, 0x00000101, 0x59325808, 0x497a5c08,
+       0x0401fd81, 0x0401f7f1, 0x4a0370e5, 0x00020000,
+       0x5c025800, 0x5c026000, 0x1c01f000, 0x4803c856,
+       0x4c000000, 0x0201f800, 0x00105c9a, 0x04020011,
+       0x0201f800, 0x001045a6, 0x02020800, 0x001005d8,
+       0x5c000000, 0x48026802, 0x0201f800, 0x0002075a,
+       0x04000009, 0x49366009, 0x4a026406, 0x00000001,
+       0x42027000, 0x00000001, 0x0201f000, 0x000207a1,
+       0x5c000000, 0x1c01f000, 0x59300203, 0x82000c80,
+       0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+       0x0c01f001, 0x00106503, 0x00106503, 0x00106503,
+       0x00106505, 0x00106565, 0x00106503, 0x00106503,
+       0x001065b7, 0x001065b8, 0x00106503, 0x00106503,
+       0x00106503, 0x00106503, 0x00106503, 0x0201f800,
+       0x001005d8, 0x493bc857, 0x83380480, 0x00000050,
+       0x02021800, 0x001005d8, 0x83380480, 0x00000049,
+       0x02001800, 0x001005d8, 0x0c01f001, 0x00106518,
+       0x0010653a, 0x00106516, 0x00106516, 0x00106516,
+       0x00106516, 0x00106549, 0x0201f800, 0x001005d8,
+       0x4d2c0000, 0x59325808, 0x592c0206, 0x48025c06,
+       0x4a025a06, 0x00000000, 0x4c5c0000, 0x592cbc0a,
+       0x592c0000, 0x48026008, 0x0201f800, 0x00104cde,
+       0x59300008, 0x80000540, 0x04000008, 0x4a026203,
+       0x00000007, 0x42027000, 0x00000043, 0x5c00b800,
+       0x5c025800, 0x0401f08a, 0x8c5cbd08, 0x04020006,
+       0x4a026203, 0x00000007, 0x497a6206, 0x497a6008,
+       0x0401f003, 0x0201f800, 0x0002077d, 0x5c00b800,
+       0x5c025800, 0x1c01f000, 0x0201f800, 0x00106b8a,
+       0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+       0x04000006, 0x4d400000, 0x42028000, 0x00000001,
+       0x0401f8f8, 0x5c028000, 0x5c025800, 0x0201f000,
+       0x0002077d, 0x0201f800, 0x00106b8a, 0x4d3c0000,
+       0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+       0x42003000, 0x00000014, 0x0201f800, 0x0010a942,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+       0x04000006, 0x4d400000, 0x42028000, 0x00000029,
+       0x0401f8dc, 0x5c028000, 0x5c025800, 0x0201f000,
+       0x0002077d, 0x493bc857, 0x497a6206, 0x83380480,
+       0x00000054, 0x02021800, 0x001005d8, 0x83380480,
+       0x00000047, 0x02001800, 0x001005d8, 0x0c01f001,
+       0x001065b6, 0x0010657f, 0x0010657d, 0x0010657d,
+       0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d,
+       0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d,
+       0x00106583, 0x0201f800, 0x001005d8, 0x59300011,
+       0x82000500, 0xffff0000, 0x04020034, 0x59840802,
+       0x8c040d04, 0x04000025, 0x59300009, 0x80026d40,
+       0x0400001f, 0x4c5c0000, 0x4c600000, 0x497a6206,
+       0x5930b808, 0x585c0005, 0x8000c540, 0x02000800,
+       0x001005d8, 0x0401fe8d, 0x40625800, 0x0201f800,
+       0x00104cde, 0x4978b805, 0x0401fef5, 0x497a6009,
+       0x585c3408, 0x0401fcbd, 0x0400000e, 0x42001000,
+       0x0010b519, 0x0401fcf2, 0x0400000a, 0x0201f800,
+       0x001007e4, 0x04000007, 0x492cb805, 0x585c5408,
+       0x0401fc83, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+       0x0401fca9, 0x0401f7fc, 0x8c040d06, 0x040207fc,
+       0x59300009, 0x80026d40, 0x04000006, 0x5934000e,
+       0x80000540, 0x02020800, 0x001005d8, 0x497a6009,
+       0x0401fd0d, 0x0401f7f2, 0x0401f06f, 0x4803c856,
+       0x4803c856, 0x83380580, 0x00000043, 0x02020800,
+       0x001005d8, 0x4a026203, 0x00000003, 0x493a6403,
+       0x59325808, 0x592c000f, 0x48026011, 0x497a6013,
+       0x592c0406, 0x800000c2, 0x800010c4, 0x80081400,
+       0x480a6206, 0x0201f800, 0x00100f4e, 0x42000800,
+       0x80000060, 0x0401f154, 0x42000000, 0x0010b875,
+       0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80,
+       0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+       0x82000d80, 0x00000003, 0x04000006, 0x82000d80,
+       0x00000004, 0x04000045, 0x0201f800, 0x001005d8,
+       0x0201f800, 0x00106c55, 0x59300004, 0x8c00053e,
+       0x04020007, 0x0201f800, 0x00106b6c, 0x02020800,
+       0x001005d8, 0x0201f000, 0x00106c4b, 0x0401f9c3,
+       0x0201f800, 0x00106c4b, 0x59325808, 0x42028000,
+       0x00000006, 0x0401f84b, 0x0201f000, 0x0002077d,
+       0x4803c856, 0x59300203, 0x82000c80, 0x0000000e,
+       0x02021800, 0x001005d8, 0x82000d80, 0x00000003,
+       0x04000006, 0x82000d80, 0x00000004, 0x04000023,
+       0x0201f800, 0x001005d8, 0x4803c856, 0x0201f800,
+       0x00106c55, 0x4df00000, 0x59300004, 0x8c00053e,
+       0x04020006, 0x0201f800, 0x00106f60, 0x02020800,
+       0x001005d8, 0x0401f010, 0x0201f800, 0x00108cd6,
+       0x04020004, 0x0201f800, 0x00106e62, 0x0402000a,
+       0x0401f99a, 0x02020800, 0x001005d8, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x82000540, 0x00000001,
+       0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b,
+       0x80000580, 0x1c01f000, 0x4933c857, 0x0201f800,
+       0x00100e99, 0x4933c857, 0x4c5c0000, 0x4d340000,
+       0x497a6206, 0x5930b808, 0x59300009, 0x80026d40,
+       0x04020e5f, 0x42001000, 0x0010b519, 0x0401fc60,
+       0x04000009, 0x58c80204, 0x4800bc08, 0x41785000,
+       0x0201f800, 0x00106227, 0x5c026800, 0x5c00b800,
+       0x1c01f000, 0x4978bc08, 0x0401fc17, 0x0401f7fb,
+       0x4803c856, 0x0201f800, 0x00109037, 0x0400000f,
+       0x592c0000, 0x80000d40, 0x04000009, 0x497a5800,
+       0x49425a06, 0x4c040000, 0x0201f800, 0x000202da,
+       0x5c000800, 0x40065800, 0x0401f7f6, 0x49425a06,
+       0x0201f800, 0x000202da, 0x1c01f000, 0x4933c857,
+       0x59300c06, 0x82040580, 0x0000000e, 0x04000004,
+       0x82040580, 0x00000009, 0x04020004, 0x0401ffe5,
+       0x497a6008, 0x80000580, 0x1c01f000, 0x592e6009,
+       0x83300480, 0x0010d1c0, 0x04001016, 0x41580000,
+       0x81300480, 0x04021013, 0x40040000, 0x59300c06,
+       0x80040580, 0x04020012, 0x59300a03, 0x82040580,
+       0x00000007, 0x02020800, 0x001005d8, 0x59300008,
+       0x80000540, 0x02020800, 0x001005d8, 0x0201f800,
+       0x0002077d, 0x42000000, 0x00000000, 0x0401f009,
+       0x42000000, 0x00000008, 0x0401f006, 0x82040580,
+       0x00000007, 0x040207fb, 0x42000000, 0x00000005,
+       0x592c0a06, 0x48065c06, 0x48025a06, 0x0201f000,
+       0x000202da, 0x4c0c0000, 0x4c100000, 0x4c140000,
+       0x4c180000, 0x80001d80, 0x80002580, 0x42003000,
+       0x00000020, 0x82040500, 0x00000001, 0x04000003,
+       0x40080000, 0x800c1c00, 0x400c2800, 0x800c1902,
+       0x80102102, 0x82140500, 0x00000001, 0x04000003,
+       0x82102540, 0x80000000, 0x80040902, 0x80183040,
+       0x040207f1, 0x40100800, 0x400c0000, 0x5c003000,
+       0x5c002800, 0x5c002000, 0x5c001800, 0x1c01f000,
+       0x4c580000, 0x4200b000, 0x00000020, 0x80000540,
+       0x04000018, 0x80041c80, 0x04021016, 0x800810c2,
+       0x80040982, 0x04001006, 0x80041c80, 0x04021005,
+       0x8058b040, 0x040207fa, 0x0401f006, 0x80041c80,
+       0x400c0800, 0x80081000, 0x8058b040, 0x040207f4,
+       0x4c000000, 0x41f00000, 0x82000500, 0xf7ffffff,
+       0x4003e000, 0x5c000000, 0x5c00b000, 0x1c01f000,
+       0x4c000000, 0x41f00000, 0x82000540, 0x08000000,
+       0x0401f7f8, 0x4a0378e8, 0x00000000, 0x4a03c821,
+       0x00000010, 0x4a03c823, 0x00000004, 0x0401f82c,
+       0x4a0378e9, 0x00003a0d, 0x4a0378e8, 0x00000001,
+       0x42000000, 0x00001000, 0x50000000, 0x82000480,
+       0x24220001, 0x04000004, 0x59e00002, 0x84000548,
+       0x4803c002, 0x42000800, 0x00000005, 0x4203a000,
+       0x00007600, 0x42000000, 0x00001000, 0x50000000,
+       0x82000480, 0x24320001, 0x04021003, 0x4a03a005,
+       0xd0000001, 0x59d00006, 0x4a03a005, 0x90000001,
+       0x83d3a400, 0x00000020, 0x80040840, 0x040207fa,
+       0x59e00003, 0x82000500, 0xffffffe0, 0x82000540,
+       0x00008000, 0x4803c003, 0x59c40006, 0x82000500,
+       0xfffcffff, 0x48038806, 0x1c01f000, 0x4d900000,
+       0x4d180000, 0x4a0378e7, 0xaaaaaaaa, 0x4a0378e6,
+       0xaaaaaaaa, 0x4a0378e5, 0xaaaaaaaa, 0x4a0378e4,
+       0xaaaaaaaa, 0x42000800, 0x0000bf00, 0x4a00081a,
+       0x0010b7d4, 0x4a00081b, 0x001010bd, 0x4a00081c,
+       0x001010cd, 0x4a031800, 0x00000000, 0x4a031801,
+       0x0010b544, 0x4a031802, 0x0010b54b, 0x42000800,
+       0x0010b7d7, 0x417a3000, 0x811b20c8, 0x83932400,
+       0x0000bf32, 0x48072000, 0x4a032001, 0x00000000,
+       0x83180400, 0x001070ea, 0x50000000, 0x48032002,
+       0x82040c00, 0x00000003, 0x811a3000, 0x83180480,
+       0x00000005, 0x040017f1, 0x5c023000, 0x5c032000,
+       0x1c01f000, 0x48066004, 0x497a6000, 0x497a6001,
+       0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400,
+       0xa0000000, 0x480378e1, 0x1c01f000, 0x4933c857,
+       0x42000800, 0x80000040, 0x48066004, 0x497a6000,
+       0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400,
+       0x60000000, 0x480378e1, 0x1c01f000, 0x0201f800,
+       0x00106c55, 0x4df00000, 0x4d300000, 0x4d340000,
+       0x4d2c0000, 0x4d180000, 0x4c5c0000, 0x4c600000,
+       0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+       0x42003000, 0x0000bf2e, 0x581a6001, 0x813261c0,
+       0x0400002c, 0x41302800, 0x4178c000, 0x59300000,
+       0x4c000000, 0x59326809, 0x5930b801, 0x59300406,
+       0x82000d80, 0x00000006, 0x04020003, 0x8d3e7d18,
+       0x04000010, 0x8d3e7d06, 0x04000007, 0x82000580,
+       0x00000003, 0x04020004, 0x59340200, 0x8c00050e,
+       0x04020008, 0x0401f92f, 0x4c0c0000, 0x4c140000,
+       0x0401fb5f, 0x5c002800, 0x5c001800, 0x0401f005,
+       0x41301800, 0x8060c1c0, 0x04020002, 0x400cc000,
+       0x805cb9c0, 0x04000003, 0x405e6000, 0x0401f7e3,
+       0x5c026000, 0x813261c0, 0x04000006, 0x8060c1c0,
+       0x04000002, 0x40602800, 0x4178c000, 0x0401f7d8,
+       0x417a3000, 0x0201f800, 0x001070d8, 0x59926004,
+       0x813261c0, 0x04000023, 0x59326809, 0x4130c000,
+       0x59300001, 0x8000bd40, 0x04000016, 0x40026000,
+       0x40602800, 0x5930b801, 0x59300406, 0x82000d80,
+       0x00000006, 0x0400000e, 0x8d3e7d06, 0x04000007,
+       0x82000580, 0x00000003, 0x04020004, 0x59340200,
+       0x8c00050e, 0x04020006, 0x0401f8dc, 0x4c140000,
+       0x0401fb2f, 0x5c002800, 0x0401f002, 0x41302800,
+       0x405e6000, 0x813261c0, 0x040207eb, 0x8060c1c0,
+       0x04000004, 0x40626000, 0x4178c000, 0x0401f7e7,
+       0x811a3000, 0x83180480, 0x00000005, 0x040017d6,
+       0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+       0x5c00c000, 0x5c00b800, 0x5c023000, 0x5c025800,
+       0x5c026800, 0x5c026000, 0x5c03e000, 0x02000800,
+       0x00106c4b, 0x1c01f000, 0x4933c857, 0x0201f800,
+       0x00106c55, 0x4df00000, 0x4d340000, 0x4d180000,
+       0x4d900000, 0x42003000, 0x0000bf2e, 0x59326809,
+       0x58182001, 0x40102800, 0x801021c0, 0x04000016,
+       0x41300000, 0x80100580, 0x04000011, 0x58100009,
+       0x81340580, 0x0402000b, 0x40101800, 0x58102001,
+       0x41300000, 0x801021c0, 0x0400000b, 0x80100d80,
+       0x04000007, 0x40101800, 0x58102001, 0x0401f7fa,
+       0x40102800, 0x58102000, 0x0401f7ec, 0x0401f8bd,
+       0x0401f01a, 0x42032000, 0x0000bf32, 0x417a3000,
+       0x59902004, 0x40102800, 0x801021c0, 0x0400000b,
+       0x58100009, 0x81340580, 0x04020008, 0x41300000,
+       0x80100580, 0x0400000c, 0x40102800, 0x58102001,
+       0x801021c0, 0x040207fa, 0x811a3000, 0x83180480,
+       0x00000005, 0x0402100d, 0x83932400, 0x00000010,
+       0x0401f7ec, 0x0401f881, 0x5c032000, 0x5c023000,
+       0x5c026800, 0x5c03e000, 0x02000800, 0x00106c4b,
+       0x80000580, 0x1c01f000, 0x0401fb6f, 0x040007f7,
+       0x5c032000, 0x5c023000, 0x5c026800, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x82000540, 0x00000001,
+       0x1c01f000, 0x0201f800, 0x00106c55, 0x4df00000,
+       0x4d300000, 0x4d340000, 0x4d180000, 0x4d2c0000,
+       0x4c5c0000, 0x4c600000, 0x4d900000, 0x4dd00000,
+       0x4da40000, 0x4d140000, 0x42003000, 0x0000bf2e,
+       0x581a6001, 0x813261c0, 0x04000023, 0x41302800,
+       0x5930b800, 0x59326809, 0x59340403, 0x81440580,
+       0x04000006, 0x805cb9c0, 0x0400001b, 0x41302800,
+       0x405e6000, 0x0401f7f7, 0x5930b801, 0x8d3e7d00,
+       0x04000003, 0x0401fb67, 0x0402000e, 0x59300406,
+       0x82000580, 0x00000006, 0x04020003, 0x8d3e7d18,
+       0x04000008, 0x0401f867, 0x4c0c0000, 0x4c140000,
+       0x0401fa97, 0x5c002800, 0x5c001800, 0x0401f002,
+       0x41301800, 0x405e6000, 0x813261c0, 0x040207eb,
+       0x0401f02d, 0x417a3000, 0x0201f800, 0x001070d8,
+       0x59926004, 0x813261c0, 0x04000005, 0x59326809,
+       0x59340403, 0x81440580, 0x04000006, 0x811a3000,
+       0x83180480, 0x00000005, 0x040017f4, 0x0401f01e,
+       0x4130c000, 0x59300001, 0x8000bd40, 0x04000012,
+       0x40026000, 0x40602800, 0x5930b801, 0x8d3e7d00,
+       0x04000003, 0x0401fb3b, 0x0402000a, 0x59300406,
+       0x82000580, 0x00000006, 0x04000006, 0x0401f81b,
+       0x4c140000, 0x0401fa6e, 0x5c002800, 0x0401f002,
+       0x41302800, 0x405e6000, 0x813261c0, 0x040207ef,
+       0x8060c1c0, 0x04000004, 0x40626000, 0x4178c000,
+       0x0401f7eb, 0x5c022800, 0x5c034800, 0x5c03a000,
+       0x5c032000, 0x5c00c000, 0x5c00b800, 0x5c025800,
+       0x5c023000, 0x5c026800, 0x5c026000, 0x5c03e000,
+       0x04000be3, 0x1c01f000, 0x0401fbc8, 0x59900004,
+       0x81300580, 0x04020018, 0x4c140000, 0x0201f800,
+       0x00106dc3, 0x0401fbb8, 0x5c002800, 0x59300001,
+       0x800001c0, 0x04020003, 0x497a680c, 0x1c01f000,
+       0x42003000, 0x0000bf2e, 0x497a6001, 0x58180801,
+       0x800409c0, 0x04020004, 0x48003000, 0x48003001,
+       0x1c01f000, 0x58180800, 0x48000800, 0x48003000,
+       0x1c01f000, 0x59300001, 0x48002801, 0x800001c0,
+       0x04020002, 0x4816680c, 0x497a6001, 0x1c01f000,
+       0x0401fba6, 0x42003000, 0x0000bf2e, 0x58180001,
+       0x81300580, 0x0402001c, 0x59300801, 0x800409c0,
+       0x0400000e, 0x59300000, 0x800001c0, 0x04020005,
+       0x48043001, 0x48043000, 0x497a6001, 0x1c01f000,
+       0x59300000, 0x48000800, 0x48043001, 0x497a6000,
+       0x497a6001, 0x1c01f000, 0x59300800, 0x800409c0,
+       0x04020005, 0x49783001, 0x49783000, 0x497a680c,
+       0x1c01f000, 0x48043001, 0x497a6000, 0x497a680c,
+       0x1c01f000, 0x58180000, 0x81300580, 0x0402000c,
+       0x59300001, 0x800001c0, 0x04020005, 0x48143000,
+       0x49782800, 0x497a680c, 0x1c01f000, 0x48003000,
+       0x48002800, 0x497a6001, 0x1c01f000, 0x59300000,
+       0x800001c0, 0x04020008, 0x59300001, 0x48001801,
+       0x800001c0, 0x04020002, 0x480e680c, 0x497a6001,
+       0x1c01f000, 0x59300801, 0x800409c0, 0x04020006,
+       0x59300800, 0x48042800, 0x497a6000, 0x497a680c,
+       0x1c01f000, 0x59300000, 0x48000800, 0x48042800,
+       0x497a6000, 0x497a6001, 0x1c01f000, 0x0401fb82,
+       0x4df00000, 0x0401f839, 0x040208c4, 0x04020945,
+       0x04020a89, 0x04020005, 0x5c03e000, 0x04000b70,
+       0x80000580, 0x1c01f000, 0x5c03e000, 0x04000b6c,
+       0x82000540, 0x00000001, 0x1c01f000, 0x4d2c0000,
+       0x4d340000, 0x4d300000, 0x41783000, 0x598e6009,
+       0x813261c0, 0x04000021, 0x59300406, 0x82000580,
+       0x00000006, 0x04020004, 0x8d3e7d18, 0x0402000a,
+       0x0401f017, 0x82040580, 0x00000005, 0x04020006,
+       0x8d3e7d16, 0x04000004, 0x59300420, 0x8c000500,
+       0x0402000f, 0x0401fa4e, 0x59300000, 0x4c000000,
+       0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7,
+       0x04000005, 0x0401f867, 0x4c180000, 0x0401f9bc,
+       0x5c003000, 0x5c026000, 0x0401f7e2, 0x41303000,
+       0x59326000, 0x0401f7df, 0x5c026000, 0x5c026800,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+       0x813261c0, 0x02000800, 0x001005d8, 0x41300000,
+       0x598cb809, 0x41783000, 0x805cb9c0, 0x04000013,
+       0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800,
+       0x0401f7fa, 0x0401f84b, 0x598c000d, 0x81300580,
+       0x02000800, 0x001070b9, 0x59300403, 0x82000580,
+       0x00000042, 0x04020002, 0x497a6007, 0x80000580,
+       0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001,
+       0x5c00b800, 0x1c01f000, 0x0401fb27, 0x4df00000,
+       0x4d2c0000, 0x4d340000, 0x4d300000, 0x41783000,
+       0x598e6009, 0x813261c0, 0x0400002c, 0x59300c06,
+       0x82040580, 0x00000006, 0x04020004, 0x8d3e7d18,
+       0x0402000a, 0x0401f022, 0x82040580, 0x00000005,
+       0x04020006, 0x8d3e7d18, 0x04000004, 0x59300420,
+       0x8c000500, 0x0402001a, 0x59326809, 0x59340403,
+       0x81440580, 0x04020016, 0x8d3e7d00, 0x04000006,
+       0x82040580, 0x00000003, 0x04020011, 0x0401fa35,
+       0x0402000f, 0x0401f9f6, 0x59300000, 0x4c000000,
+       0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7,
+       0x04000005, 0x0401f80f, 0x4c180000, 0x0401f964,
+       0x5c003000, 0x5c026000, 0x0401f7d7, 0x41303000,
+       0x59326000, 0x0401f7d4, 0x5c026000, 0x5c026800,
+       0x5c025800, 0x5c03e000, 0x04000ae5, 0x1c01f000,
+       0x59300800, 0x497a6000, 0x0401fac8, 0x801831c0,
+       0x04020009, 0x598c0008, 0x81300580, 0x04020004,
+       0x48031808, 0x48031809, 0x0401f008, 0x48071809,
+       0x0401f006, 0x48043000, 0x598c0008, 0x81300580,
+       0x04020002, 0x481b1808, 0x0401f2ca, 0x4d2c0000,
+       0x4d300000, 0x4d340000, 0x41783000, 0x598e600b,
+       0x813261c0, 0x04000013, 0x8d3e7d06, 0x04000005,
+       0x59326809, 0x59340200, 0x8c00050e, 0x0402000a,
+       0x0401f9bf, 0x59300000, 0x4c000000, 0x0401f853,
+       0x4c180000, 0x0401f932, 0x5c003000, 0x5c026000,
+       0x0401f7f0, 0x41303000, 0x59326000, 0x0401f7ed,
+       0x0201f800, 0x00104773, 0x5c026800, 0x5c026000,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+       0x813261c0, 0x02000800, 0x001005d8, 0x41300000,
+       0x598cb80b, 0x41783000, 0x805cb9c0, 0x0400000f,
+       0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800,
+       0x0401f7fa, 0x0401f835, 0x598c000d, 0x81300580,
+       0x02000800, 0x001070b9, 0x497a6007, 0x80000580,
+       0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001,
+       0x5c00b800, 0x1c01f000, 0x0401fa9f, 0x4df00000,
+       0x4d340000, 0x4d300000, 0x4d2c0000, 0x0201f800,
+       0x00020245, 0x02020800, 0x001005d8, 0x41783000,
+       0x598e600b, 0x813261c0, 0x04000014, 0x59300009,
+       0x81340580, 0x0402000e, 0x8d3e7d00, 0x04000003,
+       0x0401f9bc, 0x0402000a, 0x0401f97d, 0x59300000,
+       0x4c000000, 0x0401f811, 0x4c180000, 0x0401f8f0,
+       0x5c003000, 0x5c026000, 0x0401f7ef, 0x41303000,
+       0x59326000, 0x0401f7ec, 0x0201f800, 0x0010479c,
+       0x5c025800, 0x5c026000, 0x5c026800, 0x5c03e000,
+       0x04000a6f, 0x1c01f000, 0x59300800, 0x497a6000,
+       0x0401fa52, 0x801831c0, 0x04020009, 0x598c000a,
+       0x81300580, 0x04020004, 0x4803180a, 0x4803180b,
+       0x0401f008, 0x4807180b, 0x0401f006, 0x48043000,
+       0x598c000a, 0x81300580, 0x04020002, 0x481b180a,
+       0x0401f254, 0x0401fa64, 0x4df00000, 0x4d300000,
+       0x598e6005, 0x813261c0, 0x04000020, 0x59300000,
+       0x4c000000, 0x59300c06, 0x82040580, 0x00000011,
+       0x04020007, 0x833c0500, 0x00001800, 0x04000015,
+       0x8d3e7d16, 0x04020013, 0x0401f009, 0x82040580,
+       0x00000004, 0x04020006, 0x8d3e7d16, 0x04000004,
+       0x59300420, 0x8c000500, 0x0402000a, 0x0201f800,
+       0x0010914e, 0x02000800, 0x0010801c, 0x0201f800,
+       0x00109326, 0x0201f800, 0x0002077d, 0x0401fa31,
+       0x5c026000, 0x0401f7e0, 0x497b1805, 0x497b1804,
+       0x5c026000, 0x5c03e000, 0x04000a31, 0x1c01f000,
+       0x4933c857, 0x4c5c0000, 0x4c600000, 0x813261c0,
+       0x02000800, 0x001005d8, 0x41300000, 0x598cb805,
+       0x405cc000, 0x805cb9c0, 0x04000025, 0x805c0d80,
+       0x04000004, 0x405cc000, 0x5860b800, 0x0401f7fa,
+       0x598c000d, 0x81300580, 0x02000800, 0x001070b9,
+       0x0401fa02, 0x598c0005, 0x805c0580, 0x04020009,
+       0x585c0000, 0x48031805, 0x4978b800, 0x598c0004,
+       0x805c0580, 0x0402000d, 0x497b1804, 0x0401f00b,
+       0x598c0004, 0x805c0580, 0x04020005, 0x48631804,
+       0x4978b800, 0x4978c000, 0x0401f004, 0x585c0000,
+       0x4800c000, 0x4978b800, 0x0401f9fe, 0x80000580,
+       0x5c00c000, 0x5c00b800, 0x1c01f000, 0x82000540,
+       0x00000001, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+       0x4933c857, 0x0401fa04, 0x4df00000, 0x4d2c0000,
+       0x4d340000, 0x4d300000, 0x4c5c0000, 0x4178b800,
+       0x8d3e7d18, 0x0400000d, 0x8d3e7d16, 0x0402000b,
+       0x0201f800, 0x00109037, 0x04000008, 0x0201f800,
+       0x00109597, 0x04020005, 0x592c0207, 0x492fc857,
+       0x8200bd00, 0x0000000f, 0x41783000, 0x598e6005,
+       0x813261c0, 0x04000029, 0x59326809, 0x813669c0,
+       0x04000023, 0x59340403, 0x81440580, 0x04020020,
+       0x59300c06, 0x82040580, 0x00000011, 0x0400001a,
+       0x82040580, 0x00000004, 0x04020004, 0x59300420,
+       0x8c000500, 0x04020016, 0x0201f800, 0x00109037,
+       0x04000008, 0x0201f800, 0x00109597, 0x04020005,
+       0x59300403, 0x82000580, 0x00000043, 0x0400000c,
+       0x0401f8c3, 0x59300000, 0x4c000000, 0x0401f812,
+       0x4c180000, 0x0401f836, 0x5c003000, 0x5c026000,
+       0x0401f7dc, 0x805cb9c0, 0x040207ec, 0x41303000,
+       0x59326000, 0x0401f7d7, 0x5c00b800, 0x5c026000,
+       0x5c026800, 0x5c025800, 0x5c03e000, 0x040009b4,
+       0x1c01f000, 0x59300800, 0x497a6000, 0x0401f997,
+       0x801831c0, 0x04020009, 0x598c0004, 0x81300580,
+       0x04020004, 0x48031804, 0x48031805, 0x0401f008,
+       0x48071805, 0x0401f006, 0x48043000, 0x598c0004,
+       0x81300580, 0x04020002, 0x481b1804, 0x0401f199,
+       0x4943c857, 0x0401f9a8, 0x4df00000, 0x0401fe34,
+       0x0401fecb, 0x5c03e000, 0x04000999, 0x1c01f000,
+       0x4947c857, 0x0401f9a0, 0x4df00000, 0x4d3c0000,
+       0x853e7d00, 0x0401fe75, 0x0401fefc, 0x5c027800,
+       0x5c03e000, 0x0400098e, 0x1c01f000, 0x5c000000,
+       0x4c000000, 0x4803c857, 0x4d340000, 0x4d2c0000,
+       0x59326809, 0x59325808, 0x59300406, 0x82000c80,
+       0x00000012, 0x02021800, 0x001005d8, 0x4933c857,
+       0x4943c857, 0x493fc857, 0x4803c857, 0x0c01f804,
+       0x5c025800, 0x5c026800, 0x1c01f000, 0x00106ae5,
+       0x00106ae7, 0x00106af1, 0x00106b0b, 0x00106ae7,
+       0x00106afb, 0x00106b23, 0x00106ae5, 0x00106ae5,
+       0x00106b36, 0x00106b2d, 0x00106ae5, 0x00106ae5,
+       0x00106ae5, 0x00106ae5, 0x00106ae5, 0x00106b3c,
+       0x00106b3c, 0x0201f800, 0x001005d8, 0x0201f800,
+       0x00109134, 0x02000800, 0x00102074, 0x0201f800,
+       0x00109326, 0x0201f800, 0x0010801c, 0x0201f000,
+       0x00107911, 0x812e59c0, 0x02020800, 0x001005d8,
+       0x5930021d, 0x82000580, 0x00000003, 0x02000800,
+       0x0010912a, 0x0201f000, 0x00107911, 0x0201f800,
+       0x00109037, 0x02000000, 0x00107911, 0x592c1204,
+       0x82081500, 0x000000ff, 0x82080580, 0x00000055,
+       0x02020800, 0x001005d8, 0x49425a06, 0x0201f800,
+       0x000202da, 0x0201f000, 0x00107911, 0x59300004,
+       0x8400055c, 0x48026004, 0x59300007, 0x8c000500,
+       0x02020800, 0x00100e99, 0x0201f800, 0x00109037,
+       0x0400000d, 0x4a025a04, 0x00000103, 0x49425a06,
+       0x497a5c09, 0x0201f800, 0x001091c6, 0x0201f800,
+       0x0010a693, 0x0201f800, 0x000202da, 0x0201f800,
+       0x0010912a, 0x0201f000, 0x00107911, 0x59300007,
+       0x8c000500, 0x02020800, 0x00100e99, 0x0201f800,
+       0x00109037, 0x02020800, 0x0010a3ef, 0x0201f000,
+       0x00107911, 0x0201f800, 0x00109037, 0x04000005,
+       0x49425a06, 0x497a5c09, 0x0201f800, 0x000202da,
+       0x0201f000, 0x00107911, 0x0201f800, 0x00109037,
+       0x02020800, 0x0010664f, 0x0201f000, 0x00107911,
+       0x0201f800, 0x00109037, 0x04000004, 0x49425a06,
+       0x0201f800, 0x000202da, 0x59325817, 0x0201f800,
+       0x001007fd, 0x0201f000, 0x00107911, 0x598c000d,
+       0x81300580, 0x04000003, 0x497a6007, 0x1c01f000,
+       0x59c40004, 0x82000500, 0x0000000c, 0x04000005,
+       0x4a038804, 0x0000000c, 0x497b2807, 0x0401f00a,
+       0x0401facd, 0x59300403, 0x82000d80, 0x00000040,
+       0x04000004, 0x82000580, 0x00000042, 0x04020002,
+       0x497a6007, 0x0201f800, 0x001070b9, 0x80000580,
+       0x1c01f000, 0x59300804, 0x8c040d3e, 0x04020004,
+       0x82000540, 0x00000001, 0x0401f005, 0x4933c857,
+       0x84040d3e, 0x48066004, 0x80000580, 0x1c01f000,
+       0x59300804, 0x8c040d20, 0x04020004, 0x82000540,
+       0x00000001, 0x1c01f000, 0x4933c857, 0x4d380000,
+       0x59300804, 0x84040d20, 0x48066004, 0x42027000,
+       0x00000049, 0x59300203, 0x82000580, 0x00000003,
+       0x04000003, 0x42027000, 0x00000013, 0x0201f800,
+       0x000207a1, 0x80000580, 0x5c027000, 0x1c01f000,
+       0x59300017, 0x81480580, 0x04020003, 0x59300018,
+       0x814c0580, 0x1c01f000, 0x4d2c0000, 0x4d300000,
+       0x0401f8c9, 0x4df00000, 0x0201f800, 0x00106062,
+       0x59900001, 0x82000500, 0x00000003, 0x0c01f001,
+       0x00106bba, 0x00106b9a, 0x00106b98, 0x00106b98,
+       0x0201f800, 0x001005d8, 0x59926004, 0x0401f88e,
+       0x813261c0, 0x0400001d, 0x59300004, 0x8c000516,
+       0x04000004, 0x59325808, 0x497a5808, 0x497a5809,
+       0x0401f88e, 0x59300001, 0x800001c0, 0x0400000e,
+       0x497a6001, 0x42003000, 0x0000bf2e, 0x58180801,
+       0x800409c0, 0x04020004, 0x48003001, 0x48003000,
+       0x0401f00a, 0x58180800, 0x48000800, 0x48003000,
+       0x0401f006, 0x59300809, 0x800409c0, 0x02000800,
+       0x001005d8, 0x4978080c, 0x5c03e000, 0x04000890,
+       0x5c026000, 0x5c025800, 0x1c01f000, 0x4d300000,
+       0x497b2807, 0x0401f894, 0x4df00000, 0x598c0000,
+       0x82000500, 0x00000007, 0x4803c857, 0x0c01f001,
+       0x00106bef, 0x00106bd2, 0x00106bdb, 0x00106bdf,
+       0x00106bea, 0x00106bef, 0x00106bd0, 0x00106bd0,
+       0x0201f800, 0x001005d8, 0x598c000d, 0x80026540,
+       0x04000004, 0x0401f81e, 0x02020800, 0x001005d8,
+       0x0201f800, 0x001070b9, 0x0401f015, 0x0401f827,
+       0x0201f800, 0x001070b9, 0x0401f011, 0x598c000d,
+       0x80026540, 0x0400000e, 0x0401f838, 0x04000004,
+       0x0401f80f, 0x04000002, 0x0401f81c, 0x0201f800,
+       0x001070b9, 0x0401f006, 0x0401f830, 0x02020800,
+       0x001005d8, 0x0201f800, 0x001070b9, 0x5c03e000,
+       0x0400085b, 0x5c026000, 0x1c01f000, 0x598c0009,
+       0x81300580, 0x0402000c, 0x0401f84e, 0x0401f83b,
+       0x59300000, 0x800001c0, 0x04000004, 0x48031809,
+       0x497a6000, 0x0401f003, 0x497b1809, 0x497b1808,
+       0x80000580, 0x1c01f000, 0x4d2c0000, 0x59300406,
+       0x82000580, 0x00000003, 0x04020012, 0x598c000b,
+       0x81300580, 0x0402000f, 0x0401f83a, 0x59325808,
+       0x497a5808, 0x497a5809, 0x0401f824, 0x59300000,
+       0x800001c0, 0x04000004, 0x4803180b, 0x497a6000,
+       0x0401f003, 0x497b180a, 0x497b180b, 0x80000580,
+       0x5c025800, 0x1c01f000, 0x598c0005, 0x81300580,
+       0x0402000c, 0x0401f827, 0x0401f814, 0x59300000,
+       0x800001c0, 0x04000004, 0x48031805, 0x497a6000,
+       0x0401f003, 0x497b1805, 0x497b1804, 0x80000580,
+       0x1c01f000, 0x4a032001, 0x00000000, 0x497b2004,
+       0x497b2005, 0x59900006, 0x82000500, 0x0000ffff,
+       0x48032006, 0x1c01f000, 0x4c040000, 0x59300004,
+       0x82000500, 0x7ffeffff, 0x48026004, 0x59bc00e4,
+       0x8c000514, 0x04000009, 0x42000800, 0x0000bf00,
+       0x58040012, 0x81300580, 0x04020004, 0x49780812,
+       0x4a0378e4, 0x00000800, 0x5c000800, 0x1c01f000,
+       0x4803c856, 0x598c000c, 0x80000540, 0x04000003,
+       0x80000040, 0x4803180c, 0x1c01f000, 0x59bc00ea,
+       0x82000500, 0x00000007, 0x82000580, 0x00000003,
+       0x04020004, 0x4803c856, 0x4a0378e8, 0x00000001,
+       0x1c01f000, 0x59bc00ea, 0x82000500, 0x00000007,
+       0x82000580, 0x00000001, 0x04020011, 0x4803c856,
+       0x42000800, 0x00000000, 0x0401f80e, 0x42000800,
+       0x00001000, 0x59bc00ea, 0x82000500, 0x00000007,
+       0x82000580, 0x00000003, 0x04000005, 0x80040840,
+       0x040207f9, 0x0201f800, 0x001005d8, 0x1c01f000,
+       0x59bc00ea, 0x82000500, 0x00000007, 0x82000580,
+       0x00000001, 0x02020800, 0x001005d8, 0x59bc00ea,
+       0x8c000516, 0x040207fe, 0x480778e1, 0x1c01f000,
+       0x59bc00ea, 0x8c000516, 0x040207fe, 0x480778e1,
+       0x59bc00ea, 0x8c000516, 0x040207fe, 0x480b78e1,
+       0x1c01f000, 0x82000d00, 0x80000018, 0x02020800,
+       0x001005d0, 0x0201f800, 0x001005d8, 0x00106c97,
+       0x00106d3b, 0x00106d55, 0x00106c97, 0x00106c99,
+       0x00106cba, 0x00106cd9, 0x00106d0d, 0x00106c97,
+       0x00106d39, 0x00106c97, 0x00106c97, 0x00106c97,
+       0x00106c97, 0x00106c97, 0x00106c97, 0x0201f800,
+       0x001005d8, 0x4d300000, 0x4d900000, 0x4dd00000,
+       0x4da40000, 0x4d140000, 0x0201f800, 0x001070d8,
+       0x59bc00ea, 0x8c000510, 0x040007fe, 0x59be60e0,
+       0x59300004, 0x8c000520, 0x04000011, 0x82000500,
+       0xfffefeff, 0x48026004, 0x4a026203, 0x00000003,
+       0x0401ffa9, 0x0201f800, 0x00100fd0, 0x5c022800,
+       0x5c034800, 0x5c03a000, 0x5c032000, 0x5c026000,
+       0x4a0378e4, 0x00000008, 0x0401f795, 0x84000510,
+       0x48026004, 0x0401f7f6, 0x4d300000, 0x4d900000,
+       0x4dd00000, 0x4da40000, 0x4d140000, 0x0201f800,
+       0x001070d8, 0x59bc00ea, 0x8c000510, 0x040007fe,
+       0x59be60e0, 0x59300004, 0x8c000520, 0x0400000f,
+       0x82000500, 0xfffefeff, 0x48026004, 0x0401ff8a,
+       0x0201f800, 0x0010100e, 0x5c022800, 0x5c034800,
+       0x5c03a000, 0x5c032000, 0x5c026000, 0x4a0378e4,
+       0x00000008, 0x0401f776, 0x84000510, 0x48026004,
+       0x0401f7f6, 0x4d300000, 0x4d2c0000, 0x4d340000,
+       0x4da40000, 0x4cd00000, 0x59bc00ea, 0x8c000510,
+       0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800,
+       0x001005d8, 0x59300004, 0x8c000520, 0x0400001d,
+       0x82000500, 0xfffefeff, 0x48026004, 0x59326809,
+       0x42034800, 0x0010b544, 0x04011000, 0x4a03c840,
+       0x0010b54b, 0x4a03c842, 0x00000012, 0x04011000,
+       0x4a03c840, 0x0010b55d, 0x4a03c842, 0x000000ff,
+       0x04011000, 0x4a03c840, 0x0010b65c, 0x4a03c842,
+       0x000000ff, 0x0401fbf2, 0x5c01a000, 0x5c034800,
+       0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000,
+       0x84000510, 0x48026004, 0x5c01a000, 0x5c034800,
+       0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000,
+       0x1c01f000, 0x4d300000, 0x4d2c0000, 0x4d340000,
+       0x4cd00000, 0x4d900000, 0x4dd00000, 0x4da40000,
+       0x4d140000, 0x0401fbc3, 0x59bc00ea, 0x8c000510,
+       0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800,
+       0x001005d8, 0x59300004, 0x8c000520, 0x0400000f,
+       0x82000500, 0xfffefeff, 0x48026004, 0x0201f800,
+       0x0010783a, 0x5c022800, 0x5c034800, 0x5c03a000,
+       0x5c032000, 0x5c01a000, 0x5c026800, 0x5c025800,
+       0x5c026000, 0x1c01f000, 0x84000510, 0x48026004,
+       0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+       0x5c01a000, 0x5c026800, 0x5c025800, 0x5c026000,
+       0x1c01f000, 0x0201f800, 0x001005d8, 0x4d300000,
+       0x4d380000, 0x42000000, 0x0010b8c4, 0x0201f800,
+       0x0010aa47, 0x0401ff14, 0x598e600d, 0x59c40004,
+       0x8c000506, 0x04000004, 0x0401f8db, 0x4a038804,
+       0x00000008, 0x813261c0, 0x04000006, 0x0401fb87,
+       0x42027000, 0x00000014, 0x0201f800, 0x000207a1,
+       0x4a0378e4, 0x00000002, 0x5c027000, 0x5c026000,
+       0x0401f6f7, 0x4d180000, 0x4d300000, 0x4d380000,
+       0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+       0x0401fef9, 0x417a3000, 0x59c40804, 0x83180400,
+       0x0010709f, 0x50000000, 0x80040500, 0x0400001b,
+       0x42000000, 0x0010b8c5, 0x0201f800, 0x0010aa47,
+       0x0401fb70, 0x59926004, 0x0401f859, 0x83180400,
+       0x0010709f, 0x50000000, 0x48038804, 0x813261c0,
+       0x0400000a, 0x59300004, 0x8c00050c, 0x04020003,
+       0x4a026203, 0x00000003, 0x42027000, 0x0000004a,
+       0x0201f800, 0x000207a1, 0x59c40004, 0x82000500,
+       0x00f80000, 0x04000005, 0x811a3000, 0x83180480,
+       0x00000005, 0x040017dd, 0x4a0378e4, 0x00000008,
+       0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+       0x5c027000, 0x5c026000, 0x5c023000, 0x0401f6c0,
+       0x4d2c0000, 0x4d340000, 0x59326809, 0x598c0800,
+       0x82040580, 0x00000004, 0x04020004, 0x838c1400,
+       0x00000005, 0x0401f00c, 0x82040580, 0x00000001,
+       0x04020004, 0x838c1400, 0x00000009, 0x0401f006,
+       0x82040580, 0x00000002, 0x04020022, 0x838c1400,
+       0x0000000b, 0x41306800, 0x58340000, 0x80007d40,
+       0x0400001c, 0x583c0009, 0x81340580, 0x04020006,
+       0x403c6800, 0x583c0000, 0x80007d40, 0x040207fa,
+       0x0401f014, 0x4933c857, 0x483fc857, 0x583c0000,
+       0x48006800, 0x49307800, 0x443c1000, 0x80000580,
+       0x4803180d, 0x4803180f, 0x598c0000, 0x82000580,
+       0x00000003, 0x04000003, 0x4a031800, 0x00000000,
+       0x80000580, 0x5c026800, 0x5c025800, 0x1c01f000,
+       0x82000540, 0x00000001, 0x0401f7fb, 0x491bc857,
+       0x59c80840, 0x82040540, 0x00000010, 0x48039040,
+       0x59c41008, 0x82080500, 0xffffff7f, 0x48038808,
+       0x4c040000, 0x4c080000, 0x0401fabb, 0x04020007,
+       0x0401fabf, 0x04000022, 0x48038804, 0x0201f800,
+       0x0010107a, 0x0401f042, 0x4a038803, 0x00000008,
+       0x59c40003, 0x82000500, 0x00000003, 0x040007fd,
+       0x8c000502, 0x04020007, 0x0401fab1, 0x04000014,
+       0x48038804, 0x0201f800, 0x0010107a, 0x0401f034,
+       0x59c80040, 0x8400056a, 0x48039040, 0x59c80040,
+       0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500,
+       0xc0000000, 0x04000006, 0x59c400a3, 0x84000540,
+       0x480388a3, 0x4a038805, 0xc0000000, 0x0201f800,
+       0x0010101d, 0x4a03a005, 0x30000000, 0x59d00006,
+       0x4a03a005, 0x30000000, 0x59900006, 0x82000500,
+       0xffff0000, 0x48032006, 0x59d00005, 0x8c000504,
+       0x040207fe, 0x42000800, 0x00007600, 0x83180540,
+       0x60000000, 0x480008a1, 0x811800dc, 0x59c80840,
+       0x80040540, 0x48039040, 0x82000540, 0x00003000,
+       0x48039040, 0x59c80040, 0x82000500, 0x00003000,
+       0x040207fd, 0x0201f800, 0x00101068, 0x83180400,
+       0x0010709f, 0x50000000, 0x48038804, 0x80000580,
+       0x4df00000, 0x0201f800, 0x00106062, 0x5c03e000,
+       0x5c001000, 0x5c000800, 0x480b8808, 0x48079040,
+       0x1c01f000, 0x4803c856, 0x59c80840, 0x82040540,
+       0x00000010, 0x48039040, 0x59c41008, 0x82080500,
+       0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000,
+       0x59c40004, 0x82000500, 0x00000003, 0x04020010,
+       0x59c40004, 0x82000500, 0x0000000c, 0x04000005,
+       0x4a038804, 0x0000000c, 0x8c000504, 0x0401f025,
+       0x59c80040, 0x8400056e, 0x48039040, 0x59c80040,
+       0x8c00052e, 0x040207fe, 0x0401f01e, 0x4a038803,
+       0x00000008, 0x59c40003, 0x82000500, 0x00000003,
+       0x040007fd, 0x8c000502, 0x04020006, 0x59c40004,
+       0x4a038804, 0x0000000c, 0x8c000504, 0x0401f011,
+       0x59c80040, 0x8400056a, 0x48039040, 0x59c80040,
+       0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500,
+       0xc0000000, 0x04000007, 0x59c400a3, 0x84000540,
+       0x480388a3, 0x4a038805, 0xc0000000, 0x80000580,
+       0x497b2807, 0x5c001000, 0x5c000800, 0x480b8808,
+       0x48079040, 0x1c01f000, 0x4933c857, 0x4d900000,
+       0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fdee,
+       0x4df00000, 0x0401fa6f, 0x59900004, 0x800001c0,
+       0x04000011, 0x81300580, 0x0402000f, 0x59300004,
+       0x84000520, 0x48026004, 0x0401ff51, 0x04020009,
+       0x5c03e000, 0x04000dd6, 0x80000580, 0x5c022800,
+       0x5c034800, 0x5c03a000, 0x5c032000, 0x1c01f000,
+       0x0401fd0e, 0x42027000, 0x00000049, 0x59300004,
+       0x84000520, 0x48026004, 0x8c00050c, 0x02020800,
+       0x000207a1, 0x5c03e000, 0x04000dc5, 0x82000540,
+       0x00000001, 0x5c022800, 0x5c034800, 0x5c03a000,
+       0x5c032000, 0x1c01f000, 0x4933c857, 0x0401fdc6,
+       0x4df00000, 0x598c000d, 0x80026540, 0x04000012,
+       0x59300004, 0x84000520, 0x48026004, 0x0401ff8a,
+       0x04000017, 0x0401fd26, 0x42027000, 0x00000013,
+       0x59300004, 0x8c00050c, 0x02020800, 0x000207a1,
+       0x5c03e000, 0x04000daa, 0x82000540, 0x00000001,
+       0x1c01f000, 0x836c1580, 0x00000001, 0x040007f9,
+       0x836c1580, 0x00000004, 0x040007f6, 0x42001000,
+       0x00104148, 0x0201f800, 0x00105f90, 0x5c03e000,
+       0x04000d9b, 0x80000580, 0x1c01f000, 0x4d300000,
+       0x4d180000, 0x4d3c0000, 0x0401fd9f, 0x4df00000,
+       0x4a0378e4, 0x0000000f, 0x0401f9ff, 0x417a3000,
+       0x59926004, 0x813261c0, 0x04000010, 0x417a7800,
+       0x0201f800, 0x001048d9, 0x0400000a, 0x59300c06,
+       0x82040580, 0x00000003, 0x04000004, 0x82040580,
+       0x00000006, 0x04020003, 0x42027800, 0x00000002,
+       0x0201f800, 0x00108be3, 0x811a3000, 0x83180480,
+       0x00000005, 0x040017eb, 0x42000800, 0x00000040,
+       0x0201f800, 0x00101345, 0x4a0378e4, 0x0000000a,
+       0x5c03e000, 0x04000d72, 0x5c027800, 0x5c023000,
+       0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+       0x0401fd75, 0x4df00000, 0x59c80840, 0x82040540,
+       0x00000010, 0x48039040, 0x59c41008, 0x82080500,
+       0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000,
+       0x42001000, 0x00000003, 0x0401f9c2, 0x598e600d,
+       0x813261c0, 0x04020f9d, 0x040009c7, 0x497b2807,
+       0x0401f80a, 0x5c001000, 0x5c000800, 0x480b8808,
+       0x84040d74, 0x48079040, 0x5c03e000, 0x04000d50,
+       0x5c026000, 0x1c01f000, 0x4d380000, 0x4d180000,
+       0x4d300000, 0x4d900000, 0x4dd00000, 0x4da40000,
+       0x4d140000, 0x59c41004, 0x480bc857, 0x82080500,
+       0x00003ff0, 0x04000025, 0x417a3000, 0x4c080000,
+       0x0201f800, 0x00106062, 0x5c001000, 0x82080500,
+       0x00000210, 0x04020004, 0x811a3000, 0x80081102,
+       0x0401f7f7, 0x0401f9c3, 0x59926004, 0x4933c857,
+       0x813261c0, 0x04020005, 0x59c400a3, 0x8c00051a,
+       0x02000800, 0x001005d8, 0x0401fea5, 0x04000009,
+       0x0401fc6a, 0x42027000, 0x00000049, 0x59300004,
+       0x8c00050c, 0x02020800, 0x000207a1, 0x0401f007,
+       0x42027000, 0x0000004a, 0x4a026203, 0x00000003,
+       0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800,
+       0x5c03a000, 0x5c032000, 0x5c026000, 0x5c023000,
+       0x5c027000, 0x1c01f000, 0x4d300000, 0x4d180000,
+       0x4d900000, 0x0401fd1c, 0x42001000, 0x00000000,
+       0x598c0000, 0x82000580, 0x00000005, 0x04000971,
+       0x417a3000, 0x811b20c8, 0x83932400, 0x0000bf32,
+       0x59900001, 0x82000580, 0x00000001, 0x0402000d,
+       0x42000800, 0x000007d0, 0x59926004, 0x59300011,
+       0x82000500, 0xfff00000, 0x80000540, 0x04000003,
+       0x42000800, 0x00001b58, 0x0201f800, 0x00106054,
+       0x811a3000, 0x83180480, 0x00000005, 0x040017ea,
+       0x59c81040, 0x84081534, 0x480b9040, 0x0401fcf0,
+       0x5c032000, 0x5c023000, 0x5c026000, 0x1c01f000,
+       0x4933c857, 0x4d900000, 0x4dd00000, 0x4da40000,
+       0x4d140000, 0x4d380000, 0x0401fcef, 0x4df00000,
+       0x59300004, 0x8c00053e, 0x04020007, 0x8c000520,
+       0x04000025, 0x0201f800, 0x00106b6c, 0x04000022,
+       0x0401f02a, 0x598c000d, 0x81300580, 0x04000011,
+       0x0201f800, 0x00108cd6, 0x04020024, 0x0401f918,
+       0x04000022, 0x48038804, 0x0401f95e, 0x0201f800,
+       0x0010107a, 0x0401fc0d, 0x42027000, 0x00000049,
+       0x59300004, 0x8c00050c, 0x0402000d, 0x0401f00e,
+       0x59c40004, 0x8c000504, 0x04000014, 0x4a038804,
+       0x00000004, 0x0401fc36, 0x42027000, 0x00000013,
+       0x59300004, 0x8c00050c, 0x04000003, 0x0201f800,
+       0x000207a1, 0x5c03e000, 0x04000cb9, 0x5c027000,
+       0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+       0x80000580, 0x1c01f000, 0x5c03e000, 0x04000cb0,
+       0x5c027000, 0x5c022800, 0x5c034800, 0x5c03a000,
+       0x5c032000, 0x82000540, 0x00000001, 0x1c01f000,
+       0x497b2807, 0x0401fcb0, 0x59c400af, 0x800001c0,
+       0x04020004, 0x0401fca2, 0x0201f000, 0x001014fb,
+       0x598c000f, 0x82001480, 0x00000002, 0x04021007,
+       0x80000000, 0x4803180f, 0x80000580, 0x0201f800,
+       0x0010604d, 0x0400000e, 0x0401fed8, 0x0402000c,
+       0x0401fdd4, 0x0400000a, 0x0201f800, 0x0010a9c7,
+       0x0401f916, 0x4d380000, 0x42027000, 0x00000014,
+       0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc88,
+       0x0201f000, 0x001014fb, 0x4d900000, 0x4dd00000,
+       0x4da40000, 0x4d140000, 0x4d300000, 0x0201f800,
+       0x00106062, 0x0401fc88, 0x59c400af, 0x800001c0,
+       0x04000027, 0x0401f907, 0x59926004, 0x4933c857,
+       0x59300004, 0x8c000516, 0x0400000b, 0x0401fe8b,
+       0x0402001f, 0x0201f800, 0x00106b8a, 0x0401fc70,
+       0x42000800, 0x80000804, 0x0201f800, 0x00106721,
+       0x0401f017, 0x42001800, 0x00007530, 0x0401f8c1,
+       0x04020004, 0x0201f800, 0x00106052, 0x0401f010,
+       0x0401fe7a, 0x0402000e, 0x0201f800, 0x0010a9c7,
+       0x59300004, 0x8c00050c, 0x04020003, 0x4a026203,
+       0x00000003, 0x4d380000, 0x42027000, 0x0000004a,
+       0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc54,
+       0x5c026000, 0x5c022800, 0x5c034800, 0x5c03a000,
+       0x5c032000, 0x0201f000, 0x001014fb, 0x4d900000,
+       0x4dd00000, 0x4da40000, 0x4d140000, 0x4d300000,
+       0x4d2c0000, 0x0401fc50, 0x0401f8d2, 0x59926004,
+       0x4933c857, 0x0401f880, 0x04000016, 0x0201f800,
+       0x00106062, 0x813261c0, 0x04000034, 0x59325808,
+       0x812e59c0, 0x02000800, 0x001005d8, 0x0201f800,
+       0x0010513b, 0x0402001d, 0x592c0208, 0x84000550,
+       0x48025a08, 0x0201f800, 0x00105258, 0x04020027,
+       0x592c0208, 0x84000510, 0x48025a08, 0x0401f023,
+       0x0201f800, 0x00106052, 0x0401f020, 0x0201f800,
+       0x0010a9c7, 0x0401fd9e, 0x592c0208, 0x84000550,
+       0x48025a08, 0x4d380000, 0x42027000, 0x0000004a,
+       0x4a026203, 0x00000003, 0x0201f800, 0x000207a1,
+       0x5c027000, 0x0401f011, 0x59900006, 0x82000500,
+       0xffff0000, 0x040207ee, 0x59c408af, 0x82040480,
+       0x000003e8, 0x040217ea, 0x59900006, 0x82000400,
+       0x00010000, 0x48032006, 0x0201f800, 0x00106052,
+       0x0201f800, 0x0010411d, 0x5c025800, 0x5c026000,
+       0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+       0x0401f403, 0x4d300000, 0x4d2c0000, 0x0401fc0a,
+       0x598e600d, 0x4933c857, 0x59c41004, 0x8c081500,
+       0x04000007, 0x0201f800, 0x0010513b, 0x04020007,
+       0x0201f800, 0x00105258, 0x0402002f, 0x0201f800,
+       0x0010604d, 0x0401f02c, 0x598c000f, 0x80000540,
+       0x04020011, 0x59c408af, 0x82040480, 0x000003e8,
+       0x0402100d, 0x598c080f, 0x80040800, 0x4807180f,
+       0x0201f800, 0x0010604d, 0x42000000, 0x0010b852,
+       0x0201f800, 0x0010aa47, 0x0201f800, 0x0010411d,
+       0x0401f019, 0x0401fdb4, 0x813261c0, 0x04020003,
+       0x0401f849, 0x0401f014, 0x0201f800, 0x0010a9c7,
+       0x59300406, 0x82000580, 0x00000003, 0x04020007,
+       0x59325808, 0x812e59c0, 0x04000004, 0x592c0208,
+       0x84000550, 0x48025a08, 0x0401f854, 0x4d380000,
+       0x42027000, 0x00000014, 0x0201f800, 0x000207a1,
+       0x5c027000, 0x5c025800, 0x5c026000, 0x0201f000,
+       0x00106c4b, 0x59c40804, 0x83180400, 0x00107095,
+       0x50000000, 0x80040500, 0x1c01f000, 0x59c40804,
+       0x83180400, 0x0010709a, 0x50000000, 0x80040500,
+       0x1c01f000, 0x00000210, 0x00000420, 0x00000840,
+       0x00001080, 0x00002100, 0x00004000, 0x00008000,
+       0x00010000, 0x00020000, 0x00040000, 0x00080000,
+       0x00100000, 0x00200000, 0x00400000, 0x00800000,
+       0x59900806, 0x80040120, 0x800c0480, 0x04021004,
+       0x82000540, 0x00000001, 0x0401f005, 0x82040c00,
+       0x00010000, 0x48072006, 0x80000580, 0x1c01f000,
+       0x480bc857, 0x0201f800, 0x00106c55, 0x4df00000,
+       0x480b1800, 0x5c03e000, 0x02000800, 0x00106c4b,
+       0x1c01f000, 0x4803c856, 0x0201f800, 0x00106c55,
+       0x4df00000, 0x497b180d, 0x497b1803, 0x497b180e,
+       0x497b180f, 0x497b1810, 0x598c0000, 0x82000580,
+       0x00000003, 0x04000009, 0x836c0580, 0x00000002,
+       0x04020004, 0x4a031800, 0x00000005, 0x0401f003,
+       0x4a031800, 0x00000000, 0x5c03e000, 0x02000800,
+       0x00106c4b, 0x1c01f000, 0x59300004, 0x8c00050c,
+       0x04020003, 0x4a026203, 0x00000001, 0x1c01f000,
+       0x83180480, 0x00000005, 0x02021800, 0x001005d8,
+       0x491bc857, 0x811b20c8, 0x83932400, 0x0000bf32,
+       0x811ba0ca, 0x83d3a400, 0x00007600, 0x83180400,
+       0x001070ea, 0x50034800, 0x811a28c2, 0x83162c00,
+       0x00006100, 0x1c01f000, 0x0010b75b, 0x0010b772,
+       0x0010b789, 0x0010b7a0, 0x0010b7b7, 0x4933c857,
+       0x59300406, 0x82000c80, 0x00000012, 0x04021016,
+       0x4803c857, 0x04011000, 0x0c01f001, 0x00107109,
+       0x00107198, 0x001074d1, 0x00107556, 0x00107198,
+       0x001074d1, 0x00107556, 0x00107109, 0x00107198,
+       0x00107109, 0x00107109, 0x00107109, 0x00107109,
+       0x00107109, 0x00107109, 0x00107109, 0x0010710f,
+       0x0010710f, 0x0201f800, 0x00106c55, 0x0201f800,
+       0x00106bbf, 0x0201f000, 0x00106c4b, 0x42001000,
+       0x0010b7f6, 0x50081000, 0x4930100c, 0x58080002,
+       0x82000580, 0x00000100, 0x04020032, 0x59325808,
+       0x812e59c0, 0x02000800, 0x001005d8, 0x59326809,
+       0x813669c0, 0x04000019, 0x592c040b, 0x82000500,
+       0x0000e000, 0x04000003, 0x0401fba8, 0x0401f002,
+       0x0401fb98, 0x42001000, 0x0010b7f6, 0x50081000,
+       0x4930100b, 0x492c100a, 0x82d00400, 0x00000006,
+       0x48001003, 0x592c000d, 0x80000104, 0x48001004,
+       0x592c000e, 0x48001007, 0x592c000f, 0x48001008,
+       0x0201f000, 0x00100858, 0x42026800, 0x0010be0d,
+       0x592c080a, 0x48066802, 0x82040500, 0x00ffff00,
+       0x04000007, 0x497a6a12, 0x59a81010, 0x82081500,
+       0x00ffff00, 0x80080580, 0x040207dc, 0x82040d00,
+       0x000000ff, 0x800408d0, 0x48066a12, 0x0401f7d7,
+       0x1c01f000, 0x4d2c0000, 0x4d300000, 0x4c580000,
+       0x4c540000, 0x4c500000, 0x5832580a, 0x812e59c0,
+       0x02000800, 0x001005d8, 0x58300002, 0x4a006002,
+       0x00000100, 0x82000580, 0x00000100, 0x0402001c,
+       0x5830000b, 0x5832600c, 0x81300580, 0x04020010,
+       0x0401f828, 0x04020010, 0x592c080d, 0x80040904,
+       0x4004b000, 0x4200a000, 0x0010b54b, 0x4050a800,
+       0x0201f800, 0x0010ab28, 0x42001000, 0x0000dc00,
+       0x0201f800, 0x001078bc, 0x0401f003, 0x0401f819,
+       0x04000fa3, 0x5c00a000, 0x5c00a800, 0x5c00b000,
+       0x5c026000, 0x5c025800, 0x1c01f000, 0x5830000b,
+       0x5832600c, 0x81300580, 0x040207f5, 0x0401f80d,
+       0x040207f5, 0x0201f800, 0x001068d3, 0x02020800,
+       0x001005d8, 0x4a025a06, 0x00000002, 0x0201f800,
+       0x000202da, 0x0201f800, 0x00107911, 0x0401f7ea,
+       0x0201f800, 0x00106c55, 0x4df00000, 0x598c000d,
+       0x81300580, 0x04020009, 0x598c0005, 0x81300580,
+       0x04020006, 0x5c03e000, 0x02000800, 0x00106c4b,
+       0x80000580, 0x1c01f000, 0x5c03e000, 0x02000800,
+       0x00106c4b, 0x82000540, 0x00000001, 0x1c01f000,
+       0x59300403, 0x82000c80, 0x00000056, 0x02021800,
+       0x001005d8, 0x4803c857, 0x0c01f001, 0x00107302,
+       0x0010731d, 0x0010732e, 0x00107431, 0x001073f1,
+       0x001073f5, 0x00107406, 0x0010741a, 0x0010740f,
+       0x0010741a, 0x00107455, 0x0010741a, 0x00107497,
+       0x0010741a, 0x001074a5, 0x0010741a, 0x0010740f,
+       0x0010741a, 0x001074a9, 0x001071f5, 0x001071f5,
+       0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5,
+       0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5,
+       0x001071f5, 0x00107574, 0x00107593, 0x0010759d,
+       0x001071f5, 0x001075b3, 0x00107406, 0x001071f5,
+       0x00107406, 0x0010741a, 0x001071f5, 0x0010732e,
+       0x00107431, 0x001071f5, 0x00107603, 0x0010741a,
+       0x001071f5, 0x00107613, 0x0010741a, 0x001071f5,
+       0x0010740f, 0x001072f3, 0x001071f7, 0x001071f5,
+       0x0010762a, 0x0010765d, 0x001076d7, 0x001071f5,
+       0x001076e7, 0x00107404, 0x001076da, 0x001071f5,
+       0x001075bf, 0x00107700, 0x001071f5, 0x00107735,
+       0x00107788, 0x001071f5, 0x0010720c, 0x00107265,
+       0x00107272, 0x001071f5, 0x00107406, 0x001071f5,
+       0x001072b9, 0x001072c4, 0x001071f5, 0x001071f5,
+       0x00107220, 0x00107245, 0x001077c7, 0x00107808,
+       0x0010782e, 0x001071f5, 0x001071f5, 0x001071f5,
+       0x001077fc, 0x0201f800, 0x001005d8, 0x0401fac5,
+       0x59325808, 0x592c0009, 0x4801a006, 0x592c000a,
+       0x4801a007, 0x592c000b, 0x4801a008, 0x592c000c,
+       0x4801a009, 0x592c000d, 0x4801a00a, 0x4979a00b,
+       0x592c0809, 0x82040d00, 0x00000fff, 0x80040904,
+       0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+       0x4a026202, 0x0000ffff, 0x0401faae, 0x4d2c0000,
+       0x4a01a006, 0x05000000, 0x59325808, 0x592c0009,
+       0x4801a007, 0x592c000a, 0x4801a008, 0x592c000b,
+       0x4801a009, 0x42000800, 0x00000004, 0x42001000,
+       0x0000dc00, 0x5c025800, 0x0201f000, 0x001078bc,
+       0x4c580000, 0x4c500000, 0x4c540000, 0x4d2c0000,
+       0x0401fa98, 0x59325808, 0x5930040b, 0x800000c2,
+       0x4200a800, 0x0010b54b, 0x592cb205, 0x832ca400,
+       0x00000006, 0x0201f800, 0x0010ab17, 0x40580000,
+       0x8054ac00, 0x592c0001, 0x80000540, 0x04000003,
+       0x40025800, 0x0401f7f5, 0x4200a000, 0x0010b54b,
+       0x4050a800, 0x5930b40b, 0x0201f800, 0x0010ab28,
+       0x59300c0b, 0x42001000, 0x0000dc00, 0x5c025800,
+       0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000,
+       0x001078bc, 0x4c580000, 0x4c500000, 0x4c540000,
+       0x4d2c0000, 0x42034800, 0x0010b544, 0x0401fa7f,
+       0x59325808, 0x4a025805, 0x02000000, 0x592c0802,
+       0x82d0ac00, 0x00000006, 0x592cb011, 0x832ca400,
+       0x00000005, 0x0201f800, 0x0010ab17, 0x40580000,
+       0x8054ac00, 0x592e5801, 0x41780000, 0x812e5d40,
+       0x040207f6, 0x42001000, 0x0000dc00, 0x5c025800,
+       0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000,
+       0x001078bc, 0x0401fa57, 0x4a01a006, 0x78000000,
+       0x5930001c, 0x840001c0, 0x4801a407, 0x4979a207,
+       0x42000800, 0x00000002, 0x42001000, 0x0000dc00,
+       0x0201f000, 0x001078bc, 0x4c580000, 0x4c540000,
+       0x4c500000, 0x0401fa55, 0x4a01a006, 0x02000000,
+       0x59a80002, 0x4801a008, 0x59a80003, 0x4801a009,
+       0x59a80000, 0x4801a00a, 0x59a80001, 0x4801a00b,
+       0x5930001c, 0x82000d80, 0x0000e000, 0x04000016,
+       0x82000d80, 0x0000df00, 0x04000006, 0x4a01a407,
+       0x00000010, 0x42000800, 0x00000006, 0x0401f027,
+       0x4a03c840, 0x0010b4eb, 0x4a03c842, 0x0000000d,
+       0x42001800, 0x0010b4eb, 0x0201f800, 0x001007af,
+       0x42000000, 0x0000df00, 0x4200a000, 0x0010b4eb,
+       0x0401f00d, 0x4a03c840, 0x0010b4f8, 0x4a03c842,
+       0x0000000d, 0x42001800, 0x0010b4f8, 0x0201f800,
+       0x001007af, 0x42000000, 0x0000e000, 0x4200a000,
+       0x0010b4f8, 0x82000540, 0x00000010, 0x4801a407,
+       0x4a01a207, 0x00000034, 0x4200b000, 0x0000000d,
+       0x82d0ac00, 0x0000000c, 0x0201f800, 0x0010ab17,
+       0x42000800, 0x00000013, 0x42001000, 0x0000dc00,
+       0x5c00a000, 0x5c00a800, 0x5c00b000, 0x0201f000,
+       0x001078bc, 0x0401fa03, 0x4a01a006, 0x63000028,
+       0x5930001c, 0x4801a007, 0x42000800, 0x00000002,
+       0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+       0x0401fa06, 0x41780000, 0x41780800, 0x42002000,
+       0x00080000, 0x0c01f81b, 0x80000000, 0x80040800,
+       0x42001000, 0x0000000c, 0x59841802, 0x8c0c1d00,
+       0x04020008, 0x42002000, 0x00050000, 0x0c01f811,
+       0x80000000, 0x80040800, 0x82081400, 0x00000004,
+       0x82080540, 0x02000000, 0x4801a006, 0x800408e0,
+       0x5930001c, 0x80040540, 0x4801a007, 0x80080904,
+       0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+       0x001072e9, 0x001072eb, 0x001072ed, 0x001072ef,
+       0x001072f1, 0x4811a008, 0x1c01f000, 0x4811a009,
+       0x1c01f000, 0x4811a00a, 0x1c01f000, 0x4811a00b,
+       0x1c01f000, 0x4811a00c, 0x1c01f000, 0x4a026009,
+       0x0010be0d, 0x59a80010, 0x82000500, 0x000000ff,
+       0x800000d0, 0x42026800, 0x0010be0d, 0x48026a12,
+       0x0401fa3b, 0x41780800, 0x42001000, 0x00005c00,
+       0x0201f000, 0x001078bc, 0x0401f9ba, 0x4a01a006,
+       0x52000000, 0x4979a007, 0x599c0017, 0x8c000500,
+       0x04000005, 0x599c0402, 0x0201f800, 0x001015da,
+       0x4805a007, 0x59a80002, 0x4801a008, 0x59a80003,
+       0x4801a009, 0x59a80000, 0x4801a00a, 0x59a80001,
+       0x4801a00b, 0x59a80010, 0x4801a00c, 0x42000800,
+       0x00000007, 0x42001000, 0x0000dc00, 0x0201f000,
+       0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f99d,
+       0x4a01a006, 0x05000000, 0x59a80010, 0x4801a007,
+       0x59a80002, 0x59a80803, 0x4801a008, 0x4805a009,
+       0x42000800, 0x00000004, 0x42001000, 0x0000dc00,
+       0x0201f000, 0x001078bc, 0x4a026202, 0x0000ffff,
+       0x0401f98c, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x001048f6, 0x5c027800, 0x4a01a006, 0x03000000,
+       0x59340403, 0x82000580, 0x000007fe, 0x0402006e,
+       0x4a01a006, 0x04000000, 0x81a40800, 0x4a000800,
+       0x22fffffe, 0x5934000a, 0x84000500, 0x4802680a,
+       0x59c41002, 0x8408150c, 0x480b8802, 0x59a80026,
+       0x8c000508, 0x04000010, 0x59a8002a, 0x4801a007,
+       0x59a8002b, 0x82000500, 0xffff2000, 0x599c0818,
+       0x8c040d16, 0x04000002, 0x8400056a, 0x4801a008,
+       0x4a01a009, 0x00002710, 0x59a8002d, 0x4801a00a,
+       0x0401f039, 0x59a8002a, 0x4801a007, 0x0201f800,
+       0x0010513b, 0x04020009, 0x497b8880, 0x82000500,
+       0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606,
+       0x5c000000, 0x48038880, 0x59a8002b, 0x0201f800,
+       0x0010513b, 0x04020004, 0x82000500, 0x37ffffff,
+       0x0401f003, 0x82000500, 0x3fffffff, 0x599c0818,
+       0x8c040d16, 0x04000002, 0x8400056a, 0x59a80805,
+       0x8c040d10, 0x04000019, 0x59300c03, 0x82041580,
+       0x00000051, 0x04000015, 0x82041580, 0x00000031,
+       0x04000012, 0x4c580000, 0x4c500000, 0x4c540000,
+       0x4200b000, 0x00000004, 0x4200a000, 0x0010b8fa,
+       0x82d0ac00, 0x0000001f, 0x4c000000, 0x0201f800,
+       0x0010ab17, 0x5c000000, 0x5c00a800, 0x5c00a000,
+       0x5c00b000, 0x8400057a, 0x4801a008, 0x4979a009,
+       0x4979a00a, 0x59a80002, 0x59a80803, 0x4801a00b,
+       0x4805a00c, 0x59a80000, 0x59a80801, 0x4801a00d,
+       0x4805a00e, 0x4979a00f, 0x4979a010, 0x4979a011,
+       0x4979a012, 0x4979a013, 0x4979a014, 0x4979a015,
+       0x4979a016, 0x59a8002e, 0x84000576, 0x4801a017,
+       0x59a8002f, 0x4801a018, 0x4979a019, 0x4979a01a,
+       0x0401f043, 0x59a80026, 0x8c000508, 0x0400000d,
+       0x59a8002a, 0x82000500, 0x0000ffff, 0x59c40880,
+       0x80040d80, 0x04000007, 0x497b8880, 0x4c000000,
+       0x0201f800, 0x00101606, 0x5c000000, 0x48038880,
+       0x59a8002a, 0x4801a007, 0x4c640000, 0x4d2c0000,
+       0x59a8c82b, 0x0201f800, 0x00109037, 0x0400000d,
+       0x0201f800, 0x00109597, 0x0402000a, 0x592c0207,
+       0x8c00050e, 0x04000007, 0x8264cd00, 0x0000ffff,
+       0x592c0009, 0x82000500, 0xffff0000, 0x8064cd40,
+       0x4865a008, 0x5c025800, 0x5c00c800, 0x59a8002c,
+       0x4801a009, 0x59a8002d, 0x4801a00a, 0x59a80002,
+       0x59a80803, 0x4801a00b, 0x4805a00c, 0x59a80000,
+       0x59a80801, 0x4801a00d, 0x4805a00e, 0x4979a00f,
+       0x4979a010, 0x4979a011, 0x4979a012, 0x4979a013,
+       0x4979a014, 0x4979a015, 0x4979a016, 0x59a8002e,
+       0x4801a017, 0x59a8002f, 0x4801a018, 0x59a80030,
+       0x4801a019, 0x59a80031, 0x4801a01a, 0x42000800,
+       0x0000001d, 0x42001000, 0x0000dc00, 0x0201f000,
+       0x001078bc, 0x0401f8cb, 0x4a01a006, 0x50000000,
+       0x0401f7b5, 0x0401f8c7, 0x4a01a406, 0x21000010,
+       0x4a01a206, 0x00000014, 0x4979a007, 0x4979a008,
+       0x4979a009, 0x4979a00a, 0x42000800, 0x00000005,
+       0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+       0x0401f8bf, 0x0401f002, 0x0401f8c4, 0x4a01a006,
+       0x02000000, 0x42000800, 0x00000001, 0x42001000,
+       0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f8bb,
+       0x4a01a006, 0x02000000, 0x59300403, 0x82000580,
+       0x00000031, 0x04020794, 0x81a40800, 0x4a000801,
+       0x00fffffe, 0x0401f72b, 0x0401f8b0, 0x4a01a006,
+       0x01000000, 0x5930041a, 0x80000540, 0x04000003,
+       0x4801a407, 0x0401f003, 0x4a01a407, 0x00000003,
+       0x5930021a, 0x80000540, 0x04000003, 0x4801a207,
+       0x0401f003, 0x4a01a207, 0x00002a00, 0x42000800,
+       0x00000002, 0x42001000, 0x0000dc00, 0x0201f000,
+       0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f889,
+       0x4a01a406, 0x00002010, 0x4a01a206, 0x00000014,
+       0x4a01a407, 0x00000800, 0x4a01a207, 0x00002000,
+       0x80000580, 0x599c0817, 0x8c040d0a, 0x04020003,
+       0x82000540, 0x00000020, 0x8c040d08, 0x04000003,
+       0x82000540, 0x00000010, 0x82000540, 0x00000002,
+       0x5934080a, 0x8c040d14, 0x04000005, 0x82040d00,
+       0x00000380, 0x80040540, 0x0401f006, 0x599c0818,
+       0x8c040d18, 0x04000003, 0x82000540, 0x00000380,
+       0x0401f03c, 0x0401f875, 0x4a01a406, 0x00000210,
+       0x4a01a206, 0x00000014, 0x4a01a407, 0x00000800,
+       0x5934000a, 0x8c000516, 0x04000014, 0x59340c05,
+       0x82040500, 0x00000030, 0x04000013, 0x59340a05,
+       0x82040500, 0x0000c000, 0x04020009, 0x8c040d1a,
+       0x04000004, 0x4a01a207, 0x00002100, 0x0401f00c,
+       0x4a01a207, 0x00000100, 0x0401f009, 0x4a01a207,
+       0x00000400, 0x0401f006, 0x4a01a207, 0x00000700,
+       0x0401f003, 0x4a01a207, 0x00000800, 0x80000580,
+       0x599c0817, 0x8c040d0a, 0x04020003, 0x82000540,
+       0x00000020, 0x8c040d08, 0x04000003, 0x82000540,
+       0x00000010, 0x82000540, 0x00000002, 0x59340a00,
+       0x8c040d0e, 0x0400000b, 0x84000550, 0x599c1017,
+       0x8c08150a, 0x04020004, 0x8c040d0a, 0x04000002,
+       0x8400054e, 0x8c040d1c, 0x04000002, 0x84000552,
+       0x4801a20a, 0x42000800, 0x00000005, 0x42001000,
+       0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f833,
+       0x4a01a006, 0x02100014, 0x4a01a007, 0x01000000,
+       0x4979a008, 0x4979a009, 0x4979a00a, 0x42000800,
+       0x00000005, 0x42001000, 0x0000dc00, 0x0201f000,
+       0x001078bc, 0x0401f825, 0x4a01a006, 0x02000000,
+       0x0401f65d, 0x4933c857, 0x0401f820, 0x4a01a006,
+       0x01000000, 0x4a01a407, 0x0000000b, 0x42000800,
+       0x00000002, 0x42001000, 0x0000dc00, 0x0201f000,
+       0x001078bc, 0x42005000, 0x32000000, 0x42006000,
+       0x08290000, 0x41786800, 0x41787800, 0x0401f3df,
+       0x42005000, 0x22000000, 0x42006000, 0x01290000,
+       0x41786800, 0x41787800, 0x0401f3d8, 0x42005000,
+       0x33000000, 0x42006000, 0x08980000, 0x41786800,
+       0x41787800, 0x0401f3d1, 0x42005000, 0x23000000,
+       0x42006000, 0x01980000, 0x41786800, 0x41787800,
+       0x0401f3ca, 0x59300403, 0x82000c80, 0x00000085,
+       0x02001800, 0x001005d8, 0x82000c80, 0x00000093,
+       0x02021800, 0x001005d8, 0x82000480, 0x00000085,
+       0x0c01f001, 0x001074eb, 0x001074ed, 0x001074fb,
+       0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb,
+       0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb,
+       0x001074eb, 0x001074eb, 0x00107506, 0x0201f800,
+       0x001005d8, 0x4933c857, 0x0401f850, 0x59300402,
+       0x4801a407, 0x5930001c, 0x4801a207, 0x4979a408,
+       0x4a01a208, 0x0000ffff, 0x42000800, 0x00000003,
+       0x42001000, 0x0000dc00, 0x0401f3c2, 0x4933c857,
+       0x0401f84e, 0x4a01a406, 0x00000003, 0x4a01a206,
+       0x00000300, 0x42000800, 0x00000001, 0x42001000,
+       0x0000dc00, 0x0401f3b7, 0x4d2c0000, 0x59325808,
+       0x4933c857, 0x492fc857, 0x812e59c0, 0x02000800,
+       0x001005d8, 0x59340a12, 0x82040d00, 0x0000ff00,
+       0x592c000a, 0x82000500, 0x000000ff, 0x900001c0,
+       0x80040540, 0x82000540, 0x00000011, 0x44034800,
+       0x81a5a000, 0x42001000, 0x00000009, 0x42000800,
+       0x00000003, 0x592c0009, 0x82000500, 0xff000000,
+       0x82001d80, 0x84000000, 0x04000009, 0x82001d80,
+       0x85000000, 0x02020800, 0x001005d8, 0x42001000,
+       0x00000007, 0x42000800, 0x00000001, 0x832c1c00,
+       0x00000009, 0x500c0000, 0x4401a000, 0x800c1800,
+       0x80d1a000, 0x80081040, 0x040207fb, 0x42001000,
+       0x0000dc00, 0x5c025800, 0x0401f386, 0x42005000,
+       0x81000000, 0x42006000, 0x00090000, 0x41786800,
+       0x41787800, 0x0401f35d, 0x42005000, 0x84000000,
+       0x42006000, 0x00990000, 0x59300406, 0x82000580,
+       0x00000005, 0x04000002, 0x8430652e, 0x41786800,
+       0x41787800, 0x0401f351, 0x42005000, 0x85000000,
+       0x42006000, 0x00990000, 0x59300406, 0x82000580,
+       0x00000005, 0x04000002, 0x8430652e, 0x41786800,
+       0x41787800, 0x0401f345, 0x59300403, 0x82000c80,
+       0x00000053, 0x02021800, 0x001005d8, 0x82000480,
+       0x0000004b, 0x02001800, 0x001005d8, 0x59326809,
+       0x59368c03, 0x4803c857, 0x0c01f001, 0x001075da,
+       0x001075e2, 0x001075ea, 0x001075f2, 0x0010756b,
+       0x0010756b, 0x0010756b, 0x001075d2, 0x0201f800,
+       0x001005d8, 0x42005000, 0x06000000, 0x42006000,
+       0x08290000, 0x41786800, 0x41787800, 0x0401f327,
+       0x4933c857, 0x0401ff47, 0x4a01a006, 0x12000000,
+       0x59300406, 0x82000580, 0x00000004, 0x04020003,
+       0x59340002, 0x0401f002, 0x59a80010, 0x82000500,
+       0x00ffffff, 0x4801a007, 0x59300419, 0x4801a408,
+       0x59300219, 0x4801a208, 0x4979a009, 0x4979a00a,
+       0x4979a00b, 0x4979a00c, 0x4979a00d, 0x4979a00e,
+       0x4979a00f, 0x4979a010, 0x42000800, 0x0000000b,
+       0x42001000, 0x0000dc00, 0x0401f32a, 0x0401ff29,
+       0x4a01a006, 0x0f000000, 0x5930001c, 0x4801a007,
+       0x42000800, 0x00000002, 0x42001000, 0x0000dc00,
+       0x0401f320, 0x0401ff2d, 0x4a01a006, 0x02000000,
+       0x59c40085, 0x48031004, 0x59880000, 0x4801a007,
+       0x59880001, 0x4801a008, 0x59880002, 0x4801a009,
+       0x59880003, 0x4801a00a, 0x59880004, 0x4801a00b,
+       0x59880005, 0x4801a00c, 0x42000800, 0x00000007,
+       0x42001000, 0x0000dc00, 0x0401f30a, 0x4a026202,
+       0x0000ffff, 0x0401ff07, 0x4a01a006, 0x62000000,
+       0x5930001c, 0x4801a007, 0x42000800, 0x00000002,
+       0x42001000, 0x0000dc00, 0x0401f2fe, 0x0401fefd,
+       0x59300808, 0x4c500000, 0x4c540000, 0x4c580000,
+       0x8204a400, 0x0000000a, 0x5930b01c, 0x82d0ac00,
+       0x00000006, 0x0201f800, 0x0010ab17, 0x5930081c,
+       0x42001000, 0x0000dc00, 0x5c00b000, 0x5c00a800,
+       0x5c00a000, 0x0401f2eb, 0x0401ff9b, 0x59300017,
+       0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+       0x00001000, 0x0401f020, 0x0401ff93, 0x59300017,
+       0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+       0x00004000, 0x0401f018, 0x0401ff8b, 0x59300017,
+       0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+       0x00002000, 0x0401f010, 0x0401ff83, 0x59300017,
+       0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+       0x00000400, 0x0401f008, 0x0401ff7b, 0x59300017,
+       0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+       0x00000200, 0x4979a009, 0x4979a00a, 0x4979a00b,
+       0x4979a00c, 0x4979a00d, 0x42000800, 0x00000008,
+       0x42001000, 0x0000dc00, 0x0401f2ba, 0x0401fec7,
+       0x4a01a006, 0x02000014, 0x4979a407, 0x4979a207,
+       0x59a8003a, 0x4801a008, 0x59a8003b, 0x4801a009,
+       0x4a01a00a, 0x00047878, 0x42000800, 0x00000005,
+       0x42001000, 0x0000dc00, 0x0401f2aa, 0x0401feb7,
+       0x4a01a006, 0x02140018, 0x4a01a407, 0x00000800,
+       0x5930001c, 0x82000d00, 0xff000000, 0x900409c0,
+       0x4805a207, 0x82000500, 0x00ffffff, 0x4801a00a,
+       0x4979a408, 0x4979a208, 0x4979a409, 0x4979a209,
+       0x4979a00b, 0x42000800, 0x00000006, 0x42001000,
+       0x0000dc00, 0x0401f293, 0x4803c856, 0x4d380000,
+       0x4d1c0000, 0x42027000, 0x00000035, 0x0201f800,
+       0x001093ba, 0x0402001e, 0x0401fe8a, 0x4a01a006,
+       0x13000000, 0x5932381e, 0x591c0019, 0x4801a005,
+       0x591c0406, 0x82000580, 0x00000003, 0x04000007,
+       0x59300809, 0x58040002, 0x82000500, 0x00ffffff,
+       0x4801a007, 0x0401f003, 0x59a80010, 0x4801a007,
+       0x59300419, 0x4801a408, 0x59300219, 0x4801a208,
+       0x42000800, 0x00000003, 0x42001000, 0x0000dc00,
+       0x5c023800, 0x5c027000, 0x0401f26e, 0x0201f800,
+       0x00106c55, 0x598c000d, 0x81300580, 0x02020800,
+       0x001005d8, 0x0201f800, 0x00106bbf, 0x0201f800,
+       0x0002077d, 0x5c023800, 0x5c027000, 0x0201f000,
+       0x00106c4b, 0x4803c856, 0x4d2c0000, 0x4d1c0000,
+       0x5932381e, 0x811e39c0, 0x02000800, 0x001005d8,
+       0x591c0c06, 0x82040580, 0x00000006, 0x0400000d,
+       0x82040580, 0x00000003, 0x04000036, 0x4a026403,
+       0x00000037, 0x4a02641a, 0x00000003, 0x4a02621a,
+       0x00001700, 0x5c023800, 0x5c025800, 0x0401f064,
+       0x0401f84b, 0x42001000, 0x40000000, 0x591c0203,
+       0x591c0804, 0x8c040d3e, 0x04020023, 0x82000c80,
+       0x0000000e, 0x0c001003, 0x0201f800, 0x001005d8,
+       0x00107691, 0x0010769d, 0x00107693, 0x0010769d,
+       0x00107699, 0x00107691, 0x00107691, 0x0010769d,
+       0x0010769d, 0x00107691, 0x00107691, 0x00107691,
+       0x00107691, 0x00107691, 0x0010769d, 0x00107691,
+       0x0010769d, 0x0201f800, 0x001005d8, 0x591c0414,
+       0x4803c857, 0x8c000518, 0x04000003, 0x8c000512,
+       0x04000003, 0x80001580, 0x0401f003, 0x42001000,
+       0x20000000, 0x591c0015, 0x4801a00a, 0x0401f018,
+       0x0401f81f, 0x591e5808, 0x812e59c0, 0x02000800,
+       0x001005d8, 0x592c100f, 0x591c0011, 0x80080480,
+       0x4801a00a, 0x591c0203, 0x591c0804, 0x8c040d3e,
+       0x04020007, 0x82000d80, 0x00000002, 0x04000007,
+       0x82000d80, 0x00000004, 0x04000004, 0x42001000,
+       0x40000000, 0x0401f002, 0x80001580, 0x4809a00b,
+       0x42000800, 0x00000006, 0x42001000, 0x0000dc00,
+       0x5c023800, 0x5c025800, 0x0401f1fe, 0x4803c856,
+       0x0401fe0a, 0x4a01a006, 0x02000000, 0x59300c19,
+       0x4805a407, 0x59300a19, 0x4805a207, 0x59a81010,
+       0x59300809, 0x58041802, 0x820c1d00, 0x00ffffff,
+       0x5930081e, 0x58040406, 0x82000580, 0x00000003,
+       0x04020004, 0x4809a008, 0x480da009, 0x0401f003,
+       0x480da008, 0x4809a009, 0x1c01f000, 0x4803c856,
+       0x0401fdf2, 0x0401f003, 0x4803c856, 0x0401fde8,
+       0x4a01a006, 0x01000000, 0x5930041a, 0x4801a407,
+       0x5930021a, 0x4801a207, 0x42000800, 0x00000002,
+       0x42001000, 0x0000dc00, 0x0401f1d6, 0x4803c856,
+       0x4d1c0000, 0x0401fdcc, 0x4a01a006, 0x14000000,
+       0x5932381e, 0x591c0019, 0x4801a005, 0x59300419,
+       0x4801a407, 0x59300219, 0x4801a207, 0x59300015,
+       0x4801a008, 0x59300216, 0x82000500, 0x000000ff,
+       0x840001c0, 0x4801a409, 0x42000800, 0x00000004,
+       0x42001000, 0x0000dc00, 0x5c023800, 0x0401f1bd,
+       0x4803c856, 0x0401f80b, 0x5930041a, 0x900001c0,
+       0x4801a005, 0x0401f9ec, 0x41780800, 0x42001000,
+       0x00005c00, 0x0401f9b3, 0x0201f000, 0x0010604d,
+       0x4803c856, 0x59300817, 0x82041c00, 0x00000005,
+       0x46034800, 0x00000021, 0x58040404, 0x82000500,
+       0x0000f000, 0x82000580, 0x00003000, 0x04000003,
+       0x46034800, 0x00000041, 0x81a5a000, 0x580c0001,
+       0x82000d00, 0x00ffffff, 0x82040d40, 0xc2000000,
+       0x4805a000, 0x580c0800, 0x82041500, 0x00ffffff,
+       0x82000500, 0xff000000, 0x80080540, 0x4801a001,
+       0x580c0002, 0x82000580, 0x00c00000, 0x82000500,
+       0x00fd0300, 0x4801a002, 0x580c0003, 0x4801a003,
+       0x580c0404, 0x4801a404, 0x580c0204, 0x4801a204,
+       0x1c01f000, 0x4803c856, 0x59a80026, 0x82000500,
+       0x00000028, 0x04020009, 0x59a80026, 0x82000500,
+       0x00000028, 0x04000003, 0x497a6a12, 0x0401f003,
+       0x4a026a12, 0x0000ff00, 0x42005000, 0x22000000,
+       0x42006000, 0x01380000, 0x41786800, 0x41787800,
+       0x0401f952, 0x59301008, 0x4a01a006, 0x54000000,
+       0x59a80010, 0x82000500, 0x00ffffff, 0x58080c0a,
+       0x800408f0, 0x80040540, 0x4801a007, 0x5808000a,
+       0x82000500, 0xff000000, 0x4801a008, 0x59a80002,
+       0x4801a009, 0x59a80003, 0x4801a00a, 0x59a80000,
+       0x4801a00b, 0x59a80001, 0x4801a00c, 0x5808000c,
+       0x9c0001c0, 0x4801a00d, 0x5808000d, 0x9c0001c0,
+       0x4801a00e, 0x5808000e, 0x9c0001c0, 0x4801a00f,
+       0x5808000f, 0x9c0001c0, 0x4801a010, 0x58080010,
+       0x9c0001c0, 0x4801a011, 0x58080011, 0x9c0001c0,
+       0x4801a012, 0x58080012, 0x9c0001c0, 0x4801a013,
+       0x58080013, 0x9c0001c0, 0x4801a014, 0x58080010,
+       0x9c0001c0, 0x4801a015, 0x58080011, 0x9c0001c0,
+       0x4801a016, 0x58080012, 0x9c0001c0, 0x4801a017,
+       0x58080013, 0x9c0001c0, 0x4801a018, 0x42000800,
+       0x00000013, 0x42001000, 0x0000dc00, 0x0401f135,
+       0x4803c856, 0x42005000, 0x22000000, 0x42006000,
+       0x01290000, 0x41786800, 0x41787800, 0x0401f90b,
+       0x59301008, 0x4a01a006, 0x55000000, 0x5808000b,
+       0x82000500, 0x00ffffff, 0x58080c0a, 0x800408f0,
+       0x80040540, 0x4801a007, 0x5808080a, 0x82040d00,
+       0xff000000, 0x59a80010, 0x82000500, 0x00ffffff,
+       0x80040540, 0x4801a008, 0x5808000c, 0x9c0001c0,
+       0x4801a009, 0x5808000d, 0x9c0001c0, 0x4801a00a,
+       0x5808000e, 0x9c0001c0, 0x4801a00b, 0x5808000f,
+       0x9c0001c0, 0x4801a00c, 0x59a80002, 0x4801a00d,
+       0x59a80003, 0x4801a00e, 0x59a80000, 0x4801a00f,
+       0x59a80001, 0x4801a010, 0x58080010, 0x4801a011,
+       0x58080011, 0x4801a012, 0x58080012, 0x4801a013,
+       0x58080013, 0x4801a014, 0x4979a015, 0x4979a016,
+       0x4979a017, 0x4979a018, 0x42000800, 0x00000013,
+       0x42001000, 0x0000dc00, 0x0401f0f6, 0x0401fd03,
+       0x5930001c, 0x800001c0, 0x04000008, 0x4a01a006,
+       0x01000000, 0x4a01a407, 0x00000003, 0x42000800,
+       0x00000002, 0x0401f028, 0x4a01a006, 0x02000000,
+       0x41780800, 0x836c0580, 0x00000004, 0x04020003,
+       0x84040d42, 0x0401f00d, 0x0201f800, 0x0010513b,
+       0x04020003, 0x84040d4a, 0x0401f002, 0x84040d48,
+       0x59a80026, 0x8c000506, 0x04020003, 0x8c00050a,
+       0x04000002, 0x84040d46, 0x4805a207, 0x59c40085,
+       0x48031004, 0x4c580000, 0x4c500000, 0x4c540000,
+       0x4200b000, 0x00000006, 0x8388a400, 0x00000000,
+       0x82d0ac00, 0x00000008, 0x0201f800, 0x0010ab17,
+       0x5c00a800, 0x5c00a000, 0x5c00b000, 0x42000800,
+       0x00000008, 0x42001000, 0x0000dc00, 0x0401f0c1,
+       0x0401fcc0, 0x4a01a006, 0x56000000, 0x59340006,
+       0x4801a007, 0x59340007, 0x4801a008, 0x42000800,
+       0x00000003, 0x42001000, 0x0000dc00, 0x0401f0b5,
+       0x4803c856, 0x0401fcc1, 0x5930081c, 0x800409c0,
+       0x0400000e, 0x82040580, 0x0000ffff, 0x04000004,
+       0x82040480, 0x00000007, 0x04021008, 0x4a01a006,
+       0x01000000, 0x4a01a407, 0x00000003, 0x42000800,
+       0x00000002, 0x0401f012, 0x4a01a006, 0x0200001c,
+       0x4a01a007, 0x00000001, 0x42001000, 0x0010b4f0,
+       0x50080000, 0x9c0001c0, 0x4801a009, 0x59a80010,
+       0x4801a00a, 0x59a80002, 0x59a80803, 0x4801a00b,
+       0x4805a00c, 0x42000800, 0x00000007, 0x42001000,
+       0x0000dc00, 0x0401f08f, 0x4d2c0000, 0x0401fc8d,
+       0x59325808, 0x592c0008, 0x82000500, 0x00ffffff,
+       0x4801a001, 0x4a01a006, 0x51000000, 0x5c025800,
+       0x0201f000, 0x00107344, 0x4803c856, 0x59a80810,
+       0x82040d00, 0x000000ff, 0x59325808, 0x59326809,
+       0x59a83026, 0x8c18350a, 0x04020008, 0x8c00050e,
+       0x04020006, 0x80001d80, 0x59a82010, 0x82102500,
+       0x000000ff, 0x0401f001, 0x59300406, 0x4803c857,
+       0x82000d80, 0x00000009, 0x04000006, 0x82000d80,
+       0x0000000a, 0x0400002e, 0x0201f800, 0x001005d8,
+       0x59300015, 0x8c00051e, 0x04020020, 0x42005000,
+       0x04000000, 0x42006000, 0x05000000, 0x592c040a,
+       0x82000500, 0x00000030, 0x800000e0, 0x80306540,
+       0x5934000a, 0x8c000508, 0x04000002, 0x84306546,
+       0x41786800, 0x41787800, 0x0401f831, 0x59300c14,
+       0x80040000, 0x48026414, 0x40040000, 0x800000d0,
+       0x82000540, 0x00000020, 0x4801a403, 0x83180d40,
+       0x00000038, 0x42001000, 0x0000c920, 0x0401f860,
+       0x0201f000, 0x00106052, 0x59a80026, 0x82000500,
+       0x00000028, 0x04000003, 0x497a6a12, 0x0401f7dc,
+       0x4a026a12, 0x0000ff00, 0x0401f7d9, 0x42005000,
+       0x02000000, 0x42006000, 0x20290000, 0x41786800,
+       0x41787800, 0x0401f812, 0x83180d40, 0x00000038,
+       0x42001000, 0x0000c9a0, 0x0401f849, 0x42000800,
+       0x000007d0, 0x59300011, 0x82000500, 0xfff00000,
+       0x80000540, 0x04000003, 0x42000800, 0x00001b58,
+       0x41781000, 0x0201f000, 0x00106054, 0x4201a000,
+       0x00000000, 0x0401f003, 0x4201a000, 0x00000011,
+       0x59340a12, 0x82040d00, 0x0000ff00, 0x59a80010,
+       0x82000500, 0x000000ff, 0x900001c0, 0x80040540,
+       0x80d00540, 0x44034800, 0x81a5a000, 0x59340002,
+       0x82000500, 0x00ffffff, 0x80280540, 0x4801a000,
+       0x59a80010, 0x4801a001, 0x4831a002, 0x82340540,
+       0x00000000, 0x4801a003, 0x59300402, 0x4801a404,
+       0x59300a02, 0x4805a204, 0x8c30652e, 0x04000003,
+       0x4805a404, 0x4801a204, 0x483da005, 0x1c01f000,
+       0x4803c856, 0x4c040000, 0x0401f822, 0x5c000800,
+       0x40040000, 0x80081540, 0x800000c4, 0x82000540,
+       0x00002000, 0x4803910a, 0x59b400f6, 0x82000500,
+       0x00000018, 0x040207fd, 0x4a0368f0, 0x0010b544,
+       0x4a0368f1, 0x0010b54b, 0x480b68f3, 0x4a0378e4,
+       0x00008000, 0x0201f000, 0x0010604d, 0x4807c857,
+       0x480a2800, 0x4c040000, 0x0401f80a, 0x5c000800,
+       0x59b400f6, 0x8c00050a, 0x040207fe, 0x49a768f2,
+       0x480768f4, 0x4a0378e4, 0x00008000, 0x1c01f000,
+       0x4a0378e4, 0x0000c000, 0x59bc00e4, 0x8c000520,
+       0x0400000c, 0x4a0378e4, 0x00008000, 0x42007000,
+       0x000003e8, 0x59bc00e4, 0x8c000520, 0x040007f5,
+       0x80387040, 0x02000800, 0x001005d8, 0x0401f7fa,
+       0x1c01f000, 0x82000500, 0xffff0000, 0x82000580,
+       0x01050000, 0x0402000d, 0x599c0818, 0x8c040d10,
+       0x0400000a, 0x59a80807, 0x8c040d0a, 0x04000007,
+       0x42001000, 0x0000804f, 0x41781800, 0x41782000,
+       0x0201f800, 0x00103a3e, 0x1c01f000, 0x41781000,
+       0x42026000, 0x0010d1c0, 0x59a8180e, 0x480a6402,
+       0x4a026202, 0x0000ffff, 0x80081000, 0x800c1840,
+       0x04000004, 0x83326400, 0x00000024, 0x0401f7f8,
+       0x1c01f000, 0x4933c857, 0x59300203, 0x82000580,
+       0x00000000, 0x0400002c, 0x59300406, 0x4803c857,
+       0x82000d80, 0x00000004, 0x04000011, 0x82000d80,
+       0x00000001, 0x0400000e, 0x82000d80, 0x00000003,
+       0x04000006, 0x82000d80, 0x00000006, 0x04020011,
+       0x0201f800, 0x0010a5df, 0x5930001c, 0x800001c0,
+       0x02020800, 0x0010984e, 0x0401f00a, 0x5930081e,
+       0x4807c857, 0x800409c0, 0x04000006, 0x5804001c,
+       0x4803c857, 0x81300580, 0x04020002, 0x4978081c,
+       0x497a6008, 0x4a026004, 0x00004000, 0x59a80037,
+       0x82000c80, 0x00000051, 0x04001002, 0x80000102,
+       0x48026206, 0x497a6205, 0x497a6009, 0x4a026406,
+       0x00000007, 0x1c01f000, 0x8166c9c0, 0x0400001c,
+       0x41626000, 0x41580000, 0x59300a03, 0x82040d80,
+       0x00000000, 0x04000008, 0x83326400, 0x00000024,
+       0x81300c80, 0x040017f9, 0x42026000, 0x0010d1c0,
+       0x0401f7f6, 0x4933c857, 0x8166c840, 0x83300c00,
+       0x00000024, 0x80040480, 0x04021006, 0x4006c000,
+       0x4a026203, 0x00000008, 0x813261c0, 0x1c01f000,
+       0x4202c000, 0x0010d1c0, 0x0401f7fa, 0x42000000,
+       0x0010b854, 0x0201f800, 0x0010aa47, 0x4933c856,
+       0x417a6000, 0x0401f7f5, 0x4933c857, 0x83380580,
+       0x00000013, 0x0402000b, 0x59300004, 0x8c00053e,
+       0x04000007, 0x0201f800, 0x00106c55, 0x0201f800,
+       0x00106bbf, 0x0201f800, 0x00106c4b, 0x1c01f000,
+       0x4933c857, 0x59880052, 0x80000000, 0x48031052,
+       0x1c01f000, 0x4933c857, 0x59300203, 0x82003480,
+       0x0000000e, 0x02021800, 0x001005d8, 0x4d2c0000,
+       0x0c01f803, 0x5c025800, 0x1c01f000, 0x00107991,
+       0x00107efd, 0x0010804a, 0x00107991, 0x001080b0,
+       0x00107af5, 0x00107991, 0x00107991, 0x00107e93,
+       0x00107991, 0x00107991, 0x00107991, 0x00107991,
+       0x00107991, 0x0201f800, 0x001005d8, 0x4933c857,
+       0x59300203, 0x82003480, 0x0000000e, 0x02021800,
+       0x001005d8, 0x0c01f001, 0x001079a8, 0x00108a3d,
+       0x001079a8, 0x001079a8, 0x001079a8, 0x001079a8,
+       0x001079a8, 0x001079a8, 0x001089e5, 0x00108a58,
+       0x00108ac6, 0x00108a58, 0x00108ac6, 0x001079a8,
+       0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8,
+       0x4933c857, 0x4d2c0000, 0x59325808, 0x59300203,
+       0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+       0x0c01f803, 0x5c025800, 0x1c01f000, 0x001079c5,
+       0x001079c5, 0x001079c5, 0x001079e1, 0x00107a2d,
+       0x001079c5, 0x001079c5, 0x001079c5, 0x001079c7,
+       0x001079c5, 0x001079c5, 0x001079c5, 0x001079c5,
+       0x001079c5, 0x0201f800, 0x001005d8, 0x4933c857,
+       0x83380580, 0x00000040, 0x02020800, 0x001005d8,
+       0x4a026007, 0x00082000, 0x4a026203, 0x00000003,
+       0x493a6403, 0x4a025c08, 0x00000001, 0x592c000d,
+       0x48026011, 0x497a6013, 0x592c0208, 0x800000c2,
+       0x800010c4, 0x80081400, 0x480a6206, 0x0201f800,
+       0x00100f4e, 0x42000800, 0x80000060, 0x0201f000,
+       0x00106721, 0x4933c857, 0x83380480, 0x00000050,
+       0x02021800, 0x001005d8, 0x83380480, 0x00000049,
+       0x02001800, 0x001005d8, 0x0c01f001, 0x001079f4,
+       0x001079ff, 0x001079f2, 0x001079f2, 0x001079f2,
+       0x001079f2, 0x00107a0a, 0x0201f800, 0x001005d8,
+       0x4a026203, 0x00000004, 0x4a025c08, 0x00000002,
+       0x592c0207, 0x48025c09, 0x592c0209, 0x48025a07,
+       0x592c000c, 0x4802580d, 0x1c01f000, 0x0201f800,
+       0x00106b8a, 0x0201f800, 0x00109037, 0x04000005,
+       0x4a025a06, 0x00000006, 0x0201f800, 0x000202da,
+       0x0201f000, 0x0002077d, 0x0201f800, 0x00106b8a,
+       0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x5c027800, 0x42003000, 0x00000014, 0x41782800,
+       0x42002000, 0x00000002, 0x4d400000, 0x4d440000,
+       0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+       0x0010985e, 0x5c028800, 0x5c028000, 0x42000000,
+       0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+       0x00109037, 0x02000000, 0x0002077d, 0x4a025a06,
+       0x00000029, 0x0201f800, 0x000202da, 0x0201f000,
+       0x0002077d, 0x4933c857, 0x83380580, 0x00000048,
+       0x04000005, 0x83380580, 0x00000053, 0x02020800,
+       0x001005d8, 0x592c0206, 0x82000580, 0x00000007,
+       0x04000009, 0x59300011, 0x80000540, 0x04000006,
+       0x592c080c, 0x80040480, 0x4802580c, 0x4a025a06,
+       0x00000015, 0x592c0206, 0x80000540, 0x04020003,
+       0x4a025a06, 0x00000000, 0x0201f800, 0x000202da,
+       0x0201f000, 0x0002077d, 0x4933c857, 0x4d2c0000,
+       0x4c500000, 0x4c540000, 0x4c580000, 0x0201f800,
+       0x001007e4, 0x02000800, 0x001005d8, 0x497a5a06,
+       0x59c80017, 0x82000500, 0x0000f000, 0x48025c07,
+       0x59a80816, 0x82040c00, 0x00000018, 0x48065a07,
+       0x412c7800, 0x4d2c0000, 0x41cca000, 0x42002800,
+       0x00000001, 0x42001000, 0x0000002c, 0x82040480,
+       0x0000002d, 0x04021006, 0x832cac00, 0x00000009,
+       0x0201f800, 0x00108b96, 0x0401f02e, 0x40043000,
+       0x42000800, 0x0000002c, 0x832cac00, 0x00000009,
+       0x0201f800, 0x00108b96, 0x82183480, 0x0000002c,
+       0x0201f800, 0x001007e4, 0x0400001a, 0x80142800,
+       0x4a025804, 0x00000110, 0x492c7801, 0x82180c80,
+       0x0000003d, 0x04021007, 0x40180800, 0x832cac00,
+       0x00000005, 0x0201f800, 0x00108b96, 0x0401f015,
+       0x82081400, 0x0000003c, 0x82183480, 0x0000003c,
+       0x42000800, 0x0000003c, 0x412c7800, 0x832cac00,
+       0x00000005, 0x0201f800, 0x00108b96, 0x0401f7e5,
+       0x5c025800, 0x592c0206, 0x8400055e, 0x48025a06,
+       0x592c0407, 0x80080540, 0x48025c07, 0x0401f002,
+       0x5c025800, 0x813669c0, 0x04000003, 0x59343403,
+       0x0401f003, 0x42003000, 0x0000ffff, 0x49325808,
+       0x481a5c06, 0x82100580, 0x00000054, 0x04020002,
+       0x491e5813, 0x841401c0, 0x80100540, 0x48025804,
+       0x592c0001, 0x497a5801, 0x4c000000, 0x0201f800,
+       0x000202da, 0x5c025800, 0x812e59c0, 0x040207f9,
+       0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800,
+       0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000,
+       0x4c500000, 0x4c540000, 0x4c580000, 0x412cb800,
+       0x592c040b, 0x8c000516, 0x04000003, 0x41cca000,
+       0x0401f003, 0x83cca400, 0x00000006, 0x4008b000,
+       0x41781000, 0x82580480, 0x00000012, 0x04001004,
+       0x4200b000, 0x00000012, 0x40001000, 0x4c080000,
+       0x4d2c0000, 0x0201f800, 0x001007e4, 0x04000023,
+       0x5c001800, 0x492c1801, 0x485a5800, 0x832cac00,
+       0x00000002, 0x0201f800, 0x0010ab28, 0x585c040b,
+       0x8c000500, 0x0400000e, 0x832c1400, 0x00000002,
+       0x8c000516, 0x04000003, 0x82081400, 0x00000006,
+       0x46001000, 0x00000001, 0x80081000, 0x46001000,
+       0x00000900, 0x84000500, 0x4800bc0b, 0x5c001000,
+       0x800811c0, 0x040207da, 0x82000540, 0x00000001,
+       0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800,
+       0x5c00b800, 0x1c01f000, 0x5c025800, 0x5c001000,
+       0x0401f7f8, 0x4933c857, 0x83380d80, 0x00000015,
+       0x04020003, 0x0201f000, 0x0002077d, 0x83380d80,
+       0x00000016, 0x02020800, 0x001005d8, 0x0201f000,
+       0x0002077d, 0x4933c857, 0x4d2c0000, 0x4c500000,
+       0x4c540000, 0x4c580000, 0x59325808, 0x83cca400,
+       0x00000006, 0x59cc1806, 0x820c0580, 0x01000000,
+       0x04020004, 0x4200b000, 0x00000002, 0x0401f00f,
+       0x4200b000, 0x00000008, 0x832cac00, 0x00000005,
+       0x0201f800, 0x0010ab17, 0x8c0c1d00, 0x0400000b,
+       0x4200b000, 0x00000008, 0x592e5801, 0x812e59c0,
+       0x02000800, 0x001005d8, 0x832cac00, 0x00000005,
+       0x0201f800, 0x0010ab17, 0x0401f816, 0x5c00b000,
+       0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000,
+       0x4933c857, 0x4c500000, 0x4c540000, 0x4c580000,
+       0x83cca400, 0x00000006, 0x5930a808, 0x8254ac00,
+       0x00000005, 0x4200b000, 0x00000007, 0x0201f800,
+       0x0010ab17, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+       0x4933c857, 0x0201f800, 0x00109037, 0x02000000,
+       0x0002077d, 0x4d2c0000, 0x0201f800, 0x00109597,
+       0x0402000b, 0x41780800, 0x4d400000, 0x42028000,
+       0x00000000, 0x0201f800, 0x0010943b, 0x5c028000,
+       0x5c025800, 0x0201f000, 0x0002077d, 0x5931d821,
+       0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103,
+       0x58ec0009, 0x0801f800, 0x5c025800, 0x0201f000,
+       0x0002077d, 0x4933c857, 0x59cc1806, 0x820c0580,
+       0x02000000, 0x04020014, 0x4a026802, 0x00fffffd,
+       0x5934000a, 0x84000504, 0x4802680a, 0x59300808,
+       0x800409c0, 0x02000000, 0x0002077d, 0x4a000a04,
+       0x00000103, 0x480c0805, 0x5931d821, 0x58ef400b,
+       0x58ee580d, 0x58ec0009, 0x0801f800, 0x0201f000,
+       0x0002077d, 0x42000000, 0x0010b86c, 0x0201f800,
+       0x0010aa47, 0x4c0c0000, 0x0401f804, 0x5c001800,
+       0x040207eb, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+       0x59325808, 0x812e59c0, 0x04020009, 0x497a6206,
+       0x497a6205, 0x4d380000, 0x42027000, 0x00000022,
+       0x0401fb77, 0x5c027000, 0x80000580, 0x5c025800,
+       0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c500000,
+       0x4c540000, 0x4c580000, 0x59325808, 0x592e5801,
+       0x832cac00, 0x00000005, 0x83cca400, 0x00000006,
+       0x59c80817, 0x82040d00, 0x000003ff, 0x82041480,
+       0x0000000f, 0x0400101b, 0x4200b000, 0x0000000f,
+       0x0201f800, 0x0010ab17, 0x592e5801, 0x832cac00,
+       0x00000005, 0x82080c80, 0x0000000f, 0x0400100d,
+       0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab17,
+       0x592e5801, 0x832cac00, 0x00000005, 0x82041480,
+       0x0000000f, 0x04001007, 0x42001000, 0x0000000f,
+       0x4008b000, 0x0201f800, 0x0010ab17, 0x0401f004,
+       0x4004b000, 0x0201f800, 0x0010ab17, 0x5931d821,
+       0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103,
+       0x592e5801, 0x58ec0009, 0x0801f800, 0x0201f800,
+       0x0002077d, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+       0x4c500000, 0x4c540000, 0x4c580000, 0x59cc0006,
+       0x82000d80, 0x01000000, 0x0400002c, 0x59cc0007,
+       0x9000b1c0, 0x8258b500, 0x000000ff, 0x8058b104,
+       0x8258b400, 0x00000002, 0x82580c80, 0x00000007,
+       0x04001003, 0x4200b000, 0x00000006, 0x83cca400,
+       0x00000006, 0x59301008, 0x800811c0, 0x02000800,
+       0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800,
+       0x0010ab17, 0x82000d00, 0xff000000, 0x800409c0,
+       0x04000019, 0x8200b500, 0x000000ff, 0x8058b104,
+       0x82580c80, 0x0000000e, 0x04001003, 0x4200b000,
+       0x0000000d, 0x58081001, 0x800811c0, 0x02000800,
+       0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800,
+       0x0010ab17, 0x0401f008, 0x59301008, 0x800811c0,
+       0x02000800, 0x001005d8, 0x48001005, 0x59cc0007,
+       0x48001006, 0x0401ff3b, 0x5c00b000, 0x5c00a800,
+       0x5c00a000, 0x5c025800, 0x1c01f000, 0x4933c857,
+       0x42000800, 0x00000000, 0x59cc0006, 0x82000580,
+       0x02000000, 0x04000003, 0x42000800, 0x00000001,
+       0x4d2c0000, 0x59325808, 0x812e59c0, 0x02000800,
+       0x001005d8, 0x48065a06, 0x0201f800, 0x000202da,
+       0x5c025800, 0x0201f000, 0x0002077d, 0x4933c857,
+       0x4d2c0000, 0x4c500000, 0x4c540000, 0x4c580000,
+       0x4200b000, 0x00000002, 0x59cc0806, 0x82040580,
+       0x01000000, 0x04000004, 0x8204b500, 0x0000ffff,
+       0x8058b104, 0x83cca400, 0x00000006, 0x59300008,
+       0x8200ac00, 0x00000005, 0x0201f800, 0x0010ab17,
+       0x0401ff0c, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x4803c857,
+       0x4807c857, 0x480bc857, 0x480fc857, 0x4813c857,
+       0x481bc857, 0x492fc857, 0x4d2c0000, 0x4c000000,
+       0x0201f800, 0x001007d3, 0x5c000000, 0x0400000f,
+       0x48025803, 0x5c000000, 0x4802580a, 0x4c000000,
+       0x481a5801, 0x48125809, 0x48065804, 0x480a5807,
+       0x480e5808, 0x412c1000, 0x0201f800, 0x00100858,
+       0x82000540, 0x00000001, 0x5c025800, 0x1c01f000,
+       0x4933c857, 0x4d1c0000, 0x59cc0001, 0x82000500,
+       0x00ffffff, 0x59341002, 0x82081500, 0x00ffffff,
+       0x80080580, 0x0402001f, 0x497a6205, 0x4d380000,
+       0x42027000, 0x00000035, 0x0201f800, 0x001093ba,
+       0x5c027000, 0x04020012, 0x591c001c, 0x800001c0,
+       0x0400000f, 0x497a381c, 0x591c0414, 0x8c000502,
+       0x02000800, 0x001005d8, 0x84000502, 0x48023c14,
+       0x591c1406, 0x82080580, 0x00000003, 0x04000006,
+       0x82080580, 0x00000006, 0x04000005, 0x0401fc9e,
+       0x0401f004, 0x0401f805, 0x0401f002, 0x0401f8c0,
+       0x5c023800, 0x1c01f000, 0x4d2c0000, 0x591e5808,
+       0x4933c857, 0x491fc857, 0x493bc857, 0x492fc857,
+       0x83380580, 0x00000015, 0x040000b3, 0x83380580,
+       0x00000016, 0x040200ae, 0x4d300000, 0x411e6000,
+       0x59cc0207, 0x4803c857, 0x82000d00, 0x0000ff00,
+       0x82040580, 0x00001700, 0x04000004, 0x82040580,
+       0x00000300, 0x0402005b, 0x591c0203, 0x4803c857,
+       0x82000580, 0x0000000d, 0x0400003f, 0x812e59c0,
+       0x0400009a, 0x591c0202, 0x4803c857, 0x82000580,
+       0x0000ffff, 0x0402007e, 0x592c020a, 0x4803c857,
+       0x82000500, 0x00000003, 0x82000580, 0x00000002,
+       0x04020007, 0x592c080f, 0x591c0011, 0x4803c857,
+       0x4807c857, 0x80040580, 0x04020071, 0x591c0414,
+       0x4803c857, 0x8c000500, 0x0402006d, 0x41780800,
+       0x591c1206, 0x42000000, 0x0000000a, 0x0201f800,
+       0x001066a0, 0x592c0406, 0x4803c857, 0x800001c0,
+       0x0400000c, 0x80080c80, 0x04001004, 0x02020800,
+       0x001005d8, 0x80001040, 0x480a5c06, 0x800811c0,
+       0x04020004, 0x0201f800, 0x00108d88, 0x0401f06b,
+       0x0201f800, 0x0010912a, 0x591c0817, 0x591c0018,
+       0x48065808, 0x48025809, 0x59300007, 0x8c000500,
+       0x02020800, 0x00100e99, 0x497a3808, 0x0201f800,
+       0x000201ba, 0x0402004a, 0x411e6000, 0x0401fc3e,
+       0x0401f05a, 0x0401fc6d, 0x04000013, 0x49366009,
+       0x4a026406, 0x00000003, 0x492e6008, 0x591c0817,
+       0x591c1018, 0x48066017, 0x480a6018, 0x4d380000,
+       0x591e7403, 0x4d300000, 0x411e6000, 0x0401fc2e,
+       0x5c026000, 0x0201f800, 0x000207a1, 0x5c027000,
+       0x0401f046, 0x59a80039, 0x48023a05, 0x0401f043,
+       0x59cc0407, 0x82000580, 0x0000000b, 0x04020025,
+       0x59340a00, 0x84040d0e, 0x48066a00, 0x592c0a04,
+       0x82040d00, 0x000000ff, 0x82040d80, 0x00000014,
+       0x04000003, 0x4a02621d, 0x00000003, 0x59300007,
+       0x8c000500, 0x02020800, 0x00100e99, 0x4d400000,
+       0x42028000, 0x00000003, 0x592c0a08, 0x0201f800,
+       0x00104e70, 0x0201f800, 0x000202da, 0x5c028000,
+       0x497a6008, 0x4a026403, 0x00000085, 0x4a026203,
+       0x00000009, 0x4a026406, 0x00000002, 0x42000800,
+       0x8000404b, 0x0201f800, 0x00020721, 0x0401f01b,
+       0x59cc0207, 0x82000580, 0x00002a00, 0x04020004,
+       0x59a80039, 0x48023a05, 0x0401f014, 0x812e59c0,
+       0x02000800, 0x001005d8, 0x4a025a04, 0x00000103,
+       0x591c0007, 0x8c000500, 0x02020800, 0x00100e99,
+       0x591c0402, 0x48025c06, 0x4a025a06, 0x00000003,
+       0x0201f800, 0x000202c1, 0x0201f800, 0x00107911,
+       0x0201f800, 0x001049b2, 0x5c026000, 0x0201f800,
+       0x0002077d, 0x0401f002, 0x5c026000, 0x5c025800,
+       0x1c01f000, 0x0401f819, 0x0401f7fd, 0x4933c857,
+       0x83380580, 0x00000015, 0x04020004, 0x59a80039,
+       0x48023a05, 0x0401f00d, 0x83380580, 0x00000016,
+       0x0402000d, 0x4d300000, 0x411e6000, 0x0201f800,
+       0x0010a5df, 0x0201f800, 0x000206fd, 0x0201f800,
+       0x0002077d, 0x5c026000, 0x497a381c, 0x0201f800,
+       0x0002077d, 0x1c01f000, 0x591c0414, 0x84000540,
+       0x48023c14, 0x59cc100b, 0x4933c857, 0x491fc857,
+       0x492fc857, 0x4803c857, 0x480bc857, 0x8c08153c,
+       0x04000006, 0x59a80039, 0x48023a05, 0x497a381c,
+       0x0201f000, 0x0002077d, 0x4d300000, 0x411e6000,
+       0x0201f800, 0x00108bd7, 0x5c026000, 0x591c0406,
+       0x82000580, 0x00000000, 0x02000000, 0x0002077d,
+       0x591c0403, 0x82000580, 0x00000050, 0x0402000d,
+       0x4d300000, 0x411e6000, 0x4a026203, 0x00000001,
+       0x42000800, 0x80000043, 0x0201f800, 0x00020721,
+       0x5c026000, 0x497a381c, 0x0201f000, 0x0002077d,
+       0x591c0203, 0x82000580, 0x0000000d, 0x04000014,
+       0x812e59c0, 0x02000800, 0x001005d8, 0x591c0203,
+       0x82000580, 0x00000004, 0x04020011, 0x592c020a,
+       0x8c000502, 0x0400000e, 0x4a023812, 0x0fffffff,
+       0x592c0208, 0x8400051e, 0x48025a08, 0x42000000,
+       0x00000001, 0x48023a14, 0x0401f021, 0x42000000,
+       0x00000007, 0x48023a14, 0x0401f01d, 0x592c020a,
+       0x4803c857, 0x8c000500, 0x0402000b, 0x8c000502,
+       0x040007f7, 0x591c0414, 0x8c00051c, 0x040207eb,
+       0x591c0011, 0x4803c857, 0x800001c0, 0x040007f0,
+       0x0401f7e6, 0x8c08153a, 0x040207ed, 0x59cc000a,
+       0x592c180f, 0x4803c857, 0x480fc857, 0x800c0580,
+       0x040007e7, 0x59cc000a, 0x4803c857, 0x48023816,
+       0x42000000, 0x00000005, 0x48023a14, 0x0201f000,
+       0x00109259, 0x4933c857, 0x4d1c0000, 0x59cc0001,
+       0x59341002, 0x80080580, 0x82000500, 0x00ffffff,
+       0x04020041, 0x59301419, 0x0201f800, 0x00109410,
+       0x02000800, 0x001005d8, 0x591c1406, 0x82080580,
+       0x00000007, 0x04000038, 0x82080580, 0x00000002,
+       0x04000035, 0x82080580, 0x00000000, 0x04000032,
+       0x591c0202, 0x82000d80, 0x0000ffff, 0x04000004,
+       0x59301a19, 0x800c0580, 0x0402002b, 0x83380580,
+       0x00000015, 0x04000026, 0x4d300000, 0x4d2c0000,
+       0x411e6000, 0x59325808, 0x0201f800, 0x00109037,
+       0x02000800, 0x001005d8, 0x592c0204, 0x82000500,
+       0x000000ff, 0x82000580, 0x00000014, 0x04000003,
+       0x4a02621d, 0x00000003, 0x42028000, 0x00000003,
+       0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+       0x000202da, 0x5c025800, 0x497a6008, 0x4a026403,
+       0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+       0x00000002, 0x42000800, 0x8000404b, 0x0201f800,
+       0x00020721, 0x5c026000, 0x0401f003, 0x59a80039,
+       0x48023a05, 0x497a381c, 0x0201f800, 0x0002077d,
+       0x5c023800, 0x1c01f000, 0x4933c857, 0x4c580000,
+       0x4d2c0000, 0x59325808, 0x83383580, 0x00000015,
+       0x04000010, 0x59342200, 0x84102502, 0x48126a00,
+       0x0201f800, 0x00109037, 0x04000066, 0x0201f800,
+       0x00109597, 0x04020005, 0x4200b000, 0x00000002,
+       0x0201f800, 0x0010957d, 0x0401fa0a, 0x0401f079,
+       0x83cc1400, 0x00000008, 0x4200b000, 0x00000002,
+       0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+       0x04020015, 0x83cc1400, 0x0000000a, 0x4200b000,
+       0x00000002, 0x83341c00, 0x00000008, 0x0201f800,
+       0x0010855a, 0x0402000c, 0x0201f800, 0x00102074,
+       0x59342200, 0x59cc1007, 0x800811c0, 0x04000003,
+       0x480a6801, 0x84102542, 0x8410251a, 0x48126a00,
+       0x0401f05f, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+       0x0201f800, 0x0010aa47, 0x59340200, 0x84000558,
+       0x48026a00, 0x4d300000, 0x0201f800, 0x0002075a,
+       0x02000800, 0x001005d8, 0x49366009, 0x497a6008,
+       0x4a026406, 0x00000001, 0x4a026403, 0x00000001,
+       0x42003000, 0x00000003, 0x0201f800, 0x0010a942,
+       0x0201f800, 0x00103b25, 0x04000011, 0x41782800,
+       0x42003000, 0x00000001, 0x4d400000, 0x42028000,
+       0x00000029, 0x0201f800, 0x0010a43e, 0x5c028000,
+       0x4a026406, 0x00000004, 0x4a026203, 0x00000007,
+       0x4a026420, 0x00000001, 0x0401f009, 0x4a026203,
+       0x00000001, 0x42000800, 0x0000000b, 0x0201f800,
+       0x00104571, 0x0201f800, 0x0010672b, 0x5c026000,
+       0x0201f800, 0x00109037, 0x04000022, 0x0201f800,
+       0x00109597, 0x04020022, 0x0401f9ae, 0x0401f01d,
+       0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x59340200, 0x84000558, 0x48026a00, 0x42003000,
+       0x00000003, 0x41782800, 0x42002000, 0x00000005,
+       0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+       0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+       0x5c028000, 0x5c027800, 0x0201f800, 0x00102074,
+       0x0201f800, 0x0002077d, 0x0401f002, 0x0401fca9,
+       0x5c025800, 0x5c00b000, 0x1c01f000, 0x4933c857,
+       0x41380000, 0x83383480, 0x00000056, 0x02021800,
+       0x001005d8, 0x0c01f001, 0x00107ef7, 0x00107ef2,
+       0x00107ef7, 0x00107ef7, 0x00107ef7, 0x00107ef7,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef7, 0x00107ef0, 0x00107ef7,
+       0x00107ef7, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef7, 0x00107ef7, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+       0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef7,
+       0x00107ef0, 0x00107ef7, 0x00107ef7, 0x00107ef0,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+       0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+       0x0201f800, 0x001005d8, 0x4a026203, 0x00000001,
+       0x493a6403, 0x0201f000, 0x0010672b, 0x4933c857,
+       0x4a026203, 0x00000001, 0x493a6403, 0x0201f000,
+       0x0010672b, 0x4933c857, 0x59300403, 0x82003480,
+       0x00000056, 0x02021800, 0x001005d8, 0x83383580,
+       0x00000013, 0x04000093, 0x83383580, 0x00000027,
+       0x0402004b, 0x0201f800, 0x00106bbf, 0x0201f800,
+       0x00109134, 0x0400000b, 0x0201f800, 0x0010914e,
+       0x04000041, 0x59300403, 0x82000d80, 0x00000022,
+       0x04020038, 0x0401fc61, 0x0400003a, 0x0401f03a,
+       0x0201f800, 0x00102074, 0x42000800, 0x00000007,
+       0x0201f800, 0x00104571, 0x0401f8fe, 0x4d440000,
+       0x59368c03, 0x83440580, 0x000007fe, 0x04020008,
+       0x59a81026, 0x84081540, 0x0201f800, 0x0010513b,
+       0x04020002, 0x8408154a, 0x480b5026, 0x42028000,
+       0x00000029, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x836c0580, 0x00000003,
+       0x0400000c, 0x59326809, 0x59340008, 0x800001c0,
+       0x04020008, 0x59368c03, 0x4933c857, 0x4937c857,
+       0x4947c857, 0x0201f800, 0x001045fb, 0x0401f00c,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x42003000, 0x00000015, 0x41782800, 0x42002000,
+       0x00000003, 0x0201f800, 0x0010985e, 0x5c028800,
+       0x0201f800, 0x00109326, 0x0201f000, 0x0002077d,
+       0x1c01f000, 0x0401f8cb, 0x0401f7fa, 0x83380580,
+       0x00000014, 0x0400000b, 0x0201f800, 0x00106f60,
+       0x02020000, 0x00107974, 0x59300203, 0x82000580,
+       0x00000002, 0x040000ed, 0x0201f800, 0x001005d8,
+       0x0201f800, 0x00106bbf, 0x4d3c0000, 0x417a7800,
+       0x0201f800, 0x0010203c, 0x5c027800, 0x42003000,
+       0x00000016, 0x41782800, 0x4d400000, 0x4d440000,
+       0x59368c03, 0x42002000, 0x00000009, 0x42028000,
+       0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+       0x5c028000, 0x42000000, 0x0010b864, 0x0201f800,
+       0x0010aa47, 0x0201f800, 0x00109134, 0x0402000c,
+       0x0201f800, 0x00102074, 0x0401f89e, 0x59340c03,
+       0x82040580, 0x000007fe, 0x040207ca, 0x59a80826,
+       0x84040d40, 0x48075026, 0x0401f7c6, 0x0201f800,
+       0x0010914e, 0x04020003, 0x0401f892, 0x0401f7c1,
+       0x59300403, 0x82000d80, 0x00000032, 0x04020004,
+       0x0201f800, 0x0010230c, 0x0401f7ba, 0x59300403,
+       0x82000d80, 0x00000022, 0x04000886, 0x0401f7b5,
+       0x4803c857, 0x0c01f001, 0x00108016, 0x00108016,
+       0x00108016, 0x00108016, 0x00108016, 0x00108016,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff9, 0x00108016, 0x00107ff0, 0x00108016,
+       0x00108016, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00108016, 0x00108016,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+       0x00108007, 0x00108016, 0x00107ff0, 0x00108000,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108000,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+       0x00108003, 0x00107ff0, 0x00107ff2, 0x00108016,
+       0x00107ff0, 0x00108016, 0x00108016, 0x00107ff0,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+       0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+       0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808,
+       0x0201f800, 0x000202da, 0x5c025800, 0x0201f000,
+       0x0002077d, 0x4a026203, 0x00000005, 0x59a80039,
+       0x48026205, 0x59a80037, 0x48026206, 0x1c01f000,
+       0x5930081e, 0x49780a05, 0x0401f014, 0x0201f800,
+       0x00109326, 0x0201f000, 0x0002077d, 0x0201f800,
+       0x0010230c, 0x0201f800, 0x00106c55, 0x04000005,
+       0x0201f800, 0x00106bbf, 0x0201f000, 0x0002077d,
+       0x0201f800, 0x00106bbf, 0x0201f800, 0x0002077d,
+       0x0201f000, 0x00106c4b, 0x4933c857, 0x4a026203,
+       0x00000002, 0x59a80037, 0x48026206, 0x1c01f000,
+       0x4933c857, 0x0201f800, 0x00109037, 0x0400002a,
+       0x4d2c0000, 0x0201f800, 0x00109597, 0x0402000a,
+       0x4d400000, 0x42028000, 0x00000031, 0x42000800,
+       0x00000004, 0x0201f800, 0x0010943b, 0x5c028000,
+       0x0401f01c, 0x59300c06, 0x82040580, 0x00000010,
+       0x04000004, 0x82040580, 0x00000011, 0x0402000a,
+       0x4a025a06, 0x00000031, 0x4a02580d, 0x00000004,
+       0x4a02580e, 0x000000ff, 0x0201f800, 0x000202da,
+       0x0401f00c, 0x592c0404, 0x8c00051e, 0x04000009,
+       0x4a025a04, 0x00000103, 0x4a025805, 0x01000000,
+       0x5931d821, 0x58ef400b, 0x58ec0009, 0x0801f800,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x59340400,
+       0x82000500, 0x000000ff, 0x82003480, 0x0000000c,
+       0x02021800, 0x001005d8, 0x59303403, 0x82180d80,
+       0x0000004d, 0x02000000, 0x0010938b, 0x82180d80,
+       0x00000033, 0x02000000, 0x00109349, 0x82180d80,
+       0x00000028, 0x02000000, 0x0010918f, 0x82180d80,
+       0x00000029, 0x02000000, 0x001091a3, 0x82180d80,
+       0x0000001f, 0x02000000, 0x00107b28, 0x82180d80,
+       0x00000055, 0x02000000, 0x00107b01, 0x82180d80,
+       0x00000000, 0x04000591, 0x82180d80, 0x00000022,
+       0x02000000, 0x00107b55, 0x82180d80, 0x00000035,
+       0x02000000, 0x00107c50, 0x82180d80, 0x00000039,
+       0x04000539, 0x82180d80, 0x0000003d, 0x02000000,
+       0x00107b85, 0x82180d80, 0x00000044, 0x02000000,
+       0x00107bc2, 0x82180d80, 0x00000049, 0x02000000,
+       0x00107c17, 0x82180d80, 0x00000041, 0x02000000,
+       0x00107c03, 0x82180d80, 0x00000043, 0x02000000,
+       0x001094dc, 0x82180d80, 0x00000051, 0x02000000,
+       0x00109542, 0x82180d80, 0x00000004, 0x04020003,
+       0x42000000, 0x00000001, 0x83380d80, 0x00000015,
+       0x04000006, 0x83380d80, 0x00000016, 0x02020000,
+       0x00107974, 0x0401f20f, 0x4d2c0000, 0x4d3c0000,
+       0x0c01f804, 0x5c027800, 0x5c025800, 0x1c01f000,
+       0x001080b8, 0x001080bc, 0x001080b8, 0x00108131,
+       0x001080b8, 0x00108226, 0x001082bf, 0x001080b8,
+       0x001080b8, 0x00108288, 0x001080b8, 0x0010829a,
+       0x4933c857, 0x497a6007, 0x59300808, 0x58040000,
+       0x4a000a04, 0x00000103, 0x0201f000, 0x0002077d,
+       0x4933c857, 0x40000000, 0x40000000, 0x1c01f000,
+       0x4933c857, 0x59a80016, 0x82000580, 0x00000074,
+       0x0402005c, 0x0201f800, 0x0010a2c8, 0x04020016,
+       0x0401f85c, 0x0201f800, 0x00109037, 0x0400000c,
+       0x0201f800, 0x00109597, 0x04020009, 0x41780800,
+       0x4d400000, 0x42028000, 0x00000000, 0x0201f800,
+       0x0010943b, 0x5c028000, 0x0401f003, 0x0201f800,
+       0x00102074, 0x0201f800, 0x001048c1, 0x0201f000,
+       0x0002077d, 0x0201f800, 0x00109037, 0x04000007,
+       0x0201f800, 0x00109597, 0x04020004, 0x0401ff3d,
+       0x0201f000, 0x0002077d, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x42000000, 0x0010b864, 0x0201f800,
+       0x0010aa47, 0x59340200, 0x84000558, 0x48026a00,
+       0x42003000, 0x00000003, 0x0201f800, 0x0010a942,
+       0x4d300000, 0x0201f800, 0x0002075a, 0x02000800,
+       0x001005d8, 0x49366009, 0x497a6008, 0x4a026406,
+       0x00000001, 0x4a026403, 0x00000001, 0x0201f800,
+       0x00103b25, 0x04000011, 0x4a026406, 0x00000004,
+       0x4a026203, 0x00000007, 0x4a026420, 0x00000001,
+       0x42003000, 0x00000001, 0x4d400000, 0x42028000,
+       0x00000029, 0x41782800, 0x0201f800, 0x0010a43e,
+       0x5c028000, 0x0401f009, 0x42000800, 0x0000000b,
+       0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+       0x0201f800, 0x0010672b, 0x5c026000, 0x0401ff05,
+       0x0201f800, 0x00102074, 0x0201f000, 0x0002077d,
+       0x0401ff00, 0x42000000, 0x00000001, 0x0401f0c7,
+       0x4933c857, 0x59340200, 0x8c000500, 0x0400000d,
+       0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567,
+       0x5c027800, 0x0201f800, 0x00103b25, 0x04000005,
+       0x42000800, 0x00000006, 0x0201f800, 0x00104571,
+       0x1c01f000, 0x4933c857, 0x59a80816, 0x82040580,
+       0x00000074, 0x0400000e, 0x4807c857, 0x82040580,
+       0x00000100, 0x040200a0, 0x59cc0408, 0x4803c857,
+       0x8c000500, 0x0400009c, 0x59341403, 0x82080580,
+       0x000007fe, 0x04000006, 0x0401f097, 0x59341403,
+       0x82080580, 0x000007fe, 0x04020003, 0x0401fa9c,
+       0x0401f04c, 0x0201f800, 0x0010462a, 0x59341403,
+       0x82080580, 0x000007fc, 0x0402001f, 0x4a026802,
+       0x00fffffc, 0x0201f800, 0x00109037, 0x04000012,
+       0x0201f800, 0x00109597, 0x0402000f, 0x0401f8a9,
+       0x41780800, 0x4d400000, 0x42028000, 0x00000000,
+       0x0201f800, 0x0010943b, 0x5c028000, 0x42000800,
+       0x00000004, 0x0201f800, 0x00104571, 0x0201f000,
+       0x0002077d, 0x42000800, 0x00000004, 0x0201f800,
+       0x00104571, 0x0201f800, 0x00102074, 0x0201f000,
+       0x0002077d, 0x59a80005, 0x8c000514, 0x04000011,
+       0x0201f800, 0x0010513b, 0x42001000, 0x00000010,
+       0x04020009, 0x59340002, 0x82000500, 0x00ff0000,
+       0x82000580, 0x00ff0000, 0x04000006, 0x42001000,
+       0x00000008, 0x0201f800, 0x00104c6d, 0x0402005a,
+       0x0201f800, 0x00109037, 0x0400005b, 0x0201f800,
+       0x00109597, 0x04020005, 0x592c0404, 0x8c00051c,
+       0x040207c9, 0x0401f877, 0x42000800, 0x00000005,
+       0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+       0x4a026403, 0x00000003, 0x0201f000, 0x0010672b,
+       0x59cc0408, 0x8c000518, 0x04000010, 0x0201f800,
+       0x001092e5, 0x0201f800, 0x0010513b, 0x04000004,
+       0x59cc0408, 0x8c000516, 0x040207b3, 0x59a80026,
+       0x8400054a, 0x48035026, 0x59a80010, 0x84000570,
+       0x48038832, 0x0401f7ac, 0x42001000, 0x000000ef,
+       0x480b5010, 0x497b8830, 0x84081570, 0x480b8832,
+       0x59c40802, 0x84040d4c, 0x48078802, 0x0201f800,
+       0x0010930f, 0x59a80026, 0x84000548, 0x48035026,
+       0x0201f800, 0x0010a3da, 0x0402079b, 0x59a80026,
+       0x8400054c, 0x48035026, 0x42000800, 0x00000006,
+       0x0201f800, 0x00104571, 0x417a7800, 0x0201f800,
+       0x00104567, 0x42000000, 0x000000e8, 0x0201f800,
+       0x00105c9a, 0x02000800, 0x001045a6, 0x02020800,
+       0x001005d8, 0x49366009, 0x59340200, 0x8400051a,
+       0x48026a00, 0x42000800, 0x00000003, 0x0201f800,
+       0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+       0x00000001, 0x4a026403, 0x00000002, 0x0201f000,
+       0x0010672b, 0x0401fe43, 0x42000000, 0x00000001,
+       0x0401f00a, 0x599c0017, 0x8c00050a, 0x040007ab,
+       0x42000800, 0x00000004, 0x0201f800, 0x00104571,
+       0x0201f000, 0x0002077d, 0x4933c857, 0x80003540,
+       0x04000005, 0x42000800, 0x00000007, 0x0201f800,
+       0x00104571, 0x801831c0, 0x0402000e, 0x59302008,
+       0x801021c0, 0x04000004, 0x58100404, 0x8c00051e,
+       0x04020008, 0x59341c03, 0x42002000, 0x00000004,
+       0x42003000, 0x00000012, 0x0201f800, 0x00103aae,
+       0x0201f800, 0x00102074, 0x0201f000, 0x0002077d,
+       0x4c5c0000, 0x4d2c0000, 0x59325808, 0x0201f800,
+       0x00105755, 0x5c025800, 0x59cc0008, 0x48002805,
+       0x59cc0009, 0x48002806, 0x49782807, 0x49782808,
+       0x49782809, 0x4978280a, 0x59cc0013, 0x8c00053e,
+       0x04000009, 0x59cc0414, 0x900001c0, 0x59ccbc15,
+       0x805c0540, 0x48002807, 0x59cc0416, 0x900001c0,
+       0x48002808, 0x59cc0017, 0x8c00053e, 0x04000009,
+       0x59cc0418, 0x900001c0, 0x59ccbc19, 0x805c0540,
+       0x48002809, 0x59cc041a, 0x900001c0, 0x4800280a,
+       0x5c00b800, 0x1c01f000, 0x4933c857, 0x59a80016,
+       0x82000580, 0x00000014, 0x04020048, 0x59a80005,
+       0x8c000514, 0x04000015, 0x0201f800, 0x0010513b,
+       0x42001000, 0x00000010, 0x04020009, 0x59340002,
+       0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+       0x0400000a, 0x42001000, 0x00000008, 0x0201f800,
+       0x00104c6d, 0x04000005, 0x59a80005, 0x84000556,
+       0x48035005, 0x0401f031, 0x836c0580, 0x00000003,
+       0x0402000b, 0x59300008, 0x80000540, 0x04020008,
+       0x59341c03, 0x42002000, 0x00000006, 0x42003000,
+       0x00000013, 0x0201f800, 0x00103aae, 0x0201f800,
+       0x0010468d, 0x0401fecf, 0x0401fa1d, 0x0402001f,
+       0x59340404, 0x80000540, 0x0400001c, 0x42000800,
+       0x00000006, 0x0201f800, 0x00104571, 0x0201f800,
+       0x00109037, 0x04000011, 0x0201f800, 0x00109597,
+       0x0402000a, 0x41780800, 0x4d400000, 0x42028000,
+       0x00000000, 0x0201f800, 0x0010943b, 0x5c028000,
+       0x0201f000, 0x0002077d, 0x4a025a04, 0x00000103,
+       0x4a025805, 0x02000000, 0x0201f800, 0x00102074,
+       0x0201f000, 0x0002077d, 0x0201f800, 0x00104c19,
+       0x0201f800, 0x00109037, 0x04000007, 0x0201f800,
+       0x00109597, 0x04020004, 0x0401fda2, 0x0201f000,
+       0x0002077d, 0x0401fd9f, 0x80000580, 0x59a80005,
+       0x8c000516, 0x04000005, 0x84000516, 0x48035005,
+       0x82000540, 0x00000001, 0x0401ff60, 0x1c01f000,
+       0x4933c857, 0x59a80016, 0x82000580, 0x00000014,
+       0x0402000b, 0x42000800, 0x0000000b, 0x0201f800,
+       0x00104571, 0x4a026203, 0x00000001, 0x4a026403,
+       0x00000001, 0x0201f000, 0x0010672b, 0x42000000,
+       0x00000001, 0x0401f74d, 0x4933c857, 0x40003000,
+       0x59a80016, 0x82000580, 0x00000004, 0x0402000a,
+       0x82183580, 0x0000000b, 0x04020005, 0x42000800,
+       0x00000007, 0x0201f800, 0x00104571, 0x0201f000,
+       0x0002077d, 0x42000000, 0x00000001, 0x0401f73b,
+       0x4803c857, 0x4d2c0000, 0x4d3c0000, 0x0c01f804,
+       0x5c027800, 0x5c025800, 0x1c01f000, 0x001080b8,
+       0x001082ce, 0x001080b8, 0x00108323, 0x001080b8,
+       0x00108391, 0x001082bf, 0x001080b8, 0x001080b8,
+       0x001083b1, 0x001080b8, 0x001083c1, 0x4933c857,
+       0x4d1c0000, 0x59301403, 0x82080580, 0x00000003,
+       0x04000008, 0x82081580, 0x0000001e, 0x04020003,
+       0x0201f800, 0x0002077d, 0x5c023800, 0x1c01f000,
+       0x0401ff5a, 0x0401f7fd, 0x4933c857, 0x0201f800,
+       0x00109037, 0x0400000b, 0x0201f800, 0x00109597,
+       0x04020008, 0x4200b000, 0x00000002, 0x0201f800,
+       0x0010957d, 0x0401fd43, 0x0201f000, 0x0002077d,
+       0x0401f8f5, 0x04020030, 0x417a7800, 0x0201f800,
+       0x00104567, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x59340200, 0x84000558, 0x48026a00, 0x4a026403,
+       0x00000002, 0x42003000, 0x00000003, 0x0201f800,
+       0x0010a942, 0x0201f800, 0x00103b25, 0x04000011,
+       0x4d400000, 0x41782800, 0x42003000, 0x00000005,
+       0x42028000, 0x00000029, 0x0201f800, 0x0010a43e,
+       0x5c028000, 0x4a026203, 0x00000007, 0x4a026406,
+       0x00000004, 0x4a026420, 0x00000001, 0x1c01f000,
+       0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+       0x4a026203, 0x00000001, 0x0201f800, 0x0010672b,
+       0x0401f7f7, 0x59cc0407, 0x82000580, 0x00000009,
+       0x0402000a, 0x59340412, 0x82000500, 0x000000ff,
+       0x0400000c, 0x80000040, 0x48026c12, 0x4a026206,
+       0x0000000a, 0x0401f7ea, 0x59cc0207, 0x82000500,
+       0x0000ff00, 0x82000580, 0x00001900, 0x040007c2,
+       0x0401fcfc, 0x80000580, 0x0401f6c4, 0x4933c857,
+       0x59a80032, 0x80000540, 0x04000015, 0x59340403,
+       0x82000580, 0x000007fe, 0x04020011, 0x59a80010,
+       0x80000000, 0x48035010, 0x417a7800, 0x0201f800,
+       0x00104567, 0x42000800, 0x00000003, 0x0201f800,
+       0x00104571, 0x4a026203, 0x00000001, 0x4a026403,
+       0x00000002, 0x0201f000, 0x0010672b, 0x0201f800,
+       0x00109037, 0x04000011, 0x0201f800, 0x00109597,
+       0x0402000e, 0x4c580000, 0x4200b000, 0x00000002,
+       0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fcd5,
+       0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+       0x0201f000, 0x0002077d, 0x0401fcce, 0x59cc3407,
+       0x82183500, 0x000000ff, 0x82180580, 0x00000005,
+       0x0400001c, 0x82180580, 0x0000000b, 0x04000016,
+       0x59cc0207, 0x82000500, 0x0000ff00, 0x04020004,
+       0x82180580, 0x00000009, 0x04000012, 0x82000580,
+       0x00001900, 0x0402000c, 0x82180580, 0x00000009,
+       0x0400000c, 0x42000800, 0x00000004, 0x0201f800,
+       0x00104571, 0x0201f800, 0x00102074, 0x0201f000,
+       0x0002077d, 0x42000000, 0x00000001, 0x0401f677,
+       0x0201f800, 0x00109037, 0x59325808, 0x04000008,
+       0x592c0204, 0x82000580, 0x00000139, 0x040007f6,
+       0x592c0404, 0x8c00051e, 0x040207f3, 0x59340403,
+       0x82000580, 0x000007fe, 0x04020007, 0x59a80026,
+       0x84000540, 0x48035026, 0x0201f800, 0x00104229,
+       0x0401f7e9, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x42003000, 0x00000005, 0x0201f800, 0x0010a942,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x0401f7dd, 0x4933c857, 0x0401f84d, 0x0402000b,
+       0x42000800, 0x00000005, 0x0201f800, 0x00104571,
+       0x4a026203, 0x00000001, 0x4a026403, 0x00000003,
+       0x0201f000, 0x0010672b, 0x42000800, 0x00000004,
+       0x0201f800, 0x00104571, 0x0201f800, 0x00109597,
+       0x0402000a, 0x4c580000, 0x4200b000, 0x00000002,
+       0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fc71,
+       0x0201f000, 0x0002077d, 0x0401fc6e, 0x80000580,
+       0x0401f636, 0x4933c857, 0x0401f82d, 0x0402000b,
+       0x42000800, 0x00000009, 0x0201f800, 0x00104571,
+       0x4a026203, 0x00000001, 0x4a026403, 0x00000005,
+       0x0201f000, 0x0010672b, 0x42000000, 0x00000001,
+       0x0401f626, 0x4933c857, 0x0401f81d, 0x0402000b,
+       0x42000800, 0x0000000b, 0x0201f800, 0x00104571,
+       0x4a026203, 0x00000001, 0x4a026403, 0x00000001,
+       0x0201f000, 0x0010672b, 0x42000000, 0x00000001,
+       0x0401f616, 0x4933c857, 0x59cc0407, 0x82000580,
+       0x00000003, 0x04020009, 0x59cc0207, 0x82000500,
+       0x0000ff00, 0x82000d80, 0x00002a00, 0x04000003,
+       0x82000d80, 0x00001e00, 0x1c01f000, 0x4933c857,
+       0x82000540, 0x00000001, 0x1c01f000, 0x4933c857,
+       0x4d400000, 0x4c580000, 0x59a80026, 0x82000540,
+       0x00000003, 0x48035026, 0x0401f85c, 0x04000038,
+       0x4d340000, 0x4d440000, 0x59a80026, 0x84000552,
+       0x48035026, 0x0201f800, 0x00103b25, 0x0400000c,
+       0x42028000, 0x0000002a, 0x42028800, 0x0000ffff,
+       0x42003000, 0x00000002, 0x0201f800, 0x0010a446,
+       0x59a80805, 0x84040d44, 0x48075005, 0x42028000,
+       0x0000002a, 0x4d3c0000, 0x42027800, 0x00000204,
+       0x0201f800, 0x00101fe5, 0x5c027800, 0x42000000,
+       0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+       0x00101e45, 0x4200b000, 0x00000010, 0x42028800,
+       0x000007f0, 0x4d2c0000, 0x83440580, 0x000007fe,
+       0x04000003, 0x0201f800, 0x001045fb, 0x81468800,
+       0x8058b040, 0x040207f9, 0x5c025800, 0x59cc0408,
+       0x8c00051e, 0x04000004, 0x59a80026, 0x84000512,
+       0x48035026, 0x5c028800, 0x5c026800, 0x0201f800,
+       0x0010462a, 0x4a026802, 0x00fffffe, 0x59a80826,
+       0x84040d50, 0x59cc0013, 0x8c00053e, 0x04000003,
+       0x8c000536, 0x04000004, 0x59cc0017, 0x8c000536,
+       0x04020002, 0x84040d10, 0x48075026, 0x59cc0800,
+       0x82040d00, 0x00ffffff, 0x48075010, 0x80040110,
+       0x4803501d, 0x48038881, 0x0201f800, 0x0010513b,
+       0x04000007, 0x59cc0009, 0x48035035, 0x59cc000a,
+       0x48035036, 0x0201f800, 0x001092e5, 0x5c00b000,
+       0x5c028000, 0x1c01f000, 0x4933c857, 0x4c580000,
+       0x59a80010, 0x82000500, 0x00ffff00, 0x04000022,
+       0x59cc1000, 0x82081500, 0x00ffff00, 0x80080580,
+       0x04000004, 0x42000000, 0x0010b83b, 0x0401f016,
+       0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+       0x83341c00, 0x00000006, 0x0401f900, 0x04000004,
+       0x42000000, 0x0010b83c, 0x0401f00b, 0x83cc1400,
+       0x0000000d, 0x4200b000, 0x00000002, 0x83341c00,
+       0x00000008, 0x0401f8f5, 0x04000007, 0x42000000,
+       0x0010b83d, 0x0201f800, 0x0010aa47, 0x82000540,
+       0x00000001, 0x5c00b000, 0x1c01f000, 0x4933c857,
+       0x59cc0206, 0x82000580, 0x00000014, 0x04020016,
+       0x59cc0407, 0x82000580, 0x00000800, 0x04020012,
+       0x59cc0207, 0x8c00051a, 0x0400000d, 0x82000500,
+       0x00000f00, 0x82000580, 0x00000100, 0x04020008,
+       0x59cc020a, 0x8c000508, 0x04020003, 0x8c00050a,
+       0x04000003, 0x80000580, 0x1c01f000, 0x82000540,
+       0x00000001, 0x1c01f000, 0x4933c857, 0x4943c857,
+       0x493fc857, 0x4c5c0000, 0x4d300000, 0x4d340000,
+       0x4d2c0000, 0x4d380000, 0x4130b800, 0x42026000,
+       0x0010d1c0, 0x59a8000e, 0x81640480, 0x040210bd,
+       0x8d3e7d12, 0x04000004, 0x405c0000, 0x81300580,
+       0x040000b3, 0x59300406, 0x82000c80, 0x00000012,
+       0x04021015, 0x59326809, 0x0c01f001, 0x0010854f,
+       0x001084bc, 0x001084d3, 0x001084de, 0x001084b7,
+       0x001084ce, 0x00108507, 0x0010854f, 0x001084b5,
+       0x0010851b, 0x0010852a, 0x001084b5, 0x001084b5,
+       0x001084b5, 0x001084b5, 0x0010854f, 0x00108540,
+       0x00108538, 0x0201f800, 0x001005d8, 0x8d3e7d18,
+       0x04000004, 0x59300420, 0x8c000500, 0x04020094,
+       0x59300403, 0x82000580, 0x00000043, 0x04000090,
+       0x0201f800, 0x00109134, 0x02000800, 0x00102074,
+       0x0201f800, 0x0010914e, 0x02000800, 0x0010801c,
+       0x8d3e7d06, 0x04000084, 0x0201f800, 0x001092d7,
+       0x04000083, 0x0401f080, 0x8d3e7d16, 0x04000004,
+       0x59300420, 0x8c000500, 0x0402007d, 0x59325808,
+       0x0201f800, 0x00109037, 0x04000077, 0x49425a06,
+       0x497a5c09, 0x0201f800, 0x000202da, 0x0201f800,
+       0x0010912a, 0x0401f070, 0x813669c0, 0x02000800,
+       0x001005d8, 0x8d3e7d06, 0x04000004, 0x59340200,
+       0x8c00050e, 0x0402006a, 0x59300004, 0x8400055c,
+       0x48026004, 0x59300203, 0x82000580, 0x00000004,
+       0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+       0x00109037, 0x0400005c, 0x4a025a04, 0x00000103,
+       0x59300402, 0x48025c06, 0x592c0408, 0x8c000512,
+       0x04000006, 0x4d2c0000, 0x592e5809, 0x0201f800,
+       0x001007fd, 0x5c025800, 0x49425a06, 0x497a5c09,
+       0x0201f800, 0x0010959c, 0x0201f800, 0x000202da,
+       0x0201f800, 0x0010912a, 0x0401f047, 0x8c000518,
+       0x04000047, 0x59300203, 0x82000580, 0x00000004,
+       0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+       0x00109037, 0x0400003c, 0x49425a06, 0x497a5c09,
+       0x0201f800, 0x0010a693, 0x0201f800, 0x0010959c,
+       0x0201f800, 0x000202da, 0x0401f033, 0x0201f800,
+       0x001062d5, 0x04000032, 0x59300203, 0x82000580,
+       0x00000004, 0x04020004, 0x0201f800, 0x00100e99,
+       0x0401f02b, 0x42027000, 0x00000047, 0x0201f800,
+       0x000207a1, 0x0401f026, 0x59300203, 0x82000580,
+       0x00000004, 0x02000800, 0x00100e99, 0x59325808,
+       0x0201f800, 0x00109037, 0x0400001b, 0x49425a06,
+       0x497a5c09, 0x0201f800, 0x000202da, 0x0401f016,
+       0x833c0500, 0x00001800, 0x04000015, 0x8d3e7d16,
+       0x04020013, 0x59325817, 0x0201f800, 0x001007fd,
+       0x59300203, 0x82000580, 0x00000004, 0x02000800,
+       0x00100e99, 0x59325808, 0x0201f800, 0x00109037,
+       0x04000005, 0x49425a06, 0x497a5c09, 0x0201f800,
+       0x000202da, 0x0201f800, 0x00107911, 0x83326400,
+       0x00000024, 0x41580000, 0x81300480, 0x04001742,
+       0x5c027000, 0x5c025800, 0x5c026800, 0x5c026000,
+       0x5c00b800, 0x1c01f000, 0x5c000000, 0x4c000000,
+       0x4803c857, 0x480bc857, 0x480fc857, 0x485bc857,
+       0x50080800, 0x500c0000, 0x80042580, 0x04020007,
+       0x80081000, 0x800c1800, 0x8058b040, 0x040207f9,
+       0x80000580, 0x1c01f000, 0x4803c857, 0x4807c857,
+       0x480bc857, 0x480fc857, 0x80040480, 0x04001006,
+       0x42000000, 0x00000001, 0x82040d40, 0x00000001,
+       0x1c01f000, 0x41780000, 0x0401f7fc, 0x83380480,
+       0x00000053, 0x02021800, 0x001005d8, 0x83380480,
+       0x0000004b, 0x02001800, 0x001005d8, 0x0c01f001,
+       0x0010858a, 0x0010858a, 0x0010858a, 0x0010858a,
+       0x00108588, 0x00108588, 0x00108588, 0x0010858a,
+       0x0201f800, 0x001005d8, 0x493bc857, 0x4a026203,
+       0x0000000d, 0x493a6403, 0x42000800, 0x80000000,
+       0x0201f000, 0x00020721, 0x83380580, 0x00000013,
+       0x04020008, 0x59300403, 0x82000580, 0x00000050,
+       0x02020800, 0x001005d8, 0x0201f000, 0x0002077d,
+       0x4933c857, 0x83380580, 0x00000027, 0x04020030,
+       0x4933c857, 0x0201f800, 0x00106bbf, 0x4d3c0000,
+       0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+       0x492fc857, 0x0400000d, 0x4a025a04, 0x00000103,
+       0x59300c02, 0x48065c06, 0x4a025a06, 0x00000029,
+       0x497a5c09, 0x592c0c08, 0x84040d50, 0x48065c08,
+       0x0201f800, 0x000202da, 0x5c025800, 0x42003000,
+       0x00000015, 0x41782800, 0x42002000, 0x00000003,
+       0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+       0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+       0x5c028000, 0x0201f000, 0x0002077d, 0x83380580,
+       0x00000014, 0x0402000c, 0x59300403, 0x82000c80,
+       0x00000053, 0x02021800, 0x001005d8, 0x82000480,
+       0x00000040, 0x02001800, 0x001005d8, 0x4803c857,
+       0x0c01f00e, 0x83380580, 0x00000053, 0x0400000a,
+       0x83380580, 0x00000048, 0x02020800, 0x001005d8,
+       0x59300403, 0x82000580, 0x00000050, 0x02020800,
+       0x001005d8, 0x1c01f000, 0x001085ff, 0x001085fd,
+       0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd,
+       0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd,
+       0x001085fd, 0x00108616, 0x00108616, 0x00108616,
+       0x00108616, 0x001085fd, 0x00108616, 0x001085fd,
+       0x00108616, 0x0201f800, 0x001005d8, 0x4933c857,
+       0x0201f800, 0x00106bbf, 0x0201f800, 0x00109037,
+       0x02000000, 0x0002077d, 0x4d2c0000, 0x59325808,
+       0x4a025a04, 0x00000103, 0x59300402, 0x48025c06,
+       0x4a025a06, 0x00000006, 0x497a5c09, 0x0201f800,
+       0x000202da, 0x5c025800, 0x0201f800, 0x0010912a,
+       0x0201f000, 0x0002077d, 0x4933c857, 0x0201f800,
+       0x00106bbf, 0x0201f000, 0x0002077d, 0x0201f800,
+       0x001005d8, 0x5930001c, 0x800001c0, 0x02020800,
+       0x0010984e, 0x59300004, 0x8c00053e, 0x04020029,
+       0x59325808, 0x592c0c08, 0x59cc2a08, 0x82141d00,
+       0x00000c00, 0x04000002, 0x59cc1809, 0x84040d58,
+       0x48065c08, 0x82143500, 0x00000fff, 0x04020027,
+       0x59340200, 0x8c00050e, 0x04020080, 0x0201f800,
+       0x0002082b, 0x04020006, 0x4a025a06, 0x00000000,
+       0x59300811, 0x800409c0, 0x0402094b, 0x4a025a04,
+       0x00000103, 0x48065807, 0x480e580a, 0x48165c09,
+       0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+       0x0201f800, 0x001049b2, 0x59cc0208, 0x8c000518,
+       0x02020000, 0x001091d1, 0x0201f000, 0x0002077d,
+       0x0201f800, 0x00106f60, 0x040007d6, 0x4d3c0000,
+       0x42027800, 0x00000002, 0x0201f800, 0x00108be3,
+       0x5c027800, 0x0401f7cf, 0x4817c857, 0x480fc857,
+       0x82180500, 0x000000ff, 0x0400000e, 0x592c0204,
+       0x82000500, 0x000000ff, 0x82000580, 0x00000048,
+       0x04020008, 0x592c0407, 0x800001c0, 0x04000005,
+       0x0201f800, 0x0010973f, 0x0201f000, 0x00109787,
+       0x82180d00, 0x00000c00, 0x04000004, 0x59340200,
+       0x8c00050e, 0x04020032, 0x4a025a06, 0x00000000,
+       0x41782000, 0x8c183510, 0x04000007, 0x59cc000c,
+       0x82000500, 0x000000ff, 0x04000002, 0x4803c857,
+       0x59cc200b, 0x4812580c, 0x41780000, 0x8c183512,
+       0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00,
+       0x040007b8, 0x82041480, 0x0000001d, 0x04001006,
+       0x592c0404, 0x8c00051e, 0x0400000e, 0x42000800,
+       0x0000001c, 0x4c500000, 0x4c540000, 0x83cca400,
+       0x0000000c, 0x832cac00, 0x0000000d, 0x0201f800,
+       0x00108b9f, 0x5c00a800, 0x5c00a000, 0x0401f7a5,
+       0x59300011, 0x59301402, 0x480a5c06, 0x48025807,
+       0x480e580a, 0x48165c09, 0x0201f800, 0x00108b48,
+       0x0201f800, 0x00108b84, 0x0401f7a6, 0x592c020a,
+       0x8c000502, 0x040007cd, 0x592c0208, 0x8c00050e,
+       0x040207ca, 0x59300011, 0x800c0d80, 0x040007c7,
+       0x4803c857, 0x480fc857, 0x8c183514, 0x02000000,
+       0x0010920f, 0x80000540, 0x040007c0, 0x4807c856,
+       0x0201f000, 0x0010920f, 0x592c020a, 0x8c000502,
+       0x04000782, 0x59300011, 0x800001c0, 0x0400077f,
+       0x592c0208, 0x8c00050e, 0x0402077c, 0x0201f000,
+       0x0010920f, 0x59cc2006, 0x59cc2807, 0x0401f035,
+       0x0401f034, 0x1c01f000, 0x4933c857, 0x5930001c,
+       0x800001c0, 0x02020800, 0x0010984e, 0x59325808,
+       0x592c0c08, 0x41782800, 0x41781800, 0x84040d58,
+       0x48065c08, 0x41783000, 0x59340200, 0x8c00050e,
+       0x04020018, 0x0201f800, 0x0002082b, 0x04020007,
+       0x4a025a06, 0x00000000, 0x59300811, 0x4807c857,
+       0x800409c0, 0x040208ac, 0x4a025a04, 0x00000103,
+       0x48065807, 0x480e580a, 0x48165c09, 0x4933c857,
+       0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+       0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d,
+       0x592c020a, 0x8c000502, 0x040007ea, 0x59300011,
+       0x4803c857, 0x800001c0, 0x040007e6, 0x592c0208,
+       0x8c00050e, 0x040207e3, 0x0201f000, 0x0010920f,
+       0x5930001c, 0x800001c0, 0x4c100000, 0x4c140000,
+       0x02020800, 0x0010984e, 0x5c002800, 0x5c002000,
+       0x4a026203, 0x00000002, 0x4a026403, 0x00000043,
+       0x59325808, 0x592c020a, 0x8c000502, 0x04020018,
+       0x40100000, 0x592c080f, 0x80040c80, 0x40140000,
+       0x80040480, 0x04001014, 0x48126013, 0x48166011,
+       0x59300004, 0x8c00053e, 0x04020008, 0x497a6205,
+       0x0201f800, 0x00100f93, 0x04020009, 0x59300804,
+       0x0201f000, 0x00106721, 0x0201f800, 0x00106f60,
+       0x040007f7, 0x0201f000, 0x00107974, 0x4933c857,
+       0x1c01f000, 0x4807c857, 0x40042800, 0x0401f7eb,
+       0x83380480, 0x00000058, 0x04021005, 0x83380480,
+       0x00000040, 0x04001002, 0x0c01f002, 0x1c01f000,
+       0x00108740, 0x00108740, 0x00108740, 0x00108740,
+       0x00108740, 0x00108740, 0x00108740, 0x00108740,
+       0x00108740, 0x00108740, 0x00108742, 0x00108740,
+       0x00108740, 0x00108740, 0x00108740, 0x0010874f,
+       0x00108740, 0x00108740, 0x00108740, 0x00108740,
+       0x0010877d, 0x00108740, 0x00108740, 0x00108740,
+       0x0201f800, 0x001005d8, 0x4933c857, 0x0201f800,
+       0x00106dc3, 0x4a026203, 0x00000002, 0x59a80039,
+       0x48026205, 0x59300011, 0x59300815, 0x80040c80,
+       0x48066015, 0x0201f000, 0x00106b8a, 0x4933c857,
+       0x0201f800, 0x00106b8a, 0x4d3c0000, 0x417a7800,
+       0x0201f800, 0x0010203c, 0x5c027800, 0x42000000,
+       0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+       0x00109037, 0x04000010, 0x4d2c0000, 0x59325808,
+       0x4a025a04, 0x00000103, 0x59300402, 0x48025c06,
+       0x4a025a06, 0x00000029, 0x497a5c09, 0x592c0c08,
+       0x84040d50, 0x48065c08, 0x0201f800, 0x000202da,
+       0x5c025800, 0x42003000, 0x00000014, 0x41782800,
+       0x4d400000, 0x4d440000, 0x59368c03, 0x42002000,
+       0x00000002, 0x42028000, 0x00000029, 0x0201f800,
+       0x0010985e, 0x5c028800, 0x5c028000, 0x0201f000,
+       0x0002077d, 0x4933c857, 0x59300808, 0x49780c09,
+       0x4978080a, 0x58041408, 0x84081558, 0x48080c08,
+       0x1c01f000, 0x4807c857, 0x8c040d3e, 0x04020023,
+       0x497a5a06, 0x5930001f, 0x80000540, 0x04000017,
+       0x497a5a06, 0x4c040000, 0x4c080000, 0x4c0c0000,
+       0x4c100000, 0x4c140000, 0x58f41003, 0x40040000,
+       0x80081480, 0x5930001f, 0x4809e803, 0x0201f800,
+       0x00100d56, 0x5c002800, 0x5c002000, 0x5c001800,
+       0x5c001000, 0x5c000800, 0x592c0206, 0x80000540,
+       0x04020009, 0x0401f005, 0x592c0408, 0x8c00051c,
+       0x04000002, 0x592c0803, 0x4807c857, 0x4a025a06,
+       0x00000015, 0x1c01f000, 0x5930001f, 0x80000540,
+       0x04000009, 0x4a025a06, 0x00000011, 0x5930001f,
+       0x4c040000, 0x0201f800, 0x00100d56, 0x5c000800,
+       0x0401f7f5, 0x4807c856, 0x4a025a06, 0x00000007,
+       0x1c01f000, 0x83380480, 0x00000058, 0x04021007,
+       0x83380480, 0x00000040, 0x04001004, 0x4d2c0000,
+       0x0c01f803, 0x5c025800, 0x1c01f000, 0x001087db,
+       0x001087db, 0x001087db, 0x001087db, 0x001087db,
+       0x001087dd, 0x001087db, 0x001087db, 0x00108860,
+       0x001087db, 0x001087db, 0x001087db, 0x001087db,
+       0x001087db, 0x001087db, 0x001087db, 0x001087db,
+       0x001087db, 0x001087db, 0x00108910, 0x00108939,
+       0x00108918, 0x001087db, 0x00108945, 0x0201f800,
+       0x001005d8, 0x5930001c, 0x800001c0, 0x02020800,
+       0x0010984e, 0x59300007, 0x8c00050e, 0x0400007c,
+       0x8c000500, 0x0400006e, 0x8c00051c, 0x04000009,
+       0x84000500, 0x48026007, 0x59325808, 0x592c3c08,
+       0x841c3d58, 0x481e5c08, 0x0201f000, 0x000207dd,
+       0x59325808, 0x592c3c08, 0x841c3d58, 0x59300007,
+       0x8c00051c, 0x040207f3, 0x481e5c08, 0x42000000,
+       0x00000005, 0x40000000, 0x80000040, 0x040207fe,
+       0x59300007, 0x8c00051c, 0x040207ea, 0x59cc0a08,
+       0x592c0204, 0x82000500, 0x000000ff, 0x82000580,
+       0x00000048, 0x0402000c, 0x497a580b, 0x82040500,
+       0x000000ff, 0x04000008, 0x592c0407, 0x800001c0,
+       0x04000005, 0x0201f800, 0x0010973f, 0x0201f000,
+       0x00100e56, 0x48065c09, 0x41782000, 0x82040500,
+       0x00000c00, 0x04000002, 0x59cc2009, 0x82043500,
+       0x00000fff, 0x04020027, 0x481e5c08, 0x4a025a06,
+       0x00000000, 0x801831c0, 0x02000000, 0x00100e56,
+       0x41782000, 0x8c183510, 0x04000002, 0x59cc200b,
+       0x4812580c, 0x41780000, 0x8c183512, 0x04000002,
+       0x59cc000a, 0x4802580b, 0x80100c00, 0x02001800,
+       0x001005d8, 0x02000000, 0x00100e56, 0x82041480,
+       0x0000001d, 0x0402100c, 0x4c500000, 0x4c540000,
+       0x83cca400, 0x0000000c, 0x832cac00, 0x0000000d,
+       0x0401fb67, 0x5c00a800, 0x5c00a000, 0x0201f000,
+       0x00100e56, 0x0401fb0b, 0x0201f000, 0x00100e56,
+       0x412c7800, 0x0201f800, 0x001007e4, 0x02000800,
+       0x001005d8, 0x492c7809, 0x841c3d52, 0x481c7c08,
+       0x4a025a04, 0x00000103, 0x4812580a, 0x48065c09,
+       0x583c0404, 0x583c1005, 0x583c2208, 0x48025c04,
+       0x480a5805, 0x48125a08, 0x0401f7c8, 0x8c000524,
+       0x04000794, 0x59325808, 0x4c000000, 0x592c0408,
+       0x8c00051c, 0x5c000000, 0x04020003, 0x4a026011,
+       0xffffffff, 0x84000524, 0x0401f78a, 0x1c01f000,
+       0x59a80039, 0x48026205, 0x59325808, 0x4a026203,
+       0x00000002, 0x592c2408, 0x59300807, 0x4933c857,
+       0x4807c857, 0x592c0204, 0x82000500, 0x000000ff,
+       0x82000580, 0x00000048, 0x04020004, 0x8c102500,
+       0x02020000, 0x00109787, 0x4a025a06, 0x00000000,
+       0x8c040d1e, 0x04000027, 0x41780800, 0x497a5c09,
+       0x592c1c09, 0x59300011, 0x59341200, 0x497a6205,
+       0x8c08150e, 0x0402006e, 0x4807c857, 0x4806580a,
+       0x80000d40, 0x04020f04, 0x59300402, 0x48025c06,
+       0x48065807, 0x4a025a04, 0x00000103, 0x4c040000,
+       0x4c0c0000, 0x4c100000, 0x0201f800, 0x0010959c,
+       0x5c002000, 0x5c001800, 0x5c000800, 0x8c102512,
+       0x0402001a, 0x4c0c0000, 0x0201f800, 0x000202c1,
+       0x0201f800, 0x001049b2, 0x5c001800, 0x8c0c1d18,
+       0x02000000, 0x0002077d, 0x0201f000, 0x001091d1,
+       0x4813c857, 0x8c102518, 0x0400004b, 0x41780800,
+       0x592c1c09, 0x820c0580, 0x00001000, 0x040007d6,
+       0x8c102512, 0x040007d4, 0x592c7809, 0x583c080a,
+       0x583c1c09, 0x0401f7d0, 0x4807c857, 0x592c7809,
+       0x59300402, 0x592c1404, 0x8c08151e, 0x0402000d,
+       0x592c1206, 0x48007c06, 0x48047807, 0x48087a06,
+       0x84102512, 0x48107c08, 0x4c0c0000, 0x0201f800,
+       0x001007fd, 0x403e5800, 0x0401faca, 0x0401f7d9,
+       0x48025c06, 0x48065807, 0x583c080c, 0x583c000b,
+       0x80040c00, 0x82041480, 0x0000001d, 0x04001006,
+       0x583c1001, 0x480a5801, 0x49787801, 0x42000800,
+       0x0000001c, 0x82040c00, 0x00000014, 0x4c0c0000,
+       0x4c500000, 0x4c540000, 0x823ca400, 0x00000008,
+       0x832cac00, 0x00000008, 0x4c100000, 0x4c3c0000,
+       0x0401facb, 0x5c007800, 0x5c002000, 0x5c00a800,
+       0x5c00a000, 0x84102512, 0x48125c08, 0x403e5800,
+       0x0201f800, 0x001007fd, 0x42034000, 0x0010b4a4,
+       0x59a1d81e, 0x80edd9c0, 0x02000800, 0x001005d8,
+       0x48efc857, 0x58ec0009, 0x4803c857, 0x0801f800,
+       0x0401f7ac, 0x4933c857, 0x1c01f000, 0x59301414,
+       0x480bc857, 0x8c08151c, 0x0402000e, 0x80000540,
+       0x4803c857, 0x0400078d, 0x80042c80, 0x0402178b,
+       0x8c081514, 0x04020005, 0x592c080f, 0x4807c857,
+       0x80040480, 0x48026016, 0x8408155c, 0x480a6414,
+       0x59301007, 0x8408151e, 0x480a6007, 0x4a025c09,
+       0x00000001, 0x0201f800, 0x0010959c, 0x497a5c09,
+       0x8c102512, 0x04000006, 0x4d2c0000, 0x403e5800,
+       0x0201f800, 0x001007fd, 0x5c025800, 0x82102500,
+       0xffffedff, 0x48125c08, 0x0201f000, 0x0010920f,
+       0x59325808, 0x592c0408, 0x8c000518, 0x04000004,
+       0x412df800, 0x0201f000, 0x00100e6f, 0x1c01f000,
+       0x4933c857, 0x59325808, 0x497a5c09, 0x4a025a06,
+       0x00000000, 0x4a025a04, 0x00000103, 0x59300811,
+       0x4807c857, 0x800409c0, 0x0402000a, 0x48065807,
+       0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+       0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d,
+       0x59340200, 0x8c00050e, 0x04020005, 0x59300811,
+       0x0401fe55, 0x48065807, 0x0401f7f2, 0x592c0208,
+       0x8c00050e, 0x040207fa, 0x4933c857, 0x0201f000,
+       0x0010920f, 0x4933c857, 0x59325808, 0x812e59c0,
+       0x02000800, 0x001005d8, 0x592c020a, 0x8c000502,
+       0x02000800, 0x001005d8, 0x4a026206, 0x00000002,
+       0x1c01f000, 0x5930001c, 0x800001c0, 0x02020800,
+       0x0010984e, 0x59300007, 0x4933c857, 0x4803c857,
+       0x8c00050e, 0x04000037, 0x8c000500, 0x04000029,
+       0x8c00051c, 0x0400000a, 0x84000500, 0x48026007,
+       0x59325808, 0x592c3c08, 0x481fc857, 0x841c3d58,
+       0x481e5c08, 0x0201f000, 0x000207dd, 0x59325808,
+       0x592c3c08, 0x841c3d58, 0x59300007, 0x8c00051c,
+       0x040207f2, 0x481e5c08, 0x42000000, 0x00000005,
+       0x40000000, 0x80000040, 0x040207fe, 0x59300007,
+       0x8c00051c, 0x040207e9, 0x592c0204, 0x82000500,
+       0x000000ff, 0x82000580, 0x00000048, 0x04020003,
+       0x497a580b, 0x0401f002, 0x497a5c09, 0x481e5c08,
+       0x4a025a06, 0x00000000, 0x0201f000, 0x00100e56,
+       0x8c000524, 0x040007d9, 0x59325808, 0x4c000000,
+       0x592c0408, 0x8c00051c, 0x5c000000, 0x04020003,
+       0x4a026011, 0xffffffff, 0x84000524, 0x0401f7cf,
+       0x1c01f000, 0x4933c857, 0x41780800, 0x83380480,
+       0x00000058, 0x0402100b, 0x83380480, 0x00000040,
+       0x04001008, 0x4d2c0000, 0x59325808, 0x812e59c0,
+       0x0c020806, 0x5c025800, 0x0201f000, 0x0002077d,
+       0x493bc857, 0x1c01f000, 0x001089ae, 0x001089ae,
+       0x001089ae, 0x001089ae, 0x001089ae, 0x001089b0,
+       0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+       0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+       0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+       0x001089ae, 0x001089ae, 0x001089b5, 0x001089ae,
+       0x001089ae, 0x001089ae, 0x0201f800, 0x001005d8,
+       0x59cc0a08, 0x497a5807, 0x4807c857, 0x82040d00,
+       0x00000fff, 0x59300402, 0x48025c06, 0x4a025a04,
+       0x00000103, 0x48065c09, 0x4a025a06, 0x00000000,
+       0x800409c0, 0x02000000, 0x000202c1, 0x59cc0009,
+       0x4802580a, 0x82042500, 0x00000100, 0x04000002,
+       0x59cc200b, 0x4812580c, 0x82040500, 0x00000200,
+       0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00,
+       0x02001800, 0x001005d8, 0x02000000, 0x000202da,
+       0x82041480, 0x0000001d, 0x04001006, 0x592c0404,
+       0x8c00051e, 0x0400000e, 0x42000800, 0x0000001c,
+       0x4c500000, 0x4c540000, 0x83cca400, 0x0000000c,
+       0x832cac00, 0x0000000d, 0x0401f9c1, 0x5c00a800,
+       0x5c00a000, 0x0201f000, 0x000202da, 0x0401f965,
+       0x0401f1a0, 0x83380480, 0x00000093, 0x02021800,
+       0x001005d8, 0x83380480, 0x00000085, 0x02001800,
+       0x001005d8, 0x0c01f001, 0x001089fd, 0x001089fb,
+       0x001089fb, 0x00108a04, 0x001089fb, 0x001089fb,
+       0x001089fb, 0x001089fb, 0x001089fb, 0x001089fb,
+       0x001089fb, 0x001089fb, 0x001089fb, 0x0201f800,
+       0x001005d8, 0x4a026203, 0x00000001, 0x493a6403,
+       0x42000800, 0x80000040, 0x0201f000, 0x00020721,
+       0x4933c857, 0x59cc1204, 0x480a601c, 0x59cc1404,
+       0x0201f800, 0x00109410, 0x0400001b, 0x591c0203,
+       0x82000580, 0x00000000, 0x04000017, 0x591c0009,
+       0x81340580, 0x04020014, 0x4d300000, 0x4d1c0000,
+       0x411e6000, 0x0401f9c2, 0x5c023800, 0x5c026000,
+       0x0400000b, 0x59cc0005, 0x8c000500, 0x04020003,
+       0x0401f98c, 0x0401f003, 0x4a023a03, 0x00000002,
+       0x4a026403, 0x00000086, 0x0401f005, 0x0401f9a6,
+       0x040007f5, 0x4a026403, 0x00000087, 0x4a026203,
+       0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+       0x00020721, 0x59340200, 0x8c00050e, 0x0400000d,
+       0x59cc1404, 0x0201f800, 0x00109410, 0x04000009,
+       0x591c0414, 0x8c00051a, 0x04000006, 0x4d300000,
+       0x411e6000, 0x0201f800, 0x0010921e, 0x5c026000,
+       0x1c01f000, 0x83380580, 0x00000013, 0x0402000a,
+       0x59300403, 0x82000d80, 0x00000086, 0x04000012,
+       0x82000d80, 0x00000087, 0x02020800, 0x001005d8,
+       0x0401f00d, 0x83380580, 0x00000027, 0x04000005,
+       0x83380580, 0x00000014, 0x02020800, 0x001005d8,
+       0x493bc857, 0x0201f800, 0x00106bbf, 0x0201f000,
+       0x00107911, 0x4933c857, 0x0201f000, 0x00107911,
+       0x83380580, 0x00000013, 0x04020005, 0x59300403,
+       0x82000480, 0x00000085, 0x0c01f04d, 0x83380580,
+       0x00000027, 0x04020041, 0x4933c857, 0x0201f800,
+       0x00106bbf, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x42003000, 0x00000015,
+       0x41782800, 0x42002000, 0x00000003, 0x42028000,
+       0x00000029, 0x4d400000, 0x4d440000, 0x59368c03,
+       0x0201f800, 0x0010985e, 0x5c028800, 0x5c028000,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x00109037, 0x0400000c, 0x4d2c0000,
+       0x59325808, 0x4a025a04, 0x00000103, 0x59300402,
+       0x48025c06, 0x497a5c09, 0x49425a06, 0x0201f800,
+       0x000202da, 0x5c025800, 0x0201f800, 0x0010912a,
+       0x0201f000, 0x0002077d, 0x83380580, 0x00000089,
+       0x04000005, 0x83380580, 0x0000008a, 0x02020000,
+       0x00107974, 0x0201f800, 0x00106f60, 0x02020000,
+       0x00107974, 0x59300a03, 0x82040580, 0x0000000a,
+       0x0400002a, 0x82040580, 0x0000000c, 0x04000027,
+       0x0201f800, 0x001005d8, 0x83380580, 0x00000014,
+       0x040207ea, 0x4933c857, 0x0201f800, 0x00106bbf,
+       0x42028000, 0x00000006, 0x0401f7d2, 0x00108aba,
+       0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8,
+       0x00108ab8, 0x00108ac0, 0x00108ab8, 0x00108ab8,
+       0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8,
+       0x0201f800, 0x001005d8, 0x4933c857, 0x59a80037,
+       0x48026206, 0x4a026203, 0x0000000a, 0x1c01f000,
+       0x4933c857, 0x59a80037, 0x48026206, 0x4a026203,
+       0x0000000c, 0x1c01f000, 0x83380580, 0x00000089,
+       0x04000008, 0x83380580, 0x0000008a, 0x04000032,
+       0x4933c857, 0x493bc857, 0x0201f000, 0x00107974,
+       0x4933c857, 0x59325808, 0x59300a1d, 0x82040580,
+       0x00000003, 0x04020004, 0x0201f800, 0x001049b2,
+       0x0401f00c, 0x5930021d, 0x82000580, 0x00000001,
+       0x04020008, 0x59300c16, 0x82040580, 0x00000039,
+       0x0400002c, 0x82040580, 0x00000035, 0x04000029,
+       0x4c340000, 0x41306800, 0x0201f800, 0x0002075a,
+       0x04000010, 0x4a026203, 0x00000001, 0x4a026403,
+       0x0000001e, 0x59cc0c07, 0x48066419, 0x59cc0a07,
+       0x48066219, 0x49366009, 0x4a026406, 0x00000001,
+       0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+       0x40366000, 0x0201f800, 0x0002077d, 0x5c006800,
+       0x1c01f000, 0x4933c857, 0x5930021d, 0x82000580,
+       0x00000001, 0x04020040, 0x59300c16, 0x82040580,
+       0x00000035, 0x04000007, 0x82040580, 0x0000001e,
+       0x04000004, 0x82040580, 0x00000039, 0x04020036,
+       0x4933c857, 0x4c500000, 0x4d1c0000, 0x4130a000,
+       0x40067000, 0x0201f800, 0x001093ba, 0x04020029,
+       0x0201f800, 0x0002075a, 0x04000026, 0x491fc857,
+       0x4933c857, 0x83380580, 0x00000035, 0x04000004,
+       0x83380580, 0x00000039, 0x04020002, 0x4932381c,
+       0x493a6403, 0x4a026203, 0x00000001, 0x4a026406,
+       0x00000001, 0x58500809, 0x4807c857, 0x48066009,
+       0x58500c15, 0x4807c857, 0x48066415, 0x58500a15,
+       0x4807c857, 0x48066215, 0x58500a16, 0x4807c857,
+       0x48066216, 0x58500c19, 0x4807c857, 0x48066419,
+       0x58500a19, 0x4807c857, 0x48066219, 0x491e601e,
+       0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+       0x40526000, 0x5c023800, 0x5c00a000, 0x0201f000,
+       0x0002077d, 0x5930021d, 0x82000580, 0x00000003,
+       0x02000800, 0x001049b2, 0x0201f000, 0x0002077d,
+       0x4803c856, 0x4c500000, 0x4c540000, 0x412c7800,
+       0x4c3c0000, 0x42002800, 0x00000001, 0x82040480,
+       0x00000101, 0x04001003, 0x42000800, 0x00000100,
+       0x40043000, 0x42000800, 0x0000001c, 0x83cca400,
+       0x0000000c, 0x832cac00, 0x0000000d, 0x0401f844,
+       0x82183480, 0x0000001c, 0x592e5801, 0x812e59c0,
+       0x02020800, 0x001007fd, 0x0201f800, 0x001007e4,
+       0x04000017, 0x80142800, 0x4a025a04, 0x00000110,
+       0x497a5c04, 0x492c7801, 0x82180c80, 0x0000003d,
+       0x04021006, 0x40180800, 0x832cac00, 0x00000005,
+       0x0401f82f, 0x0401f00a, 0x82183480, 0x0000003c,
+       0x42000800, 0x0000003c, 0x412c7800, 0x832cac00,
+       0x00000005, 0x0401f826, 0x0401f7e8, 0x5c007800,
+       0x841429c0, 0x82142d40, 0x00000003, 0x48147a04,
+       0x403e5800, 0x5c00a800, 0x5c00a000, 0x1c01f000,
+       0x492fc857, 0x812e59c0, 0x0400000f, 0x4d2c0000,
+       0x4c3c0000, 0x592c7801, 0x803c79c0, 0x04000006,
+       0x497a5801, 0x0201f800, 0x000202da, 0x403e5800,
+       0x0401f7f9, 0x5c007800, 0x0201f800, 0x000202da,
+       0x5c025800, 0x1c01f000, 0x4803c856, 0x4c580000,
+       0x82040c00, 0x00000003, 0x8004b104, 0x0201f800,
+       0x0010ab17, 0x5c00b000, 0x1c01f000, 0x4803c856,
+       0x4c580000, 0x82040c00, 0x00000003, 0x8004b104,
+       0x0201f800, 0x0010ab17, 0x5c00b000, 0x1c01f000,
+       0x591c0c06, 0x82040580, 0x00000003, 0x04000004,
+       0x82040580, 0x00000002, 0x0402001a, 0x4d300000,
+       0x4d2c0000, 0x411e6000, 0x59325808, 0x0201f800,
+       0x00109037, 0x0400000f, 0x4d400000, 0x42028000,
+       0x00000013, 0x592c0a08, 0x84040d54, 0x0201f800,
+       0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c,
+       0x0201f800, 0x000202da, 0x0201f800, 0x0010912a,
+       0x0201f800, 0x00107911, 0x5c025800, 0x5c026000,
+       0x1c01f000, 0x59cc0005, 0x8c000500, 0x0402000b,
+       0x591c0406, 0x82000580, 0x00000002, 0x04020007,
+       0x591c0c03, 0x82040580, 0x00000085, 0x04000003,
+       0x82040580, 0x0000008b, 0x1c01f000, 0x4933c857,
+       0x4d3c0000, 0x42027800, 0x00000002, 0x59300406,
+       0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+       0x0c01f80a, 0x5c027800, 0x1c01f000, 0x4933c857,
+       0x59300406, 0x82000c80, 0x00000012, 0x02021800,
+       0x001005d8, 0x0c01f001, 0x00108c01, 0x00108bfe,
+       0x00108bfe, 0x00108c29, 0x00108bfc, 0x00108bfe,
+       0x00108c1a, 0x00108bfe, 0x00108bfc, 0x001065f4,
+       0x00108bfe, 0x00108bfe, 0x00108bfe, 0x00108bfc,
+       0x00108bfc, 0x00108bfc, 0x00108cf9, 0x00108bfe,
+       0x0201f800, 0x001005d8, 0x4803c856, 0x80000580,
+       0x1c01f000, 0x4803c856, 0x8d3e7d02, 0x04020016,
+       0x0201f800, 0x00109037, 0x0400000f, 0x59325808,
+       0x41780800, 0x4d400000, 0x42028000, 0x00000005,
+       0x0201f800, 0x00104e70, 0x5c028000, 0x0201f800,
+       0x0010959c, 0x0201f800, 0x001091cc, 0x0201f800,
+       0x000202da, 0x0201f800, 0x00107911, 0x82000540,
+       0x00000001, 0x1c01f000, 0x4933c857, 0x0201f800,
+       0x001048d9, 0x0402000c, 0x4d400000, 0x42028000,
+       0x00000010, 0x0201f800, 0x0010a1d1, 0x4a026406,
+       0x00000006, 0x4a026203, 0x00000007, 0x5c028000,
+       0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55,
+       0x4df00000, 0x0401f8b8, 0x82000c80, 0x0000000e,
+       0x02021800, 0x001005d8, 0x0c01f001, 0x00108c43,
+       0x00108cb0, 0x00108c5a, 0x00108cc3, 0x00108cab,
+       0x00108c41, 0x00108c43, 0x00108c43, 0x00108c47,
+       0x00108c43, 0x00108c43, 0x00108c43, 0x00108c43,
+       0x00108c5a, 0x0201f800, 0x001005d8, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x0401f7b8, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x59300406, 0x82000580,
+       0x00000003, 0x040207b4, 0x59300203, 0x82000580,
+       0x0000000d, 0x040007b0, 0x8d3e7d02, 0x040207ae,
+       0x4d340000, 0x59326809, 0x0201f800, 0x001049b2,
+       0x5c026800, 0x0401f7a8, 0x59300004, 0x8400055c,
+       0x48026004, 0x0201f800, 0x00106c4b, 0x59300406,
+       0x82000580, 0x00000006, 0x04000043, 0x8d3e7d02,
+       0x04020041, 0x497a621d, 0x59300203, 0x82000580,
+       0x0000000d, 0x04000003, 0x4a02621d, 0x00000003,
+       0x0401fbcb, 0x04000024, 0x4d2c0000, 0x4d400000,
+       0x59325808, 0x0201f800, 0x001091cc, 0x592c0408,
+       0x8c000512, 0x04000009, 0x4d2c0000, 0x84000512,
+       0x48025c08, 0x592c0809, 0x40065800, 0x0201f800,
+       0x001007fd, 0x5c025800, 0x4d400000, 0x42028000,
+       0x00000005, 0x592c0a08, 0x8c040d0e, 0x04000004,
+       0x42028000, 0x00000002, 0x0401f001, 0x0201f800,
+       0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c,
+       0x0201f800, 0x000202da, 0x497a6008, 0x5c028000,
+       0x5c025800, 0x8d3e7d00, 0x04000009, 0x4d340000,
+       0x59326809, 0x0201f800, 0x001049b2, 0x5c026800,
+       0x0201f800, 0x00107911, 0x0401f00b, 0x4a026403,
+       0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+       0x00000002, 0x42000800, 0x8000404b, 0x0201f800,
+       0x00020721, 0x5c03e000, 0x02020800, 0x00106c55,
+       0x82000540, 0x00000001, 0x1c01f000, 0x0201f800,
+       0x00106c4b, 0x0201f800, 0x00100e99, 0x0401f7ab,
+       0x598c000d, 0x81300580, 0x04020004, 0x0201f800,
+       0x00106e8e, 0x0402001b, 0x0201f800, 0x001068d3,
+       0x04020006, 0x59300c03, 0x82040580, 0x00000040,
+       0x0400078b, 0x0401f79d, 0x0201f800, 0x00106b6c,
+       0x04000010, 0x0201f800, 0x001005d8, 0x0401f813,
+       0x04020004, 0x0201f800, 0x00106e62, 0x04020009,
+       0x0201f800, 0x001067ae, 0x040207f4, 0x59300c03,
+       0x82040580, 0x00000040, 0x04000779, 0x0401f78b,
+       0x59300203, 0x82000c80, 0x0000000e, 0x02021800,
+       0x001005d8, 0x0c01f75e, 0x417a3000, 0x42032000,
+       0x0000bf32, 0x59900004, 0x81300580, 0x04000009,
+       0x83932400, 0x00000010, 0x811a3000, 0x83180480,
+       0x00000005, 0x040017f8, 0x82000540, 0x00000001,
+       0x1c01f000, 0x59300004, 0x8c00053e, 0x04000010,
+       0x8c00050c, 0x0402000e, 0x8c000516, 0x04020006,
+       0x82000d00, 0x0000001f, 0x82040580, 0x00000005,
+       0x04020004, 0x42000000, 0x00000003, 0x0401f005,
+       0x42000000, 0x00000001, 0x0401f002, 0x59300203,
+       0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55,
+       0x4df00000, 0x59300203, 0x82000c80, 0x0000000e,
+       0x02021800, 0x001005d8, 0x0c01f001, 0x00108d13,
+       0x00108d30, 0x00108d17, 0x00108d11, 0x00108d11,
+       0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11,
+       0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11,
+       0x00108d11, 0x0201f800, 0x001005d8, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x0401f6e8, 0x5c03e000,
+       0x02000800, 0x00106c4b, 0x4d2c0000, 0x59325808,
+       0x59300403, 0x82000580, 0x00000052, 0x02000800,
+       0x00101231, 0x0401fb16, 0x02000800, 0x001005d8,
+       0x4a025a06, 0x00000005, 0x0201f800, 0x000202da,
+       0x0201f800, 0x00104c19, 0x0201f800, 0x00107911,
+       0x5c025800, 0x82000540, 0x00000001, 0x1c01f000,
+       0x598c000d, 0x81300580, 0x0402001a, 0x59300004,
+       0x8c000520, 0x04000004, 0x84000520, 0x48026004,
+       0x0401f01a, 0x42001000, 0x0010b7f6, 0x50081000,
+       0x58080002, 0x82000580, 0x00000100, 0x0400000a,
+       0x5808000c, 0x81300580, 0x02020800, 0x001005d8,
+       0x0201f800, 0x001068d3, 0x02020800, 0x001005d8,
+       0x0401f7cf, 0x0201f800, 0x00106e8e, 0x0402000c,
+       0x59300004, 0x8c000520, 0x04000004, 0x84000520,
+       0x48026004, 0x0401f7c6, 0x0201f800, 0x001068d3,
+       0x040007c3, 0x0201f800, 0x001005d8, 0x59300203,
+       0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+       0x0c01f7a7, 0x59300406, 0x4933c857, 0x4803c857,
+       0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+       0x0c01f001, 0x00108d7c, 0x00108e41, 0x00108f79,
+       0x00108d88, 0x00107911, 0x00108d7c, 0x0010a1c0,
+       0x0002077d, 0x00108e41, 0x001065ce, 0x00108fda,
+       0x00108d77, 0x00108d77, 0x00108d77, 0x00108d77,
+       0x00108d77, 0x001096eb, 0x001096eb, 0x0201f800,
+       0x001005d8, 0x0401fbd5, 0x02000000, 0x0010801c,
+       0x1c01f000, 0x0201f800, 0x00106c55, 0x0201f800,
+       0x00106bbf, 0x0201f800, 0x00106c4b, 0x0201f000,
+       0x0002077d, 0x4a026206, 0x00000001, 0x1c01f000,
+       0x42000000, 0x0010b872, 0x0201f800, 0x0010aa47,
+       0x4d2c0000, 0x4d400000, 0x417a5800, 0x0401faa8,
+       0x04000007, 0x59325808, 0x592c0208, 0x8400054c,
+       0x48025a08, 0x42028000, 0x00000006, 0x0201f800,
+       0x00106c55, 0x0401ff4c, 0x4803c857, 0x82000c80,
+       0x0000000e, 0x02021800, 0x001005d8, 0x0c01f806,
+       0x0201f800, 0x00106c4b, 0x5c028000, 0x5c025800,
+       0x1c01f000, 0x00108e40, 0x00108db5, 0x00108dc3,
+       0x00108de5, 0x00108e11, 0x00108db3, 0x00108d7c,
+       0x00108d7c, 0x00108d7c, 0x00108db3, 0x00108db3,
+       0x00108db3, 0x00108db3, 0x00108dc3, 0x0201f800,
+       0x001005d8, 0x598c000d, 0x81300580, 0x04020004,
+       0x0201f800, 0x00106e8e, 0x04020038, 0x0201f800,
+       0x001068d3, 0x0400003b, 0x0201f800, 0x00106b6c,
+       0x04000032, 0x0201f800, 0x001005d8, 0x497a621d,
+       0x812e59c0, 0x02000800, 0x001005d8, 0x592c0204,
+       0x82000500, 0x000000ff, 0x82000580, 0x00000014,
+       0x04000003, 0x4a02621d, 0x00000003, 0x592c0a08,
+       0x0201f800, 0x00104e70, 0x0201f800, 0x0010959c,
+       0x0201f800, 0x000202da, 0x497a6008, 0x4a026403,
+       0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+       0x00000002, 0x4a026004, 0x8000404b, 0x0201f800,
+       0x00106c4b, 0x42000800, 0x8000404b, 0x0201f000,
+       0x00020721, 0x0401fef1, 0x04020004, 0x0201f800,
+       0x00106e62, 0x04020009, 0x0201f800, 0x001067ae,
+       0x040207d2, 0x59300c03, 0x82040580, 0x00000040,
+       0x04000008, 0x0401f7d2, 0x59300203, 0x82000c80,
+       0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ae,
+       0x0201f800, 0x00106c4b, 0x812e59c0, 0x04000013,
+       0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+       0x0010959c, 0x0201f800, 0x000202da, 0x59300203,
+       0x82000580, 0x0000000d, 0x04000008, 0x0201f800,
+       0x00106c4b, 0x4d340000, 0x59326809, 0x0201f800,
+       0x001049b2, 0x5c026800, 0x0201f800, 0x00107911,
+       0x0401f030, 0x812e59c0, 0x02000800, 0x001005d8,
+       0x0201f800, 0x0010940a, 0x04020004, 0x0201f800,
+       0x00100e99, 0x0401f7aa, 0x0201f800, 0x00106c4b,
+       0x592c0208, 0x8400050c, 0x48025a08, 0x592c0406,
+       0x800000c2, 0x800008c4, 0x80040c00, 0x48066206,
+       0x42000000, 0x10000000, 0x41300800, 0x0201f800,
+       0x00100b94, 0x0400000d, 0x592c0208, 0x8c00051c,
+       0x04020006, 0x8400055c, 0x48025a08, 0x4a026206,
+       0x00000002, 0x0401f00f, 0x4d300000, 0x0201f800,
+       0x001012e5, 0x5c026000, 0x59300203, 0x82000580,
+       0x00000004, 0x04020007, 0x4d380000, 0x42027000,
+       0x00000048, 0x0201f800, 0x000207a1, 0x5c027000,
+       0x1c01f000, 0x42000000, 0x0010b86e, 0x0201f800,
+       0x0010aa47, 0x59300203, 0x82000c80, 0x0000000e,
+       0x02021800, 0x001005d8, 0x4803c857, 0x0c01f001,
+       0x00108e5a, 0x00108d85, 0x00108e5c, 0x00108e5a,
+       0x00108e5c, 0x00108e5c, 0x00108d7d, 0x00108e5a,
+       0x00108d79, 0x00108e5a, 0x00108e5a, 0x00108e5a,
+       0x00108e5a, 0x00108e5a, 0x0201f800, 0x001005d8,
+       0x4d340000, 0x4d2c0000, 0x59326809, 0x59340400,
+       0x82000500, 0x000000ff, 0x82000c80, 0x0000000c,
+       0x02021800, 0x001005d8, 0x59303403, 0x82180d80,
+       0x00000004, 0x04020004, 0x42000000, 0x00000001,
+       0x0401f006, 0x82180d80, 0x00000000, 0x04020003,
+       0x42000000, 0x00000001, 0x4803c857, 0x0c01f804,
+       0x5c025800, 0x5c026800, 0x1c01f000, 0x00108e83,
+       0x00108f22, 0x00108e85, 0x00108eba, 0x00108e85,
+       0x00108f3f, 0x00108e85, 0x00108e8f, 0x00108e83,
+       0x00108f3f, 0x00108e83, 0x00108e9e, 0x0201f800,
+       0x001005d8, 0x59300403, 0x82000d80, 0x00000016,
+       0x0400002e, 0x82000d80, 0x00000004, 0x0400002b,
+       0x82000d80, 0x00000002, 0x04000028, 0x0401fabf,
+       0x04000079, 0x59300403, 0x82000d80, 0x00000022,
+       0x040000ae, 0x82000d80, 0x00000039, 0x040000b3,
+       0x82000d80, 0x00000035, 0x040000b0, 0x82000d80,
+       0x0000001e, 0x0400001b, 0x0401f999, 0x04000007,
+       0x0201f800, 0x00109597, 0x04020004, 0x0201f800,
+       0x00104a14, 0x0401f011, 0x59300403, 0x82000d80,
+       0x00000001, 0x04020004, 0x0201f800, 0x001049e7,
+       0x0400000a, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+       0x0201f800, 0x0010aa47, 0x0201f800, 0x0010801c,
+       0x0201f000, 0x00107911, 0x0401f97d, 0x04000004,
+       0x0201f800, 0x00109597, 0x040000a9, 0x59300c03,
+       0x82040580, 0x00000016, 0x04000056, 0x82040580,
+       0x00000002, 0x04020034, 0x59a80026, 0x8c000502,
+       0x04020013, 0x0201f800, 0x0010513b, 0x04020010,
+       0x0201f800, 0x00105151, 0x04020006, 0x42000000,
+       0x00000001, 0x0201f800, 0x00105113, 0x0401f094,
+       0x4a035033, 0x00000001, 0x4202d800, 0x00000001,
+       0x0201f800, 0x001050a2, 0x0401f08d, 0x59340403,
+       0x82000580, 0x000007fc, 0x04000008, 0x59a80026,
+       0x8c00050a, 0x04020084, 0x59340212, 0x82000500,
+       0x0000ff00, 0x04000082, 0x59340412, 0x82000500,
+       0x000000ff, 0x04000010, 0x80000040, 0x48026c12,
+       0x497a6008, 0x4a026406, 0x00000007, 0x4a026206,
+       0x00000398, 0x497a6205, 0x0201f800, 0x0002075a,
+       0x04000005, 0x49366009, 0x4a026406, 0x00000001,
+       0x0401f020, 0x59300403, 0x82000d80, 0x00000002,
+       0x0402000d, 0x59340403, 0x82000580, 0x000007fe,
+       0x04020009, 0x59a80026, 0x84000540, 0x48035026,
+       0x0201f800, 0x00104237, 0x0201f800, 0x0010801c,
+       0x0401f00c, 0x0201f800, 0x0010801c, 0x4d3c0000,
+       0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+       0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+       0x0201f800, 0x00102074, 0x0201f000, 0x00107911,
+       0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+       0x4a026203, 0x00000001, 0x4a026403, 0x00000002,
+       0x0201f000, 0x0010672b, 0x0401f915, 0x04020793,
+       0x0201f800, 0x00102074, 0x4d3c0000, 0x417a7800,
+       0x0201f800, 0x0010203c, 0x5c027800, 0x42000000,
+       0x0010b864, 0x0201f800, 0x0010aa47, 0x42003000,
+       0x00000018, 0x41782800, 0x42002000, 0x00000000,
+       0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+       0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+       0x5c028000, 0x0201f000, 0x00107911, 0x0201f800,
+       0x00104a14, 0x0401f7c8, 0x42000000, 0x0010b86d,
+       0x0201f800, 0x0010aa47, 0x0201f800, 0x00107b76,
+       0x040207c1, 0x1c01f000, 0x4d380000, 0x59327403,
+       0x0201f800, 0x001093ba, 0x5c027000, 0x02020000,
+       0x0002077d, 0x836c0580, 0x00000003, 0x04000004,
+       0x4a026206, 0x00000002, 0x1c01f000, 0x59300403,
+       0x48026416, 0x4a02621d, 0x00000001, 0x4a026403,
+       0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+       0x00000002, 0x42000800, 0x8000004b, 0x0201f000,
+       0x00020721, 0x0201f800, 0x00102074, 0x0201f800,
+       0x0010801c, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+       0x0201f800, 0x0010aa47, 0x497a6008, 0x4a026406,
+       0x00000007, 0x4a026206, 0x00000398, 0x497a6205,
+       0x1c01f000, 0x42000000, 0x0010b870, 0x0201f800,
+       0x0010aa47, 0x4d340000, 0x59326809, 0x59300203,
+       0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+       0x4803c857, 0x0c01f803, 0x5c026800, 0x1c01f000,
+       0x00108f96, 0x00108d85, 0x00108f96, 0x00108f96,
+       0x00108f96, 0x00108f96, 0x00108f96, 0x00108f96,
+       0x00108f96, 0x00108d85, 0x00108f98, 0x00108d85,
+       0x00108fa0, 0x00108f96, 0x0201f800, 0x001005d8,
+       0x4a026403, 0x0000008b, 0x4a026203, 0x0000000b,
+       0x42000800, 0x8000404b, 0x0201f000, 0x00020721,
+       0x59300a1d, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x42003000, 0x00000011,
+       0x0201f800, 0x0010a942, 0x42000000, 0x0010b864,
+       0x0201f800, 0x0010aa47, 0x41306800, 0x0201f800,
+       0x0002075a, 0x04000008, 0x49366009, 0x4d300000,
+       0x40366000, 0x0201f800, 0x00107911, 0x5c026000,
+       0x0401f002, 0x40366000, 0x497a6008, 0x4a026406,
+       0x00000001, 0x4a026403, 0x00000001, 0x0201f800,
+       0x00103b25, 0x04000011, 0x4a026406, 0x00000004,
+       0x4a026203, 0x00000007, 0x4a026420, 0x00000001,
+       0x42003000, 0x00000004, 0x4d400000, 0x42028000,
+       0x00000029, 0x41782800, 0x0201f800, 0x0010a43e,
+       0x5c028000, 0x1c01f000, 0x42000800, 0x0000000b,
+       0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+       0x0201f000, 0x0010672b, 0x42000000, 0x0010b876,
+       0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80,
+       0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+       0x0c01f001, 0x0010900b, 0x00108ff3, 0x00108ff7,
+       0x0010900c, 0x00108ff5, 0x00108ff3, 0x00108ff3,
+       0x00108ff3, 0x00108ff3, 0x00108ff3, 0x00108ff3,
+       0x00108ff3, 0x00108ff3, 0x00108ff3, 0x0201f800,
+       0x001005d8, 0x0201f800, 0x00100e99, 0x4d2c0000,
+       0x59325808, 0x4a025a06, 0x00000006, 0x0201f800,
+       0x000202da, 0x5c025800, 0x497a6008, 0x4a02621d,
+       0x0000000a, 0x4a026403, 0x00000085, 0x4a026203,
+       0x00000009, 0x4a026406, 0x00000002, 0x42000800,
+       0x8000404b, 0x0201f000, 0x00020721, 0x1c01f000,
+       0x0201f800, 0x00106c55, 0x4df00000, 0x0401fcc7,
+       0x04020004, 0x0201f800, 0x00106e62, 0x0402000c,
+       0x0201f800, 0x001067ae, 0x04020005, 0x5c03e000,
+       0x0201f800, 0x00106c4b, 0x0401f7dd, 0x0201f800,
+       0x00106b6c, 0x02020800, 0x001005d8, 0x5c03e000,
+       0x0201f800, 0x00106c4b, 0x59300203, 0x82000d80,
+       0x00000003, 0x02000800, 0x001005d8, 0x82000c80,
+       0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ba,
+       0x4803c856, 0x59a8000e, 0x59a80867, 0x80040400,
+       0x80080480, 0x04021004, 0x82000540, 0x00000001,
+       0x1c01f000, 0x80000580, 0x1c01f000, 0x4803c856,
+       0x4c080000, 0x59301008, 0x82081500, 0xfff00000,
+       0x5c001000, 0x1c01f000, 0x4803c856, 0x4d300000,
+       0x0201f800, 0x0002075a, 0x0400000a, 0x0401f82f,
+       0x4d380000, 0x42027000, 0x0000004b, 0x0201f800,
+       0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+       0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+       0x0201f800, 0x00107942, 0x0400001b, 0x0401f81f,
+       0x4d300000, 0x0201f800, 0x00106c55, 0x4d3c0000,
+       0x417a7800, 0x0201f800, 0x00106ab4, 0x0201f800,
+       0x001067fd, 0x5c027800, 0x0201f800, 0x0010a2ff,
+       0x0201f800, 0x00106c4b, 0x5c026000, 0x8d3e7d3e,
+       0x0402000b, 0x4d380000, 0x42027000, 0x0000004c,
+       0x0201f800, 0x000207a1, 0x5c027000, 0x82000540,
+       0x00000001, 0x5c026000, 0x1c01f000, 0x0201f800,
+       0x0002077d, 0x0401f7fa, 0x592c0407, 0x494a6017,
+       0x494e6018, 0x49366009, 0x492e6008, 0x4a026406,
+       0x00000003, 0x800000c2, 0x800008c4, 0x80040400,
+       0x48026206, 0x1c01f000, 0x493bc857, 0x4d300000,
+       0x0201f800, 0x0002075a, 0x0400000d, 0x0401ffef,
+       0x4d400000, 0x42028000, 0x00000005, 0x0401f80d,
+       0x5c028000, 0x8d3e7d3e, 0x04020007, 0x0201f800,
+       0x000207a1, 0x82000540, 0x00000001, 0x5c026000,
+       0x1c01f000, 0x0201f800, 0x0002077d, 0x0401f7fa,
+       0x4803c856, 0x0201f800, 0x00106c55, 0x4d3c0000,
+       0x4d440000, 0x59368c03, 0x42027800, 0x00000001,
+       0x0201f800, 0x001069b6, 0x0201f800, 0x0010692e,
+       0x0201f800, 0x001067fd, 0x0201f800, 0x0010a2ff,
+       0x5c028800, 0x5c027800, 0x0201f000, 0x00106c4b,
+       0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a,
+       0x0400000f, 0x481a601c, 0x48ee6021, 0x49366009,
+       0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+       0x42027000, 0x0000001f, 0x0201f800, 0x000207a1,
+       0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+       0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+       0x0002075a, 0x0400000e, 0x48ee6021, 0x49366009,
+       0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+       0x42027000, 0x00000055, 0x0201f800, 0x000207a1,
+       0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+       0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+       0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021,
+       0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+       0x4d380000, 0x42027000, 0x0000003d, 0x0201f800,
+       0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+       0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+       0x0201f800, 0x00107942, 0x04000014, 0x49366009,
+       0x492fc857, 0x4933c857, 0x592c0404, 0x8c00051e,
+       0x04000003, 0x48efc857, 0x48ee6021, 0x4a026406,
+       0x00000001, 0x492e6008, 0x4d380000, 0x42027000,
+       0x00000000, 0x0201f800, 0x000207a1, 0x5c027000,
+       0x82000540, 0x00000001, 0x5c026000, 0x1c01f000,
+       0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a,
+       0x0400000f, 0x48ee6021, 0x481a601c, 0x49366009,
+       0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+       0x42027000, 0x00000044, 0x0201f800, 0x000207a1,
+       0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+       0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+       0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021,
+       0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+       0x4d380000, 0x42027000, 0x00000049, 0x0201f800,
+       0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+       0x5c026000, 0x1c01f000, 0x59300009, 0x80001540,
+       0x02000800, 0x001005d8, 0x5808040b, 0x4803c856,
+       0x80000040, 0x04001002, 0x4800140b, 0x1c01f000,
+       0x4803c856, 0x59300403, 0x82000d80, 0x00000002,
+       0x04000015, 0x82000d80, 0x00000003, 0x04000012,
+       0x82000d80, 0x00000004, 0x0400000f, 0x82000d80,
+       0x00000008, 0x0400000c, 0x82000d80, 0x0000000a,
+       0x04000009, 0x599c0819, 0x8c040d0e, 0x04000004,
+       0x82000d80, 0x00000000, 0x04000003, 0x82000540,
+       0x00000001, 0x1c01f000, 0x4803c856, 0x4c000000,
+       0x4d2c0000, 0x59300406, 0x82000580, 0x00000004,
+       0x0400001d, 0x59300008, 0x80025d40, 0x800001c0,
+       0x04000019, 0x0201f800, 0x00109597, 0x04000014,
+       0x59300406, 0x82004580, 0x00000010, 0x04000010,
+       0x82004580, 0x00000011, 0x0400000d, 0x82004580,
+       0x00000003, 0x0400000c, 0x82004580, 0x00000002,
+       0x04000009, 0x82004580, 0x0000000a, 0x04000006,
+       0x592c0404, 0x8c00051e, 0x04000003, 0x80000580,
+       0x0401f003, 0x82000540, 0x00000001, 0x5c025800,
+       0x5c000000, 0x1c01f000, 0x4803c856, 0x4d300000,
+       0x0201f800, 0x00107942, 0x04000013, 0x49366009,
+       0x48ee6021, 0x4a026406, 0x00000001, 0x492e6008,
+       0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x5c027800, 0x4d380000, 0x42027000, 0x00000028,
+       0x0201f800, 0x000207a1, 0x5c027000, 0x82000540,
+       0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856,
+       0x83380580, 0x00000015, 0x0402000d, 0x59a80016,
+       0x82000580, 0x00000074, 0x04020009, 0x0201f800,
+       0x0010462a, 0x4a026203, 0x00000001, 0x4a026403,
+       0x00000029, 0x0201f000, 0x0010672b, 0x0201f800,
+       0x0010801c, 0x0201f000, 0x0002077d, 0x4803c856,
+       0x83380580, 0x00000016, 0x04020007, 0x42000800,
+       0x00000004, 0x0201f800, 0x00104571, 0x0201f000,
+       0x00107b38, 0x83380580, 0x00000015, 0x04020013,
+       0x59a80016, 0x82000580, 0x00000014, 0x0402000f,
+       0x0201f800, 0x0010468d, 0x0201f800, 0x0010846f,
+       0x0402000a, 0x59340404, 0x80000540, 0x04000007,
+       0x42000800, 0x00000006, 0x0201f800, 0x00104571,
+       0x0201f000, 0x00107b38, 0x0201f800, 0x0010801c,
+       0x0201f000, 0x0002077d, 0x4803c856, 0x592c0206,
+       0x82000580, 0x00000005, 0x04000002, 0x1c01f000,
+       0x4803c856, 0x592c0208, 0x8400054a, 0x48025a08,
+       0x1c01f000, 0x497a6205, 0x497a6008, 0x4a026203,
+       0x00000001, 0x4a026403, 0x00000050, 0x42000800,
+       0x80000043, 0x0201f000, 0x00020721, 0x4933c857,
+       0x4d340000, 0x59326809, 0x59340200, 0x8c00050e,
+       0x04000006, 0x59300406, 0x82000c80, 0x00000012,
+       0x04021004, 0x0c01f806, 0x5c026800, 0x1c01f000,
+       0x0201f800, 0x00108d7c, 0x0401f7fc, 0x00108d7c,
+       0x001091fd, 0x00109201, 0x00109204, 0x0010a49b,
+       0x0010a4b8, 0x0010a4bc, 0x00108d7c, 0x00108d7c,
+       0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c,
+       0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c,
+       0x00108d7c, 0x4803c856, 0x40000000, 0x40000000,
+       0x1c01f000, 0x40000000, 0x40000000, 0x1c01f000,
+       0x5930001c, 0x4803c857, 0x59300414, 0x4933c857,
+       0x4803c857, 0x8c000502, 0x04000005, 0x84000502,
+       0x84000540, 0x48026414, 0x1c01f000, 0x42000000,
+       0xd0000000, 0x41300800, 0x0201f800, 0x00100b94,
+       0x0401f80a, 0x04020008, 0x59a80037, 0x82000400,
+       0x0000000a, 0x48026205, 0x59300414, 0x84000542,
+       0x48026414, 0x1c01f000, 0x4933c857, 0x4d340000,
+       0x59326809, 0x59340200, 0x8c00050e, 0x02000800,
+       0x001005d8, 0x5930001c, 0x80000540, 0x0402002f,
+       0x59a80021, 0x80000540, 0x0402002a, 0x4d1c0000,
+       0x41323800, 0x0201f800, 0x0002075a, 0x04000023,
+       0x4932381c, 0x591c0414, 0x84000542, 0x48023c14,
+       0x49366009, 0x591c0406, 0x82000580, 0x00000003,
+       0x04000006, 0x591c0202, 0x48026419, 0x591c0402,
+       0x48026219, 0x0401f005, 0x591c0202, 0x48026219,
+       0x591c0402, 0x48026419, 0x491e601e, 0x4a026406,
+       0x00000001, 0x4a026403, 0x00000035, 0x4a026203,
+       0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+       0x00020721, 0x411e6000, 0x5c023800, 0x80000580,
+       0x5c026800, 0x1c01f000, 0x411e6000, 0x5c023800,
+       0x59a80039, 0x48026205, 0x82000540, 0x00000001,
+       0x0401f7f8, 0x4933c857, 0x4d2c0000, 0x4932381c,
+       0x4a026202, 0x0000ffff, 0x591e5808, 0x591c0007,
+       0x8c00051e, 0x04000005, 0x8400051e, 0x48023807,
+       0x497a5c09, 0x0401f014, 0x592c0408, 0x8c000518,
+       0x04000011, 0x84000518, 0x48025c08, 0x4a025c09,
+       0x00000001, 0x0401fb2f, 0x497a5c09, 0x592c0408,
+       0x8c000512, 0x04000008, 0x4d2c0000, 0x84000512,
+       0x48025c08, 0x592e5809, 0x0201f800, 0x001007fd,
+       0x5c025800, 0x59a80039, 0x48026205, 0x591c0214,
+       0x48026216, 0x82000d80, 0x00000001, 0x04000008,
+       0x4a023a03, 0x00000002, 0x82000580, 0x00000005,
+       0x04000008, 0x497a6015, 0x0401f01e, 0x591c0007,
+       0x84000540, 0x48023807, 0x4a023a03, 0x00000004,
+       0x591c0414, 0x4803c857, 0x8400051c, 0x84000554,
+       0x48023c14, 0x592c000f, 0x40001000, 0x591c0816,
+       0x80040480, 0x040217f0, 0x591c0016, 0x82000500,
+       0xfffffffc, 0x48026015, 0x48023816, 0x591c0a14,
+       0x4807c857, 0x82040d80, 0x00000005, 0x04020005,
+       0x480bc857, 0x4803c857, 0x4a023812, 0xffffffff,
+       0x591c0402, 0x48026419, 0x591c0202, 0x48026219,
+       0x591e6809, 0x49366009, 0x4a026406, 0x00000001,
+       0x4a026403, 0x00000039, 0x4a026203, 0x00000001,
+       0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x59300414,
+       0x8c000514, 0x04000015, 0x8c00051c, 0x04020012,
+       0x59300016, 0x80100480, 0x04001006, 0x04000005,
+       0x59300414, 0x84000514, 0x8400055c, 0x0401f009,
+       0x48126016, 0x48126012, 0x40100000, 0x592c180f,
+       0x800c0480, 0x48026011, 0x59300414, 0x84000514,
+       0x48026414, 0x1c01f000, 0x4933c857, 0x8c00051c,
+       0x04020006, 0x59300012, 0x48026016, 0x59300414,
+       0x8400055c, 0x48026414, 0x1c01f000, 0x59300c03,
+       0x4933c857, 0x4807c857, 0x82040480, 0x00000034,
+       0x04001006, 0x82040480, 0x0000003c, 0x04021003,
+       0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+       0x0401f7fd, 0x41780800, 0x59a81035, 0x42000000,
+       0x00000032, 0x0201f800, 0x001066a0, 0x800811c0,
+       0x04020003, 0x42001000, 0x00000014, 0x480b5037,
+       0x59a81036, 0x480b502d, 0x41780800, 0x42000000,
+       0x00000064, 0x0201f800, 0x001066a0, 0x800811c0,
+       0x04020003, 0x42001000, 0x00000014, 0x480b5038,
+       0x82081400, 0x0000000a, 0x480b5039, 0x42000800,
+       0x00000001, 0x0201f800, 0x00106c78, 0x42000000,
+       0x30000000, 0x40080800, 0x0201f800, 0x00100b68,
+       0x42000800, 0x00000003, 0x59a81010, 0x0201f800,
+       0x00106c78, 0x0201f000, 0x00104906, 0x4a035037,
+       0x00000028, 0x4a035038, 0x00000014, 0x4a03502d,
+       0x000007d0, 0x42001000, 0x0000001e, 0x480b5039,
+       0x42000800, 0x00000001, 0x0201f800, 0x00106c78,
+       0x42000000, 0x30000000, 0x40080800, 0x0201f800,
+       0x00100b68, 0x42000800, 0x00000003, 0x59a81010,
+       0x0201f000, 0x00106c78, 0x4933c857, 0x4d2c0000,
+       0x59300403, 0x82000580, 0x0000003e, 0x04020005,
+       0x59325817, 0x812e59c0, 0x02020800, 0x001007f4,
+       0x5c025800, 0x1c01f000, 0x4937c857, 0x4d300000,
+       0x0201f800, 0x0002075a, 0x04000011, 0x49366009,
+       0x4a026406, 0x00000001, 0x492e6008, 0x42000800,
+       0x00000009, 0x0201f800, 0x00104571, 0x4d380000,
+       0x42027000, 0x00000033, 0x0201f800, 0x000207a1,
+       0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+       0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c580000,
+       0x4d3c0000, 0x59325808, 0x83380580, 0x00000015,
+       0x04020022, 0x59a8b016, 0x82580c80, 0x00000019,
+       0x04001003, 0x4200b000, 0x00000018, 0x8058b104,
+       0x0401fa07, 0x80000580, 0x0401fa17, 0x832cac00,
+       0x00000009, 0x83cca400, 0x00000006, 0x0201f800,
+       0x0010ab17, 0x42027800, 0x00000001, 0x592c100a,
+       0x8c081518, 0x04020006, 0x59a80010, 0x592c100d,
+       0x80080580, 0x04020006, 0x417a7800, 0x59301009,
+       0x58081403, 0x0201f800, 0x001020a1, 0x0201f800,
+       0x00107b38, 0x0401f008, 0x4200b000, 0x00000002,
+       0x0401fa09, 0x0201f800, 0x0010801c, 0x0201f800,
+       0x0002077d, 0x5c027800, 0x5c00b000, 0x5c025800,
+       0x1c01f000, 0x4933c856, 0x49366009, 0x4a026406,
+       0x00000001, 0x492e6008, 0x4d380000, 0x42027000,
+       0x0000004d, 0x0201f800, 0x000207a1, 0x5c027000,
+       0x82000540, 0x00000001, 0x1c01f000, 0x4803c856,
+       0x4d2c0000, 0x83380580, 0x00000015, 0x04020027,
+       0x59a80816, 0x59325808, 0x5930040b, 0x800000c4,
+       0x80040580, 0x04020021, 0x4c500000, 0x4c540000,
+       0x4c580000, 0x83cca400, 0x00000006, 0x4050a800,
+       0x5930b40b, 0x0201f800, 0x0010ab28, 0x83cca400,
+       0x00000006, 0x592cb205, 0x832cac00, 0x00000006,
+       0x0201f800, 0x0010ab17, 0x592e5801, 0x812e59c0,
+       0x040207f9, 0x5931d821, 0x58ef400b, 0x58ee580d,
+       0x4a025a04, 0x00000103, 0x58ec0009, 0x0801f800,
+       0x59300402, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+       0x5c025800, 0x1c01f000, 0x0201f800, 0x0010801c,
+       0x5c025800, 0x1c01f000, 0x4933c857, 0x83380580,
+       0x00000035, 0x04000005, 0x59301419, 0x0401f851,
+       0x04000027, 0x0401f006, 0x4d300000, 0x5932601e,
+       0x0401f856, 0x5c026000, 0x04000020, 0x591c0c06,
+       0x82040580, 0x00000003, 0x04000004, 0x82040580,
+       0x00000006, 0x0402001c, 0x591c0c02, 0x59300419,
+       0x80040580, 0x04000009, 0x59300219, 0x80040580,
+       0x04020015, 0x591c0a02, 0x59300419, 0x80040580,
+       0x04020011, 0x0401f009, 0x59300a19, 0x82040580,
+       0x0000ffff, 0x04000005, 0x591c0202, 0x59300a19,
+       0x80040580, 0x04020008, 0x591c0009, 0x59300809,
+       0x80040580, 0x1c01f000, 0x417a3800, 0x82000540,
+       0x00000001, 0x1c01f000, 0x4803c856, 0x59b800e4,
+       0x8c000538, 0x02020800, 0x001005d8, 0x42000800,
+       0x0000012c, 0x4a0370e4, 0x20000000, 0x59b800e4,
+       0x80040840, 0x02000800, 0x001005d8, 0x8c00053c,
+       0x040207f9, 0x4a0370e4, 0x30000000, 0x40000000,
+       0x40000000, 0x40000000, 0x59b800e4, 0x8c00053c,
+       0x040207f1, 0x1c01f000, 0x4803c856, 0x4a0370e4,
+       0x20000000, 0x40000000, 0x59b800e4, 0x8c000538,
+       0x040207fb, 0x1c01f000, 0x59300807, 0x8c040d1e,
+       0x592c0c08, 0x04020002, 0x8c040d18, 0x1c01f000,
+       0x0401fc1c, 0x04000008, 0x42000800, 0x00000024,
+       0x0201f800, 0x00106681, 0x82063c00, 0x0010d1c0,
+       0x491fc857, 0x1c01f000, 0x83300480, 0x0010d1c0,
+       0x0400100a, 0x59a8000b, 0x81300480, 0x04021007,
+       0x59301402, 0x0401ffef, 0x04000007, 0x411c0000,
+       0x81300580, 0x04000003, 0x81780500, 0x0401f002,
+       0x81300540, 0x1c01f000, 0x4947c857, 0x4d300000,
+       0x0201f800, 0x00020245, 0x0402000a, 0x42026000,
+       0x0010bde9, 0x49366009, 0x492e6008, 0x0201f800,
+       0x0010203c, 0x80000580, 0x5c026000, 0x1c01f000,
+       0x82000540, 0x00000001, 0x0401f7fc, 0x4933c857,
+       0x0201f800, 0x00109037, 0x02000800, 0x001005d8,
+       0x4d2c0000, 0x4d340000, 0x4d440000, 0x4c580000,
+       0x59325808, 0x59326809, 0x49425a06, 0x0201f800,
+       0x00105755, 0x592e8c06, 0x592c4207, 0x82200500,
+       0x0000000f, 0x0c01f806, 0x5c00b000, 0x5c028800,
+       0x5c026800, 0x5c025800, 0x1c01f000, 0x00109466,
+       0x00109488, 0x0010948f, 0x00109493, 0x0010949c,
+       0x00109463, 0x00109463, 0x00109463, 0x001094a0,
+       0x001094ac, 0x001094ac, 0x00109463, 0x00109463,
+       0x00109463, 0x00109463, 0x00109463, 0x4803c857,
+       0x0201f800, 0x001005d8, 0x814281c0, 0x04020012,
+       0x41785800, 0x592c0404, 0x8c00051c, 0x04020002,
+       0x59345c05, 0x442c2800, 0x59340008, 0x48002802,
+       0x59340009, 0x48002801, 0x59340006, 0x48002804,
+       0x59340007, 0x48002803, 0x4200b000, 0x0000000b,
+       0x0401f037, 0x592c0207, 0x8c00051e, 0x4200b000,
+       0x00000002, 0x04020032, 0x8204b540, 0x00000000,
+       0x0400002f, 0x44042800, 0x59326809, 0x59340400,
+       0x48002801, 0x4200b000, 0x00000002, 0x0401f028,
+       0x814281c0, 0x04020030, 0x59345c05, 0x442c2800,
+       0x4200b000, 0x00000001, 0x0401f021, 0x8340b540,
+       0x00000000, 0x0400001e, 0x0401f027, 0x814281c0,
+       0x04020025, 0x59340200, 0x44002800, 0x59340001,
+       0x48002801, 0x4200b000, 0x00000002, 0x0401f014,
+       0x8340b540, 0x00000000, 0x0402001b, 0x0401f010,
+       0x8340b540, 0x00000000, 0x0400000d, 0x0201f800,
+       0x00104a1f, 0x04000014, 0x8c20450e, 0x04000002,
+       0x497a6009, 0x4178b000, 0x497a5a06, 0x0401f004,
+       0x8340b540, 0x00000000, 0x0402000b, 0x592c0404,
+       0x8400051c, 0x48025c04, 0x592c0207, 0x8400051e,
+       0x48025a07, 0x0401f8aa, 0x497a6008, 0x0201f000,
+       0x000202da, 0x592c0207, 0x8c00051e, 0x4200b000,
+       0x00000002, 0x040207f2, 0x8204b540, 0x00000000,
+       0x040007ef, 0x44042800, 0x4200b000, 0x00000001,
+       0x0401f7eb, 0x4937c857, 0x4d300000, 0x0201f800,
+       0x0002075a, 0x04000011, 0x49366009, 0x4a026406,
+       0x00000001, 0x492e6008, 0x42000800, 0x0000000b,
+       0x0201f800, 0x00104571, 0x4d380000, 0x42027000,
+       0x00000043, 0x0201f800, 0x000207a1, 0x5c027000,
+       0x82000540, 0x00000001, 0x5c026000, 0x1c01f000,
+       0x4937c857, 0x4d2c0000, 0x59325808, 0x83380580,
+       0x00000015, 0x04020025, 0x59a80016, 0x82000580,
+       0x00000004, 0x04020021, 0x59a80010, 0x592c1009,
+       0x80080580, 0x04020010, 0x4d440000, 0x592e8c06,
+       0x592c0207, 0x4803c856, 0x82000500, 0x00000080,
+       0x84000548, 0x4d3c0000, 0x42027800, 0x00001000,
+       0x0201f800, 0x001049bb, 0x5c027800, 0x5c028800,
+       0x0401f004, 0x4803c856, 0x0201f800, 0x00104a1f,
+       0x0201f800, 0x00109037, 0x04000017, 0x4d400000,
+       0x42028000, 0x00000000, 0x41780800, 0x0401ff38,
+       0x5c028000, 0x0401f00e, 0x0201f800, 0x00104a1f,
+       0x040207f4, 0x0201f800, 0x00109037, 0x0400000a,
+       0x4c580000, 0x4200b000, 0x00000002, 0x0401f86e,
+       0x5c00b000, 0x0201f800, 0x0010801c, 0x0201f800,
+       0x0002077d, 0x5c025800, 0x1c01f000, 0x4937c857,
+       0x4d300000, 0x0201f800, 0x0002075a, 0x04000012,
+       0x49366009, 0x4a026406, 0x00000001, 0x4d3c0000,
+       0x4d380000, 0x417a7800, 0x0201f800, 0x00104567,
+       0x492e6008, 0x42027000, 0x00000004, 0x0201f800,
+       0x000207a1, 0x5c027000, 0x5c027800, 0x82000540,
+       0x00000001, 0x5c026000, 0x1c01f000, 0x4937c857,
+       0x4d300000, 0x0201f800, 0x00107942, 0x0400000d,
+       0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+       0x4d380000, 0x42027000, 0x00000051, 0x0201f800,
+       0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+       0x5c026000, 0x1c01f000, 0x4933c857, 0x4c580000,
+       0x59325808, 0x83383580, 0x00000015, 0x04020011,
+       0x592c0008, 0x82000500, 0x00ffffff, 0x0402000a,
+       0x0201f800, 0x00105755, 0x59cc0000, 0x82000500,
+       0x00ffffff, 0x44002800, 0x4200b000, 0x00000001,
+       0x0401f80b, 0x0201f800, 0x00107b38, 0x0401f006,
+       0x4200b000, 0x00000002, 0x0401f823, 0x0201f800,
+       0x0010801c, 0x5c00b000, 0x1c01f000, 0x492fc857,
+       0x4c580000, 0x4c000000, 0x8058b1c0, 0x0400000b,
+       0x82580500, 0xfffffff0, 0x02020800, 0x001005d8,
+       0x8058b0d0, 0x592c0408, 0x82000500, 0xfffff0ff,
+       0x80580540, 0x48025c08, 0x5c000000, 0x5c00b000,
+       0x1c01f000, 0x492fc857, 0x4c000000, 0x4c040000,
+       0x800000d8, 0x592c0c08, 0x82040d00, 0xffff0fff,
+       0x80040540, 0x48025c08, 0x5c000800, 0x5c000000,
+       0x1c01f000, 0x4933c857, 0x4d2c0000, 0x59325808,
+       0x592c0207, 0x8400055e, 0x48025a07, 0x4c500000,
+       0x4c540000, 0x4c580000, 0x0401ffd9, 0x0201f800,
+       0x00105755, 0x46002800, 0x00000018, 0x80142800,
+       0x8058b040, 0x83cca400, 0x00000007, 0x4014a800,
+       0x0201f800, 0x0010ab17, 0x5c00b000, 0x5c00a800,
+       0x5c00a000, 0x5c025800, 0x1c01f000, 0x59325808,
+       0x592c0204, 0x82000580, 0x00000152, 0x1c01f000,
+       0x5930001f, 0x80000540, 0x02020800, 0x00100d56,
+       0x1c01f000, 0x4d2c0000, 0x59325808, 0x59300203,
+       0x4933c857, 0x492fc857, 0x493bc857, 0x4803c857,
+       0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+       0x0c01f803, 0x5c025800, 0x1c01f000, 0x001095bd,
+       0x001095c8, 0x00109603, 0x001095bd, 0x001095bd,
+       0x001095bd, 0x001095bd, 0x001095bd, 0x001095bf,
+       0x001095bd, 0x001095bd, 0x001095bd, 0x001095bd,
+       0x001095bd, 0x0201f800, 0x001005d8, 0x83383480,
+       0x00000056, 0x02021800, 0x001005d8, 0x493a6403,
+       0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+       0x83380580, 0x00000013, 0x0402000f, 0x592c000c,
+       0x800001c0, 0x04000006, 0x4a026203, 0x00000002,
+       0x59a80037, 0x48026206, 0x1c01f000, 0x4a025a06,
+       0x00000000, 0x0201f800, 0x000202da, 0x0201f000,
+       0x0002077d, 0x83380580, 0x00000027, 0x0400001a,
+       0x83380580, 0x00000014, 0x04000012, 0x83380580,
+       0x00000015, 0x04000005, 0x83380580, 0x00000016,
+       0x02020800, 0x001005d8, 0x0201f800, 0x00106f60,
+       0x02020000, 0x00107974, 0x59300203, 0x82000580,
+       0x00000002, 0x02020800, 0x001005d8, 0x0401f014,
+       0x0201f800, 0x00106bbf, 0x4a02580e, 0x00000011,
+       0x0401f005, 0x0201f800, 0x00106bbf, 0x4a02580e,
+       0x00000010, 0x4a025a06, 0x00000031, 0x4a02580d,
+       0x00000004, 0x0201f800, 0x000202da, 0x0201f800,
+       0x00104c19, 0x0201f000, 0x00107911, 0x59341400,
+       0x82081d00, 0x000000ff, 0x59300c03, 0x480bc857,
+       0x4807c857, 0x82040580, 0x00000053, 0x0400002e,
+       0x82040580, 0x00000002, 0x04000016, 0x82040580,
+       0x00000001, 0x04000017, 0x82040580, 0x00000003,
+       0x0400001c, 0x82040580, 0x00000005, 0x0400001d,
+       0x82040580, 0x00000033, 0x0400001a, 0x82040580,
+       0x00000000, 0x0400001b, 0x82040580, 0x00000004,
+       0x02020800, 0x001005d8, 0x0401f8a1, 0x0401f016,
+       0x820c0580, 0x00000003, 0x0400084c, 0x0401f012,
+       0x820c0580, 0x0000000b, 0x0402000f, 0x42000800,
+       0x00000007, 0x0201f800, 0x00104571, 0x0401f00a,
+       0x820c0580, 0x00000005, 0x04000864, 0x0401f006,
+       0x820c0580, 0x00000009, 0x04000889, 0x0401f002,
+       0x0401f893, 0x4a026403, 0x00000052, 0x59a81016,
+       0x592c040b, 0x8c000500, 0x04000003, 0x42001000,
+       0x00000008, 0x592c040b, 0x8c000516, 0x04000003,
+       0x82081400, 0x00000018, 0x592c000c, 0x497a580d,
+       0x497a580e, 0x80080c80, 0x04000009, 0x04001005,
+       0x4a025a06, 0x00000007, 0x40001000, 0x0401f006,
+       0x4a025a06, 0x00000015, 0x0401f003, 0x4a025a06,
+       0x00000000, 0x480a580c, 0x82081400, 0x00000003,
+       0x80081104, 0x0201f800, 0x00107ab5, 0x04000010,
+       0x592c1001, 0x480a600b, 0x58080800, 0x82080400,
+       0x00000002, 0x592c1011, 0x592c1812, 0x42003000,
+       0x00000000, 0x42002000, 0x00101200, 0x0201f800,
+       0x00107c32, 0x04000002, 0x1c01f000, 0x4a025a06,
+       0x0000002c, 0x497a580c, 0x0201f800, 0x000202da,
+       0x0201f000, 0x0002077d, 0x83380580, 0x00000015,
+       0x0402000a, 0x59a80005, 0x8c000514, 0x0402000b,
+       0x0201f800, 0x0010462a, 0x42000800, 0x00000004,
+       0x0201f000, 0x00104571, 0x42000800, 0x00000007,
+       0x0201f000, 0x00104571, 0x0201f800, 0x0010513b,
+       0x42001000, 0x00000010, 0x04020009, 0x59340002,
+       0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+       0x040007ec, 0x42001000, 0x00000008, 0x0201f800,
+       0x00104c6d, 0x040007e7, 0x592c040b, 0x84000540,
+       0x48025c0b, 0x0401f7e9, 0x83380580, 0x00000015,
+       0x0402000f, 0x59a80005, 0x8c000514, 0x04020010,
+       0x0201f800, 0x0010468d, 0x4d3c0000, 0x417a7800,
+       0x0201f800, 0x00104567, 0x5c027800, 0x42000800,
+       0x00000006, 0x0201f000, 0x00104571, 0x42000800,
+       0x00000004, 0x0201f000, 0x00104571, 0x0201f800,
+       0x0010513b, 0x42001000, 0x00000010, 0x04020009,
+       0x59340002, 0x82000500, 0x00ff0000, 0x82000580,
+       0x00ff0000, 0x040007e7, 0x42001000, 0x00000008,
+       0x0201f800, 0x00104c6d, 0x040007e2, 0x592c040b,
+       0x84000540, 0x48025c0b, 0x0401f7e9, 0x42000800,
+       0x00000004, 0x0201f000, 0x00104571, 0x83380580,
+       0x00000015, 0x04020005, 0x0201f800, 0x0010a2c8,
+       0x02000800, 0x001048c1, 0x1c01f000, 0x83380580,
+       0x00000015, 0x0402001d, 0x4c580000, 0x83cc1400,
+       0x00000008, 0x4200b000, 0x00000002, 0x83341c00,
+       0x00000006, 0x0201f800, 0x0010855a, 0x04020012,
+       0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002,
+       0x83341c00, 0x00000008, 0x0201f800, 0x0010855a,
+       0x04020009, 0x59342200, 0x59cc1007, 0x800811c0,
+       0x04000003, 0x480a6801, 0x84102542, 0x8410251a,
+       0x48126a00, 0x5c00b000, 0x1c01f000, 0x42000000,
+       0x0010b87b, 0x0201f800, 0x0010aa47, 0x0201f800,
+       0x00106c55, 0x59300203, 0x4933c857, 0x4803c857,
+       0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+       0x0c01f803, 0x0201f000, 0x00106c4b, 0x0010970b,
+       0x0010971a, 0x0010970c, 0x00109709, 0x00109709,
+       0x00109709, 0x00109709, 0x00109709, 0x00109709,
+       0x00109709, 0x00109709, 0x00109709, 0x00109709,
+       0x00109709, 0x0201f800, 0x001005d8, 0x1c01f000,
+       0x59300403, 0x82000580, 0x00000052, 0x02000000,
+       0x00108d85, 0x0201f800, 0x00104c19, 0x59325808,
+       0x4a025a06, 0x00000006, 0x0201f800, 0x000202da,
+       0x0201f000, 0x00107911, 0x59301804, 0x840c0520,
+       0x48026004, 0x598c000d, 0x81300580, 0x04020010,
+       0x8c0c1d20, 0x04020010, 0x42001000, 0x0010b7f6,
+       0x50081000, 0x58080002, 0x82000580, 0x00000100,
+       0x0400000e, 0x5808000c, 0x81300580, 0x02020800,
+       0x001005d8, 0x4978100c, 0x0401f003, 0x8c0c1d20,
+       0x040207dc, 0x0201f800, 0x001068d3, 0x040007d9,
+       0x0201f800, 0x001005d8, 0x0201f800, 0x00106e8e,
+       0x040007f9, 0x59300203, 0x82000c80, 0x0000000e,
+       0x02021800, 0x001005d8, 0x0c01f7bd, 0x4933c857,
+       0x4c500000, 0x4c540000, 0x4c580000, 0x592c0c07,
+       0x4806580a, 0x59cc0809, 0x48065807, 0x59cc0a08,
+       0x4806580b, 0x59c80817, 0x82040500, 0x000003ff,
+       0x800010c4, 0x8c040d14, 0x04000005, 0x59cc0002,
+       0x82000500, 0x00000003, 0x80081480, 0x82080480,
+       0x000000f1, 0x02021800, 0x001005d8, 0x480a621a,
+       0x412c0800, 0x0201f800, 0x001007d3, 0x02000800,
+       0x001005d8, 0x492c0809, 0x58040408, 0x84000552,
+       0x84000540, 0x48000c08, 0x82081400, 0x00000003,
+       0x80081104, 0x83cca400, 0x00000006, 0x832cac00,
+       0x00000004, 0x42000800, 0x00000010, 0x82080480,
+       0x00000010, 0x04021003, 0x40080800, 0x80000580,
+       0x4004b000, 0x4c000000, 0x0201f800, 0x0010ab28,
+       0x5c000000, 0x800001c0, 0x0400000d, 0x412c1000,
+       0x4c000000, 0x0201f800, 0x001007d3, 0x02000800,
+       0x001005d8, 0x492c1001, 0x832cac00, 0x00000004,
+       0x5c000000, 0x40001000, 0x0401f7e9, 0x5c00b000,
+       0x5c00a800, 0x5c00a000, 0x1c01f000, 0x4933c857,
+       0x4d2c0000, 0x4c380000, 0x59325808, 0x5930021a,
+       0x48025a08, 0x59301011, 0x800811c0, 0x04020008,
+       0x4a025a06, 0x00000000, 0x592c000b, 0x82000500,
+       0x00000c00, 0x0400000b, 0x0401f00b, 0x8c08153e,
+       0x04000006, 0x4a025a06, 0x00000007, 0x80081080,
+       0x80081000, 0x0401f003, 0x4a025a06, 0x00000015,
+       0x480a5807, 0x42000000, 0x0010bed9, 0x50007000,
+       0x5838000b, 0x80000540, 0x04020008, 0x4930700c,
+       0x4930700b, 0x58380002, 0x82000580, 0x00000000,
+       0x04020809, 0x0401f005, 0x82001400, 0x00000000,
+       0x45301000, 0x4930700b, 0x5c007000, 0x5c025800,
+       0x1c01f000, 0x4933c857, 0x592c0009, 0x40001000,
+       0x4800700a, 0x82080400, 0x00000004, 0x48007003,
+       0x592c000d, 0x592c100e, 0x48007007, 0x48087008,
+       0x592c000a, 0x592c1208, 0x80080c80, 0x04001002,
+       0x40001000, 0x82081400, 0x00000003, 0x80081104,
+       0x82080480, 0x00000010, 0x04021003, 0x80000580,
+       0x0401f003, 0x42001000, 0x00000010, 0x4800700d,
+       0x48087004, 0x800810c4, 0x48087005, 0x40381000,
+       0x0201f800, 0x00100858, 0x1c01f000, 0x4d2c0000,
+       0x0201f800, 0x001007d3, 0x02000800, 0x001005d8,
+       0x42000800, 0x0010bed9, 0x452c0800, 0x497a580b,
+       0x497a580c, 0x497a580d, 0x4a025809, 0x001097ea,
+       0x4a025802, 0x00000100, 0x4a025801, 0x00000000,
+       0x5c025800, 0x1c01f000, 0x4833c857, 0x4d300000,
+       0x4d2c0000, 0x4c5c0000, 0x4030b800, 0x585c000a,
+       0x80025d40, 0x04020004, 0x585c000c, 0x4c000000,
+       0x0401f044, 0x585c0002, 0x82000580, 0x00000100,
+       0x04020022, 0x592c0801, 0x4c040000, 0x0201f800,
+       0x001007f4, 0x5c000800, 0x800409c0, 0x0400001c,
+       0x4804b80a, 0x585c100d, 0x800811c0, 0x04020005,
+       0x40065800, 0x0201f800, 0x001007fd, 0x0401f014,
+       0x82080480, 0x00000010, 0x04021003, 0x80000580,
+       0x0401f003, 0x42001000, 0x00000010, 0x4800b80d,
+       0x4808b804, 0x800810c4, 0x4808b805, 0x82040400,
+       0x00000004, 0x4800b803, 0x405c1000, 0x0201f800,
+       0x00100858, 0x0401f025, 0x0401f828, 0x585c000c,
+       0x80026540, 0x59300000, 0x80000d40, 0x04020002,
+       0x4800b80b, 0x4800b80c, 0x497a6000, 0x4c000000,
+       0x4978b80a, 0x59325808, 0x4a025a04, 0x00000103,
+       0x59300402, 0x48025c06, 0x592c100b, 0x4c080000,
+       0x0201f800, 0x000202c1, 0x0201f800, 0x0010912a,
+       0x5c001000, 0x8c081518, 0x04000004, 0x0201f800,
+       0x001091d1, 0x0401f003, 0x0201f800, 0x0002077d,
+       0x405c7000, 0x5c000000, 0x80026540, 0x04000003,
+       0x59325808, 0x0401ff78, 0x5c00b800, 0x5c025800,
+       0x5c026000, 0x1c01f000, 0x483bc857, 0x5838000a,
+       0x40025800, 0x0201f800, 0x001007fd, 0x5838000c,
+       0x80026540, 0x59300008, 0x80025d40, 0x4a025a06,
+       0x00000002, 0x1c01f000, 0x4803c857, 0x4d1c0000,
+       0x497a601c, 0x41323800, 0x40026000, 0x4d3c0000,
+       0x42027800, 0x00000005, 0x0401f83c, 0x5c027800,
+       0x411e6000, 0x59300414, 0x84000502, 0x48026414,
+       0x5c023800, 0x1c01f000, 0x481bc857, 0x4933c857,
+       0x4c5c0000, 0x4c600000, 0x4010b800, 0x4014c000,
+       0x0201f800, 0x0010a942, 0x0201f800, 0x00103b25,
+       0x04000008, 0x40602800, 0x405c3000, 0x0201f800,
+       0x0010a446, 0x82000540, 0x00000001, 0x0401f002,
+       0x80000580, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+       0x4803c856, 0x4d300000, 0x42026000, 0x0010d1c0,
+       0x59a8000e, 0x81640580, 0x04000016, 0x59300c06,
+       0x82040580, 0x00000001, 0x04000009, 0x82040580,
+       0x00000004, 0x04000006, 0x82040580, 0x00000010,
+       0x02000800, 0x00108cf9, 0x0401f005, 0x4807c857,
+       0x0201f800, 0x001092d7, 0x04020808, 0x83326400,
+       0x00000024, 0x41580000, 0x81300480, 0x040017e9,
+       0x5c026000, 0x1c01f000, 0x4933c857, 0x59300403,
+       0x4803c857, 0x0201f800, 0x00106c55, 0x4df00000,
+       0x59300406, 0x4803c857, 0x82000d80, 0x00000002,
+       0x04000018, 0x82000d80, 0x00000001, 0x04000009,
+       0x82000d80, 0x00000004, 0x04000006, 0x4933c856,
+       0x5c03e000, 0x02000800, 0x00106c4b, 0x0401f03c,
+       0x59300203, 0x82000d80, 0x00000001, 0x04000018,
+       0x82000d80, 0x00000002, 0x04000026, 0x82000d80,
+       0x00000005, 0x04000023, 0x0201f800, 0x001005d8,
+       0x59300203, 0x82000d80, 0x00000009, 0x0400000c,
+       0x82000d80, 0x0000000b, 0x04000009, 0x82000d80,
+       0x0000000a, 0x04000017, 0x82000d80, 0x0000000c,
+       0x04000014, 0x0201f800, 0x001005d8, 0x598c000d,
+       0x81300580, 0x04020004, 0x0201f800, 0x00106e8e,
+       0x0402000c, 0x59300004, 0x4803c857, 0x8c000520,
+       0x04000004, 0x84000520, 0x48026004, 0x0401f005,
+       0x0201f800, 0x001068d3, 0x02020800, 0x001005d8,
+       0x5c03e000, 0x02000800, 0x00106c4b, 0x59300406,
+       0x82000d80, 0x00000002, 0x04000009, 0x0201f800,
+       0x00104c19, 0x0201f800, 0x0010914e, 0x02000800,
+       0x0010801c, 0x8d3e7d00, 0x04000003, 0x0201f000,
+       0x00107911, 0x4a02621d, 0x00000001, 0x4a026403,
+       0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+       0x00000002, 0x42000800, 0x8000004b, 0x0201f000,
+       0x00020721, 0x4933c857, 0x59368c03, 0x4c180000,
+       0x59300203, 0x82003480, 0x0000000e, 0x02021800,
+       0x001005d8, 0x0c01f803, 0x5c003000, 0x1c01f000,
+       0x0010990a, 0x00109dcf, 0x00109edb, 0x0010990a,
+       0x0010990a, 0x0010990a, 0x0010990a, 0x0010990a,
+       0x0010992d, 0x0010990a, 0x0010990a, 0x0010990a,
+       0x0010990a, 0x0010990a, 0x0201f800, 0x001005d8,
+       0x4933c857, 0x42028800, 0x0000ffff, 0x813669c0,
+       0x04000002, 0x59368c03, 0x4c180000, 0x59300203,
+       0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+       0x0c01f803, 0x5c003000, 0x1c01f000, 0x00109929,
+       0x0010a180, 0x00109929, 0x00109929, 0x00109929,
+       0x00109929, 0x00109929, 0x0010a952, 0x0010a0ed,
+       0x0010a52c, 0x0010a562, 0x0010a52c, 0x0010a562,
+       0x00109929, 0x0201f800, 0x001005d8, 0x0201f800,
+       0x001005d8, 0x83383480, 0x00000051, 0x02021800,
+       0x001005d8, 0x41380000, 0x493bc857, 0x4d1c0000,
+       0x4d400000, 0x0c01f804, 0x5c028000, 0x5c023800,
+       0x1c01f000, 0x0010998a, 0x00109b69, 0x0010998a,
+       0x0010998a, 0x0010998a, 0x00109b74, 0x0010998a,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+       0x001099ac, 0x001099f5, 0x00109a0c, 0x00109a62,
+       0x00109ac6, 0x00109b04, 0x00109b34, 0x0010998a,
+       0x0010998a, 0x00109b7c, 0x0010998a, 0x0010998a,
+       0x00109b8a, 0x00109b93, 0x0010998a, 0x0010998a,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x00109c15,
+       0x0010998a, 0x0010998a, 0x00109a9a, 0x0010998a,
+       0x0010998a, 0x00109bec, 0x0010998a, 0x0010998a,
+       0x0010998a, 0x00109c23, 0x0010998a, 0x0010998a,
+       0x0010998a, 0x00109c6c, 0x0010998a, 0x0010998a,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+       0x00109cb9, 0x0010998a, 0x00109ce5, 0x00109cf0,
+       0x0010998a, 0x0010998a, 0x0010998c, 0x00109cfb,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x0010999b,
+       0x0010998a, 0x0010998a, 0x0010998a, 0x00109d02,
+       0x00109d0a, 0x00109d28, 0x0201f800, 0x001005d8,
+       0x4933c857, 0x0201f800, 0x0010a592, 0x040203a4,
+       0x0201f800, 0x0010210a, 0x040203a1, 0x59cc0407,
+       0x4802601c, 0x4a026403, 0x00000045, 0x4a026203,
+       0x00000001, 0x0201f000, 0x0010672b, 0x4933c857,
+       0x0201f800, 0x0010a592, 0x04020395, 0x0201f800,
+       0x0010210a, 0x04020392, 0x0401fbce, 0x040201a0,
+       0x59cc0007, 0x4802601c, 0x4a026403, 0x0000004a,
+       0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+       0x4933c857, 0x0201f800, 0x0010210a, 0x04020009,
+       0x0201f800, 0x001048ec, 0x04020006, 0x82000500,
+       0x00000009, 0x82000580, 0x00000008, 0x04020008,
+       0x4a026403, 0x00000009, 0x4a02641a, 0x00000009,
+       0x4a02621a, 0x00000000, 0x0401f1b2, 0x0201f800,
+       0x001048c1, 0x0201f800, 0x00104a09, 0x04000021,
+       0x0201f800, 0x001049ed, 0x0400001e, 0x0201f800,
+       0x0010a252, 0x04020025, 0x42028000, 0x00000029,
+       0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x5c027800, 0x0201f800, 0x0010462a, 0x836c0580,
+       0x00000002, 0x04020004, 0x59a8001b, 0x80000000,
+       0x4803501b, 0x4a026403, 0x00000008, 0x42003000,
+       0x00000003, 0x0201f800, 0x00103b25, 0x04000191,
+       0x4a026203, 0x00000007, 0x41782800, 0x0401f180,
+       0x0201f800, 0x0010a3da, 0x040207e1, 0x4a026403,
+       0x00000009, 0x4a02641a, 0x0000000e, 0x4a02621a,
+       0x00001900, 0x0401f183, 0x4a026403, 0x00000009,
+       0x4a02641a, 0x00000003, 0x4a02621a, 0x00000f00,
+       0x0401f17c, 0x4933c857, 0x0201f800, 0x0010210a,
+       0x0402033b, 0x0201f800, 0x001048ec, 0x04020338,
+       0x493a6403, 0x0201f800, 0x0010a22d, 0x04020006,
+       0x42003000, 0x00000005, 0x4a026403, 0x00000006,
+       0x0401f7d9, 0x4a026403, 0x00000007, 0x4a02641a,
+       0x00000009, 0x4a02621a, 0x00000000, 0x0401f165,
+       0x4933c857, 0x0201f800, 0x001048ec, 0x04020324,
+       0x0201f800, 0x0010a592, 0x02000800, 0x0010210a,
+       0x0402031f, 0x0201f800, 0x00104a09, 0x04020005,
+       0x42027800, 0x00000001, 0x0201f800, 0x00104567,
+       0x0201f800, 0x001049fc, 0x0402002b, 0x59cc0206,
+       0x82003500, 0x00000003, 0x0402002e, 0x82003480,
+       0x00000014, 0x0400102b, 0x5934300a, 0x84183516,
+       0x82000580, 0x00000014, 0x04020002, 0x84183556,
+       0x481a680a, 0x59cc0406, 0x82000500, 0x00000003,
+       0x04020020, 0x0201f800, 0x0010a29f, 0x04020028,
+       0x0201f800, 0x001049e7, 0x0402000c, 0x417a7800,
+       0x0201f800, 0x001020a1, 0x42003000, 0x00000006,
+       0x0201f800, 0x0010a93a, 0x42000000, 0x0010b865,
+       0x0201f800, 0x0010aa47, 0x0201f800, 0x0010468d,
+       0x4a026403, 0x0000000a, 0x42003000, 0x00000020,
+       0x0401f795, 0x4a026403, 0x0000000b, 0x4a02641a,
+       0x00000009, 0x4a02621a, 0x00001e00, 0x0401f121,
+       0x42000000, 0x0010b860, 0x0201f800, 0x0010aa47,
+       0x4a026403, 0x0000000b, 0x4a02641a, 0x00000007,
+       0x4a02621a, 0x00000000, 0x0401f116, 0x4a026403,
+       0x0000000b, 0x4a02641a, 0x00000003, 0x4a02621a,
+       0x00000000, 0x0401f10f, 0x4933c857, 0x0201f800,
+       0x001048ec, 0x040202ce, 0x0201f800, 0x0010a592,
+       0x040202cb, 0x0201f800, 0x0010210a, 0x040202c8,
+       0x59cc0206, 0x82003500, 0x00000003, 0x0402001d,
+       0x82003480, 0x00000014, 0x0400101a, 0x59cc0406,
+       0x82000500, 0x00000003, 0x04020016, 0x59340400,
+       0x82000580, 0x00000707, 0x04000019, 0x417a7800,
+       0x0201f800, 0x001020a1, 0x42003000, 0x0000000a,
+       0x0201f800, 0x0010a93a, 0x42000000, 0x0010b862,
+       0x0201f800, 0x0010aa47, 0x4a026403, 0x0000000c,
+       0x41782800, 0x42003000, 0x00000021, 0x0401f752,
+       0x4a026403, 0x0000000d, 0x4a02641a, 0x00000007,
+       0x4a02621a, 0x00000000, 0x0401f0de, 0x4a026403,
+       0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a,
+       0x00001e00, 0x0401f0d7, 0x4933c857, 0x0201f800,
+       0x001048ec, 0x04020296, 0x0201f800, 0x0010a592,
+       0x04020293, 0x0201f800, 0x0010210a, 0x04020290,
+       0x0401facc, 0x0402001a, 0x493a6403, 0x4c5c0000,
+       0x0401fad2, 0x0402000e, 0x4a026403, 0x0000002e,
+       0x405c2800, 0x42003000, 0x00000024, 0x0201f800,
+       0x00103b25, 0x0400000c, 0x4a026203, 0x00000007,
+       0x405c2800, 0x5c00b800, 0x0401f0ad, 0x4a026403,
+       0x0000000d, 0x4a02641a, 0x00000007, 0x4a02621a,
+       0x00000000, 0x5c00b800, 0x0401f0b2, 0x4a026403,
+       0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a,
+       0x00001e00, 0x0401f0ab, 0x4933c857, 0x0201f800,
+       0x001048ec, 0x040206ef, 0x59a80026, 0x82000500,
+       0x00000009, 0x82000580, 0x00000008, 0x040006e9,
+       0x0201f800, 0x001049fc, 0x0402002d, 0x0201f800,
+       0x0010a2a7, 0x04020007, 0x4a026403, 0x0000000e,
+       0x41782800, 0x42003000, 0x00000052, 0x0401f702,
+       0x4933c857, 0x42003000, 0x00000003, 0x0201f800,
+       0x0010a942, 0x4d3c0000, 0x417a7800, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+       0x0201f800, 0x0010aa47, 0x59340200, 0x84000558,
+       0x48026a00, 0x42000800, 0x0000000b, 0x0201f800,
+       0x00104571, 0x0201f800, 0x00103b25, 0x04000076,
+       0x42003000, 0x00000007, 0x0401f062, 0x4933c857,
+       0x4a026403, 0x0000000f, 0x4a02641a, 0x00000003,
+       0x4a02621a, 0x00001e00, 0x0401f072, 0x59340400,
+       0x82000580, 0x00000703, 0x040007f5, 0x0401f040,
+       0x4933c857, 0x0201f800, 0x001048ec, 0x0402022c,
+       0x59a80026, 0x82000500, 0x00000009, 0x82000580,
+       0x00000008, 0x04000226, 0x0201f800, 0x001049f3,
+       0x0402002f, 0x0201f800, 0x0010a2c8, 0x02000800,
+       0x0010a252, 0x04020007, 0x4a026403, 0x00000010,
+       0x41782800, 0x42003000, 0x00000050, 0x0401f6c2,
+       0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x5c027800, 0x42003000, 0x00000003, 0x0201f800,
+       0x0010a942, 0x42000000, 0x0010b864, 0x0201f800,
+       0x0010aa47, 0x59340200, 0x84000558, 0x48026a00,
+       0x0401f7c5, 0x4a026403, 0x00000011, 0x4a02641a,
+       0x00000003, 0x4a02621a, 0x00001e00, 0x0401f03d,
+       0x4933c857, 0x0201f800, 0x0010210a, 0x02000800,
+       0x0010a592, 0x040201fa, 0x0401fa36, 0x04020008,
+       0x4a026403, 0x00000012, 0x0401f032, 0x59340400,
+       0x82000580, 0x00000703, 0x040007eb, 0x4d3c0000,
+       0x417a7800, 0x42028000, 0x00000029, 0x0201f800,
+       0x0010203c, 0x5c027800, 0x42003000, 0x00000017,
+       0x0201f800, 0x0010a942, 0x42000000, 0x0010b864,
+       0x0201f800, 0x0010aa47, 0x0201f800, 0x00103b25,
+       0x04000015, 0x42003000, 0x00000006, 0x41782800,
+       0x42028000, 0x00000029, 0x4933c857, 0x4a026403,
+       0x00000001, 0x4a026203, 0x00000007, 0x0201f800,
+       0x0010a974, 0x0201f000, 0x0010a43e, 0x42028000,
+       0x00000046, 0x0201f800, 0x0010a974, 0x0201f000,
+       0x0010a43e, 0x4933c857, 0x4a026403, 0x00000001,
+       0x42000800, 0x0000000b, 0x0201f800, 0x00104571,
+       0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+       0x4933c857, 0x42000800, 0x00000009, 0x0201f800,
+       0x00104571, 0x4a026403, 0x00000005, 0x0401f7f5,
+       0x0201f800, 0x0010a592, 0x040201b5, 0x0201f800,
+       0x0010210a, 0x040201b2, 0x0401f9ee, 0x040207c0,
+       0x4a026403, 0x00000020, 0x4a026203, 0x00000001,
+       0x0201f000, 0x0010672b, 0x0201f800, 0x0010210a,
+       0x040201a7, 0x4a026403, 0x00000023, 0x4a026203,
+       0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+       0x0010a592, 0x02000800, 0x0010210a, 0x0402019c,
+       0x0401f9d8, 0x040207aa, 0x40300800, 0x59a81010,
+       0x59cc0007, 0x82000500, 0x00ffffff, 0x80080580,
+       0x04000019, 0x59cc1408, 0x0201f800, 0x0010902c,
+       0x0400002d, 0x59cc0c08, 0x4d300000, 0x0201f800,
+       0x00105dd7, 0x41323800, 0x5c026000, 0x04000026,
+       0x591c0202, 0x82000580, 0x0000ffff, 0x04000005,
+       0x59cc1208, 0x591c0202, 0x80080580, 0x0402001e,
+       0x591c0406, 0x82000580, 0x00000007, 0x0402001a,
+       0x0401f02c, 0x59cc1208, 0x82080580, 0x0000ffff,
+       0x0400000c, 0x0201f800, 0x00109410, 0x04000012,
+       0x59cc1408, 0x591c0202, 0x80080580, 0x0402000e,
+       0x591c0009, 0x81340580, 0x04000016, 0x0401f00a,
+       0x59cc1408, 0x417a7800, 0x0201f800, 0x0010a405,
+       0x04020010, 0x59cc1208, 0x82080580, 0x0000ffff,
+       0x04000019, 0x4a026403, 0x00000026, 0x4a02621a,
+       0x00001700, 0x59cc1204, 0x82081580, 0x0000ffff,
+       0x04020798, 0x4a026403, 0x00000025, 0x0401f795,
+       0x591c0406, 0x82000580, 0x00000007, 0x040207f2,
+       0x591c0403, 0x82000580, 0x00000024, 0x04020006,
+       0x4d300000, 0x411e6000, 0x0201f800, 0x0002077d,
+       0x5c026000, 0x4a026403, 0x00000025, 0x0401f785,
+       0x4933c857, 0x4d3c0000, 0x42027800, 0x00000001,
+       0x0201f800, 0x00104567, 0x5c027800, 0x4c580000,
+       0x4200b000, 0x00000002, 0x83a81c00, 0x00000002,
+       0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+       0x5c00b000, 0x04000004, 0x4a026403, 0x00000031,
+       0x0401f770, 0x0201f800, 0x00107911, 0x0201f800,
+       0x0010513b, 0x0402000f, 0x0201f800, 0x00105149,
+       0x04020008, 0x4a035033, 0x00000001, 0x4202d800,
+       0x00000001, 0x0201f800, 0x001050a2, 0x0401f005,
+       0x42000000, 0x00000001, 0x0201f800, 0x00105113,
+       0x1c01f000, 0x0201f800, 0x0010210a, 0x0402011c,
+       0x0401f958, 0x0402072a, 0x493a6403, 0x0401f996,
+       0x04020004, 0x4a026403, 0x0000002b, 0x0401f751,
+       0x4a026403, 0x0000002c, 0x0401f74e, 0x4933c857,
+       0x0201f800, 0x0010210a, 0x0402010d, 0x0201f800,
+       0x001049e7, 0x04020740, 0x0201f800, 0x001048d9,
+       0x0400003c, 0x59cc0408, 0x48026419, 0x59cc0208,
+       0x48026219, 0x59cc0807, 0x59340002, 0x82000500,
+       0x00ffffff, 0x80040580, 0x04000012, 0x59a80010,
+       0x80040580, 0x04020021, 0x59cc1408, 0x0201f800,
+       0x00109410, 0x04000023, 0x0201f800, 0x0010a4ca,
+       0x04000020, 0x0201f800, 0x0010a921, 0x0400001d,
+       0x491e601e, 0x4a026403, 0x00000036, 0x0401f0e6,
+       0x59cc1208, 0x82080580, 0x0000ffff, 0x04000009,
+       0x0201f800, 0x00109410, 0x04000012, 0x591c0202,
+       0x59cc0c08, 0x80040580, 0x0402000e, 0x0401f7eb,
+       0x59cc1408, 0x41327800, 0x0201f800, 0x0010a405,
+       0x04000008, 0x0401f7e5, 0x4803c856, 0x4a02641a,
+       0x00000009, 0x4a02621a, 0x00001500, 0x0401f006,
+       0x4803c856, 0x4a02641a, 0x00000003, 0x4a02621a,
+       0x00001700, 0x4a026403, 0x00000037, 0x0401f0c6,
+       0x4803c856, 0x4a026403, 0x00000012, 0x0401f0c2,
+       0x4933c857, 0x0201f800, 0x0010210a, 0x040200c4,
+       0x0201f800, 0x001049e7, 0x040206f7, 0x0201f800,
+       0x001048d9, 0x0400003e, 0x59cc0407, 0x48026419,
+       0x59cc1207, 0x480a6219, 0x82080580, 0x0000ffff,
+       0x04000005, 0x0201f800, 0x00109410, 0x0400002c,
+       0x0401f006, 0x59cc1407, 0x41327800, 0x0201f800,
+       0x0010a405, 0x04000026, 0x59cc0c07, 0x591c0202,
+       0x80040580, 0x04020022, 0x4d300000, 0x411e6000,
+       0x0201f800, 0x00108bd7, 0x5c026000, 0x59cc0c09,
+       0x82040d00, 0x0000ff00, 0x840409c0, 0x0201f800,
+       0x0010a921, 0x04000016, 0x82040580, 0x00000001,
+       0x0400000a, 0x82040580, 0x00000005, 0x04000004,
+       0x82040580, 0x00000007, 0x04020007, 0x591c0008,
+       0x80000540, 0x04000004, 0x59cc2808, 0x0201f000,
+       0x0010a4de, 0x4803c856, 0x4a02641a, 0x00000009,
+       0x4a02621a, 0x00002a00, 0x0401f006, 0x4803c856,
+       0x4a02641a, 0x00000003, 0x4a02621a, 0x00000300,
+       0x4a026403, 0x0000003b, 0x0401f07b, 0x4803c856,
+       0x4a02641a, 0x0000000b, 0x4a02621a, 0x00000000,
+       0x0401f7f8, 0x4c080000, 0x0201f800, 0x001048ec,
+       0x04000026, 0x0201f800, 0x001048c1, 0x0201f800,
+       0x0010a601, 0x0402001e, 0x59a80026, 0x82000540,
+       0x00000003, 0x48035026, 0x59a8001d, 0x800000d0,
+       0x59a80810, 0x82040d00, 0x000000ff, 0x80041540,
+       0x480b5010, 0x42000800, 0x00000003, 0x0201f800,
+       0x00106c78, 0x497b5028, 0x0201f800, 0x00103b25,
+       0x04000003, 0x4a032804, 0x000007d0, 0x8c00050a,
+       0x0402000a, 0x0201f800, 0x0002077d, 0x0201f800,
+       0x00101e45, 0x5c001000, 0x1c01f000, 0x0201f800,
+       0x0010a623, 0x0401f7fc, 0x5c001000, 0x0201f000,
+       0x0002077d, 0x0201f800, 0x0010210a, 0x0402004c,
+       0x0201f800, 0x0010a628, 0x4a026403, 0x00000047,
+       0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+       0x0201f800, 0x0010210a, 0x04020041, 0x0201f800,
+       0x0010a628, 0x4a026403, 0x00000047, 0x4a026203,
+       0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+       0x0010210a, 0x04020036, 0x0201f800, 0x0010a628,
+       0x0201f000, 0x0002077d, 0x0401f834, 0x04000030,
+       0x4a026403, 0x0000004e, 0x4a026203, 0x00000001,
+       0x0201f000, 0x0010672b, 0x4a026403, 0x0000004f,
+       0x497a601c, 0x59cc0a06, 0x82040d00, 0x000000ff,
+       0x800409c0, 0x0400065f, 0x82040580, 0x00000001,
+       0x04020005, 0x59cc0808, 0x59a80005, 0x80040580,
+       0x04000658, 0x82040580, 0x00000002, 0x0402000a,
+       0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+       0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+       0x0400064c, 0x4a02601c, 0x00000001, 0x0401f649,
+       0x4a026403, 0x00000050, 0x59cc0207, 0x4802601c,
+       0x0401f644, 0x4a026203, 0x00000001, 0x42000800,
+       0x80000040, 0x0201f000, 0x00020721, 0x4803c857,
+       0x0201f000, 0x0002077d, 0x4d2c0000, 0x4c500000,
+       0x4c580000, 0x4c540000, 0x59a80016, 0x82000c80,
+       0x00000829, 0x04021029, 0x0201f800, 0x001007d3,
+       0x04000026, 0x492e6008, 0x59a80016, 0x80000104,
+       0x48025802, 0x83cca400, 0x00000006, 0x82000c80,
+       0x0000000b, 0x04001013, 0x4a025811, 0x0000000b,
+       0x4200b000, 0x0000000b, 0x832c0400, 0x00000005,
+       0x4000a800, 0x0201f800, 0x0010ab17, 0x412c7000,
+       0x0201f800, 0x001007d3, 0x04000010, 0x492c7001,
+       0x40040000, 0x800409c0, 0x04000009, 0x0401f7ec,
+       0x48025811, 0x4000b000, 0x832c0400, 0x00000005,
+       0x4000a800, 0x0201f800, 0x0010ab17, 0x82000540,
+       0x00000001, 0x0401f006, 0x497b5016, 0x59325808,
+       0x0201f800, 0x001007fd, 0x80000580, 0x5c00a800,
+       0x5c00b000, 0x5c00a000, 0x5c025800, 0x1c01f000,
+       0x4d340000, 0x59326809, 0x59343400, 0x4933c857,
+       0x4937c857, 0x481bc857, 0x0201f800, 0x001049f3,
+       0x5c026800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+       0x4d3c0000, 0x0401f840, 0x0402002c, 0x59cc0207,
+       0x82000d00, 0x0000ff00, 0x900411c0, 0x59cc000a,
+       0x82000500, 0x00ffffff, 0x80081540, 0x480a601c,
+       0x8c040d18, 0x0400000e, 0x42003000, 0x00000008,
+       0x0201f800, 0x0010a932, 0x42000000, 0x0010b863,
+       0x0201f800, 0x0010aa47, 0x4200b800, 0x00000002,
+       0x42027800, 0x00000001, 0x0401f011, 0x4178b800,
+       0x8c040d1a, 0x04000011, 0x59cc000a, 0x0201f800,
+       0x00105c9a, 0x0402000d, 0x42003000, 0x00000009,
+       0x0201f800, 0x0010a93a, 0x42000000, 0x0010b863,
+       0x0201f800, 0x0010aa47, 0x417a7800, 0x0201f800,
+       0x001020a1, 0x0401f004, 0x82000540, 0x00000001,
+       0x0401f002, 0x80000580, 0x5c027800, 0x5c00b800,
+       0x1c01f000, 0x4933c857, 0x59cc0206, 0x82000480,
+       0x00000010, 0x04021006, 0x4a02621a, 0x00000000,
+       0x82000540, 0x00000001, 0x0401f002, 0x80000580,
+       0x1c01f000, 0x4933c857, 0x4a02621a, 0x00000000,
+       0x59cc0407, 0x82000500, 0x0000ff00, 0x82000580,
+       0x00000800, 0x04020009, 0x59cc0006, 0x82000500,
+       0x00ff0000, 0x82000d80, 0x00140000, 0x04000003,
+       0x82000d80, 0x00100000, 0x1c01f000, 0x4933c857,
+       0x59300403, 0x82003480, 0x00000051, 0x02021800,
+       0x001005d8, 0x83383580, 0x00000013, 0x04020003,
+       0x4803c857, 0x0c01f012, 0x83383580, 0x00000027,
+       0x04000005, 0x83383580, 0x00000014, 0x02020800,
+       0x001005d8, 0x0201f800, 0x001048c1, 0x42000800,
+       0x00000007, 0x0201f800, 0x00104571, 0x0201f800,
+       0x00106bbf, 0x0201f000, 0x00107911, 0x00109e3c,
+       0x00109e45, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+       0x00109e45, 0x00109e50, 0x00109ecd, 0x00109e95,
+       0x00109ecd, 0x00109ead, 0x00109ecd, 0x00109ebe,
+       0x00109ecd, 0x00109ec6, 0x00109ecd, 0x00109ec6,
+       0x00109ecd, 0x00109ecd, 0x00109e3c, 0x00109e3c,
+       0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+       0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+       0x00109e3c, 0x00109e45, 0x00109e3c, 0x00109ecd,
+       0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109e3c,
+       0x00109eca, 0x00109ecd, 0x00109e3c, 0x00109e3c,
+       0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109ecd,
+       0x00109e3c, 0x00109ec3, 0x00109ecd, 0x00109e3c,
+       0x00109e4a, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+       0x00109e3c, 0x00109ec9, 0x00109ecd, 0x00109e3c,
+       0x00109e3c, 0x00109ecd, 0x00109ecd, 0x00109e3c,
+       0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+       0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+       0x00109e3e, 0x00109e3c, 0x00109e3e, 0x00109e3c,
+       0x00109e3c, 0x00109e3e, 0x00109e3c, 0x00109e3c,
+       0x00109e3c, 0x00109e3e, 0x00109e3e, 0x00109e3e,
+       0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808,
+       0x0201f800, 0x001007fd, 0x5c025800, 0x0201f000,
+       0x0002077d, 0x59a80037, 0x48026206, 0x4a026203,
+       0x00000002, 0x1c01f000, 0x4d3c0000, 0x417a7800,
+       0x0201f800, 0x00104567, 0x5c027800, 0x0401f07e,
+       0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+       0x59a80026, 0x8c000508, 0x04000012, 0x59326809,
+       0x4c580000, 0x4200b000, 0x00000002, 0x83a81c00,
+       0x00000002, 0x83341400, 0x00000006, 0x0201f800,
+       0x0010855a, 0x80000540, 0x5c00b000, 0x0402006a,
+       0x59340200, 0x8400051a, 0x48026a00, 0x0401f01b,
+       0x599c0017, 0x8c00050a, 0x04020063, 0x4d3c0000,
+       0x417a7800, 0x0201f800, 0x00104567, 0x5c027800,
+       0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+       0x59340212, 0x82000500, 0x0000ff00, 0x04000056,
+       0x599c0019, 0x8c00050e, 0x04020053, 0x416c0000,
+       0x82000580, 0x00000002, 0x04020004, 0x59a8001b,
+       0x80000000, 0x4803501b, 0x42000800, 0x00000003,
+       0x0201f800, 0x00104571, 0x4a026406, 0x00000001,
+       0x4a026203, 0x00000001, 0x4a026403, 0x00000002,
+       0x0201f800, 0x0010672b, 0x4ce80000, 0x4201d000,
+       0x00000001, 0x0201f800, 0x00105fae, 0x5c01d000,
+       0x1c01f000, 0x0201f800, 0x001049f3, 0x04000036,
+       0x0201f800, 0x0010645e, 0x42000800, 0x00000004,
+       0x0201f800, 0x00104571, 0x0201f800, 0x0010a96a,
+       0x0402002d, 0x42000800, 0x00000005, 0x0201f800,
+       0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+       0x00000001, 0x4a026403, 0x00000003, 0x0201f000,
+       0x0010672b, 0x42000800, 0x00000006, 0x0401f820,
+       0x59303009, 0x599c0017, 0x8c00050a, 0x0402001a,
+       0x59a80026, 0x8c000508, 0x04000017, 0x0201f800,
+       0x001049e7, 0x04000014, 0x59a8001b, 0x80000000,
+       0x4803501b, 0x0401f7c5, 0x42000800, 0x00000004,
+       0x0201f800, 0x00104571, 0x0401f792, 0x42000800,
+       0x00000004, 0x0401f006, 0x0201f800, 0x001048c1,
+       0x0401f005, 0x0401f004, 0x0401f003, 0x0201f800,
+       0x00104571, 0x0201f000, 0x0002077d, 0x4933c857,
+       0x4807c857, 0x0201f800, 0x00104571, 0x4d3c0000,
+       0x417a7800, 0x0201f800, 0x00104567, 0x5c027800,
+       0x0201f800, 0x00102074, 0x1c01f000, 0x4933c857,
+       0x59340400, 0x80000110, 0x82003480, 0x0000000c,
+       0x02021800, 0x001005d8, 0x83383580, 0x00000015,
+       0x04020002, 0x0c01f006, 0x83383580, 0x00000016,
+       0x02020800, 0x001005d8, 0x0c01f00d, 0x001080b8,
+       0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+       0x001080b8, 0x00109f30, 0x00109f03, 0x001080b8,
+       0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+       0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+       0x001080b8, 0x00109f30, 0x00109f37, 0x001080b8,
+       0x001080b8, 0x001080b8, 0x001080b8, 0x4933c857,
+       0x599c0017, 0x8c00050a, 0x0402001b, 0x813669c0,
+       0x04000019, 0x59340212, 0x82000500, 0x0000ff00,
+       0x04000015, 0x599c0019, 0x8c00050e, 0x04020012,
+       0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567,
+       0x5c027800, 0x42000800, 0x00000003, 0x0201f800,
+       0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+       0x00000001, 0x4a026403, 0x00000002, 0x0201f000,
+       0x0010672b, 0x59cc0001, 0x0201f800, 0x00105c9a,
+       0x0402000b, 0x0201f800, 0x00020245, 0x02020000,
+       0x0002077d, 0x59345002, 0x0201f800, 0x001042b4,
+       0x482a6802, 0x0201f000, 0x0002077d, 0x1c01f000,
+       0x4933c857, 0x59303403, 0x82183580, 0x0000001e,
+       0x02000000, 0x0002077d, 0x1c01f000, 0x4933c857,
+       0x0201f800, 0x001083df, 0x02020000, 0x0002077d,
+       0x4a026203, 0x00000001, 0x4a026403, 0x00000001,
+       0x0201f000, 0x0010672b, 0x493bc857, 0x83380580,
+       0x00000051, 0x0402000b, 0x0201f800, 0x00106f60,
+       0x02020000, 0x00107974, 0x59300203, 0x82000580,
+       0x00000002, 0x0400006d, 0x0201f800, 0x001005d8,
+       0x83380580, 0x00000027, 0x04000014, 0x83380580,
+       0x00000048, 0x04000006, 0x83380580, 0x00000014,
+       0x0400000e, 0x02020800, 0x001005d8, 0x0201f800,
+       0x00106f60, 0x02020000, 0x00107974, 0x59300203,
+       0x82000580, 0x00000004, 0x02000000, 0x0002086e,
+       0x0201f800, 0x001005d8, 0x59300403, 0x82000c80,
+       0x00000044, 0x02021800, 0x001005d8, 0x82000480,
+       0x00000040, 0x02001800, 0x001005d8, 0x40027000,
+       0x4803c857, 0x0c01f001, 0x00109f76, 0x00109f78,
+       0x00109f78, 0x00109f93, 0x0201f800, 0x001005d8,
+       0x0201f800, 0x00106bbf, 0x59325808, 0x812e59c0,
+       0x04000016, 0x832c0500, 0x00ff0000, 0x04000013,
+       0x4a026203, 0x00000002, 0x59326809, 0x59340200,
+       0x8c00050e, 0x0402000d, 0x42028000, 0x00000004,
+       0x0201f800, 0x0010a3ef, 0x497a6008, 0x59300206,
+       0x80000540, 0x04020003, 0x59a80038, 0x48026206,
+       0x4a026203, 0x00000007, 0x1c01f000, 0x0201f800,
+       0x00106bbf, 0x0201f800, 0x00109037, 0x02000000,
+       0x00107911, 0x59325808, 0x0201f800, 0x001007f4,
+       0x0201f000, 0x00107911, 0x0201f800, 0x001005d8,
+       0x59325808, 0x592c040a, 0x8c000502, 0x04000007,
+       0x4a026203, 0x00000007, 0x42027000, 0x00000043,
+       0x0201f000, 0x000207a1, 0x4a026203, 0x00000004,
+       0x1c01f000, 0x0201f800, 0x0010a597, 0x02000000,
+       0x0002086c, 0x1c01f000, 0x4a026203, 0x00000001,
+       0x4a026403, 0x00000041, 0x42027800, 0x80002042,
+       0x0201f000, 0x00020721, 0x83380580, 0x00000051,
+       0x04000006, 0x83380580, 0x00000041, 0x02020800,
+       0x001005d8, 0x1c01f000, 0x0201f800, 0x000206fd,
+       0x0201f800, 0x0010a5df, 0x0201f000, 0x0002077d,
+       0x83380480, 0x00000050, 0x02021800, 0x001005d8,
+       0x83380480, 0x00000049, 0x02001800, 0x001005d8,
+       0x0c01f001, 0x00109fda, 0x00109ffb, 0x00109fd8,
+       0x00109fd8, 0x00109fd8, 0x00109fd8, 0x00109ffb,
+       0x0201f800, 0x001005d8, 0x59325808, 0x592c040a,
+       0x8c00051e, 0x0400000d, 0x82000d00, 0x000000c0,
+       0x82040d80, 0x00000080, 0x0400000d, 0x59300804,
+       0x8c040d18, 0x0402000a, 0x42027000, 0x00000041,
+       0x0201f000, 0x0002088d, 0x4a026203, 0x00000007,
+       0x497a6206, 0x0201f000, 0x000206fd, 0x59325808,
+       0x592c0c0a, 0x8c040d1a, 0x04020005, 0x0201f800,
+       0x000206fd, 0x0201f000, 0x0002077d, 0x0201f800,
+       0x0010a597, 0x040007fa, 0x1c01f000, 0x0201f800,
+       0x00106b8a, 0x59325808, 0x59326809, 0x59340200,
+       0x8c00050e, 0x0400000e, 0x592c040a, 0x82000500,
+       0x000000c0, 0x82000580, 0x00000080, 0x04000005,
+       0x592c000f, 0x59301815, 0x800c1c80, 0x480e6015,
+       0x4a026203, 0x00000002, 0x0401f00d, 0x42028000,
+       0x00000004, 0x0401fbde, 0x59300206, 0x80000540,
+       0x04020004, 0x59a80038, 0x800000c2, 0x48026206,
+       0x497a6008, 0x4a026203, 0x00000007, 0x1c01f000,
+       0x4a026203, 0x00000007, 0x497a6206, 0x0201f000,
+       0x000206fd, 0x4a026203, 0x00000007, 0x497a6206,
+       0x0201f000, 0x000206f8, 0x59300414, 0x8c00051c,
+       0x02020000, 0x0002087e, 0x59325808, 0x592c200f,
+       0x40080000, 0x80102480, 0x59300015, 0x80102400,
+       0x48126015, 0x0201f000, 0x0002087e, 0x8c040d0e,
+       0x0402000a, 0x4a026203, 0x00000006, 0x0401f823,
+       0x5930001f, 0x80000540, 0x02020800, 0x00100d7c,
+       0x0201f000, 0x000206f8, 0x4a026203, 0x00000002,
+       0x1c01f000, 0x42000800, 0x00000001, 0x0201f800,
+       0x00100d7c, 0x82040580, 0x00000001, 0x02000000,
+       0x00020885, 0x0401f7d8, 0x59300414, 0x8c00051c,
+       0x04000006, 0x0201f800, 0x00100b63, 0x02000000,
+       0x00020877, 0x1c01f000, 0x59300011, 0x80000540,
+       0x04020005, 0x0201f800, 0x00100b63, 0x02000000,
+       0x00020877, 0x1c01f000, 0x492fc857, 0x480bc857,
+       0x8c08153e, 0x04000006, 0x80081080, 0x80081000,
+       0x42000800, 0x00000009, 0x0401f003, 0x42000800,
+       0x00000015, 0x480a580b, 0x1c01f000, 0x83380580,
+       0x00000013, 0x04000005, 0x83380580, 0x00000014,
+       0x02020800, 0x001005d8, 0x59300414, 0x8c000516,
+       0x02000800, 0x001005d8, 0x1c01f000, 0x0201f800,
+       0x001005d8, 0x59300008, 0x80000540, 0x02020800,
+       0x001005d8, 0x1c01f000, 0x59300414, 0x8c000516,
+       0x02000800, 0x001005d8, 0x1c01f000, 0x4a026203,
+       0x00000004, 0x493a6403, 0x42000800, 0x80002001,
+       0x0201f000, 0x00020721, 0x4a026203, 0x00000003,
+       0x493a6403, 0x0201f800, 0x000200c9, 0x59325808,
+       0x592c040a, 0x8c00051e, 0x04000012, 0x82000500,
+       0x000000c0, 0x82000580, 0x00000080, 0x04000011,
+       0x59300414, 0x8c000512, 0x0402000a, 0x8c000510,
+       0x04020008, 0x592c040c, 0x80000540, 0x04020005,
+       0x82080d40, 0x80003065, 0x0201f000, 0x00106721,
+       0x82080d40, 0x80002065, 0x0201f000, 0x00106721,
+       0x82080d40, 0x80002042, 0x0201f000, 0x00106721,
+       0x4933c857, 0x493bc857, 0x83380480, 0x00000044,
+       0x02021800, 0x001005d8, 0x83380480, 0x00000041,
+       0x02001800, 0x001005d8, 0x0c01f001, 0x0010a0b6,
+       0x0010a0c6, 0x0010a0db, 0x59325808, 0x592c040a,
+       0x8c00051e, 0x0400001d, 0x82001d00, 0x000000c0,
+       0x820c1d80, 0x000000c0, 0x04000018, 0x4a026203,
+       0x00000001, 0x493a6403, 0x42000800, 0x80002042,
+       0x0201f000, 0x00020721, 0x59325808, 0x592c040a,
+       0x8c00051e, 0x0400000d, 0x82001d00, 0x000000c0,
+       0x820c1d80, 0x000000c0, 0x04000008, 0x4a026203,
+       0x00000001, 0x493a6403, 0x42000800, 0x80002001,
+       0x0201f000, 0x00020721, 0x497a6008, 0x497a6206,
+       0x42028000, 0x00000004, 0x0401f315, 0x59325808,
+       0x592c040a, 0x8c00051e, 0x040007f8, 0x82001d00,
+       0x000000c0, 0x820c1d80, 0x000000c0, 0x040007f3,
+       0x4a026203, 0x00000003, 0x493a6403, 0x0201f800,
+       0x000200c9, 0x82080d40, 0x80002065, 0x0201f000,
+       0x00106721, 0x4933c857, 0x493bc857, 0x83380580,
+       0x00000085, 0x04000006, 0x83380580, 0x00000088,
+       0x0400000a, 0x0201f800, 0x001005d8, 0x4a026203,
+       0x00000009, 0x493a6403, 0x42000800, 0x8000004b,
+       0x0201f000, 0x00020721, 0x4d1c0000, 0x813669c0,
+       0x04000004, 0x0201f800, 0x0010a592, 0x04020044,
+       0x59cc1404, 0x0401f846, 0x04000018, 0x591c0406,
+       0x82000500, 0x0000001f, 0x82002580, 0x00000006,
+       0x04000007, 0x82002580, 0x00000004, 0x0400002e,
+       0x82002580, 0x00000011, 0x0402000c, 0x497a3a05,
+       0x42002000, 0x00000054, 0x0201f800, 0x00107a4a,
+       0x4a026203, 0x00000007, 0x493a6403, 0x0201f800,
+       0x0010a974, 0x0401f02c, 0x0201f800, 0x00103b25,
+       0x04000004, 0x42023800, 0xffffffff, 0x0401f7f1,
+       0x813669c0, 0x04020009, 0x59cc0001, 0x0201f800,
+       0x00105c9a, 0x0402001e, 0x0201f800, 0x001045a6,
+       0x0402001b, 0x49366009, 0x4a026403, 0x00000087,
+       0x59cc1204, 0x82081580, 0x0000ffff, 0x04020003,
+       0x4a026403, 0x00000086, 0x4a026203, 0x00000001,
+       0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+       0x0401f00d, 0x591c0203, 0x82000580, 0x00000007,
+       0x040207de, 0x4d300000, 0x411e6000, 0x0201f800,
+       0x00107911, 0x5c026000, 0x0401f7d8, 0x0201f800,
+       0x00107911, 0x5c023800, 0x1c01f000, 0x4933c857,
+       0x480bc857, 0x42002800, 0x0010d1c0, 0x41300000,
+       0x80140580, 0x04000017, 0x58140203, 0x82000580,
+       0x00000000, 0x04000013, 0x58140202, 0x80080580,
+       0x04020010, 0x58141c06, 0x820c0580, 0x00000005,
+       0x0400000c, 0x820c0580, 0x00000009, 0x0400001d,
+       0x59302009, 0x58140009, 0x800001c0, 0x0400000b,
+       0x801021c0, 0x04000003, 0x80100580, 0x04000010,
+       0x82142c00, 0x00000024, 0x41540000, 0x80140480,
+       0x0402100e, 0x0401f7e2, 0x5814001e, 0x801021c0,
+       0x04000005, 0x58102002, 0x82102500, 0x00ffffff,
+       0x0401f7f2, 0x5810201e, 0x0401f7f0, 0x40163800,
+       0x81300540, 0x0401f002, 0x80000580, 0x1c01f000,
+       0x58141807, 0x8c0c1d10, 0x040207ea, 0x0401f7e1,
+       0x4933c857, 0x493bc857, 0x83380580, 0x00000013,
+       0x0402000e, 0x59300403, 0x82000c80, 0x00000085,
+       0x02001800, 0x001005d8, 0x82000c80, 0x00000093,
+       0x02021800, 0x001005d8, 0x82000480, 0x00000085,
+       0x4803c857, 0x0c01f018, 0x83380580, 0x00000027,
+       0x04000005, 0x83380580, 0x00000014, 0x02020000,
+       0x00107974, 0x0201f800, 0x00106bbf, 0x59325808,
+       0x812e59c0, 0x02000000, 0x00107911, 0x4a025a06,
+       0x00000031, 0x4a025811, 0x00000004, 0x4a025812,
+       0x000000ff, 0x0201f800, 0x000202da, 0x0201f000,
+       0x00107911, 0x0010a1b7, 0x0010a1be, 0x0010a1be,
+       0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7,
+       0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7,
+       0x0010a1b7, 0x0010a1b7, 0x0010a1b9, 0x0201f800,
+       0x001005d8, 0x59325808, 0x4a025a06, 0x00000000,
+       0x0201f800, 0x000202da, 0x0201f000, 0x00107911,
+       0x4933c857, 0x42000000, 0x0010b873, 0x0201f800,
+       0x0010aa47, 0x0201f800, 0x0010a5df, 0x497a6205,
+       0x42028000, 0x0000000b, 0x0401f807, 0x4a026406,
+       0x00000006, 0x4a026203, 0x00000007, 0x497a6206,
+       0x1c01f000, 0x4933c857, 0x4943c857, 0x59300406,
+       0x82000580, 0x00000007, 0x04020002, 0x1c01f000,
+       0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800,
+       0x00108ce5, 0x82000c80, 0x0000000e, 0x02021800,
+       0x001005d8, 0x0c01f001, 0x0010a205, 0x0010a209,
+       0x0010a1f0, 0x0010a217, 0x0010a22a, 0x0010a1f0,
+       0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0,
+       0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0,
+       0x4d400000, 0x5930001f, 0x80000540, 0x04000005,
+       0x41400800, 0x0201f800, 0x00100d7c, 0x40068000,
+       0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+       0x040209f3, 0x4c5c0000, 0x5930b809, 0x0201f800,
+       0x00107911, 0x485e6009, 0x5c00b800, 0x5c025800,
+       0x5c028000, 0x5c03e000, 0x02000000, 0x00106c4b,
+       0x1c01f000, 0x598c000d, 0x81300580, 0x04020004,
+       0x0201f800, 0x00106e8e, 0x04020016, 0x0201f800,
+       0x001068d3, 0x040007df, 0x0201f800, 0x00106b6c,
+       0x04000010, 0x0201f800, 0x001005d8, 0x0201f800,
+       0x00108cd6, 0x04020004, 0x0201f800, 0x00106e62,
+       0x04020008, 0x0201f800, 0x001067ae, 0x040007d1,
+       0x0201f800, 0x00106b6c, 0x02020800, 0x001005d8,
+       0x59300203, 0x82000c80, 0x0000000e, 0x02021800,
+       0x001005d8, 0x0c01f7b9, 0x0201f800, 0x00100e99,
+       0x0401f7c4, 0x4933c857, 0x4d440000, 0x4d340000,
+       0x59cc0007, 0x0201f800, 0x00105c9a, 0x02000800,
+       0x00020245, 0x0402001a, 0x59300009, 0x4c000000,
+       0x49366009, 0x42003000, 0x0000000b, 0x0201f800,
+       0x0010a942, 0x42000000, 0x0010b861, 0x0201f800,
+       0x0010aa47, 0x4d3c0000, 0x4d400000, 0x42028000,
+       0x00000029, 0x417a7800, 0x0201f800, 0x0010203c,
+       0x5c028000, 0x5c027800, 0x5c000000, 0x48026009,
+       0x59cc0007, 0x48026802, 0x80000580, 0x5c026800,
+       0x5c028800, 0x1c01f000, 0x4933c857, 0x4c040000,
+       0x59a80016, 0x82000580, 0x00000074, 0x04020040,
+       0x59cc0a08, 0x82040480, 0x00000100, 0x04001033,
+       0x59cc0c08, 0x82040500, 0x00008000, 0x04000035,
+       0x59a80032, 0x80000540, 0x04020009, 0x59301009,
+       0x58080212, 0x82000500, 0x0000ff00, 0x04000004,
+       0x82040500, 0x00000800, 0x0400002a, 0x59cc0c09,
+       0x80040840, 0x04001024, 0x59a80826, 0x8c040d06,
+       0x04000004, 0x59cc0c0f, 0x8c040d1e, 0x04020012,
+       0x59cc0a17, 0x800409c0, 0x04020012, 0x59cc0a18,
+       0x82040480, 0x00000100, 0x04001014, 0x59cc0c18,
+       0x800409c0, 0x0402000e, 0x59cc0c19, 0x80040840,
+       0x04001011, 0x59cc0c1a, 0x80040840, 0x04001011,
+       0x0401f018, 0x4a02621a, 0x00000100, 0x0401f012,
+       0x4a02621a, 0x00000300, 0x0401f00f, 0x4a02621a,
+       0x00000500, 0x0401f00c, 0x4a02621a, 0x00000700,
+       0x0401f009, 0x4a02621a, 0x00000900, 0x0401f006,
+       0x4a02621a, 0x00000f00, 0x0401f003, 0x4a02621a,
+       0x00002d00, 0x82000540, 0x00000001, 0x0401f002,
+       0x80000580, 0x5c000800, 0x1c01f000, 0x59cc0407,
+       0x4803c857, 0x82000580, 0x00000800, 0x04000003,
+       0x4a02621a, 0x00000000, 0x1c01f000, 0x4933c857,
+       0x4c040000, 0x4c080000, 0x4c0c0000, 0x4c580000,
+       0x59cc000c, 0x0201f800, 0x00105c9a, 0x02000800,
+       0x00020245, 0x04020012, 0x83cc1400, 0x00000008,
+       0x4200b000, 0x00000002, 0x83341c00, 0x00000006,
+       0x0201f800, 0x0010855a, 0x04020009, 0x83cc1400,
+       0x0000000a, 0x4200b000, 0x00000002, 0x83341c00,
+       0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000,
+       0x5c001800, 0x5c001000, 0x5c000800, 0x1c01f000,
+       0x4933c857, 0x4c000000, 0x4c040000, 0x4c080000,
+       0x4c0c0000, 0x4c580000, 0x59cc0001, 0x0201f800,
+       0x00105c9a, 0x02000800, 0x00020245, 0x04020014,
+       0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+       0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+       0x0402000c, 0x83cc1400, 0x0000000d, 0x4200b000,
+       0x00000002, 0x83341c00, 0x00000008, 0x0201f800,
+       0x0010855a, 0x04000014, 0x4933c856, 0x4933c856,
+       0x4933c857, 0x59340009, 0x4803c857, 0x5934000e,
+       0x4803c857, 0x59340008, 0x4803c857, 0x5934000d,
+       0x4803c857, 0x59340007, 0x4803c857, 0x5934000c,
+       0x4803c857, 0x59340006, 0x4803c857, 0x5934000b,
+       0x4803c857, 0x5c00b000, 0x5c001800, 0x5c001000,
+       0x5c000800, 0x5c000000, 0x1c01f000, 0x4933c857,
+       0x4947c857, 0x4943c857, 0x4c600000, 0x0201f800,
+       0x00106c55, 0x4df00000, 0x4d2c0000, 0x4d300000,
+       0x4d340000, 0x4130c000, 0x42026000, 0x0010d1c0,
+       0x59a8000e, 0x8060c1c0, 0x04000005, 0x82601580,
+       0x0010bde9, 0x04000002, 0x80000040, 0x81640480,
+       0x040210be, 0x40600000, 0x81300580, 0x040000b6,
+       0x0401f97a, 0x040200b4, 0x59326809, 0x59300406,
+       0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+       0x0c01f001, 0x0010a3cd, 0x0010a338, 0x0010a351,
+       0x0010a35c, 0x0010a335, 0x0010a34c, 0x0010a387,
+       0x0010a3cd, 0x0010a333, 0x0010a39a, 0x0010a3ae,
+       0x0010a333, 0x0010a333, 0x0010a333, 0x0010a333,
+       0x0010a3cd, 0x0010a3c4, 0x0010a3bc, 0x0201f800,
+       0x001005d8, 0x59300420, 0x8c000500, 0x04020096,
+       0x59300403, 0x82000580, 0x00000043, 0x04000092,
+       0x0201f800, 0x00109134, 0x04000007, 0x0201f800,
+       0x0010914e, 0x0402008a, 0x0201f800, 0x0010801c,
+       0x0401f087, 0x0201f800, 0x00102074, 0x0201f800,
+       0x0010914e, 0x02000800, 0x0010801c, 0x0401f080,
+       0x8d3e7d18, 0x04000004, 0x59300420, 0x8c000500,
+       0x0402007d, 0x59325808, 0x0201f800, 0x00109037,
+       0x04000077, 0x49425a06, 0x497a5c09, 0x0201f800,
+       0x000202da, 0x0201f800, 0x0010912a, 0x0401f070,
+       0x8d3e7d00, 0x04000007, 0x59300017, 0x81480580,
+       0x0402006d, 0x59300018, 0x814c0580, 0x0402006a,
+       0x59300203, 0x82000580, 0x00000004, 0x02000800,
+       0x00100e99, 0x59325808, 0x0201f800, 0x00109037,
+       0x0400005f, 0x4a025a04, 0x00000103, 0x59300004,
+       0x8400055c, 0x48026004, 0x592c0408, 0x8c000512,
+       0x04000007, 0x4d2c0000, 0x592c0009, 0x40025800,
+       0x0201f800, 0x001007fd, 0x5c025800, 0x49425a06,
+       0x497a5c09, 0x0401fb16, 0x0201f800, 0x0010959c,
+       0x0201f800, 0x001091c6, 0x0201f800, 0x000202da,
+       0x0201f800, 0x0010912a, 0x0401f045, 0x8d3e7d18,
+       0x04000045, 0x59300203, 0x82000580, 0x00000004,
+       0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+       0x00109037, 0x0400003a, 0x49425a06, 0x497a5c09,
+       0x0401faff, 0x0201f800, 0x0010959c, 0x0201f800,
+       0x000202da, 0x0401f032, 0x0201f800, 0x001062d5,
+       0x04000031, 0x59300203, 0x82000580, 0x00000004,
+       0x0400002d, 0x59300203, 0x82000580, 0x00000003,
+       0x04020029, 0x0201f800, 0x00106b8a, 0x59325808,
+       0x0201f800, 0x00109037, 0x04000021, 0x0201f800,
+       0x000202da, 0x0401f01e, 0x59300203, 0x82000580,
+       0x00000004, 0x02000800, 0x00100e99, 0x59325808,
+       0x0201f800, 0x00109037, 0x04000015, 0x49425a06,
+       0x497a5c09, 0x0201f800, 0x000202da, 0x0401f010,
+       0x833c0500, 0x00001800, 0x0400000f, 0x8d3e7d16,
+       0x0402000d, 0x59325817, 0x0201f800, 0x001007fd,
+       0x59325808, 0x0201f800, 0x00109037, 0x04000004,
+       0x49425a06, 0x0201f800, 0x000202da, 0x0201f800,
+       0x00107911, 0x83326400, 0x00000024, 0x41580000,
+       0x81300480, 0x0400173b, 0x5c026800, 0x5c026000,
+       0x5c025800, 0x5c03e000, 0x02000800, 0x00106c4b,
+       0x5c00c000, 0x1c01f000, 0x5c000000, 0x4c000000,
+       0x4803c857, 0x4d3c0000, 0x42027800, 0x00000001,
+       0x0201f800, 0x00104567, 0x5c027800, 0x4c580000,
+       0x4200b000, 0x00000002, 0x83a81c00, 0x00000002,
+       0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+       0x5c00b000, 0x80000540, 0x1c01f000, 0x492fc857,
+       0x4943c857, 0x59a8000c, 0x812c0480, 0x04001011,
+       0x59a8000d, 0x812c0480, 0x0402100e, 0x592c0000,
+       0x80005d40, 0x04000008, 0x497a5800, 0x49425a06,
+       0x4c2c0000, 0x0201f800, 0x000202da, 0x5c025800,
+       0x0401f7f7, 0x49425a06, 0x0201f000, 0x000202da,
+       0x1c01f000, 0x493fc857, 0x4933c857, 0x480bc857,
+       0x0201f800, 0x00103b25, 0x0400002e, 0x41502800,
+       0x813e79c0, 0x04020006, 0x59a80066, 0x80000000,
+       0x59a8086a, 0x80040580, 0x04000026, 0x41300000,
+       0x80140580, 0x0400001a, 0x58140203, 0x82000580,
+       0x00000000, 0x04000016, 0x58140202, 0x80080580,
+       0x04020013, 0x58141c06, 0x820c0580, 0x00000005,
+       0x0400000f, 0x820c0580, 0x00000009, 0x04000017,
+       0x59300009, 0x58142009, 0x801021c0, 0x04020006,
+       0x5814201e, 0x59301809, 0x580c0002, 0x82000500,
+       0x00ffffff, 0x80100580, 0x04000007, 0x82142c00,
+       0x00000024, 0x41540000, 0x80140480, 0x04021005,
+       0x0401f7df, 0x40163800, 0x81300540, 0x0401f002,
+       0x80000580, 0x1c01f000, 0x58141807, 0x8c0c1d10,
+       0x040207f3, 0x0401f7e7, 0x42002000, 0x0000ffff,
+       0x59301009, 0x800811c0, 0x04000002, 0x58082403,
+       0x41301000, 0x0401f007, 0x41781000, 0x41442000,
+       0x0401f004, 0x41781000, 0x42002000, 0x0000ffff,
+       0x5c000000, 0x4c000000, 0x4803c857, 0x480bc857,
+       0x4813c857, 0x492fc857, 0x4943c857, 0x4d2c0000,
+       0x0201f800, 0x001007e4, 0x02000800, 0x001005d8,
+       0x4a025a04, 0x0000010d, 0x800811c0, 0x04000017,
+       0x83400580, 0x00000029, 0x04020010, 0x82180580,
+       0x00000002, 0x0400000a, 0x82180580, 0x00000003,
+       0x04000007, 0x82180580, 0x00000008, 0x04000004,
+       0x82180580, 0x00000009, 0x04020004, 0x4a025809,
+       0xffffffff, 0x0401f002, 0x480a5809, 0x58080202,
+       0x48025c13, 0x0401f005, 0x4a025809, 0xffffffff,
+       0x4a025c13, 0x0000ffff, 0x49425a08, 0x48125a06,
+       0x82100580, 0x0000ffff, 0x0400000e, 0x4d440000,
+       0x4d340000, 0x40128800, 0x0201f800, 0x00020245,
+       0x02020800, 0x001005d8, 0x59340002, 0x82000500,
+       0x00ffffff, 0x48025812, 0x5c026800, 0x5c028800,
+       0x497a5800, 0x497a5c04, 0x83400580, 0x00000046,
+       0x04020002, 0x48165a07, 0x481a5c08, 0x0401fbed,
+       0x5c025800, 0x1c01f000, 0x59300809, 0x800409c0,
+       0x04000004, 0x58040403, 0x81440580, 0x1c01f000,
+       0x82000540, 0x00000001, 0x0401f7fd, 0x4933c857,
+       0x4c040000, 0x59300403, 0x82000d80, 0x0000001e,
+       0x04020016, 0x800000d0, 0x59300a16, 0x82040d00,
+       0x000000ff, 0x80040540, 0x4803c857, 0x48026416,
+       0x4a026403, 0x00000085, 0x4a026203, 0x00000009,
+       0x4a026406, 0x00000005, 0x4a02621d, 0x00000004,
+       0x59a80038, 0x48026206, 0x42000800, 0x8000004b,
+       0x0201f800, 0x00020721, 0x5c000800, 0x1c01f000,
+       0x4933c857, 0x40000000, 0x40000000, 0x1c01f000,
+       0x59300414, 0x4933c857, 0x4803c857, 0x8c000518,
+       0x04000009, 0x8c000512, 0x02020000, 0x0010921e,
+       0x0401f91b, 0x0201f800, 0x000206fd, 0x0201f800,
+       0x0002077d, 0x1c01f000, 0x591c0406, 0x4803c857,
+       0x82000c80, 0x00000009, 0x0402100b, 0x0c01f001,
+       0x0010a4d9, 0x0010a4d9, 0x0010a4d9, 0x0010a4db,
+       0x0010a4d9, 0x0010a4db, 0x0010a4db, 0x0010a4d9,
+       0x0010a4db, 0x80000580, 0x1c01f000, 0x82000540,
+       0x00000001, 0x1c01f000, 0x591c0406, 0x82000500,
+       0x0000001f, 0x82000580, 0x00000006, 0x0400000e,
+       0x4803c857, 0x4a026403, 0x0000003b, 0x4a02641a,
+       0x00000009, 0x4a02621a, 0x00002a00, 0x4a026203,
+       0x00000001, 0x42000800, 0x80000040, 0x0201f000,
+       0x00020721, 0x4803c856, 0x4c040000, 0x4c140000,
+       0x4d300000, 0x411e6000, 0x0401f8e9, 0x497a6205,
+       0x59300414, 0x4803c857, 0x82000500, 0xffffadff,
+       0x48026414, 0x497a6405, 0x5c026000, 0x0201f800,
+       0x001007e4, 0x02000800, 0x001005d8, 0x5c002800,
+       0x5c000800, 0x4a025a04, 0x0000010d, 0x497a5800,
+       0x497a5c04, 0x4a025a08, 0x00000045, 0x491e5809,
+       0x59300402, 0x48025c07, 0x59300419, 0x48025c0b,
+       0x591c0414, 0x84000556, 0x48023c14, 0x591c1809,
+       0x580c0403, 0x48025a06, 0x4816580a, 0x48065a0b,
+       0x0401f99d, 0x4d400000, 0x42028000, 0x00000045,
+       0x591c0202, 0x4c000000, 0x4d300000, 0x411e6000,
+       0x0401fcb1, 0x5c026000, 0x5c000000, 0x48023a02,
+       0x5c028000, 0x4a023c06, 0x00000006, 0x4a023a03,
+       0x00000007, 0x497a3a06, 0x497a3a05, 0x1c01f000,
+       0x4933c857, 0x83380580, 0x00000013, 0x0402000b,
+       0x59300403, 0x4803c857, 0x82000d80, 0x00000085,
+       0x0400002b, 0x82000d80, 0x0000008b, 0x04000028,
+       0x0201f800, 0x001005d8, 0x83380580, 0x00000027,
+       0x0402000c, 0x0201f800, 0x00106bbf, 0x4d2c0000,
+       0x4d400000, 0x59325808, 0x42028000, 0x00000004,
+       0x0401feab, 0x5c028000, 0x5c025800, 0x1c01f000,
+       0x83380580, 0x00000014, 0x040007f3, 0x83380580,
+       0x00000089, 0x04000005, 0x83380580, 0x0000008a,
+       0x02020000, 0x00107974, 0x0201f800, 0x00106f60,
+       0x02020000, 0x00107974, 0x59300a03, 0x82040580,
+       0x0000000a, 0x04000009, 0x82040580, 0x0000000c,
+       0x04000006, 0x0201f800, 0x001005d8, 0x4a026203,
+       0x0000000a, 0x1c01f000, 0x83380480, 0x00000093,
+       0x0402100c, 0x83380480, 0x00000085, 0x04001009,
+       0x83380580, 0x00000089, 0x0400000a, 0x83380580,
+       0x0000008a, 0x04000022, 0x0201f800, 0x001005d8,
+       0x493bc857, 0x4933c857, 0x0201f000, 0x00107974,
+       0x4933c857, 0x4c340000, 0x41306800, 0x0201f800,
+       0x0002075a, 0x04000011, 0x4a026203, 0x00000001,
+       0x4a026403, 0x0000001e, 0x59cc0c07, 0x48066419,
+       0x59cc0a07, 0x48066219, 0x58340809, 0x48066009,
+       0x4a026406, 0x00000004, 0x42000800, 0x80000040,
+       0x0201f800, 0x00020721, 0x40366000, 0x0201f800,
+       0x0002077d, 0x5c006800, 0x1c01f000, 0x4933c857,
+       0x0201f000, 0x0002077d, 0x4933c857, 0x59300809,
+       0x58040200, 0x8c00051a, 0x1c01f000, 0x0201f800,
+       0x001048df, 0x0400001e, 0x4a026203, 0x00000002,
+       0x59300414, 0x84000558, 0x48026414, 0x8c000512,
+       0x04000004, 0x59a80039, 0x48026205, 0x0401f007,
+       0x59a80839, 0x59a80037, 0x80040400, 0x82000400,
+       0x0000000a, 0x48026205, 0x59300009, 0x82000c00,
+       0x00000011, 0x50040000, 0x80000540, 0x04000004,
+       0x82000c00, 0x00000000, 0x0401f7fb, 0x45300800,
+       0x497a6000, 0x82000540, 0x00000001, 0x1c01f000,
+       0x82100500, 0xfffffeef, 0x04020020, 0x4d2c0000,
+       0x4937c857, 0x59340811, 0x83341400, 0x00000011,
+       0x800409c0, 0x0400000e, 0x40040000, 0x81300580,
+       0x04000005, 0x58040800, 0x82041400, 0x00000000,
+       0x0401f7f8, 0x59300800, 0x497a6000, 0x44041000,
+       0x0201f800, 0x000206fd, 0x0401f002, 0x4933c857,
+       0x592c0000, 0x80000540, 0x02020800, 0x001005d8,
+       0x5c025800, 0x492e6008, 0x0201f800, 0x000206fd,
+       0x0201f000, 0x0002077d, 0x492fc857, 0x4a025a06,
+       0x00000006, 0x0201f000, 0x000202da, 0x4c340000,
+       0x59300009, 0x800001c0, 0x04000010, 0x82006c00,
+       0x00000011, 0x50340000, 0x80000540, 0x04000009,
+       0x81300580, 0x04000005, 0x50340000, 0x82006c00,
+       0x00000000, 0x0401f7f8, 0x59300000, 0x44006800,
+       0x5c006800, 0x1c01f000, 0x59300c06, 0x82040580,
+       0x00000005, 0x040007fb, 0x82040580, 0x00000011,
+       0x040007f8, 0x82040580, 0x00000006, 0x040007f5,
+       0x82040580, 0x00000001, 0x040007f2, 0x0201f800,
+       0x001005d8, 0x4933c857, 0x4c080000, 0x4c0c0000,
+       0x4c580000, 0x59a8101d, 0x59cc1807, 0x820c1d00,
+       0x00ffffff, 0x800c0110, 0x80083580, 0x04020014,
+       0x83cc1400, 0x00000008, 0x4200b000, 0x00000002,
+       0x59300009, 0x82001c00, 0x00000006, 0x0201f800,
+       0x0010855a, 0x0402000a, 0x83cc1400, 0x0000000a,
+       0x4200b000, 0x00000002, 0x59300009, 0x82001c00,
+       0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000,
+       0x5c001800, 0x5c001000, 0x1c01f000, 0x4933c856,
+       0x0201f800, 0x0010421b, 0x0201f000, 0x00101e45,
+       0x493bc857, 0x4d2c0000, 0x0201f800, 0x001007e4,
+       0x02000800, 0x001005d8, 0x832cac00, 0x00000005,
+       0x4c580000, 0x4c540000, 0x4200b000, 0x00000006,
+       0x4578a800, 0x8054a800, 0x8058b040, 0x040207fd,
+       0x83380580, 0x00000046, 0x04020004, 0x4a025a04,
+       0x00000144, 0x0401f008, 0x4a025a04, 0x00000146,
+       0x83380580, 0x00000041, 0x04000003, 0x4a025a06,
+       0x00000001, 0x59cc0007, 0x82000500, 0xff000000,
+       0x80000110, 0x59cc1008, 0x82081500, 0xff000000,
+       0x80081540, 0x480a580a, 0x83380580, 0x00000046,
+       0x04020006, 0x59cc0007, 0x82000500, 0x00ffffff,
+       0x4802580b, 0x0401f005, 0x59cc0008, 0x82000500,
+       0x00ffffff, 0x4802580b, 0x83380580, 0x00000046,
+       0x04020004, 0x83cc1400, 0x00000009, 0x0401f003,
+       0x83cc1400, 0x0000000d, 0x50080000, 0x9c0001c0,
+       0x4802580c, 0x80081000, 0x50080000, 0x9c0001c0,
+       0x4802580d, 0x83380580, 0x00000046, 0x04020008,
+       0x59cc000b, 0x9c0001c0, 0x4802580e, 0x59cc000c,
+       0x9c0001c0, 0x4802580f, 0x0401f007, 0x59cc000f,
+       0x9c0001c0, 0x4802580e, 0x59cc0010, 0x9c0001c0,
+       0x4802580f, 0x83380580, 0x00000046, 0x04020004,
+       0x83cc1400, 0x00000011, 0x0401f003, 0x83cc1400,
+       0x00000015, 0x412c3000, 0x82183400, 0x00000010,
+       0x4200b000, 0x00000004, 0x50080000, 0x9c0001c0,
+       0x44003000, 0x80081000, 0x80183000, 0x8058b040,
+       0x040207fa, 0x5c00a800, 0x5c00b000, 0x0201f800,
+       0x000202da, 0x5c025800, 0x1c01f000, 0x4933c857,
+       0x492fc857, 0x59300809, 0x58040200, 0x8c00051e,
+       0x04000004, 0x592c0208, 0x84000558, 0x48025a08,
+       0x1c01f000, 0x59e0180f, 0x599c0413, 0x800c1000,
+       0x80080580, 0x04020002, 0x41781000, 0x59e00010,
+       0x59e00810, 0x80040d80, 0x040207fd, 0x80080580,
+       0x0400000b, 0x4c080000, 0x599c0814, 0x599c1015,
+       0x800c00cc, 0x80040c00, 0x82081440, 0x00000000,
+       0x5c001800, 0x82000540, 0x00000001, 0x4803c857,
+       0x1c01f000, 0x492fc857, 0x42007000, 0x0010b7f8,
+       0x58380807, 0x800409c0, 0x04020005, 0x492c7008,
+       0x492c7007, 0x0201f000, 0x00100875, 0x492c0800,
+       0x492c7007, 0x1c01f000, 0x59300203, 0x4933c857,
+       0x4937c857, 0x493bc857, 0x4803c857, 0x82003480,
+       0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001,
+       0x0010a6da, 0x0010a82c, 0x0010a6da, 0x0010a6da,
+       0x0010a6da, 0x0010a6da, 0x0010a6da, 0x0010a791,
+       0x0010a6dc, 0x0010a6da, 0x0010a6da, 0x0010a6da,
+       0x0010a6da, 0x0010a6da, 0x0201f800, 0x001005d8,
+       0x83380580, 0x0000004c, 0x02020800, 0x001005d8,
+       0x0201f800, 0x001048ec, 0x04020020, 0x59a80826,
+       0x82040500, 0x00000009, 0x82000580, 0x00000008,
+       0x0400001a, 0x8c040d12, 0x0400003d, 0x59cc0806,
+       0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+       0x0400001f, 0x82040580, 0x50000000, 0x04000005,
+       0x82040580, 0x52000000, 0x02020000, 0x0002077d,
+       0x813669c0, 0x04000006, 0x4d3c0000, 0x417a7800,
+       0x0201f800, 0x0010203c, 0x5c027800, 0x4a026403,
+       0x00000001, 0x0401f014, 0x59cc0806, 0x82040d00,
+       0xff000000, 0x82040580, 0x03000000, 0x04000008,
+       0x82040580, 0x50000000, 0x04000005, 0x82040580,
+       0x52000000, 0x02020000, 0x0002077d, 0x4a026403,
+       0x00000009, 0x4a02641a, 0x00000009, 0x4a02621a,
+       0x00000000, 0x813669c0, 0x0402000b, 0x59cc0001,
+       0x0201f800, 0x00105c9a, 0x02020000, 0x0002077d,
+       0x0201f800, 0x001045a6, 0x02020000, 0x0002077d,
+       0x49366009, 0x4a026406, 0x00000004, 0x4a026203,
+       0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+       0x00103b25, 0x04000023, 0x59cc0806, 0x4807c857,
+       0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+       0x04000033, 0x82040580, 0x20000000, 0x04000041,
+       0x82040580, 0x21000000, 0x04000052, 0x82040580,
+       0x24000000, 0x0400004f, 0x82040580, 0x50000000,
+       0x0400004c, 0x82040580, 0x52000000, 0x04000049,
+       0x82040580, 0x05000000, 0x0402000d, 0x59cc0806,
+       0x82040d00, 0xff000000, 0x9c0431c0, 0x42028000,
+       0x00000046, 0x42002800, 0x00000001, 0x0401fcf3,
+       0x0401f93c, 0x02000800, 0x001005d8, 0x42002000,
+       0x00000051, 0x0201f800, 0x00107a4a, 0x59cc0000,
+       0x82000500, 0x00ffffff, 0x82000580, 0x00ffffff,
+       0x04000005, 0x4a026203, 0x00000007, 0x493a6403,
+       0x1c01f000, 0x59325817, 0x812e59c0, 0x02020800,
+       0x001007fd, 0x0201f000, 0x0002077d, 0x813669c0,
+       0x040007df, 0x59340400, 0x82000500, 0x000000ff,
+       0x82000580, 0x00000003, 0x040207d9, 0x0401fc6f,
+       0x040207d7, 0x4a026403, 0x00000009, 0x4a02641a,
+       0x0000000e, 0x4a02621a, 0x00001900, 0x0401f7a2,
+       0x813669c0, 0x0400000c, 0x59340c00, 0x82040500,
+       0x000000ff, 0x82000580, 0x00000009, 0x04000794,
+       0x82040500, 0x0000ff00, 0x82000580, 0x00000700,
+       0x040207c3, 0x4a026403, 0x00000009, 0x4a02641a,
+       0x00000009, 0x4a02621a, 0x00001e00, 0x0401f78e,
+       0x813669c0, 0x040007f8, 0x59340c00, 0x82040500,
+       0x0000ff00, 0x82000580, 0x00000700, 0x040007f2,
+       0x0401f7b3, 0x4d2c0000, 0x4c580000, 0x4c500000,
+       0x4c540000, 0x41385000, 0x83380580, 0x00000054,
+       0x02020800, 0x001005d8, 0x59325808, 0x592c0c0b,
+       0x82040d00, 0x0000e000, 0x82040580, 0x00002000,
+       0x04020076, 0x59300817, 0x800409c0, 0x04000014,
+       0x58041404, 0x41cca800, 0x8204a400, 0x00000005,
+       0x82080480, 0x00000010, 0x04021004, 0x4008b000,
+       0x0401fb6b, 0x0401f00a, 0x40001000, 0x4200b000,
+       0x0000000f, 0x0401fb66, 0x58040801, 0x800409c0,
+       0x040207f2, 0x0201f800, 0x001005d8, 0x813669c0,
+       0x0400005e, 0x59344c00, 0x592c0c09, 0x4807c857,
+       0x4827c857, 0x82040d00, 0x000000ff, 0x82040580,
+       0x00000003, 0x0400002a, 0x82040580, 0x00000005,
+       0x04000032, 0x82040580, 0x00000020, 0x04000036,
+       0x82040580, 0x00000052, 0x04000042, 0x82040580,
+       0x00000050, 0x04000042, 0x82040580, 0x00000021,
+       0x04000004, 0x82040580, 0x00000024, 0x04020043,
+       0x82240500, 0x0000ff00, 0x82000580, 0x00000007,
+       0x04000008, 0x42000800, 0x00000009, 0x0201f800,
+       0x00104571, 0x42005000, 0x0000000c, 0x0401f037,
+       0x4a025a06, 0x00000031, 0x4a02580d, 0x00000009,
+       0x59340400, 0x4802580e, 0x0201f800, 0x000202da,
+       0x0201f800, 0x00107911, 0x0401f03d, 0x0201f800,
+       0x001042b4, 0x0201f800, 0x0010462a, 0x42000800,
+       0x00000003, 0x0201f800, 0x00104571, 0x42005000,
+       0x00000008, 0x0401f021, 0x59cc0007, 0x0201f800,
+       0x00105eec, 0x0402001d, 0x0201f800, 0x001042b4,
+       0x0401f01a, 0x82240500, 0x0000ff00, 0x82000580,
+       0x00000007, 0x040007df, 0x82240500, 0x000000ff,
+       0x82000580, 0x00000009, 0x040007da, 0x0201f800,
+       0x0010468d, 0x42005000, 0x0000000a, 0x0401f00b,
+       0x42005000, 0x0000000e, 0x0401f003, 0x42005000,
+       0x00000010, 0x82240500, 0x0000ff00, 0x82000580,
+       0x00000007, 0x040007cb, 0x482a6403, 0x4a026203,
+       0x00000001, 0x592c000d, 0x48026011, 0x497a6013,
+       0x59a80038, 0x48026206, 0x417a7800, 0x0201f800,
+       0x0010672b, 0x59325817, 0x812e59c0, 0x04000004,
+       0x0201f800, 0x001007fd, 0x497a6017, 0x5c00a800,
+       0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000,
+       0x4d2c0000, 0x59325808, 0x83380580, 0x00000013,
+       0x04020029, 0x59300c03, 0x82040580, 0x00000054,
+       0x0400001e, 0x82040580, 0x00000010, 0x04000018,
+       0x82040580, 0x0000000e, 0x04000015, 0x82040580,
+       0x00000008, 0x0400000d, 0x82040580, 0x0000000c,
+       0x0400000a, 0x82040580, 0x0000000a, 0x02020800,
+       0x001005d8, 0x42000800, 0x00000006, 0x0201f800,
+       0x00104571, 0x0401f009, 0x42000800, 0x00000004,
+       0x0201f800, 0x00104571, 0x0401f004, 0x59340200,
+       0x8400051a, 0x48026a00, 0x4a025a06, 0x00000000,
+       0x0201f800, 0x000202da, 0x0201f800, 0x0002077d,
+       0x0401f022, 0x83380580, 0x00000027, 0x0400000e,
+       0x83380580, 0x00000014, 0x02020800, 0x001005d8,
+       0x0201f800, 0x00106bbf, 0x42028000, 0x00000031,
+       0x42000800, 0x00000004, 0x42001000, 0x000000ff,
+       0x0401f009, 0x0201f800, 0x00106bbf, 0x42028000,
+       0x00000031, 0x42000800, 0x00000004, 0x42001000,
+       0x00000010, 0x49425a06, 0x4806580d, 0x480a580e,
+       0x0201f800, 0x000202da, 0x0201f800, 0x00104c19,
+       0x0201f800, 0x00107911, 0x5c025800, 0x1c01f000,
+       0x42007000, 0x0010b7f8, 0x58380807, 0x800409c0,
+       0x04020005, 0x492c7008, 0x492c7007, 0x0201f000,
+       0x00100875, 0x492c0800, 0x492c7007, 0x1c01f000,
+       0x4d2c0000, 0x4c580000, 0x4c500000, 0x4c540000,
+       0x4933c857, 0x4937c857, 0x59cc0806, 0x4807c857,
+       0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+       0x0400000d, 0x82040580, 0x05000000, 0x0400000a,
+       0x82040580, 0x21000000, 0x04000030, 0x82040580,
+       0x24000000, 0x0400002d, 0x82040580, 0x20000000,
+       0x0402002f, 0x0201f800, 0x001007e4, 0x0400002c,
+       0x492fc857, 0x492e6017, 0x59a8b016, 0x8258b400,
+       0x0000001b, 0x8258b500, 0xfffffffc, 0x8058b104,
+       0x485a5c04, 0x412c7800, 0x41cca000, 0x82580480,
+       0x00000010, 0x04021005, 0x832cac00, 0x00000005,
+       0x0401fa63, 0x0401f015, 0x40580800, 0x4200b000,
+       0x0000000f, 0x832cac00, 0x00000005, 0x0401fa5c,
+       0x8204b480, 0x0000000f, 0x0201f800, 0x001007e4,
+       0x04000004, 0x492c7801, 0x412c7800, 0x0401f7ec,
+       0x59325817, 0x0201f800, 0x001007fd, 0x497a6017,
+       0x80000580, 0x0401f006, 0x59340200, 0x84000554,
+       0x48026a00, 0x82000540, 0x00000001, 0x5c00a800,
+       0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000,
+       0x4933c857, 0x492fc857, 0x4d2c0000, 0x59300a03,
+       0x82040580, 0x00000007, 0x04000036, 0x82040580,
+       0x00000001, 0x02020800, 0x001005d8, 0x0201f800,
+       0x00106c55, 0x4df00000, 0x598c000d, 0x81300580,
+       0x04020016, 0x59300004, 0x8c000520, 0x04000004,
+       0x84000520, 0x48026004, 0x0401f016, 0x42001000,
+       0x0010b7f6, 0x50081000, 0x58080002, 0x82000580,
+       0x00000100, 0x04000006, 0x5808000c, 0x81300580,
+       0x02020800, 0x001005d8, 0x0401f00a, 0x0201f800,
+       0x00106e8e, 0x04020020, 0x59300004, 0x8c000520,
+       0x04000004, 0x84000520, 0x48026004, 0x0401f003,
+       0x0201f800, 0x001068d3, 0x5c03e000, 0x02000800,
+       0x00106c4b, 0x0201f800, 0x00109037, 0x02000800,
+       0x001005d8, 0x59325808, 0x4a025a06, 0x00000005,
+       0x0201f800, 0x000202da, 0x0201f800, 0x00104c19,
+       0x59325817, 0x812e59c0, 0x02020800, 0x001007fd,
+       0x0201f800, 0x00107911, 0x80000580, 0x5c025800,
+       0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b,
+       0x59300406, 0x82000580, 0x00000011, 0x040007b8,
+       0x0401f7f7, 0x4c040000, 0x59340200, 0x4803c857,
+       0x8c00051c, 0x04000009, 0x59cc0805, 0x591c0019,
+       0x4803c857, 0x80040580, 0x04000004, 0x80000580,
+       0x4803c856, 0x0401f003, 0x82000540, 0x00000001,
+       0x5c000800, 0x1c01f000, 0x4c000000, 0x4c0c0000,
+       0x4c100000, 0x42001800, 0x0000ffff, 0x42002000,
+       0x00000004, 0x0401f010, 0x4c000000, 0x4c0c0000,
+       0x4c100000, 0x59302009, 0x58101c03, 0x42002000,
+       0x00000004, 0x0401f008, 0x4c000000, 0x4c0c0000,
+       0x4c100000, 0x59302009, 0x58101c03, 0x42002000,
+       0x00000007, 0x480fc857, 0x4813c857, 0x481bc857,
+       0x0201f800, 0x00103aae, 0x5c002000, 0x5c001800,
+       0x5c000000, 0x1c01f000, 0x83380580, 0x00000092,
+       0x02020800, 0x001005d8, 0x42000800, 0x80000040,
+       0x4a026203, 0x00000001, 0x493a6403, 0x0201f000,
+       0x00020721, 0x4d400000, 0x0201f800, 0x00103b25,
+       0x04000008, 0x59a80005, 0x84000544, 0x48035005,
+       0x42028000, 0x0000002a, 0x0201f800, 0x0010a449,
+       0x5c028000, 0x1c01f000, 0x59a80026, 0x8c000508,
+       0x04000005, 0x599c0017, 0x8c00050a, 0x04020002,
+       0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000,
+       0x59300420, 0x84000540, 0x48026420, 0x1c01f000,
+       0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a,
+       0x04000004, 0x598800b8, 0x80000000, 0x480310b8,
+       0x8c142d2e, 0x04000004, 0x598800b9, 0x80000000,
+       0x480310b9, 0x8c142d2c, 0x04000013, 0x40140000,
+       0x82000500, 0x00070000, 0x82000d80, 0x00030000,
+       0x0400000d, 0x82000d80, 0x00040000, 0x0400000a,
+       0x82000d80, 0x00050000, 0x04000007, 0x59880005,
+       0x80000000, 0x48031005, 0x598800ba, 0x80000000,
+       0x480310ba, 0x5c000800, 0x5c000000, 0x1c01f000,
+       0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a,
+       0x04000004, 0x598800bb, 0x80000000, 0x480310bb,
+       0x8c142d2e, 0x04000004, 0x598800bc, 0x80000000,
+       0x480310bc, 0x8c142d2c, 0x04000013, 0x40140000,
+       0x82000500, 0x00070000, 0x82000d80, 0x00030000,
+       0x0400000d, 0x82000d80, 0x00040000, 0x0400000a,
+       0x82000d80, 0x00050000, 0x04000007, 0x59880005,
+       0x80000000, 0x48031005, 0x598800bd, 0x80000000,
+       0x480310bd, 0x5c000800, 0x5c000000, 0x1c01f000,
+       0x4c000000, 0x59880001, 0x80000000, 0x4803c857,
+       0x48031001, 0x5c000000, 0x1c01f000, 0x4c000000,
+       0x59880000, 0x80000000, 0x4803c857, 0x48031000,
+       0x5c000000, 0x1c01f000, 0x4c000000, 0x59880002,
+       0x80000000, 0x4803c857, 0x48031002, 0x5c000000,
+       0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d2c,
+       0x04000004, 0x598800a6, 0x80000000, 0x480310a6,
+       0x8c040d2a, 0x04000004, 0x598800a7, 0x80000000,
+       0x480310a7, 0x8c040d28, 0x04000004, 0x598800a8,
+       0x80000000, 0x480310a8, 0x8c040d26, 0x04000004,
+       0x598800a9, 0x80000000, 0x480310a9, 0x8c040d24,
+       0x04000004, 0x598800aa, 0x80000000, 0x480310aa,
+       0x8c040d22, 0x04000004, 0x598800ab, 0x80000000,
+       0x480310ab, 0x8c040d20, 0x04000004, 0x598800ac,
+       0x80000000, 0x480310ac, 0x5c000000, 0x1c01f000,
+       0x4807c857, 0x4c000000, 0x598800ad, 0x80000000,
+       0x480310ad, 0x5c000000, 0x1c01f000, 0x4807c857,
+       0x4c000000, 0x8c040d1c, 0x04000004, 0x598800ae,
+       0x80000000, 0x480310ae, 0x8c040d1a, 0x04000004,
+       0x598800af, 0x80000000, 0x480310af, 0x5c000000,
+       0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d18,
+       0x04000004, 0x598800b0, 0x80000000, 0x480310b0,
+       0x8c040d16, 0x04000004, 0x598800b1, 0x80000000,
+       0x480310b1, 0x8c040d14, 0x04000004, 0x598800b2,
+       0x80000000, 0x480310b2, 0x5c000000, 0x1c01f000,
+       0x4807c857, 0x4c000000, 0x8c040d10, 0x04000004,
+       0x598800b3, 0x80000000, 0x480310b3, 0x8c040d0c,
+       0x04000004, 0x598800b4, 0x80000000, 0x480310b4,
+       0x5c000000, 0x1c01f000, 0x4807c857, 0x4c000000,
+       0x8c040d08, 0x04000004, 0x598800b5, 0x80000000,
+       0x480310b5, 0x8c040d04, 0x04000004, 0x598800b6,
+       0x80000000, 0x480310b6, 0x5c000000, 0x1c01f000,
+       0x4807c856, 0x4c000000, 0x5988007f, 0x80000000,
+       0x4803107f, 0x5c000000, 0x1c01f000, 0x4803c857,
+       0x4c040000, 0x50000800, 0x80040800, 0x4807c857,
+       0x44040000, 0x5c000800, 0x1c01f000, 0x480fc857,
+       0x4c000000, 0x820c0580, 0x00000000, 0x04020004,
+       0x42000000, 0x0010b819, 0x0401f014, 0x820c0580,
+       0x00001001, 0x04020004, 0x42000000, 0x0010b81a,
+       0x0401f00e, 0x820c0580, 0x00001002, 0x04020004,
+       0x42000000, 0x0010b81b, 0x0401f008, 0x820c0c80,
+       0x0000201c, 0x02021800, 0x001005d8, 0x820c0500,
+       0x0000001f, 0x0c01f804, 0x0401ffdd, 0x5c000000,
+       0x1c01f000, 0x0010aa89, 0x0010aa8c, 0x0010aa8f,
+       0x0010aa92, 0x0010aa95, 0x0010aa98, 0x0010aa9b,
+       0x0010aa9e, 0x0010aaa1, 0x0010aaa4, 0x0010aaa7,
+       0x0010aaaa, 0x0010aaad, 0x0010aab0, 0x0010aab3,
+       0x0010aab6, 0x0010aab9, 0x0010aabc, 0x0010aabf,
+       0x0010aac2, 0x0010aac5, 0x0010aac8, 0x0010aacb,
+       0x0010aace, 0x0010aad1, 0x0010aad4, 0x0010aad7,
+       0x0010aada, 0x42000000, 0x0010b81c, 0x1c01f000,
+       0x42000000, 0x0010b81d, 0x1c01f000, 0x42000000,
+       0x0010b81e, 0x1c01f000, 0x42000000, 0x0010b81f,
+       0x1c01f000, 0x42000000, 0x0010b820, 0x1c01f000,
+       0x42000000, 0x0010b821, 0x1c01f000, 0x42000000,
+       0x0010b822, 0x1c01f000, 0x42000000, 0x0010b823,
+       0x1c01f000, 0x42000000, 0x0010b824, 0x1c01f000,
+       0x42000000, 0x0010b825, 0x1c01f000, 0x42000000,
+       0x0010b826, 0x1c01f000, 0x42000000, 0x0010b827,
+       0x1c01f000, 0x42000000, 0x0010b828, 0x1c01f000,
+       0x42000000, 0x0010b829, 0x1c01f000, 0x42000000,
+       0x0010b82a, 0x1c01f000, 0x42000000, 0x0010b82b,
+       0x1c01f000, 0x42000000, 0x0010b82c, 0x1c01f000,
+       0x42000000, 0x0010b82d, 0x1c01f000, 0x42000000,
+       0x0010b82e, 0x1c01f000, 0x42000000, 0x0010b82f,
+       0x1c01f000, 0x42000000, 0x0010b830, 0x1c01f000,
+       0x42000000, 0x0010b831, 0x1c01f000, 0x42000000,
+       0x0010b832, 0x1c01f000, 0x42000000, 0x0010b833,
+       0x1c01f000, 0x42000000, 0x0010b834, 0x1c01f000,
+       0x42000000, 0x0010b835, 0x1c01f000, 0x42000000,
+       0x0010b836, 0x1c01f000, 0x42000000, 0x0010b837,
+       0x1c01f000, 0x480fc857, 0x4c000000, 0x820c0580,
+       0x00000001, 0x04020004, 0x42000000, 0x0010b80e,
+       0x0401f012, 0x820c0580, 0x00000002, 0x04020004,
+       0x42000000, 0x0010b80f, 0x0401f00c, 0x820c0580,
+       0x00000003, 0x04020004, 0x42000000, 0x0010b810,
+       0x0401f006, 0x820c0580, 0x00000004, 0x04020004,
+       0x42000000, 0x0010b811, 0x0401ff51, 0x5c000000,
+       0x1c01f000, 0x4c000000, 0x59a80026, 0x4803c857,
+       0x8c000502, 0x04000010, 0x8c000506, 0x04000004,
+       0x42000000, 0x0010b841, 0x0401f012, 0x8c00050a,
+       0x04000004, 0x42000000, 0x0010b840, 0x0401f00d,
+       0x8c000508, 0x04000004, 0x42000000, 0x0010b843,
+       0x0401f008, 0x0201f800, 0x0010513b, 0x04000006,
+       0x8c000506, 0x04020004, 0x42000000, 0x0010b842,
+       0x0401ff33, 0x5c000000, 0x1c01f000, 0x8058b1c0,
+       0x02000800, 0x001005d8, 0x5450a800, 0x8050a000,
+       0x8054a800, 0x8058b040, 0x040207fc, 0x1c01f000,
+       0x8058b1c0, 0x02000800, 0x001005d8, 0x4450a800,
+       0x8054a800, 0x8058b040, 0x040207fd, 0x1c01f000,
+       0x8058b1c0, 0x02000800, 0x001005d8, 0x50500000,
+       0x9c0001c0, 0x4400a800, 0x8050a000, 0x8054a800,
+       0x8058b040, 0x040207fa, 0x1c01f000, 0x4c000000,
+       0x59a80008, 0x8c00051c, 0x5c000000, 0x1c01f000,
+       0x00000001, 0x00000002, 0x00000004, 0x00000008,
+       0x00000010, 0x00000020, 0x00000040, 0x00000080,
+       0x00000100, 0x00000200, 0x00000400, 0x00000800,
+       0x00001000, 0x00002000, 0x00004000, 0x00008000,
+       0x00010000, 0xa5f2b3ac
+};
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_length01 = 0x0000ab4a ;
+#else
+uint32_t risc_code_length01 = 0x0000ab4a ;
+#endif
+
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_addr02 = 0x0010e000  ;
+#else
+uint32_t risc_code_addr02 = 0x0010e000 ;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_code02[] = {
+#else
+uint32_t risc_code02[] = {
+#endif
+       0x00000000, 0x00000000, 0x0010e000, 0x000014ff,
+       0x00000000, 0x00000000, 0x00020000, 0x000008c0,
+       0x836c0580, 0x00000003, 0x02020000, 0x001002e3,
+       0x42000000, 0x0010b4bb, 0x50000000, 0x800001c0,
+       0x04020956, 0x0401f923, 0x0401fbe3, 0x0401fb5c,
+       0x0201f800, 0x00020718, 0x0201f800, 0x0002057b,
+       0x0401f7f0, 0x59b800ea, 0x82000d00, 0xf0000038,
+       0x02020000, 0x00100a7a, 0x8c000510, 0x02000000,
+       0x00100a79, 0x59ba60e0, 0x81300182, 0x0402104e,
+       0x04002030, 0x8532653e, 0x59300406, 0x82000580,
+       0x00000003, 0x04020028, 0x59300203, 0x82000580,
+       0x00000004, 0x04020024, 0x59325808, 0x59300402,
+       0x4a025a04, 0x00000103, 0x900001c0, 0x48025806,
+       0x497a5807, 0x497a5c09, 0x5930001f, 0x80000540,
+       0x02020800, 0x00100d56, 0x59300004, 0x8c00053e,
+       0x04020010, 0x0401fa88, 0x59326809, 0x0201f800,
+       0x0002077d, 0x5934000f, 0x5934140b, 0x80081040,
+       0x04001002, 0x480a6c0b, 0x80000540, 0x04020a10,
+       0x59b800ea, 0x8c000510, 0x040207d7, 0x1c01f000,
+       0x0201f800, 0x00106f60, 0x040007ef, 0x0201f000,
+       0x00100a65, 0x42027000, 0x00000055, 0x0401f027,
+       0x83326500, 0x3fffffff, 0x59300406, 0x82000580,
+       0x00000003, 0x04020015, 0x59325808, 0x59326809,
+       0x59301402, 0x4a025a04, 0x00000103, 0x900811c0,
+       0x480a5806, 0x497a5c09, 0x497a5807, 0x0401fa62,
+       0x0201f800, 0x0002077d, 0x5934000f, 0x5934140b,
+       0x80081040, 0x04001002, 0x480a6c0b, 0x80000540,
+       0x040209eb, 0x0401f7db, 0x42027000, 0x00000054,
+       0x0401f00a, 0x83300500, 0x60000000, 0x02000000,
+       0x00100a68, 0x81326580, 0x8000013a, 0x82000400,
+       0x00100a80, 0x50027000, 0x59300c06, 0x82040580,
+       0x00000002, 0x02000000, 0x00100a65, 0x59300004,
+       0x8c00053e, 0x04020004, 0x0201f800, 0x000207a1,
+       0x0401f7c4, 0x0201f800, 0x00106f60, 0x040007fb,
+       0x0201f000, 0x00100a65, 0x59325808, 0x412c7000,
+       0x58380a04, 0x82040500, 0x0000000f, 0x82000c00,
+       0x001010bd, 0x50044000, 0x0c01f001, 0x00100dd9,
+       0x00100dd9, 0x0002009f, 0x00100dd9, 0x00100dd9,
+       0x00100dd9, 0x00100dd9, 0x00100dd9, 0x000200af,
+       0x00100ded, 0x00100dd9, 0x00100dd9, 0x00100ddb,
+       0x00100dd9, 0x00100dd9, 0x00100dd9, 0x5838040a,
+       0x8c000500, 0x02000800, 0x001005d8, 0x50200000,
+       0x80387c00, 0x583c1002, 0x583c2800, 0x583c2001,
+       0x58380a07, 0x5838300f, 0x59303807, 0x58384c08,
+       0x5838000d, 0x48026012, 0x0401f010, 0x5838020a,
+       0x8c000502, 0x02000000, 0x00100dd9, 0x50200000,
+       0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002,
+       0x592c0a07, 0x592c4c08, 0x592c300f, 0x59303807,
+       0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f,
+       0x480a6010, 0x481a6011, 0x80040840, 0x4806600d,
+       0x02020000, 0x00100e1a, 0x841c3d40, 0x481e6007,
+       0x1c01f000, 0x41787800, 0x59325808, 0x592c0c0a,
+       0x8c040d02, 0x02000000, 0x00100f8c, 0x592c000d,
+       0x592c100f, 0x592c0a04, 0x480a6011, 0x48026012,
+       0x48026013, 0x412c3000, 0x82040500, 0x0000000f,
+       0x82000400, 0x001010bd, 0x50003800, 0x501c0000,
+       0x401c1000, 0x592c1a07, 0x4802600a, 0x481a600b,
+       0x480a600c, 0x480e600d, 0x843c7d4a, 0x403c1000,
+       0x1c01f000, 0x41787800, 0x497a6012, 0x592c0a04,
+       0x412c3000, 0x592c1a07, 0x82040500, 0x0000000f,
+       0x82000400, 0x001010bd, 0x50004000, 0x50200000,
+       0x40201000, 0x4802600a, 0x481a600b, 0x480a600c,
+       0x480e600d, 0x80000580, 0x483e6004, 0x1c01f000,
+       0x4c000000, 0x4df00000, 0x0201f800, 0x00020729,
+       0x0401f005, 0x4c000000, 0x4df00000, 0x0401ff16,
+       0x0401f001, 0x5c03e000, 0x5c000000, 0x1801f000,
+       0x4203e000, 0xb0100000, 0x41fc0000, 0x82000500,
+       0x00000011, 0x0c01f001, 0x0002012a, 0x00020697,
+       0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+       0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+       0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+       0x0002012a, 0x0002012a, 0x0010115a, 0x0002012c,
+       0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+       0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+       0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+       0x0002012a, 0x0002012a, 0x0201f800, 0x001005d8,
+       0x0201f800, 0x00020697, 0x0201f000, 0x0010115a,
+       0x42000000, 0x0010b4c1, 0x50000000, 0x8c000504,
+       0x04000014, 0x42000000, 0x0010b4c1, 0x50000000,
+       0x8c000502, 0x04020002, 0x1c01f000, 0x4df00000,
+       0x4203e000, 0x50000000, 0x42034000, 0x0010b4a4,
+       0x59a0001d, 0x59a1d81e, 0x84000502, 0x4803401d,
+       0x58ec0009, 0x0801f800, 0x5c03e000, 0x1c01f000,
+       0x04027002, 0x04026002, 0x1c01f000, 0x4df00000,
+       0x4203e000, 0x50000000, 0x0201f800, 0x001007e4,
+       0x04000010, 0x412dd800, 0x48efc857, 0x0201f800,
+       0x00103b28, 0x42034000, 0x0010b4a4, 0x49a1d80b,
+       0x48ef401e, 0x59a0001d, 0x84000544, 0x4803401d,
+       0x0201f800, 0x00102214, 0x0201f800, 0x00102233,
+       0x5c03e000, 0x1c01f000, 0x4da00000, 0x4df00000,
+       0x4203e000, 0x50000000, 0x04006051, 0x40001000,
+       0x42034000, 0x0010b4a4, 0x59a01818, 0x800c19c0,
+       0x04020008, 0x59a0381b, 0x801c39c0, 0x02000800,
+       0x001005d8, 0x59a0041c, 0x801c3c00, 0x0401f00c,
+       0x59a00419, 0x82000400, 0x00000002, 0x48034419,
+       0x82000c80, 0x00000013, 0x04001003, 0x497b4419,
+       0x41780000, 0x59a03816, 0x801c3c00, 0x80081040,
+       0x480b4017, 0x581c0200, 0x4803c021, 0x581c0401,
+       0x4803c022, 0x581c0201, 0x4803c023, 0x581c0400,
+       0x4803c020, 0x900001c0, 0x82000540, 0x00000012,
+       0x4803c011, 0x59e00017, 0x8c000508, 0x04000003,
+       0x4a03c017, 0x00000002, 0x4203e000, 0x30000001,
+       0x800c19c0, 0x04000007, 0x800c1840, 0x480f4018,
+       0x0402001f, 0x497b4419, 0x497b4219, 0x0401f01c,
+       0x800811c0, 0x0402000b, 0x4d2c0000, 0x59a2581b,
+       0x0201f800, 0x001007f4, 0x5c025800, 0x497b401b,
+       0x497b401a, 0x497b441c, 0x497b421c, 0x0401f010,
+       0x59a0041c, 0x82000400, 0x00000002, 0x82000c80,
+       0x00000012, 0x4803441c, 0x04001009, 0x4d2c0000,
+       0x59a2581b, 0x592c3813, 0x481f401b, 0x497b441c,
+       0x0201f800, 0x001007f4, 0x5c025800, 0x5c03e000,
+       0x5c034000, 0x1c01f000, 0x59a80005, 0x82000500,
+       0x00000003, 0x02020000, 0x00104315, 0x59340400,
+       0x82000580, 0x00000606, 0x02020000, 0x001042e6,
+       0x5934000d, 0x80027d40, 0x02020000, 0x00104321,
+       0x0401f803, 0x80000580, 0x1c01f000, 0x5934000f,
+       0x59341203, 0x80080540, 0x0402006f, 0x5934020b,
+       0x5934140b, 0x80080480, 0x0402106b, 0x0201f800,
+       0x0002075a, 0x04000064, 0x80081000, 0x592c0406,
+       0x480a6c0b, 0x49366009, 0x492e6008, 0x4a026406,
+       0x00000003, 0x4a026403, 0x00000040, 0x800000c2,
+       0x800018c4, 0x800c0400, 0x48026206, 0x592c0808,
+       0x592c1809, 0x592c020a, 0x48066017, 0x480e6018,
+       0x8c000502, 0x04000030, 0x4a026203, 0x00000004,
+       0x592c0207, 0x80000040, 0x04020020, 0x59a80005,
+       0x8c000514, 0x42000000, 0x00000055, 0x04020003,
+       0x42000000, 0x00000033, 0x80000040, 0x040207ff,
+       0x592c0204, 0x82000500, 0x000000ff, 0x82000580,
+       0x00000018, 0x04020011, 0x592c180f, 0x59300007,
+       0x82000540, 0x00000091, 0x480e6011, 0x48026007,
+       0x42000000, 0x80000004, 0x48026004, 0x59bc00ea,
+       0x8c000516, 0x040207fe, 0x83300400, 0x20000000,
+       0x480378e1, 0x1c01f000, 0x0401fe78, 0x59300007,
+       0x8400054e, 0x48026007, 0x592c1a04, 0x820c1d00,
+       0x000000ff, 0x820c0580, 0x00000048, 0x04000017,
+       0x0401f7ec, 0x8c000500, 0x04020ecb, 0x4a026203,
+       0x00000002, 0x59a80805, 0x82040500, 0x00000600,
+       0x04020012, 0x42000000, 0x00000030, 0x80000040,
+       0x040207ff, 0x592c1a04, 0x820c1d00, 0x000000ff,
+       0x820c0580, 0x00000018, 0x040007da, 0x820c0580,
+       0x00000048, 0x040207d7, 0x42000800, 0x80000804,
+       0x0201f000, 0x00106721, 0x8c040d12, 0x42000000,
+       0x00000010, 0x040207ee, 0x42000000, 0x00000051,
+       0x0401f7eb, 0x800811c0, 0x04020003, 0x4a026a03,
+       0x00000001, 0x59340010, 0x492e6810, 0x80000d40,
+       0x04020003, 0x492e680f, 0x1c01f000, 0x492c0800,
+       0x1c01f000, 0x83440c80, 0x00000800, 0x04021009,
+       0x83440400, 0x0010ac00, 0x50000000, 0x80000540,
+       0x04000004, 0x40026800, 0x80000580, 0x1c01f000,
+       0x82000540, 0x00000001, 0x1c01f000, 0x59340203,
+       0x80000540, 0x0402004b, 0x4d300000, 0x4d2c0000,
+       0x5934000f, 0x80025d40, 0x04000044, 0x0201f800,
+       0x0002075a, 0x0400003f, 0x592c0000, 0x4802680f,
+       0x80000540, 0x04020002, 0x48026810, 0x592c2a04,
+       0x80081000, 0x480a6c0b, 0x49366009, 0x492e6008,
+       0x82142d00, 0x000000ff, 0x82140580, 0x00000012,
+       0x04000035, 0x4a026406, 0x00000003, 0x4a026403,
+       0x00000040, 0x592c0406, 0x800000c2, 0x800018c4,
+       0x800c0400, 0x48026206, 0x592c0808, 0x592c1809,
+       0x592c020a, 0x48066017, 0x480e6018, 0x8c000502,
+       0x02000000, 0x0010474d, 0x4a026203, 0x00000004,
+       0x592c0207, 0x80000040, 0x02020000, 0x00104740,
+       0x82140580, 0x00000018, 0x02020000, 0x00104740,
+       0x592c180f, 0x59300007, 0x82000540, 0x00000091,
+       0x480e6011, 0x48026007, 0x42000000, 0x80000004,
+       0x48026004, 0x59bc00ea, 0x8c000516, 0x040207fe,
+       0x83300400, 0x20000000, 0x480378e1, 0x5934020b,
+       0x5934140b, 0x80080480, 0x040017be, 0x0401f003,
+       0x4a026a03, 0x00000001, 0x5c025800, 0x5c026000,
+       0x1c01f000, 0x497a5800, 0x49325809, 0x4a026406,
+       0x00000006, 0x4a026203, 0x00000007, 0x0401f802,
+       0x0401f7ef, 0x59a80021, 0x800001c0, 0x02020000,
+       0x0010476f, 0x59a80005, 0x8c000504, 0x02020000,
+       0x0010476b, 0x59340200, 0x8c000518, 0x02020000,
+       0x00104767, 0x592c0a0c, 0x48066202, 0x4a025a06,
+       0x00000000, 0x8c000508, 0x02020000, 0x00104763,
+       0x4d3c0000, 0x417a7800, 0x0401fbdf, 0x5c027800,
+       0x1c01f000, 0x592c0404, 0x8c00051e, 0x02020000,
+       0x00104ce4, 0x59980022, 0x80000540, 0x04000017,
+       0x592c0a06, 0x592c0409, 0x80040540, 0x04020013,
+       0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e,
+       0x02020000, 0x00104cf3, 0x59980022, 0x80000540,
+       0x0400000a, 0x82040580, 0x00000001, 0x04020007,
+       0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e,
+       0x02020000, 0x00104dca, 0x59980026, 0x497a5800,
+       0x80000540, 0x02020000, 0x00104e1d, 0x59d80105,
+       0x82000d00, 0x00018780, 0x02020000, 0x00104edb,
+       0x80000106, 0x82000500, 0x00000003, 0x0c01f001,
+       0x000202f0, 0x00104e1d, 0x000202f6, 0x00020341,
+       0x592c0001, 0x492fb107, 0x80000d40, 0x02020000,
+       0x00104ddb, 0x1c01f000, 0x592c0001, 0x492fb107,
+       0x80000d40, 0x02020000, 0x00104de8, 0x59da5908,
+       0x835c0480, 0x00000020, 0x0400102c, 0x0402b034,
+       0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500,
+       0x00018780, 0x02020000, 0x00104edb, 0x0400601f,
+       0x59d8010a, 0x59d8090a, 0x80040580, 0x040207fd,
+       0x800408e0, 0x599c1017, 0x8c081508, 0x04020028,
+       0x82040d40, 0x00000013, 0x5998002b, 0x4807c011,
+       0x84000500, 0x4803302b, 0x59e00017, 0x8c000508,
+       0x04020004, 0x4203e000, 0x30000001, 0x1c01f000,
+       0x4a03c017, 0x00000003, 0x82040500, 0x000000ff,
+       0x82000580, 0x0000001d, 0x040207f7, 0x4a03c017,
+       0x0000000d, 0x0401f7f4, 0x5998082b, 0x84040d40,
+       0x4807302b, 0x1c01f000, 0x496a5800, 0x412ed000,
+       0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+       0x48039000, 0x0400e7ca, 0x0401f7d0, 0x0402f7f7,
+       0x492fa807, 0x0400e7c6, 0x0401f7cc, 0x59e0000f,
+       0x59e0100f, 0x80081580, 0x040207fd, 0x81281580,
+       0x040007d4, 0x40025000, 0x82040d40, 0x0000001d,
+       0x0401f7d2, 0x59d80908, 0x45680800, 0x4006d000,
+       0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540,
+       0x00001200, 0x48039000, 0x02006000, 0x00104df8,
+       0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd,
+       0x900001c0, 0x82000540, 0x00000013, 0x4803c011,
+       0x5998002b, 0x84000500, 0x4803302b, 0x59e00017,
+       0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+       0x4203e000, 0x30000001, 0x59d80105, 0x82000500,
+       0x00018780, 0x02020000, 0x00104edb, 0x0202d000,
+       0x00104dfd, 0x592c0001, 0x492fb107, 0x80000d40,
+       0x02020000, 0x00104e10, 0x1c01f000, 0x59980020,
+       0x0c01f001, 0x00020370, 0x00020371, 0x00104e88,
+       0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000,
+       0x0402681e, 0x04006004, 0x599c0017, 0x8c000508,
+       0x04020865, 0x59980029, 0x80025d40, 0x0400000a,
+       0x0402d00b, 0x59980026, 0x80000040, 0x48033026,
+       0x592c0000, 0x492fb107, 0x48033029, 0x04020002,
+       0x48033028, 0x5c03e000, 0x1c01f000, 0x59d80105,
+       0x82000500, 0x00018780, 0x02020000, 0x00104edb,
+       0x42000000, 0x0010b855, 0x0201f800, 0x0010aa47,
+       0x5c03e000, 0x1c01f000, 0x5998002b, 0x8c000500,
+       0x0402003b, 0x0400e007, 0x59d80105, 0x82000500,
+       0x00018780, 0x02020000, 0x00104edb, 0x1c01f000,
+       0x59da5908, 0x835c0c80, 0x00000020, 0x04001003,
+       0x0400b029, 0x0400f02b, 0x496a5800, 0x412ed000,
+       0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+       0x48039000, 0x0400e7f3, 0x59d8010a, 0x59d8090a,
+       0x80040580, 0x040207fd, 0x800408e0, 0x599c1017,
+       0x8c081508, 0x04020022, 0x82040d40, 0x00000013,
+       0x4807c011, 0x59e00017, 0x8c000508, 0x0400000a,
+       0x4a03c017, 0x00000003, 0x82040500, 0x000000ff,
+       0x82000580, 0x0000001d, 0x04020003, 0x4a03c017,
+       0x0000000d, 0x4203e000, 0x30000001, 0x59d80105,
+       0x82000500, 0x00018780, 0x02020000, 0x00104edb,
+       0x1c01f000, 0x492fb007, 0x0400e7d2, 0x0401f7df,
+       0x492fa807, 0x0400e7cf, 0x0401f7dc, 0x84000500,
+       0x4803302b, 0x0400e7cb, 0x0401f7d8, 0x59e0000f,
+       0x59e0100f, 0x80081580, 0x040207fd, 0x81281580,
+       0x040007da, 0x40025000, 0x82040d40, 0x0000001d,
+       0x0401f7d8, 0x59e0000f, 0x59e0100f, 0x80080d80,
+       0x040207fd, 0x81280580, 0x04020002, 0x1c01f000,
+       0x400a5000, 0x900811c0, 0x82081540, 0x0000001c,
+       0x480bc011, 0x59e00017, 0x8c000508, 0x04000003,
+       0x4a03c017, 0x0000000c, 0x4203e000, 0x30000001,
+       0x1c01f000, 0x41700000, 0x0c01f001, 0x00105420,
+       0x000203fc, 0x00105420, 0x00105421, 0x0010541e,
+       0x0010541e, 0x0010541e, 0x0010541e, 0x001058b0,
+       0x04010037, 0x59980006, 0x80000540, 0x0402003c,
+       0x0402c01c, 0x4202f800, 0x00000010, 0x4df00000,
+       0x4203e000, 0x50000000, 0x49db3005, 0x59da5808,
+       0x592c0204, 0x497a5800, 0x497a5801, 0x82000500,
+       0x000000ff, 0x82000c80, 0x00000079, 0x04021036,
+       0x0c01f839, 0x5c03e000, 0x817ef840, 0x04000009,
+       0x836c0580, 0x00000003, 0x04020006, 0x83700580,
+       0x00000001, 0x04020010, 0x0401001b, 0x0400c7e8,
+       0x0400f94a, 0x0400b134, 0x59d40005, 0x82000500,
+       0x43018780, 0x02020000, 0x0010583f, 0x59d80005,
+       0x82000500, 0x43018780, 0x02020000, 0x00105846,
+       0x1c01f000, 0x83700580, 0x00000003, 0x02000800,
+       0x00105421, 0x83700580, 0x00000001, 0x040207ed,
+       0x04010005, 0x0400c7d2, 0x0401f7ea, 0x4202f800,
+       0x00000010, 0x4df00000, 0x4203e000, 0x50000000,
+       0x49d73005, 0x59d65808, 0x0401f7ce, 0x4df00000,
+       0x4203e000, 0x50000000, 0x40025800, 0x592c0204,
+       0x497b3005, 0x497b3006, 0x4202f800, 0x00000010,
+       0x0401f7c7, 0x0201f800, 0x00105491, 0x5c03e000,
+       0x0401f7d4, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105527, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x001054a1,
+       0x00105491, 0x00105491, 0x00105491, 0x00105551,
+       0x00105491, 0x00105491, 0x00105491, 0x000204ef,
+       0x00105491, 0x001056b4, 0x00105491, 0x00105491,
+       0x00105491, 0x000204c2, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x001054c9, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x001057d3, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x0010581e, 0x00105491,
+       0x001054bb, 0x00105491, 0x00105797, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105765, 0x00105491,
+       0x00105765, 0x00105872, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105725,
+       0x00105855, 0x00105491, 0x00105865, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x00105491, 0x00105491,
+       0x00105491, 0x00105491, 0x592c0204, 0x80000110,
+       0x02000000, 0x00105499, 0x80000040, 0x04000009,
+       0x48033002, 0x492f3003, 0x492f3004, 0x4a033008,
+       0x000204d0, 0x4202e000, 0x00000003, 0x1c01f000,
+       0x592c0406, 0x82000c80, 0x0000199a, 0x02021000,
+       0x001054a9, 0x59a80021, 0x80000540, 0x02020000,
+       0x001054d7, 0x592e8a06, 0x83440c80, 0x000007f0,
+       0x02021000, 0x001054a9, 0x83440400, 0x0010ac00,
+       0x50000000, 0x80026d40, 0x02000000, 0x001054db,
+       0x59340002, 0x592c0810, 0x80040580, 0x82000500,
+       0x00ffffff, 0x02020000, 0x001054a9, 0x0401fccf,
+       0x02020000, 0x001054de, 0x1c01f000, 0x592c0204,
+       0x80000110, 0x02000000, 0x00105499, 0x80000040,
+       0x0402000b, 0x592c040a, 0x8c000504, 0x04000010,
+       0x592c0207, 0x82000c80, 0x00001001, 0x02021000,
+       0x001054a9, 0x0201f000, 0x0010588a, 0x48033002,
+       0x492f3003, 0x492f3004, 0x4a033008, 0x00020507,
+       0x4202e000, 0x00000003, 0x1c01f000, 0x592c0406,
+       0x82000c80, 0x0000199a, 0x02021000, 0x001054a9,
+       0x592e8a06, 0x417a7800, 0x0401fd37, 0x02020000,
+       0x00105658, 0x59340002, 0x592c0808, 0x80040580,
+       0x82000500, 0x00ffffff, 0x02020000, 0x001054a9,
+       0x497a5808, 0x592e6009, 0x83300580, 0xffffffff,
+       0x02000000, 0x00105618, 0x83300480, 0x0010d1c0,
+       0x02001000, 0x00105675, 0x59a8000b, 0x81300480,
+       0x02021000, 0x00105675, 0x592c240a, 0x49366009,
+       0x8c10251c, 0x02020000, 0x00105606, 0x59a80068,
+       0x8c000510, 0x02020000, 0x0010568e, 0x59a80821,
+       0x800409c0, 0x02020000, 0x001055ec, 0x59a80805,
+       0x8c040d04, 0x02020000, 0x0010567f, 0x59340200,
+       0x8c000518, 0x02020000, 0x00105670, 0x59300c06,
+       0x82040580, 0x00000006, 0x02020000, 0x00105610,
+       0x59300414, 0x8c000516, 0x02020000, 0x0010567a,
+       0x8c102508, 0x02020000, 0x0010a5b8, 0x59300808,
+       0x4a025a06, 0x00000000, 0x800409c0, 0x02020000,
+       0x001055e7, 0x592c0a0c, 0x48066202, 0x492e6008,
+       0x0401f14d, 0x4df00000, 0x4203e000, 0x50000000,
+       0x0402b00b, 0x835c0480, 0x00000020, 0x0400100d,
+       0x815eb840, 0x416a5800, 0x592ed000, 0x492fb007,
+       0x497a5800, 0x497a5801, 0x0400b7f7, 0x59d80005,
+       0x82000500, 0x43018780, 0x02020000, 0x00105846,
+       0x5c03e000, 0x1c01f000, 0x4df00000, 0x4203e000,
+       0x50000000, 0x0402f00b, 0x835c0480, 0x00000020,
+       0x0400100d, 0x815eb840, 0x416a5800, 0x592ed000,
+       0x492fa807, 0x497a5800, 0x497a5801, 0x0400f7f7,
+       0x59d40005, 0x82000500, 0x43018780, 0x02020000,
+       0x0010583f, 0x5c03e000, 0x1c01f000, 0x4df00000,
+       0x4203e000, 0x50000000, 0x59940024, 0x80000540,
+       0x04000112, 0x4c000000, 0x42000000, 0x00001000,
+       0x50000000, 0x82000480, 0x24320001, 0x04020015,
+       0x42000800, 0x00000064, 0x80040840, 0x04000007,
+       0x4a030000, 0x00000001, 0x40000000, 0x59800000,
+       0x8c000500, 0x040007f9, 0x04000008, 0x42000800,
+       0x00007a01, 0x50040000, 0x8c000510, 0x04000003,
+       0x84000510, 0x44000800, 0x4a030000, 0x00000000,
+       0x59e00002, 0x8c00051e, 0x0402001b, 0x42000000,
+       0x00001000, 0x50000000, 0x82000480, 0x24320002,
+       0x04020015, 0x42000800, 0x00000064, 0x80040840,
+       0x04000007, 0x4a030000, 0x00000001, 0x40000000,
+       0x59800000, 0x8c000500, 0x040007f9, 0x04000008,
+       0x42000800, 0x00007a17, 0x50040000, 0x8c00050e,
+       0x04020003, 0x8400054e, 0x44000800, 0x4a030000,
+       0x00000000, 0x5c000000, 0x5994781a, 0x48032825,
+       0x803c0480, 0x04001004, 0x04000003, 0x4803281a,
+       0x0401f022, 0x41787800, 0x803c7800, 0x82000400,
+       0x000003e8, 0x040027fd, 0x4803281a, 0x59a80024,
+       0x803c1400, 0x480b5024, 0x803c0040, 0x04000002,
+       0x483fc857, 0x59e40852, 0x59a80025, 0x80040580,
+       0x04000004, 0x480bc857, 0x59e40052, 0x48035025,
+       0x59940026, 0x803c0400, 0x48032826, 0x0201f800,
+       0x00106021, 0x59940000, 0x82000580, 0x00000000,
+       0x04020006, 0x59940026, 0x48032827, 0x497b2826,
+       0x4a032800, 0x00000001, 0x4c0c0000, 0x59940007,
+       0x80000d40, 0x0400001d, 0x59941006, 0x59940025,
+       0x80081c80, 0x04001004, 0x04000003, 0x480f2806,
+       0x0401f016, 0x80040840, 0x48072807, 0x82040580,
+       0x000003e8, 0x04020007, 0x4c040000, 0x4c0c0000,
+       0x59940008, 0x0801f800, 0x5c001800, 0x5c000800,
+       0x800409c0, 0x04020004, 0x59940008, 0x0801f800,
+       0x0401f006, 0x400c0000, 0x820c1c00, 0x0000000a,
+       0x040027ed, 0x480f2806, 0x5c001800, 0x4d180000,
+       0x59c40008, 0x8c000534, 0x04020025, 0x417a3000,
+       0x83947c00, 0x00000009, 0x583c0001, 0x80000d40,
+       0x04020008, 0x823c7c00, 0x00000003, 0x811a3000,
+       0x83180580, 0x00000005, 0x040207f8, 0x0401f018,
+       0x583c1000, 0x59940025, 0x80080480, 0x04001005,
+       0x04000004, 0x48007800, 0x80000040, 0x04021010,
+       0x80040840, 0x48047801, 0x04000008, 0x82000400,
+       0x0000000a, 0x48007800, 0x040027fa, 0x82040500,
+       0x0000007f, 0x0401f7e8, 0x583c0002, 0x4c3c0000,
+       0x0801f800, 0x5c007800, 0x0401f7e3, 0x5c023000,
+       0x59940019, 0x80001540, 0x04000008, 0x04002007,
+       0x59940025, 0x80080480, 0x497b2819, 0x04001003,
+       0x04000002, 0x48032819, 0x59940004, 0x80000d40,
+       0x0400002a, 0x4c040000, 0x5994001c, 0x80000d40,
+       0x04000013, 0x5994101b, 0x59940025, 0x80080480,
+       0x04001005, 0x04000004, 0x4803281b, 0x80000040,
+       0x0402100b, 0x80040840, 0x4807281c, 0x04020004,
+       0x5994001d, 0x0801f800, 0x0401f005, 0x82000400,
+       0x0000000a, 0x4803281b, 0x040027f7, 0x5c000800,
+       0x59941003, 0x59940025, 0x80080480, 0x04001005,
+       0x04000004, 0x48032803, 0x80000040, 0x0402100b,
+       0x80040840, 0x48072804, 0x04020004, 0x59940005,
+       0x0801f800, 0x0401f005, 0x82000400, 0x0000000a,
+       0x48032803, 0x040027f7, 0x5994001f, 0x80000d40,
+       0x04000013, 0x5994101e, 0x59940025, 0x80080480,
+       0x04001005, 0x04000004, 0x4803281e, 0x80000040,
+       0x0402100b, 0x80040840, 0x4807281f, 0x04020004,
+       0x59940020, 0x0801f800, 0x0401f005, 0x82000400,
+       0x00000001, 0x4803281e, 0x040027f7, 0x59940022,
+       0x80000d40, 0x04000013, 0x59941021, 0x59940025,
+       0x80080480, 0x04001005, 0x04000004, 0x48032821,
+       0x80000040, 0x0402100b, 0x80040840, 0x48072822,
+       0x04020004, 0x59940023, 0x0801f800, 0x0401f005,
+       0x82000400, 0x0000000a, 0x48032821, 0x040027f7,
+       0x59940824, 0x59940025, 0x80040480, 0x02001800,
+       0x001005d8, 0x48032824, 0x59940000, 0x0c01f001,
+       0x00105fb5, 0x00105fb7, 0x00105fdd, 0x59940024,
+       0x80000000, 0x48032824, 0x4203e000, 0x70000000,
+       0x1c01f000, 0x592c0406, 0x800000c2, 0x800008c4,
+       0x80040c00, 0x592c040a, 0x48066206, 0x82000d00,
+       0x00000003, 0x02000000, 0x0010615e, 0x8c000500,
+       0x04020029, 0x8c00051e, 0x02000000, 0x00106139,
+       0x82000d00, 0x000000c0, 0x02020000, 0x0010612f,
+       0x82000d00, 0x00002020, 0x02020000, 0x0010612c,
+       0x813e79c0, 0x02020000, 0x0010612c, 0x592c0c0c,
+       0x800409c0, 0x02020000, 0x0010612c, 0x59300a03,
+       0x82040d80, 0x00000007, 0x02020000, 0x0010612c,
+       0x4a026203, 0x00000003, 0x4a026403, 0x00000043,
+       0x0201f800, 0x000200c9, 0x82080d40, 0x80003465,
+       0x48066004, 0x497a6000, 0x59bc00ea, 0x8c000516,
+       0x040207fe, 0x83300400, 0xa0000000, 0x480378e1,
+       0x1c01f000, 0x8c000502, 0x02020000, 0x00106181,
+       0x8c00051e, 0x0400000e, 0x82000d00, 0x000000c0,
+       0x04000005, 0x82040d80, 0x000000c0, 0x02020000,
+       0x00106186, 0x82000d00, 0x00002020, 0x82040d80,
+       0x00002020, 0x02000000, 0x0010614d, 0x592c0207,
+       0x80000040, 0x02020000, 0x00106157, 0x592c180d,
+       0x800c19c0, 0x02020000, 0x00106157, 0x592c180f,
+       0x59300007, 0x82000540, 0x00000011, 0x480e6011,
+       0x48026007, 0x4a026203, 0x00000004, 0x4a026403,
+       0x00000042, 0x42000800, 0x80002001, 0x0401f02a,
+       0x5c000000, 0x4c000000, 0x4803c857, 0x4807c857,
+       0x0401f003, 0x42000800, 0x00000001, 0x59325808,
+       0x832c0500, 0x00ff0000, 0x0400000d, 0x592c0000,
+       0x48065a06, 0x48026008, 0x592c040a, 0x8c000510,
+       0x04020008, 0x0201f800, 0x000202ce, 0x417a7800,
+       0x59300008, 0x80025d40, 0x0402078f, 0x1c01f000,
+       0x456a5800, 0x412ed000, 0x815eb800, 0x59c80000,
+       0x82000540, 0x00001200, 0x48039000, 0x0401f7f4,
+       0x59840000, 0x80000540, 0x04020002, 0x1c01f000,
+       0x59840003, 0x80000540, 0x02020000, 0x001061fe,
+       0x1c01f000, 0x48066004, 0x59bc00ea, 0x8c000516,
+       0x040207fe, 0x83300400, 0x40000000, 0x480378e1,
+       0x1c01f000, 0x59bc00ea, 0x82001500, 0xb0000018,
+       0x02020000, 0x00106c81, 0x8c000510, 0x0400002a,
+       0x59bc10e0, 0x82080500, 0xfffff000, 0x0402000a,
+       0x80080108, 0x820a3500, 0x0000000f, 0x4803c857,
+       0x1201f000, 0x00106c87, 0x84000510, 0x48026004,
+       0x0401f016, 0x840a653e, 0x59300004, 0x8c000520,
+       0x040007fa, 0x82000500, 0xfffefeff, 0x48026004,
+       0x8c08153e, 0x04020005, 0x42027000, 0x00000013,
+       0x0401f859, 0x0401f009, 0x59300004, 0x8c000514,
+       0x04000003, 0x0401ffb0, 0x0401f02f, 0x42027000,
+       0x00000049, 0x0401f850, 0x59bc00ea, 0x82001500,
+       0xb0000018, 0x02020000, 0x00106c81, 0x8c000510,
+       0x040207d8, 0x1c01f000, 0x83640480, 0x00000010,
+       0x0400101a, 0x41626000, 0x41580000, 0x59300a03,
+       0x82040d80, 0x00000000, 0x04000008, 0x83326400,
+       0x00000024, 0x81300c80, 0x040017f9, 0x42026000,
+       0x0010d1c0, 0x0401f7f6, 0x8166c840, 0x83300c00,
+       0x00000024, 0x80040480, 0x04021005, 0x4006c000,
+       0x4a026203, 0x00000008, 0x1c01f000, 0x837ac540,
+       0x0010d1c0, 0x0401f7fb, 0x42000000, 0x0010b854,
+       0x0201f800, 0x0010aa47, 0x4967c857, 0x80026580,
+       0x1c01f000, 0x83300480, 0x0010d1c0, 0x02001800,
+       0x001005d8, 0x41580000, 0x81300480, 0x0402100c,
+       0x04011000, 0x457a6000, 0x4a026202, 0x0000ffff,
+       0x83300400, 0x00000003, 0x4803c840, 0x4a03c842,
+       0x00000021, 0x8166c800, 0x1c01f000, 0x41540000,
+       0x81300480, 0x02021800, 0x001005d8, 0x04011000,
+       0x457a6000, 0x4a026202, 0x0000ffff, 0x83300400,
+       0x00000003, 0x4803c840, 0x4a03c842, 0x00000021,
+       0x59a80066, 0x49335065, 0x80000000, 0x48035066,
+       0x1c01f000, 0x4d340000, 0x59326809, 0x59300406,
+       0x82000500, 0x0000001f, 0x0c01f803, 0x5c026800,
+       0x1c01f000, 0x00107966, 0x00107979, 0x00107993,
+       0x000207c9, 0x001098f1, 0x0010990c, 0x0002083e,
+       0x00107966, 0x00107979, 0x001064ee, 0x001079ac,
+       0x00107966, 0x00107966, 0x00107966, 0x00107966,
+       0x00107966, 0x001095a1, 0x0010a6c2, 0x00107966,
+       0x00107966, 0x00107966, 0x00107966, 0x00107966,
+       0x00107966, 0x00107966, 0x00107966, 0x00107966,
+       0x00107966, 0x00107966, 0x00107966, 0x00107966,
+       0x00107966, 0x59300203, 0x82000c80, 0x0000000e,
+       0x02021800, 0x001005d8, 0x0c01f001, 0x001079aa,
+       0x00108592, 0x000207dd, 0x00108720, 0x001087b9,
+       0x001079aa, 0x001079aa, 0x001079aa, 0x00108577,
+       0x001079aa, 0x001079aa, 0x001079aa, 0x001079aa,
+       0x00108985, 0x83380480, 0x00000058, 0x04021007,
+       0x83380480, 0x00000040, 0x04001004, 0x4d2c0000,
+       0x0c01f803, 0x5c025800, 0x1c01f000, 0x0010861b,
+       0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+       0x0010861d, 0x001086bd, 0x0010861b, 0x0010861b,
+       0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+       0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+       0x0010861b, 0x0010861b, 0x001086c1, 0x000207ff,
+       0x0010861b, 0x001086c0, 0x001086c2, 0x59325808,
+       0x59300811, 0x59301402, 0x59340200, 0x8c00050e,
+       0x0402001c, 0x0401f826, 0x04000005, 0x4a025a04,
+       0x00000103, 0x497a5c09, 0x0401f009, 0x4a025a04,
+       0x00000103, 0x4a025a06, 0x00000000, 0x497a5c09,
+       0x800409c0, 0x02020800, 0x00108785, 0x48065807,
+       0x480a5c06, 0x0201f800, 0x000202c1, 0x5934000f,
+       0x5934140b, 0x80081040, 0x04001002, 0x480a6c0b,
+       0x80000540, 0x02020800, 0x00020253, 0x0401f75e,
+       0x592c020a, 0x8c000502, 0x040007e9, 0x800409c0,
+       0x040007e7, 0x592c0208, 0x8c00050e, 0x040207e4,
+       0x4933c857, 0x0201f000, 0x0010920f, 0x592c020a,
+       0x8c000500, 0x04000010, 0x59300015, 0x592c380f,
+       0x801c3c80, 0x0400000c, 0x4a025a06, 0x00000015,
+       0x8c1c3d3e, 0x04000005, 0x4a025a06, 0x00000007,
+       0x801c3880, 0x801c3800, 0x481fc857, 0x821c0d40,
+       0x00000000, 0x1c01f000, 0x59300203, 0x82003480,
+       0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001,
+       0x0010992b, 0x00020852, 0x00109fba, 0x00109fc8,
+       0x0002086e, 0x0010992b, 0x0010a0a8, 0x0002088d,
+       0x0010992b, 0x0010992b, 0x0010992b, 0x0010992b,
+       0x0010992b, 0x0010992b, 0x83380580, 0x00000013,
+       0x02020000, 0x00109f42, 0x59300403, 0x82027480,
+       0x00000044, 0x02021800, 0x001005d8, 0x82000480,
+       0x00000040, 0x02001800, 0x001005d8, 0x0c01f001,
+       0x00109f9e, 0x00020864, 0x00109fa0, 0x00109fb2,
+       0x59325808, 0x832c0500, 0x00ff0000, 0x04000005,
+       0x592c0c0a, 0x8c040d1a, 0x02020000, 0x00109fad,
+       0x0401fe91, 0x0401f710, 0x83380580, 0x00000048,
+       0x04000007, 0x83380580, 0x00000053, 0x02000000,
+       0x0010a04a, 0x0201f800, 0x001005d8, 0x5930001f,
+       0x59301011, 0x59300809, 0x58040a00, 0x8c040d0e,
+       0x02020000, 0x0010a026, 0x800811c0, 0x02020000,
+       0x0010a033, 0x5930001f, 0x80000540, 0x02020000,
+       0x0010a041, 0x59325808, 0x592c040a, 0x8c00051e,
+       0x02000000, 0x0010a01c, 0x42027000, 0x00000041,
+       0x0401f001, 0x83380480, 0x00000054, 0x02021800,
+       0x001005d8, 0x83380480, 0x00000040, 0x02001000,
+       0x0010a067, 0x0c01f001, 0x0010a073, 0x000208aa,
+       0x0010a07f, 0x0010a086, 0x0010a073, 0x0010a073,
+       0x0010a073, 0x0010a073, 0x0010a075, 0x0010a07a,
+       0x0010a07a, 0x0010a073, 0x0010a073, 0x0010a073,
+       0x0010a073, 0x0010a07a, 0x0010a073, 0x0010a07a,
+       0x0010a073, 0x0010a075, 0x4a026203, 0x00000001,
+       0x493a6403, 0x42000800, 0x80002042, 0x0401f672,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x14aa62b1,
+       0x00000000, 0x00000000, 0x00000000, 0x00000005,
+       0xfffffffb, 0x02800004, 0x00000000, 0x0000c000,
+       0x0000071d, 0x073fca5a, 0x0705a5a5, 0x01928009,
+       0x070ff0e1, 0x03800006, 0x04958010, 0x05308000,
+       0x05008000, 0x0600902f, 0x04a004dc, 0x0202f051,
+       0x042e4020, 0x018f021b, 0x033e5000, 0x03020000,
+       0x078d0018, 0x0493041a, 0x0092041c, 0x038a0305,
+       0x078b0303, 0x048e8010, 0x0678aae5, 0x06000001,
+       0x07818174, 0x040010e6, 0x0448e0e6, 0x04818010,
+       0x002fb008, 0x0448e0e6, 0x04818010, 0x060ff0e6,
+       0x00580401, 0x054880ff, 0x04818010, 0x022a5001,
+       0x030430d4, 0x06780043, 0x030e0000, 0x030450ff,
+       0x06780043, 0x03019000, 0x058185c6, 0x027c0045,
+       0x03020000, 0x06810037, 0x027c0045, 0x03040000,
+       0x068100c7, 0x027c0045, 0x03080000, 0x0781061e,
+       0x04908037, 0x029105c4, 0x010410a6, 0x0379ff41,
+       0x037fffff, 0x072d6000, 0x07601241, 0x050f80ff,
+       0x032fa009, 0x05600400, 0x050f80ff, 0x056c04ff,
+       0x068105dc, 0x073fa009, 0x06000001, 0x0279ff02,
+       0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff,
+       0x045c0402, 0x048185dc, 0x060ff0d0, 0x0179feff,
+       0x0700ffff, 0x057dfeff, 0x0700ffff, 0x078105be,
+       0x05600e41, 0x050f80ff, 0x032fa069, 0x07480000,
+       0x068105d0, 0x06780043, 0x070000f0, 0x0781005f,
+       0x037c00ff, 0x06000010, 0x0781005f, 0x038005cc,
+       0x0379ff00, 0x070fffff, 0x06780043, 0x07f00000,
+       0x075a0000, 0x020ef001, 0x028605ce, 0x05484000,
+       0x02a1819e, 0x062d6001, 0x002fb001, 0x070ff069,
+       0x01868072, 0x060ff079, 0x055c0441, 0x06810010,
+       0x012fb000, 0x060560fb, 0x03800078, 0x060ff079,
+       0x02868198, 0x070ff069, 0x055c0441, 0x06810010,
+       0x060560fb, 0x0400d0d0, 0x062d6002, 0x0648300d,
+       0x06810086, 0x070ff0d1, 0x062d6001, 0x045c040b,
+       0x06810089, 0x05488000, 0x04818086, 0x072e500c,
+       0x00208001, 0x05a004e1, 0x02800010, 0x062d6001,
+       0x07f00000, 0x07f00000, 0x070ff0d1, 0x0179feff,
+       0x070000ff, 0x055c040c, 0x058180bb, 0x0007b001,
+       0x03079041, 0x0307a000, 0x06600a79, 0x050f80ff,
+       0x053fa80a, 0x06000010, 0x072d5003, 0x078d0096,
+       0x0307c003, 0x0007d004, 0x0107e005, 0x0307f006,
+       0x02080007, 0x00081008, 0x01082009, 0x0308300a,
+       0x0008400b, 0x0308500c, 0x068d00a1, 0x0678007a,
+       0x07f00000, 0x010880ff, 0x03386000, 0x03010000,
+       0x072e6300, 0x020ef07f, 0x02860010, 0x070ff07d,
+       0x0450047c, 0x050f80ff, 0x002fa819, 0x068d00ae,
+       0x02080001, 0x00081002, 0x0448807a, 0x068100b5,
+       0x0379ff03, 0x070000ff, 0x01082003, 0x068d00b6,
+       0x02386004, 0x03010000, 0x072e6c00, 0x02800010,
+       0x06780043, 0x070000f0, 0x078105d7, 0x050020ff,
+       0x027c0002, 0x06000010, 0x078100c3, 0x038005d7,
+       0x0700c0d1, 0x0379ff0c, 0x070000ff, 0x0380008e,
+       0x0204a051, 0x06780043, 0x070000f0, 0x037c00ff,
+       0x06000010, 0x0781816a, 0x072d6000, 0x019485c0,
+       0x050fb056, 0x044880e6, 0x04818010, 0x060ff0d0,
+       0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff,
+       0x078105be, 0x05a00212, 0x0349c0e4, 0x0781811d,
+       0x070ff093, 0x050010ff, 0x070ff093, 0x045c0401,
+       0x058180db, 0x02046092, 0x04002046, 0x04600202,
+       0x00540401, 0x048280e6, 0x04500425, 0x070060ff,
+       0x0730ffff, 0x0700000f, 0x0742000f, 0x05810190,
+       0x07a005a6, 0x0648a002, 0x048180e9, 0x00047089,
+       0x070ff047, 0x045c0443, 0x077800ff, 0x07f00000,
+       0x0781818e, 0x07780047, 0x0500e000, 0x048185ad,
+       0x070ff006, 0x01860117, 0x0179fe47, 0x0700000f,
+       0x010480ff, 0x056c7048, 0x06818102, 0x007a0d4a,
+       0x04003801, 0x0220f001, 0x0180010f, 0x07608e48,
+       0x034a60ff, 0x0700f0ff, 0x074b88ff, 0x037000ff,
+       0x07000600, 0x05500448, 0x074d00ff, 0x045a044a,
+       0x0304a0ff, 0x070ff00f, 0x01540406, 0x05820117,
+       0x04950120, 0x05a001bd, 0x02868123, 0x0134bfff,
+       0x070fffff, 0x0104102e, 0x050fd041, 0x00800126,
+       0x0595011d, 0x05a001bd, 0x0186011d, 0x0202f00e,
+       0x052e4030, 0x040fd02f, 0x070fc0ff, 0x05a00218,
+       0x02800010, 0x0400e02f, 0x042e4020, 0x0202f051,
+       0x0004100e, 0x0004b00e, 0x050fd041, 0x024a6c46,
+       0x04500423, 0x050070ff, 0x03620024, 0x050080ff,
+       0x04004046, 0x0700500f, 0x03206000, 0x05601048,
+       0x0700a0ff, 0x0700900a, 0x070ff005, 0x04500446,
+       0x00540425, 0x04820157, 0x05601622, 0x050f80ff,
+       0x063fa032, 0x06000002, 0x03203000, 0x01204000,
+       0x03205000, 0x0120b000, 0x0320c000, 0x07601441,
+       0x050f80ff, 0x043fa852, 0x06000001, 0x070ff056,
+       0x056c02ff, 0x050fb0ff, 0x070560ff, 0x03079041,
+       0x05600e41, 0x050f80ff, 0x073fa011, 0x0600003d,
+       0x06780043, 0x07f00000, 0x065a007a, 0x010880ff,
+       0x04a001b6, 0x058d0150, 0x0208a04a, 0x0108b04b,
+       0x02386001, 0x03010000, 0x072e6300, 0x028000a8,
+       0x0500d00a, 0x05500405, 0x014a68ff, 0x070090ff,
+       0x0154040a, 0x0700c0ff, 0x0600a023, 0x0500b024,
+       0x02206001, 0x05601622, 0x050f80ff, 0x063fa04a,
+       0x06000002, 0x05601022, 0x050f80ff, 0x043fa819,
+       0x06000001, 0x0600a00d, 0x0180013c, 0x06780043,
+       0x070000f0, 0x050010ff, 0x027c0001, 0x07000030,
+       0x078105b4, 0x027c0001, 0x06000020, 0x078105b4,
+       0x038005cc, 0x054880ff, 0x06810010, 0x070ff056,
+       0x050fb0ff, 0x044880e5, 0x0581017d, 0x044880e6,
+       0x04818010, 0x00800183, 0x056c02ff, 0x050fb0ff,
+       0x070560ff, 0x072e5300, 0x044880e6, 0x04818010,
+       0x072d5003, 0x06780043, 0x07f00000, 0x010880ff,
+       0x058d0187, 0x03386005, 0x03010000, 0x033e6000,
+       0x0700000c, 0x052e5200, 0x02800010, 0x0120918e,
+       0x018004e4, 0x01209190, 0x018004e4, 0x00209192,
+       0x018004e4, 0x03209000, 0x018004e4, 0x01209196,
+       0x018004e4, 0x00209198, 0x018004e4, 0x02493075,
+       0x06810510, 0x0120919a, 0x018004e4, 0x06601e01,
+       0x050f80ff, 0x063fa029, 0x06000008, 0x02015010,
+       0x02016051, 0x00017051, 0x00011051, 0x05601a41,
+       0x050f80ff, 0x053fa83a, 0x06000008, 0x05600e41,
+       0x050f80ff, 0x01464000, 0x032fa00a, 0x07006011,
+       0x05007012, 0x04008013, 0x07009014, 0x0600a015,
+       0x0400b016, 0x0700c017, 0x07c00000, 0x072d5003,
+       0x06601479, 0x050f80ff, 0x048d01b9, 0x063fa051,
+       0x0600003e, 0x07c00000, 0x06005051, 0x0400e02c,
+       0x0660060e, 0x050f80ff, 0x032fa009, 0x0379ff00,
+       0x070000ff, 0x076c0000, 0x058101dd, 0x0660480e,
+       0x0500e0ff, 0x034000ff, 0x01540427, 0x0582020a,
+       0x03400005, 0x070ff005, 0x055c0428, 0x0481020e,
+       0x01680e05, 0x056c0405, 0x068181bf, 0x040f8029,
+       0x053fa809, 0x07000024, 0x06600649, 0x050f80ff,
+       0x032fa009, 0x0379ff00, 0x070000ff, 0x076c0000,
+       0x068181bf, 0x0400e049, 0x0340002d, 0x050f802b,
+       0x053fa80a, 0x06000016, 0x0660480e, 0x0302c0ff,
+       0x034000ff, 0x01540427, 0x0582020c, 0x072d6000,
+       0x0460040e, 0x050f80ff, 0x0104e0d1, 0x0379ff4e,
+       0x0700ffff, 0x062d6002, 0x032fa009, 0x0004d0d0,
+       0x074b004d, 0x07780000, 0x07ffff00, 0x055a044d,
+       0x070000ff, 0x00201008, 0x04002051, 0x06003051,
+       0x05304000, 0x07000060, 0x03205009, 0x07006022,
+       0x0460040e, 0x050f80ff, 0x032fa03a, 0x06603c0e,
+       0x050f80ff, 0x073fa00a, 0x07000027, 0x050010d1,
+       0x0460320e, 0x050f80ff, 0x012fa80a, 0x060ff00e,
+       0x055c042e, 0x04810210, 0x07c00000, 0x0400e026,
+       0x008001cb, 0x0202c026, 0x008001e6, 0x0500e02e,
+       0x008001e6, 0x0400e051, 0x01800209, 0x0349c0e4,
+       0x04810215, 0x07c00000, 0x013e4000, 0x070c0000,
+       0x07c00000, 0x013e4000, 0x03080000, 0x07c00000,
+       0x009702f4, 0x022a5002, 0x0790821d, 0x00910291,
+       0x030400a6, 0x0678aae5, 0x06000001, 0x00a1860e,
+       0x06600c40, 0x050f80ff, 0x032fa021, 0x074b0000,
+       0x076c0600, 0x07818293, 0x05600403, 0x050f80ff,
+       0x073fa009, 0x06000002, 0x0279ff04, 0x0700ffff,
+       0x010440d7, 0x0179fe44, 0x0700ffff, 0x045c0404,
+       0x07818295, 0x0349f044, 0x0681829e, 0x02495001,
+       0x06818297, 0x060ff079, 0x045c0440, 0x0781823c,
+       0x0644f07a, 0x002fb008, 0x060ff079, 0x045c0440,
+       0x07818241, 0x0644f07a, 0x002fb008, 0x0648f001,
+       0x07818288, 0x04600e40, 0x050f80ff, 0x06480001,
+       0x04810257, 0x0448e001, 0x04810273, 0x02460001,
+       0x0644f001, 0x012fa80a, 0x04008040, 0x05a004ee,
+       0x0286828c, 0x05a004d8, 0x062da001, 0x013e4000,
+       0x06000080, 0x06930013, 0x02920013, 0x02800010,
+       0x0644f001, 0x012fa80a, 0x020ef002, 0x00860275,
+       0x04600840, 0x050f80ff, 0x053fa809, 0x06000002,
+       0x05780105, 0x00800440, 0x017c0105, 0x05000400,
+       0x06818275, 0x06601e02, 0x050f80ff, 0x053fa809,
+       0x06000002, 0x04602a40, 0x050f80ff, 0x070ff005,
+       0x053fa809, 0x06000002, 0x055c0405, 0x06818275,
+       0x04008040, 0x0045e008, 0x05a004d8, 0x00800251,
+       0x0644f001, 0x012fa80a, 0x050020d8, 0x04600440,
+       0x050f80ff, 0x073fa00a, 0x06000001, 0x06480001,
+       0x07818281, 0x05308000, 0x03040000, 0x06009040,
+       0x04a004dc, 0x00800251, 0x06a0060e, 0x054b0800,
+       0x056a0700, 0x06600c40, 0x050f80ff, 0x032fa00a,
+       0x00800251, 0x013e4000, 0x06000080, 0x01209288,
+       0x018004e4, 0x06009008, 0x05308000, 0x05004000,
+       0x04a004dc, 0x00800251, 0x02209002, 0x008002e5,
+       0x03209000, 0x008002e5, 0x02209004, 0x008002e5,
+       0x04a002fd, 0x062da001, 0x05308000, 0x05002000,
+       0x06009040, 0x04a004dc, 0x02800013, 0x013e4000,
+       0x06000080, 0x02495001, 0x078182db, 0x04600840,
+       0x050f80ff, 0x053fa809, 0x06000001, 0x0721f000,
+       0x0349f003, 0x058102aa, 0x0245f01f, 0x06000002,
+       0x018602db, 0x07601400, 0x050f80ff, 0x012fa809,
+       0x06480001, 0x058102db, 0x06602440, 0x050f80ff,
+       0x012fa809, 0x020ef001, 0x038682db, 0x019b02db,
+       0x050020d8, 0x062da001, 0x06303002, 0x05000430,
+       0x04600440, 0x050f80ff, 0x073fa012, 0x06000001,
+       0x028f82bf, 0x050040d8, 0x062da001, 0x07601e00,
+       0x050f80ff, 0x073fa009, 0x06000001, 0x060ff004,
+       0x00540402, 0x048202d9, 0x06005051, 0x06006051,
+       0x06602240, 0x050f80ff, 0x063fa01a, 0x06000002,
+       0x06600a40, 0x050f80ff, 0x073fa00a, 0x07000003,
+       0x060ff040, 0x045a041f, 0x010eb0ff, 0x06930013,
+       0x02920013, 0x02800010, 0x04004002, 0x018002c9,
+       0x04a002fd, 0x062da001, 0x05308000, 0x07005000,
+       0x06009040, 0x04a004dc, 0x050080d8, 0x05a004e1,
+       0x062da001, 0x02800013, 0x050fd009, 0x050fd041,
+       0x013e4000, 0x06000080, 0x05308000, 0x03013000,
+       0x04a004dc, 0x010440d7, 0x0349f044, 0x048102f2,
+       0x062da001, 0x008f02f2, 0x03e00000, 0x062da001,
+       0x02800013, 0x0249c0e5, 0x06810013, 0x062da001,
+       0x07f00000, 0x07f00000, 0x033e5000, 0x070c0000,
+       0x018f02f6, 0x03800011, 0x050020d8, 0x04600440,
+       0x050f80ff, 0x073fa00a, 0x06000001, 0x07c00000,
+       0x002fb001, 0x03800306, 0x012fb000, 0x03075087,
+       0x068d0307, 0x03386000, 0x03020000, 0x04482075,
+       0x06810352, 0x0648a0e6, 0x07810347, 0x0642007f,
+       0x06810345, 0x0340007e, 0x060ff038, 0x0154047e,
+       0x02d00334, 0x0560027d, 0x050f80ff, 0x032fa009,
+       0x030ef000, 0x02860504, 0x0107d000, 0x05600800,
+       0x050f80ff, 0x032fa009, 0x03681e00, 0x04500420,
+       0x050f80ff, 0x073fa009, 0x0700003f, 0x03800311,
+       0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819,
+       0x078d0327, 0x02080001, 0x00081002, 0x0448807a,
+       0x0781032e, 0x0379ff03, 0x070000ff, 0x01082003,
+       0x068d032f, 0x02386004, 0x03010000, 0x072e6c00,
+       0x02800352, 0x0380033a, 0x0380033c, 0x0280033e,
+       0x02800340, 0x03800342, 0x03800344, 0x0727c005,
+       0x02800323, 0x0627c008, 0x02800323, 0x0627c00b,
+       0x02800323, 0x0627c00e, 0x02800323, 0x0727c011,
+       0x02800323, 0x03800314, 0x052e6800, 0x02800352,
+       0x044880e6, 0x07810533, 0x052e6200, 0x070ff088,
+       0x0179feff, 0x070fffff, 0x04818501, 0x060ff083,
+       0x0086836d, 0x033e6000, 0x07000003, 0x068d0352,
+       0x07286000, 0x07f00000, 0x078d0355, 0x038c0306,
+       0x0648c0e6, 0x05818372, 0x0448e0e6, 0x0781036a,
+       0x004920e6, 0x07810365, 0x07a0056f, 0x05001088,
+       0x00700101, 0x03100000, 0x00088001, 0x033e6000,
+       0x07000088, 0x03800560, 0x02386001, 0x07030000,
+       0x033e6000, 0x06000008, 0x028003f1, 0x02799075,
+       0x0500040f, 0x06810010, 0x06601479, 0x050080ff,
+       0x06309052, 0x0600003e, 0x02800376, 0x06602279,
+       0x050080ff, 0x05309812, 0x07000041, 0x0648007a,
+       0x0781037e, 0x04488075, 0x0581837e, 0x040f8008,
+       0x070fa009, 0x0049107a, 0x01a183f3, 0x00798075,
+       0x06000507, 0x05818521, 0x0448b075, 0x06810385,
+       0x02493075, 0x0681050e, 0x0249c0e6, 0x048183e0,
+       0x0648c0e6, 0x0581839a, 0x068d0389, 0x02386001,
+       0x07030000, 0x0049107a, 0x07810390, 0x020ef083,
+       0x0386039a, 0x06483075, 0x068103ef, 0x0678007a,
+       0x07000035, 0x03a184cf, 0x05308000, 0x07060000,
+       0x06009079, 0x04a004dc, 0x028003ef, 0x0448807a,
+       0x0681039e, 0x06483075, 0x058104f9, 0x0448d07a,
+       0x068103a2, 0x06483075, 0x058104f9, 0x068d03a2,
+       0x02386001, 0x07030000, 0x0444e07a, 0x0648307a,
+       0x048183c7, 0x0448707a, 0x068103ea, 0x0648f07a,
+       0x078103b2, 0x05a004cf, 0x04008079, 0x05a004ee,
+       0x008683c2, 0x05a004d8, 0x028003ef, 0x0560107b,
+       0x050f80ff, 0x032fa009, 0x0349c000, 0x058183c0,
+       0x04600e79, 0x050f80ff, 0x073fa00a, 0x0600003d,
+       0x06600a79, 0x050f80ff, 0x053fa80a, 0x06000010,
+       0x028003ef, 0x0046e07a, 0x028003ea, 0x06009008,
+       0x05308000, 0x05004000, 0x04a004dc, 0x028003ef,
+       0x0560167b, 0x050f80ff, 0x032fa011, 0x070ff000,
+       0x04500401, 0x030460ff, 0x060ff025, 0x00540446,
+       0x078203d1, 0x030460ff, 0x04092046, 0x05a00218,
+       0x06600679, 0x050f80ff, 0x00201007, 0x012fa80a,
+       0x0046047a, 0x034630ff, 0x050020ff, 0x06003051,
+       0x04600e79, 0x050f80ff, 0x073fa012, 0x06000001,
+       0x028003ef, 0x033e6a00, 0x0202000e, 0x02079051,
+       0x07000088, 0x078d03e4, 0x0744c000, 0x01088000,
+       0x03386006, 0x03010000, 0x02800010, 0x05a004cf,
+       0x05308000, 0x03020000, 0x06009079, 0x04a004dc,
+       0x033e6a00, 0x0302000a, 0x02079051, 0x02800010,
+       0x04603e79, 0x050f80ff, 0x032fa009, 0x070ff000,
+       0x0186040c, 0x057dfeff, 0x07ffffff, 0x0581040c,
+       0x050f8000, 0x012fa811, 0x0079fe02, 0x070000ff,
+       0x077d66ff, 0x060000dc, 0x0781840c, 0x060ff001,
+       0x0286840d, 0x064b0002, 0x06420002, 0x060ff002,
+       0x05500400, 0x050f80ff, 0x05004084, 0x073fa00a,
+       0x06000002, 0x07c00000, 0x04600201, 0x050f80ff,
+       0x073fa009, 0x06000001, 0x0079fe02, 0x070000ff,
+       0x077d72ff, 0x070000dd, 0x0781840c, 0x064b0002,
+       0x06420002, 0x06000001, 0x01800406, 0x0605004c,
+       0x0180041e, 0x0493041a, 0x04a004d5, 0x054bc450,
+       0x05810421, 0x01d00422, 0x01800421, 0x00800432,
+       0x00800434, 0x00800432, 0x008004a7, 0x0180043f,
+       0x00800434, 0x01800471, 0x00800432, 0x00800432,
+       0x008004ab, 0x00800432, 0x018004af, 0x008004c4,
+       0x01800488, 0x00800432, 0x00800432, 0x00209432,
+       0x018004e4, 0x0379ff50, 0x070fffff, 0x060ff079,
+       0x055c0450, 0x048104a4, 0x002fb008, 0x060ff079,
+       0x055c0450, 0x058104a3, 0x04a004c7, 0x0180049c,
+       0x0179fe50, 0x070fffff, 0x070050ff, 0x060ff079,
+       0x055c0405, 0x04810449, 0x002fb008, 0x060ff079,
+       0x055c0405, 0x078184a0, 0x070ff087, 0x017980ff,
+       0x06000507, 0x06818451, 0x02203040, 0x05002087,
+       0x0049d002, 0x0481046b, 0x04930458, 0x01257000,
+       0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030,
+       0x0304c050, 0x02400057, 0x06740057, 0x06000002,
+       0x06820016, 0x04002083, 0x07003084, 0x04004085,
+       0x06602279, 0x050f80ff, 0x063fa01a, 0x06000001,
+       0x05a004cf, 0x07a00578, 0x033e6a00, 0x0302000a,
+       0x062e5020, 0x003e4002, 0x07000a00, 0x028003f1,
+       0x07420003, 0x0781844e, 0x00798002, 0x06000507,
+       0x06818451, 0x0180045c, 0x05930478, 0x01257000,
+       0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030,
+       0x0304c050, 0x067800e6, 0x07000041, 0x0581047d,
+       0x07a00581, 0x04818016, 0x002fb008, 0x067800e6,
+       0x07000041, 0x04810483, 0x07a00581, 0x04818016,
+       0x062e5020, 0x003e4002, 0x07000a00, 0x03e00000,
+       0x02800010, 0x0379ff50, 0x070fffff, 0x060ff079,
+       0x055c0450, 0x0781848e, 0x0245507a, 0x002fb008,
+       0x060ff079, 0x055c0450, 0x07818493, 0x0245507a,
+       0x002fb008, 0x05600e50, 0x050f80ff, 0x012fa809,
+       0x02455001, 0x05600e50, 0x050f80ff, 0x012fa80a,
+       0x0080049d, 0x002fb008, 0x003e4002, 0x07000a00,
+       0x02800016, 0x079384a3, 0x062e5020, 0x042e4002,
+       0x002fb008, 0x013e4000, 0x05000e00, 0x02800016,
+       0x0179fe50, 0x070fffff, 0x010210ff, 0x02800016,
+       0x0179fe50, 0x070fffff, 0x050340ff, 0x0080049d,
+       0x0179fe50, 0x070fffff, 0x0102e0ff, 0x0760282e,
+       0x050f80ff, 0x05222000, 0x07223000, 0x05224000,
+       0x07225000, 0x07226000, 0x05227000, 0x05228000,
+       0x07229000, 0x0722a000, 0x0522b000, 0x063fa051,
+       0x07000011, 0x0202c026, 0x0522d000, 0x052e400c,
+       0x02800016, 0x030430d4, 0x062e5008, 0x00800176,
+       0x05600e50, 0x050f80ff, 0x032fa009, 0x03460000,
+       0x018004d2, 0x0246007a, 0x0045207a, 0x008004d0,
+       0x0246007a, 0x0600007a, 0x04600e79, 0x050f80ff,
+       0x032fa00a, 0x07c00000, 0x029284d5, 0x070500e1,
+       0x07c00000, 0x0245f008, 0x048404d9, 0x020e0008,
+       0x07c00000, 0x070ff009, 0x065a0008, 0x058404de,
+       0x020e0008, 0x07c00000, 0x058404e1, 0x020e0008,
+       0x07c00000, 0x05308000, 0x0500d000, 0x04a004dc,
+       0x04a004e9, 0x02800010, 0x052e4300, 0x072e500c,
+       0x073c3fff, 0x0700000f, 0x07c00000, 0x06602208,
+       0x050f80ff, 0x032fa011, 0x076a0000, 0x068184f7,
+       0x066a0001, 0x048104f7, 0x04002051, 0x07c00000,
+       0x00202001, 0x07c00000, 0x0648307a, 0x00a18608,
+       0x05a004cc, 0x05308000, 0x05001000, 0x06009079,
+       0x04a004dc, 0x03800560, 0x0249c0e6, 0x058104f9,
+       0x0280036d, 0x0648307a, 0x07818196, 0x05a004cf,
+       0x05308000, 0x03013000, 0x03209006, 0x04a004dc,
+       0x033e6000, 0x07030000, 0x02800345, 0x02490075,
+       0x0781051e, 0x04002089, 0x04780102, 0x07f00000,
+       0x05001088, 0x07a0056f, 0x04740101, 0x03100000,
+       0x060ff002, 0x045c0401, 0x0481851f, 0x00088001,
+       0x033e6000, 0x070000c0, 0x0380055c, 0x07f00000,
+       0x0220951f, 0x018004e4, 0x0648307a, 0x07810527,
+       0x06780075, 0x06000007, 0x0581852e, 0x06a00608,
+       0x06486075, 0x06818194, 0x02490075, 0x0781819a,
+       0x04487075, 0x05818536, 0x0280053d, 0x05308000,
+       0x03010000, 0x06009079, 0x04a004dc, 0x02800010,
+       0x0448e0e6, 0x04818352, 0x00800192, 0x05308000,
+       0x0500e000, 0x06009079, 0x04a004dc, 0x04008089,
+       0x05a004e1, 0x0380055c, 0x05a004cc, 0x05308000,
+       0x0700f000, 0x06009079, 0x07000088, 0x06a00545,
+       0x04a004dc, 0x02800010, 0x03386000, 0x07030000,
+       0x07f00000, 0x078d0548, 0x033e6a00, 0x0202000e,
+       0x02079051, 0x0448b075, 0x07810553, 0x02493075,
+       0x07810553, 0x05301005, 0x03010000, 0x03800555,
+       0x05301006, 0x03010000, 0x05002087, 0x06485002,
+       0x05818555, 0x0744c000, 0x01088000, 0x02086001,
+       0x07c00000, 0x05001088, 0x07a0056f, 0x0644c001,
+       0x00088001, 0x033e6a00, 0x0202000e, 0x004920e6,
+       0x05818565, 0x02079051, 0x078d0565, 0x060ff089,
+       0x034990ff, 0x0781056c, 0x03386005, 0x03010000,
+       0x02800010, 0x03386006, 0x03010000, 0x02800010,
+       0x078d056f, 0x03386000, 0x07030000, 0x07f00000,
+       0x068d0573, 0x070ff087, 0x074850ff, 0x05818574,
+       0x07c00000, 0x078d0578, 0x02386001, 0x07030000,
+       0x07f00000, 0x068d057c, 0x070ff087, 0x074850ff,
+       0x0581857d, 0x07c00000, 0x05002087, 0x0049d002,
+       0x05818590, 0x002fb008, 0x067800e6, 0x07000041,
+       0x002fb008, 0x05818590, 0x07a005a6, 0x0448e002,
+       0x07810593, 0x0648a002, 0x0481859d, 0x06486002,
+       0x06810597, 0x02400057, 0x056a02ff, 0x07c00000,
+       0x07a005a6, 0x06788102, 0x06000004, 0x05818590,
+       0x04002089, 0x070ff0d4, 0x045c0402, 0x077800ff,
+       0x07f00000, 0x05818590, 0x00202010, 0x038c0590,
+       0x07f00000, 0x06420002, 0x0481859e, 0x07a00578,
+       0x033e6a00, 0x0302000a, 0x07c00000, 0x07f00000,
+       0x060ff0a2, 0x050020ff, 0x060ff0a2, 0x045c0402,
+       0x048185a7, 0x07c00000, 0x05a00218, 0x03495047,
+       0x078105b2, 0x0320901d, 0x02800604, 0x0220901f,
+       0x02800604, 0x014980e4, 0x04818010, 0x013e4000,
+       0x07003000, 0x05600e35, 0x050f80ff, 0x07a006fc,
+       0x01208003, 0x05a004e1, 0x038005cc, 0x03209009,
+       0x02800604, 0x03209011, 0x02800604, 0x02209007,
+       0x02800604, 0x03209003, 0x02800604, 0x00498043,
+       0x058185be, 0x00497043, 0x048185c2, 0x02209001,
+       0x02800604, 0x0220900d, 0x02800604, 0x0320900f,
+       0x02800604, 0x03493000, 0x068105d5, 0x027c0045,
+       0x070a0000, 0x078105de, 0x0220900b, 0x02800604,
+       0x02209013, 0x05308000, 0x01012000, 0x04a004dc,
+       0x00800183, 0x03209005, 0x02800604, 0x072e500c,
+       0x00208002, 0x05a004e1, 0x02800010, 0x02209015,
+       0x02800604, 0x072d6000, 0x05308000, 0x05007000,
+       0x07f00000, 0x070090d1, 0x0379ff09, 0x0700ffff,
+       0x04a004dc, 0x03209017, 0x02800604, 0x033e5000,
+       0x06000080, 0x02209019, 0x02800604, 0x072d6000,
+       0x033e5000, 0x06000080, 0x07f00000, 0x060ff0d0,
+       0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff,
+       0x04818010, 0x02400058, 0x00642058, 0x06820010,
+       0x033e5000, 0x06000080, 0x04058051, 0x0320901b,
+       0x02800604, 0x05308000, 0x01012000, 0x04a004dc,
+       0x00800176, 0x05a00218, 0x05308000, 0x05008000,
+       0x06009079, 0x04a004dc, 0x07c00000, 0x034900e4,
+       0x05818618, 0x013e4000, 0x070000c0, 0x07f00000,
+       0x034900e4, 0x04818616, 0x07c00000, 0x013e4000,
+       0x06000080, 0x07f00000, 0x07f00000, 0x07f00000,
+       0x034900e4, 0x06810610, 0x03800618, 0x072d6000,
+       0x00498043, 0x06810632, 0x060ff0d0, 0x0179feff,
+       0x0700ffff, 0x057dfeff, 0x0700ffff, 0x058185e2,
+       0x050f8030, 0x032fa009, 0x0379ff00, 0x0700ffff,
+       0x070ff0d1, 0x0179feff, 0x0700ffff, 0x055c0400,
+       0x078105e2, 0x04004051, 0x0280067a, 0x06a006dc,
+       0x062d6001, 0x020ef004, 0x038605e4, 0x06600004,
+       0x050f80ff, 0x032fa009, 0x074b0000, 0x05002000,
+       0x0769ff00, 0x01640800, 0x078205e4, 0x01640e00,
+       0x058285e4, 0x070ff036, 0x045c0404, 0x0581864d,
+       0x072d6000, 0x050f8030, 0x032fa009, 0x0379ff00,
+       0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff,
+       0x055c0400, 0x078105e2, 0x04482034, 0x078105ff,
+       0x06483034, 0x058185ff, 0x070ff0d4, 0x077800ff,
+       0x070000f0, 0x037c00ff, 0x06000010, 0x0681067a,
+       0x06a006d6, 0x024900e5, 0x0681065d, 0x033e5000,
+       0x06000080, 0x02800010, 0x04601c04, 0x050f80ff,
+       0x053fa809, 0x06000020, 0x030ef041, 0x038605ee,
+       0x062d6002, 0x05602a41, 0x050f80ff, 0x012fa809,
+       0x060ff0d0, 0x074b00ff, 0x045c0401, 0x05818678,
+       0x062d6001, 0x07602841, 0x050f80ff, 0x053fa809,
+       0x06000001, 0x070ff0d1, 0x054b80ff, 0x074b0003,
+       0x055c0403, 0x05818678, 0x033e5000, 0x06000080,
+       0x0080070e, 0x07600041, 0x0280065e, 0x06a006d6,
+       0x024900e5, 0x06810680, 0x033e5000, 0x06000080,
+       0x02800010, 0x06a006c2, 0x030ef041, 0x028605f2,
+       0x04058051, 0x072d6000, 0x05601041, 0x050f80ff,
+       0x012fa809, 0x0600a0d0, 0x0500b0d1, 0x062d6001,
+       0x07f00000, 0x07f00000, 0x0600c0d0, 0x0500d0d1,
+       0x062d6002, 0x0279ff0d, 0x07ff0000, 0x044d800d,
+       0x060ff0d0, 0x074b00ff, 0x065a000d, 0x06601201,
+       0x050f80ff, 0x073fa022, 0x07000005, 0x0079fe0d,
+       0x070000ff, 0x050020ff, 0x05602a41, 0x050f80ff,
+       0x073fa00a, 0x06000001, 0x020ef004, 0x028606bf,
+       0x04601c04, 0x050f80ff, 0x053fa809, 0x06000001,
+       0x050f80ff, 0x053fa80a, 0x06000020, 0x07602841,
+       0x050f80ff, 0x073fa009, 0x06000001, 0x0279ff02,
+       0x070000ff, 0x0678000d, 0x0700ff00, 0x065a0002,
+       0x07602841, 0x050f80ff, 0x073fa00a, 0x06000001,
+       0x07600041, 0x050f80ff, 0x053fa80a, 0x06000001,
+       0x07601241, 0x050f80ff, 0x073fa00a, 0x06000002,
+       0x033e5000, 0x06000080, 0x0080070e, 0x040f8032,
+       0x073fa011, 0x06000001, 0x060ff002, 0x055c0403,
+       0x058186ca, 0x00041051, 0x07c00000, 0x04600402,
+       0x04500432, 0x050f80ff, 0x053fa809, 0x06000020,
+       0x00400402, 0x01680eff, 0x070030ff, 0x040f8032,
+       0x053fa80a, 0x06000001, 0x07c00000, 0x024900e5,
+       0x068106d9, 0x07c00000, 0x033e5000, 0x070000c0,
+       0x07c00000, 0x05004036, 0x060000d0, 0x0179fe00,
+       0x0700ffff, 0x057dfeff, 0x0700ffff, 0x068106fb,
+       0x070000d1, 0x0379ff00, 0x0700ffff, 0x06005051,
+       0x060ff031, 0x05500405, 0x050f80ff, 0x073fa009,
+       0x06000002, 0x020ef004, 0x038606f5, 0x04600404,
+       0x050f80ff, 0x012fa809, 0x0079fe01, 0x0700ffff,
+       0x055c0400, 0x068106fb, 0x01400405, 0x070050ff,
+       0x057de0ff, 0x06000007, 0x058186e7, 0x04004051,
+       0x07c00000, 0x072d6000, 0x07f00000, 0x07f00000,
+       0x000110d0, 0x010120d1, 0x062d6001, 0x07f00000,
+       0x07f00000, 0x020130d0, 0x010140d1, 0x062d6002,
+       0x010170d4, 0x07f00000, 0x020150d0, 0x030160d1,
+       0x053fa83a, 0x06000008, 0x07c00000, 0x07600c41,
+       0x050f80ff, 0x073fa009, 0x06000001, 0x04780102,
+       0x07ffff00, 0x046a0702, 0x050f80ff, 0x073fa00a,
+       0x06000001, 0x05600e41, 0x050f80ff, 0x032fa069,
+       0x03800053, 0xba6b4e34, 0x02800004, 0x00000000,
+       0x00008000, 0x00000518, 0x040f801f, 0x012fa8c9,
+       0x040f801f, 0x073fa081, 0x06000010, 0x03200005,
+       0x07420000, 0x050fb000, 0x040f801f, 0x073fa011,
+       0x06000038, 0x040f801f, 0x053fa859, 0x0700003a,
+       0x050fe000, 0x0581800a, 0x0684003d, 0x04958019,
+       0x030e0011, 0x072e4200, 0x03800014, 0x0291001f,
+       0x050010c0, 0x04482001, 0x058180e8, 0x06483001,
+       0x0781814b, 0x02920029, 0x068b0029, 0x018a0150,
+       0x050010c0, 0x06780001, 0x050007c0, 0x06818223,
+       0x06780001, 0x0500f800, 0x07818263, 0x03910030,
+       0x040fe029, 0x03860030, 0x076c001d, 0x04810294,
+       0x076c0a1d, 0x048102b9, 0x0292003d, 0x040fe02f,
+       0x0286003d, 0x06000013, 0x050fb000, 0x066c0073,
+       0x068103c2, 0x0297003d, 0x014920e4, 0x0481803d,
+       0x03400000, 0x076c0a00, 0x04818034, 0x0796003f,
+       0x03b900b8, 0x05908014, 0x010170e1, 0x07780017,
+       0x03e00000, 0x06810092, 0x050010ff, 0x0179fe17,
+       0x031fffff, 0x070000ff, 0x05600800, 0x050f80ff,
+       0x073fa009, 0x06000001, 0x06780002, 0x02800040,
+       0x037c00ff, 0x03800000, 0x0681005e, 0x0249f002,
+       0x068100ab, 0x0448e002, 0x0681005e, 0x07600c00,
+       0x050f80ff, 0x073fa009, 0x06000001, 0x06780002,
+       0x07ffff00, 0x037c00ff, 0x05000200, 0x048180ab,
+       0x064bd401, 0x03d00060, 0x038000a9, 0x02800068,
+       0x03800072, 0x0280007c, 0x02800086, 0x03800090,
+       0x038000a9, 0x038000a9, 0x050fe027, 0x0186806c,
+       0x01028000, 0x0380006f, 0x07600027, 0x050f80ff,
+       0x032fa00a, 0x01027000, 0x02400029, 0x028000ab,
+       0x040fe025, 0x00868076, 0x03026000, 0x02800079,
+       0x06600025, 0x050f80ff, 0x032fa00a, 0x03025000,
+       0x02400029, 0x028000ab, 0x050fe021, 0x00868080,
+       0x01022000, 0x02800083, 0x07600021, 0x050f80ff,
+       0x032fa00a, 0x01021000, 0x02400029, 0x028000ab,
+       0x040fe023, 0x0086808a, 0x01024000, 0x0380008d,
+       0x06600023, 0x050f80ff, 0x032fa00a, 0x03023000,
+       0x02400029, 0x028000ab, 0x06a000c8, 0x028000ab,
+       0x01640817, 0x058280a9, 0x070ff017, 0x03d00096,
+       0x0280009e, 0x038000a0, 0x038000a3, 0x038000a6,
+       0x038000a9, 0x038000a9, 0x038000a9, 0x038000a9,
+       0x03e00000, 0x03800014, 0x059080a0, 0x030160e1,
+       0x028000ab, 0x059080a3, 0x030150e1, 0x028000ab,
+       0x059080a6, 0x010140e1, 0x028000ab, 0x060fc013,
+       0x06a00510, 0x03800014, 0x072e4800, 0x07000012,
+       0x038000bb, 0x0747f000, 0x05600800, 0x050f80ff,
+       0x012fa809, 0x0249f001, 0x078100bb, 0x01012000,
+       0x052e4c00, 0x07c00000, 0x070000eb, 0x0349f000,
+       0x058180af, 0x05600800, 0x050f80ff, 0x012fa809,
+       0x0448e001, 0x068100c1, 0x07c00000, 0x0079c101,
+       0x07ffffff, 0x027a4b01, 0x03800000, 0x05600800,
+       0x050f80ff, 0x012fa80a, 0x07600c00, 0x050f80ff,
+       0x012fa821, 0x06780001, 0x07ffff00, 0x037c00ff,
+       0x05000700, 0x078100dd, 0x06601804, 0x070030ff,
+       0x050f80ff, 0x012fa809, 0x05002000, 0x050f8003,
+       0x073fa00a, 0x06000001, 0x040fe001, 0x038600de,
+       0x04600201, 0x050f80ff, 0x032fa00a, 0x07c00000,
+       0x050fe02e, 0x008680e3, 0x0102e000, 0x0302f000,
+       0x038000e7, 0x0760002e, 0x050f80ff, 0x032fa00a,
+       0x0102e000, 0x07c00000, 0x022c0004, 0x056c041d,
+       0x078100fc, 0x056c021d, 0x04810113, 0x056c081d,
+       0x04810125, 0x076c061d, 0x0581013f, 0x0521d000,
+       0x0202c013, 0x0202a013, 0x02020013, 0x0460021a,
+       0x050f80ff, 0x053fa80a, 0x07000009, 0x03b600ac,
+       0x0484801f, 0x0280003d, 0x040fe02a, 0x028600f2,
+       0x06000013, 0x04001013, 0x0560102b, 0x050f80ff,
+       0x032fa012, 0x06420029, 0x0660002a, 0x050f80ff,
+       0x053fa809, 0x06000001, 0x050fe003, 0x00860110,
+       0x01028003, 0x0660002a, 0x050f80ff, 0x053fa80a,
+       0x07000009, 0x00800140, 0x00028013, 0x00027013,
+       0x00800140, 0x040fe02a, 0x028600f1, 0x06420029,
+       0x0660002a, 0x050f80ff, 0x053fa809, 0x06000001,
+       0x050fe003, 0x01860122, 0x03026003, 0x0660002a,
+       0x050f80ff, 0x053fa80a, 0x07000009, 0x00800140,
+       0x02026013, 0x02025013, 0x00800140, 0x040fe02a,
+       0x028600f1, 0x06420029, 0x0660002a, 0x050f80ff,
+       0x053fa809, 0x06000001, 0x050fe003, 0x00860134,
+       0x01022003, 0x0660002a, 0x050f80ff, 0x053fa80a,
+       0x07000009, 0x01800136, 0x00022013, 0x00021013,
+       0x0647f020, 0x007a0120, 0x04000101, 0x04a00285,
+       0x0400802a, 0x05a004f5, 0x009480f1, 0x0521d005,
+       0x028000f2, 0x038000fa, 0x0647f020, 0x06486020,
+       0x06818145, 0x04a00285, 0x028000f1, 0x007a0120,
+       0x04000101, 0x04a00285, 0x0400802a, 0x05a004f5,
+       0x028000f1, 0x040fd02a, 0x052e4003, 0x00208010,
+       0x05a004f5, 0x038000fa, 0x00018098, 0x07480018,
+       0x06818161, 0x05481018, 0x0781815f, 0x05482018,
+       0x0681815d, 0x07483018, 0x0681815b, 0x002fb004,
+       0x00800162, 0x012fb003, 0x00800162, 0x002fb002,
+       0x00800162, 0x002fb001, 0x00800162, 0x012fb000,
+       0x0179fe78, 0x070000ff, 0x030190ff, 0x00017086,
+       0x058b0166, 0x03385000, 0x03020000, 0x07780017,
+       0x00430407, 0x078181ee, 0x046c0419, 0x048101a2,
+       0x046c0219, 0x05810172, 0x07219000, 0x00800186,
+       0x07219000, 0x07483017, 0x0481018c, 0x05482017,
+       0x05810193, 0x0448b075, 0x06818186, 0x06601476,
+       0x050f80ff, 0x073fa022, 0x0600003e, 0x06000080,
+       0x05001081, 0x05002082, 0x06003083, 0x05004084,
+       0x04601c76, 0x050f80ff, 0x022fa02a, 0x07219000,
+       0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff,
+       0x0484801f, 0x0280003d, 0x040fe07f, 0x0086019b,
+       0x05a001bb, 0x00920186, 0x040fe07f, 0x07a681bb,
+       0x00800186, 0x0560107b, 0x050f80ff, 0x032fa009,
+       0x0744f000, 0x0560107b, 0x050f80ff, 0x032fa00a,
+       0x00800179, 0x052e400c, 0x040080fb, 0x046aa108,
+       0x06009076, 0x04002075, 0x05a004fc, 0x00800186,
+       0x06219001, 0x05482017, 0x058101af, 0x058b01a5,
+       0x060ff086, 0x0349f0ff, 0x07818165, 0x07483017,
+       0x058101ac, 0x050fd0ff, 0x040fe07f, 0x07a681bb,
+       0x00800186, 0x05004084, 0x05a00205, 0x00920186,
+       0x070ff07d, 0x0450047c, 0x056004ff, 0x050f80ff,
+       0x032fa009, 0x070ff000, 0x00540479, 0x030790ff,
+       0x01800193, 0x060ff079, 0x0054047a, 0x058201e7,
+       0x058101e7, 0x070ff07d, 0x0450047c, 0x050f80ff,
+       0x002fa819, 0x058b01c3, 0x02080001, 0x00081002,
+       0x01082003, 0x048b01c7, 0x03385000, 0x03010000,
+       0x02400019, 0x070ff003, 0x04500479, 0x030790ff,
+       0x0340007e, 0x0642007f, 0x058101e7, 0x070ff07e,
+       0x050f80ff, 0x032fa009, 0x050fe000, 0x028681e6,
+       0x070ff07d, 0x056002ff, 0x050f80ff, 0x032fa009,
+       0x0107d000, 0x018601e8, 0x0560087d, 0x050f80ff,
+       0x032fa009, 0x0569fe00, 0x0550041b, 0x050f80ff,
+       0x032fa009, 0x0107e000, 0x070ff07e, 0x018001d2,
+       0x0307c000, 0x07c00000, 0x052e400c, 0x040080fb,
+       0x046aa108, 0x06009076, 0x04002075, 0x018004fc,
+       0x040fd076, 0x050fd017, 0x060ff086, 0x077800ff,
+       0x07000060, 0x037c00ff, 0x07000060, 0x078181f0,
+       0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff,
+       0x06601476, 0x050f80ff, 0x073fa022, 0x0600003e,
+       0x052e400c, 0x040080fb, 0x066a8108, 0x06009076,
+       0x04002075, 0x05a004fc, 0x02800029, 0x0240007f,
+       0x0742007e, 0x050f807e, 0x032fa009, 0x050fe000,
+       0x0286821f, 0x070ff07d, 0x055c047b, 0x05810214,
+       0x0760007d, 0x050f80ff, 0x032fa009, 0x050fe000,
+       0x03868214, 0x070ff07b, 0x0107d0ff, 0x0560087d,
+       0x050f80ff, 0x032fa009, 0x03681e00, 0x0450041c,
+       0x0107e0ff, 0x050f80ff, 0x032fa009, 0x050fe000,
+       0x01860221, 0x0307c000, 0x07c00000, 0x040fd076,
+       0x02800510, 0x010180c0, 0x0548e018, 0x0781823c,
+       0x0748f018, 0x06818238, 0x03490018, 0x06818234,
+       0x01491018, 0x07818230, 0x073c0000, 0x06000040,
+       0x02200004, 0x0180023f, 0x073c0000, 0x06000020,
+       0x03200003, 0x0180023f, 0x073c0000, 0x06000010,
+       0x02200002, 0x0180023f, 0x073c0000, 0x06000008,
+       0x02200001, 0x0180023f, 0x073c0000, 0x06000004,
+       0x06000013, 0x050fb000, 0x040fe076, 0x00860258,
+       0x046c0273, 0x04810268, 0x066c0073, 0x04810249,
+       0x040fd076, 0x06a00510, 0x03800014, 0x040fd076,
+       0x0080024c, 0x00452075, 0x00077013, 0x0647f075,
+       0x06486075, 0x06818252, 0x05a0028b, 0x00800258,
+       0x007a0175, 0x04000101, 0x05a0028b, 0x04008076,
+       0x0245f008, 0x05a004f5, 0x07273000, 0x05600272,
+       0x050f80ff, 0x053fa80a, 0x07000009, 0x0379ff78,
+       0x070000ff, 0x02076013, 0x02075013, 0x0484801f,
+       0x0280003d, 0x070fc0ff, 0x052e400c, 0x00208020,
+       0x05a004f5, 0x00800261, 0x04600276, 0x050010ff,
+       0x040f8001, 0x032fa009, 0x040f8001, 0x053fa80a,
+       0x07000009, 0x070ff000, 0x0286827a, 0x06601276,
+       0x050f80ff, 0x073fa009, 0x0700000c, 0x07601818,
+       0x050f80ff, 0x053fa80a, 0x07000009, 0x0180027b,
+       0x07a000de, 0x0448b075, 0x0581024b, 0x06000013,
+       0x04001013, 0x0560107b, 0x050f80ff, 0x032fa012,
+       0x0046b075, 0x03b600ac, 0x0080024c, 0x06000020,
+       0x04001016, 0x0460082a, 0x050f80ff, 0x032fa012,
+       0x07c00000, 0x06000075, 0x040010a2, 0x044b0801,
+       0x060ff016, 0x065a0001, 0x04600876, 0x050f80ff,
+       0x032fa012, 0x07c00000, 0x050fe022, 0x0186029a,
+       0x0421d004, 0x0302a022, 0x04a002c1, 0x018002b1,
+       0x040fe026, 0x008602b3, 0x0421d001, 0x0202a026,
+       0x04a002c1, 0x0202c013, 0x00683e20, 0x070060ff,
+       0x056c0206, 0x048102f4, 0x056c0406, 0x0781030a,
+       0x076c0606, 0x06810379, 0x056c1606, 0x078182b1,
+       0x04488020, 0x07810387, 0x040fd02a, 0x0521d000,
+       0x0202a013, 0x02020013, 0x008002b3, 0x04a004ec,
+       0x008002bf, 0x050fe028, 0x008602bf, 0x0302a028,
+       0x0421d002, 0x04a002c1, 0x008002c8, 0x050fe022,
+       0x008602bf, 0x0421d004, 0x0302a022, 0x04a002c1,
+       0x04a004ec, 0x05848030, 0x0280003d, 0x0460082a,
+       0x050f80ff, 0x022fa031, 0x03020000, 0x0002b004,
+       0x01018005, 0x07c00000, 0x0400702a, 0x06a003ba,
+       0x007a0101, 0x07060000, 0x07303000, 0x07008290,
+       0x07600018, 0x050f80ff, 0x053fa809, 0x07000003,
+       0x0448e007, 0x068182d6, 0x06006013, 0x018002dd,
+       0x02400010, 0x048102d6, 0x06006010, 0x0460322a,
+       0x050f80ff, 0x073fa00a, 0x07000003, 0x050f801e,
+       0x032fa03a, 0x063aa020, 0x06000002, 0x013e4000,
+       0x07000030, 0x009802e3, 0x070ff0f6, 0x036830ff,
+       0x078182e4, 0x070f001e, 0x0560102b, 0x050f10ff,
+       0x063f3c08, 0x0600000d, 0x013e4000, 0x06000020,
+       0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012,
+       0x0202c013, 0x008002bf, 0x04007013, 0x06a003ba,
+       0x007a0101, 0x07050000, 0x07303000, 0x07008890,
+       0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a,
+       0x05601a2b, 0x050f80ff, 0x022fa019, 0x04001002,
+       0x04002013, 0x040f801f, 0x022fa01a, 0x073aa00c,
+       0x06000002, 0x07300c03, 0x0600000d, 0x028003a7,
+       0x04007013, 0x06a003ba, 0x007a0101, 0x03070000,
+       0x0660282a, 0x050f80ff, 0x073fa009, 0x06000004,
+       0x02499008, 0x07810317, 0x07303000, 0x07008890,
+       0x02800319, 0x07303000, 0x04008980, 0x05007003,
+       0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a,
+       0x0760142b, 0x050f80ff, 0x032fa021, 0x064b0002,
+       0x02499008, 0x06810325, 0x0644c002, 0x054b0400,
+       0x050040ff, 0x06698104, 0x0581833a, 0x06000013,
+       0x04001013, 0x04780102, 0x06000010, 0x06003013,
+       0x04004013, 0x06005013, 0x06006013, 0x04007013,
+       0x00644015, 0x07820336, 0x04448002, 0x02205008,
+       0x040f801f, 0x032fa042, 0x04008015, 0x03800371,
+       0x046c8004, 0x05818348, 0x01208018, 0x06780002,
+       0x07000003, 0x0581834b, 0x06003001, 0x06000013,
+       0x04001013, 0x04004013, 0x06005013, 0x040f801f,
+       0x022fa032, 0x03800371, 0x040fd02a, 0x06a00510,
+       0x03800014, 0x04488002, 0x07810350, 0x070ff003,
+       0x04500408, 0x050080ff, 0x06489002, 0x06810357,
+       0x0379ff00, 0x070000ff, 0x070ff000, 0x04500408,
+       0x050080ff, 0x07005003, 0x05004000, 0x06003001,
+       0x06000013, 0x04001013, 0x040f801f, 0x022fa032,
+       0x05601c2b, 0x050f80ff, 0x022fa031, 0x06600c1f,
+       0x050f80ff, 0x022fa032, 0x02680608, 0x07810371,
+       0x016408ff, 0x057dfeff, 0x07ffffff, 0x034000ff,
+       0x045a0407, 0x070000ff, 0x0760061e, 0x050f80ff,
+       0x032fa00a, 0x06600908, 0x0669f908, 0x027a0008,
+       0x06000020, 0x070aa0ff, 0x014a20ff, 0x037a00ff,
+       0x060000dc, 0x070000ff, 0x028003a7, 0x04007013,
+       0x06a003ba, 0x007a0101, 0x07030000, 0x07303000,
+       0x07008190, 0x06006013, 0x050f801e, 0x032fa03a,
+       0x073aa000, 0x06000002, 0x07300c00, 0x07000005,
+       0x028003a7, 0x04007013, 0x06a003ba, 0x007a0101,
+       0x07810000, 0x07303000, 0x07000090, 0x06006013,
+       0x06600c2a, 0x050f80ff, 0x053fa809, 0x07000003,
+       0x04780107, 0x07ffff00, 0x007c0107, 0x07000500,
+       0x0581839a, 0x07303000, 0x05000890, 0x074d0005,
+       0x0660282a, 0x050f80ff, 0x053fa809, 0x07000003,
+       0x0049d007, 0x068103a1, 0x02206001, 0x050f801e,
+       0x032fa03a, 0x073aa000, 0x06000002, 0x07300c00,
+       0x07000005, 0x013e4000, 0x07000030, 0x039803a9,
+       0x070ff0f6, 0x036830ff, 0x058183aa, 0x070f001e,
+       0x040f101f, 0x070f3000, 0x013e4000, 0x06000020,
+       0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012,
+       0x008002bf, 0x03200000, 0x06006076, 0x028003bc,
+       0x03200011, 0x0600602a, 0x05a00441, 0x05600406,
+       0x050f80ff, 0x053fa809, 0x06000002, 0x07c00000,
+       0x0207602f, 0x04600876, 0x050f80ff, 0x022fa031,
+       0x03075000, 0x0007b004, 0x01018005, 0x06600076,
+       0x050020ff, 0x050f80ff, 0x012fa809, 0x0202f001,
+       0x008683d0, 0x0002e013, 0x040f8002, 0x053fa80a,
+       0x07000009, 0x06273001, 0x0448b075, 0x048183da,
+       0x04602076, 0x050f80ff, 0x053fa811, 0x0700003c,
+       0x0179fe78, 0x070000ff, 0x030190ff, 0x018683e2,
+       0x07a003f6, 0x00078019, 0x039203f5, 0x0180043a,
+       0x040fd076, 0x040fd019, 0x04600276, 0x050020ff,
+       0x050f80ff, 0x032fa009, 0x040f8002, 0x053fa80a,
+       0x07000009, 0x050fe000, 0x008683f2, 0x07601818,
+       0x050f80ff, 0x053fa80a, 0x07000009, 0x038003f3,
+       0x07a000de, 0x07273000, 0x02076013, 0x0280003d,
+       0x078b03f6, 0x03385000, 0x07030000, 0x05600818,
+       0x050f80ff, 0x032fa009, 0x054b0400, 0x0308a0ff,
+       0x0179fe00, 0x070000ff, 0x010880ff, 0x0448b075,
+       0x04810410, 0x0760147b, 0x050f80ff, 0x002fa819,
+       0x064b0001, 0x02080002, 0x01081003, 0x00082001,
+       0x02083001, 0x02079001, 0x0207a001, 0x00084013,
+       0x0207f013, 0x00800432, 0x06485075, 0x05810428,
+       0x02465075, 0x06601476, 0x050f80ff, 0x073fa021,
+       0x0600003e, 0x070ff07d, 0x0450047c, 0x050f80ff,
+       0x002fa819, 0x058b041b, 0x02080001, 0x00081002,
+       0x01082003, 0x03079003, 0x0208307a, 0x0340007e,
+       0x0642007f, 0x0581042d, 0x070ff07e, 0x05a001d2,
+       0x0392842d, 0x01800439, 0x058b0428, 0x06601476,
+       0x050f80ff, 0x073fa041, 0x0600003e, 0x06602476,
+       0x050f80ff, 0x073fa009, 0x06000007, 0x0008400e,
+       0x048b0432, 0x03385000, 0x03010000, 0x06219001,
+       0x040fe07f, 0x01860439, 0x018001bb, 0x07c00000,
+       0x00683e75, 0x0581043f, 0x0448d075, 0x05810465,
+       0x01800493, 0x05a004f0, 0x038003f5, 0x0297844c,
+       0x07602418, 0x050f80ff, 0x012fa809, 0x06780001,
+       0x070000ff, 0x075a0000, 0x070ff014, 0x0569feff,
+       0x054b08ff, 0x075a0000, 0x05600418, 0x050f80ff,
+       0x012fa809, 0x040fe007, 0x03868453, 0x01204000,
+       0x00800461, 0x00700101, 0x03010000, 0x06780001,
+       0x07ff0000, 0x076c00ff, 0x0681845b, 0x00700101,
+       0x03010000, 0x05600418, 0x050f80ff, 0x012fa80a,
+       0x06780001, 0x07ff0000, 0x050040ff, 0x0279ff01,
+       0x0700ffff, 0x05002014, 0x07c00000, 0x04007076,
+       0x0448b075, 0x0481047f, 0x03200011, 0x06006076,
+       0x06a003bc, 0x007a0101, 0x07060000, 0x07303000,
+       0x07008290, 0x07600018, 0x050f80ff, 0x053fa809,
+       0x07000003, 0x0448e007, 0x07818477, 0x06006013,
+       0x0180048e, 0x02400010, 0x05810477, 0x06006010,
+       0x04603276, 0x050f80ff, 0x073fa00a, 0x07000003,
+       0x0180048e, 0x04602a76, 0x050f80ff, 0x032fa009,
+       0x060ff07a, 0x05500400, 0x070000ff, 0x04602a76,
+       0x050f80ff, 0x032fa00a, 0x07a003b7, 0x007a0101,
+       0x03010000, 0x06303008, 0x05008000, 0x0600600e,
+       0x050f8074, 0x032fa03a, 0x053079a0, 0x0700000c,
+       0x008004d3, 0x00683e75, 0x076c0aff, 0x058104b2,
+       0x04007013, 0x03200011, 0x06006076, 0x06a003bc,
+       0x007a0101, 0x03070000, 0x06602876, 0x050f80ff,
+       0x053fa809, 0x06000001, 0x03499003, 0x048104a7,
+       0x07303000, 0x07008890, 0x053079a0, 0x0700000c,
+       0x008004ab, 0x07303000, 0x04008980, 0x04307920,
+       0x0700000c, 0x074d0005, 0x06006013, 0x050f8074,
+       0x032fa03a, 0x04307920, 0x0700000c, 0x008004d3,
+       0x04602a76, 0x050f80ff, 0x032fa009, 0x060ff07a,
+       0x05500400, 0x070000ff, 0x04602a76, 0x050f80ff,
+       0x032fa00a, 0x04007076, 0x07a003b7, 0x007a0101,
+       0x03010000, 0x06303008, 0x07008800, 0x074d0005,
+       0x06600a76, 0x050f80ff, 0x073fa009, 0x07000003,
+       0x054b0406, 0x045a0404, 0x050040ff, 0x0600600e,
+       0x050f8074, 0x032fa03a, 0x0648c075, 0x058104d1,
+       0x06307d20, 0x0700000c, 0x008004d3, 0x04307920,
+       0x0700000c, 0x013e4000, 0x07000030, 0x009804d5,
+       0x070ff0f6, 0x074850ff, 0x068184d6, 0x050f2074,
+       0x060a0007, 0x040070fb, 0x046a7007, 0x050f40ff,
+       0x013e4000, 0x06000020, 0x0678007a, 0x07fff000,
+       0x068184e6, 0x0320000a, 0x022017d0, 0x008004e9,
+       0x0320000a, 0x06301b58, 0x06000001, 0x050f8072,
+       0x032fa012, 0x038003f5, 0x01208060, 0x0600902a,
+       0x04002020, 0x018004fc, 0x040080fb, 0x066ae108,
+       0x06009076, 0x04002075, 0x018004fc, 0x03201100,
+       0x078484fa, 0x06420001, 0x078184f6, 0x02800513,
+       0x020e0008, 0x07c00000, 0x050fd009, 0x040fd008,
+       0x03201100, 0x05848503, 0x06420001, 0x078184ff,
+       0x02800513, 0x007a0102, 0x04000101, 0x05600809,
+       0x050f80ff, 0x073fa00a, 0x06000001, 0x020e0008,
+       0x0684050d, 0x030e0009, 0x07c00000, 0x01011009,
+       0x052e4300, 0x07c00000, 0x052e400f, 0x01208090,
+       0x018004f5, 0x070fc0ff, 0x040f8013, 0x032fa009,
+       0x02800516, 0x15416ea9, 0xffef0b01
+};
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_length02 = 0x000014ff ;
+#else
+uint32_t risc_code_length02 = 0x000014ff ;
+#endif
+
index 48e460e..2efca52 100644 (file)
@@ -232,7 +232,7 @@ static ssize_t
 qla2x00_isp_name_show(struct class_device *cdev, char *buf)
 {
        scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
-       return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name);
+       return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device);
 }
 
 static ssize_t
index 7b3efd5..79d8a91 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/firmware.h>
 #include <asm/semaphore.h>
 
 #include <scsi/scsi.h>
@@ -29,6 +30,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
 #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE)
 #define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
 #else
 #define IS_QLA2522(ha) 0
 #endif
 
+#else  /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
+#define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
+#define IS_QLA2200(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200)
+#define IS_QLA2300(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300)
+#define IS_QLA2312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312)
+#define IS_QLA2322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322)
+#define IS_QLA6312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312)
+#define IS_QLA6322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322)
+#define IS_QLA2422(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422)
+#define IS_QLA2432(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+#define IS_QLA2512(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512)
+#define IS_QLA2522(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522)
+#endif
+
 #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
                         IS_QLA6312(ha) || IS_QLA6322(ha))
-
 #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha))
 #define IS_QLA25XX(ha) (IS_QLA2512(ha) || IS_QLA2522(ha))
 
@@ -2124,6 +2140,12 @@ struct qla_board_info {
        struct scsi_host_template *sht;
 };
 
+struct fw_blob {
+       char *name;
+       uint32_t segs[4];
+       const struct firmware *fw;
+};
+
 /* Return data from MBC_GET_ID_LIST call. */
 struct gid_list_info {
        uint8_t al_pa;
index fedcb0d..bec81ad 100644 (file)
@@ -33,8 +33,8 @@ extern int qla24xx_nvram_config(struct scsi_qla_host *);
 extern void qla2x00_update_fw_options(struct scsi_qla_host *);
 extern void qla24xx_update_fw_options(scsi_qla_host_t *);
 extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
+extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
 extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
-extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *);
 
 extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t);
 
@@ -76,6 +76,8 @@ extern void qla2x00_blink_led(scsi_qla_host_t *);
 
 extern int qla2x00_down_timeout(struct semaphore *, unsigned long);
 
+extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
+
 /*
  * Global Function Prototypes in qla_iocb.c source file.
  */
index c46d246..7d973bd 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
-#include <linux/firmware.h>
 #include <scsi/scsi_transport_fc.h>
 
 #include "qla_devtbl.h"
@@ -3484,17 +3483,16 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
        return (rval);
 }
 
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+
 int
 qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 {
-       int             rval;
-       uint16_t        cnt;
-       uint16_t        *risc_code;
-       unsigned long   risc_address;
-       unsigned long   risc_code_size;
-       int             num;
-       int             i;
-       uint16_t        *req_ring;
+       int     rval, num, i;
+       uint32_t cnt;
+       uint16_t *risc_code;
+       uint32_t risc_addr, risc_size;
+       uint16_t *req_ring;
        struct qla_fw_info *fw_iter;
 
        rval = QLA_SUCCESS;
@@ -3504,37 +3502,29 @@ qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
        *srisc_addr = *ha->brd_info->fw_info->fwstart;
        while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
                risc_code = fw_iter->fwcode;
-               risc_code_size = *fw_iter->fwlen;
-
-               if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-                       risc_address = *fw_iter->fwstart;
-               } else {
-                       /* Extended address */
-                       risc_address = *fw_iter->lfwstart;
-               }
+               risc_size = *fw_iter->fwlen;
+               if (fw_iter->addressing == FW_INFO_ADDR_NORMAL)
+                       risc_addr = *fw_iter->fwstart;
+               else
+                       risc_addr = *fw_iter->lfwstart;
 
                num = 0;
                rval = 0;
-               while (risc_code_size > 0 && !rval) {
+               while (risc_size > 0 && !rval) {
                        cnt = (uint16_t)(ha->fw_transfer_size >> 1);
-                       if (cnt > risc_code_size)
-                               cnt = risc_code_size;
+                       if (cnt > risc_size)
+                               cnt = risc_size;
 
                        DEBUG7(printk("scsi(%ld): Loading risc segment@ "
                            "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
-                           ha->host_no, risc_code, cnt, risc_address));
+                           ha->host_no, risc_code, cnt, risc_addr));
 
                        req_ring = (uint16_t *)ha->request_ring;
                        for (i = 0; i < cnt; i++)
                                req_ring[i] = cpu_to_le16(risc_code[i]);
 
-                       if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-                               rval = qla2x00_load_ram(ha, ha->request_dma,
-                                   risc_address, cnt);
-                       } else {
-                               rval = qla2x00_load_ram_ext(ha,
-                                   ha->request_dma, risc_address, cnt);
-                       }
+                       rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+                           cnt);
                        if (rval) {
                                DEBUG(printk("scsi(%ld): [ERROR] Failed to "
                                    "load segment %d of firmware\n",
@@ -3548,16 +3538,76 @@ qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
                        }
 
                        risc_code += cnt;
-                       risc_address += cnt;
-                       risc_code_size -= cnt;
+                       risc_addr += cnt;
+                       risc_size -= cnt;
                        num++;
                }
 
                /* Next firmware sequence */
                fw_iter++;
        }
+       return rval;
+}
 
-       return (rval);
+int
+qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+       int     rval, num, i;
+       uint32_t cnt;
+       uint32_t *risc_code;
+       uint32_t risc_addr, risc_size;
+       uint32_t *req_ring;
+       struct qla_fw_info *fw_iter;
+
+       rval = QLA_SUCCESS;
+
+       /* Load firmware sequences */
+       fw_iter = ha->brd_info->fw_info;
+       *srisc_addr = *((uint32_t *)fw_iter->lfwstart);
+       while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
+               risc_code = (uint32_t *)fw_iter->fwcode;
+               risc_size = *((uint32_t *)fw_iter->fwlen);
+               risc_addr = *((uint32_t *)fw_iter->lfwstart);
+
+               num = 0;
+               rval = 0;
+               while (risc_size > 0 && !rval) {
+                       cnt = (uint32_t)(ha->fw_transfer_size >> 2);
+                       if (cnt > risc_size)
+                               cnt = risc_size;
+
+                       DEBUG7(printk("scsi(%ld): Loading risc segment@ "
+                           "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
+                           ha->host_no, risc_code, cnt, risc_addr));
+
+                       req_ring = (uint32_t *)ha->request_ring;
+                       for (i = 0; i < cnt; i++)
+                               req_ring[i] = cpu_to_le32(risc_code[i]);
+
+                       rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+                           cnt);
+                       if (rval) {
+                               DEBUG(printk("scsi(%ld): [ERROR] Failed to "
+                                   "load segment %d of firmware\n",
+                                   ha->host_no, num));
+                               qla_printk(KERN_WARNING, ha,
+                                   "[ERROR] Failed to load segment %d of "
+                                   "firmware\n", num);
+
+                               qla2x00_dump_regs(ha);
+                               break;
+                       }
+
+                       risc_code += cnt;
+                       risc_addr += cnt;
+                       risc_size -= cnt;
+                       num++;
+               }
+
+               /* Next firmware sequence */
+               fw_iter++;
+       }
+       return rval;
 }
 
 int
@@ -3642,8 +3692,108 @@ qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
        return rval;
 }
 
+#else  /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
 int
-qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+       int     rval;
+       int     i, fragment;
+       uint16_t *wcode, *fwcode;
+       uint32_t risc_addr, risc_size, fwclen, wlen, *seg;
+       struct fw_blob *blob;
+
+       /* Load firmware blob. */
+       blob = qla2x00_request_firmware(ha);
+       if (!blob) {
+               qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
+               return QLA_FUNCTION_FAILED;
+       }
+
+       rval = QLA_SUCCESS;
+
+       wcode = (uint16_t *)ha->request_ring;
+       *srisc_addr = 0;
+       fwcode = (uint16_t *)blob->fw->data;
+       fwclen = 0;
+
+       /* Validate firmware image by checking version. */
+       if (blob->fw->size < 8 * sizeof(uint16_t)) {
+               qla_printk(KERN_WARNING, ha,
+                   "Unable to verify integrity of firmware image (%Zd)!\n",
+                   blob->fw->size);
+               goto fail_fw_integrity;
+       }
+       for (i = 0; i < 4; i++)
+               wcode[i] = be16_to_cpu(fwcode[i + 4]);
+       if ((wcode[0] == 0xffff && wcode[1] == 0xffff && wcode[2] == 0xffff &&
+           wcode[3] == 0xffff) || (wcode[0] == 0 && wcode[1] == 0 &&
+               wcode[2] == 0 && wcode[3] == 0)) {
+               qla_printk(KERN_WARNING, ha,
+                   "Unable to verify integrity of firmware image!\n");
+               qla_printk(KERN_WARNING, ha,
+                   "Firmware data: %04x %04x %04x %04x!\n", wcode[0],
+                   wcode[1], wcode[2], wcode[3]);
+               goto fail_fw_integrity;
+       }
+
+       seg = blob->segs;
+       while (*seg && rval == QLA_SUCCESS) {
+               risc_addr = *seg;
+               *srisc_addr = *srisc_addr == 0 ? *seg : *srisc_addr;
+               risc_size = be16_to_cpu(fwcode[3]);
+
+               /* Validate firmware image size. */
+               fwclen += risc_size * sizeof(uint16_t);
+               if (blob->fw->size < fwclen) {
+                       qla_printk(KERN_WARNING, ha,
+                           "Unable to verify integrity of firmware image "
+                           "(%Zd)!\n", blob->fw->size);
+                       goto fail_fw_integrity;
+               }
+
+               fragment = 0;
+               while (risc_size > 0 && rval == QLA_SUCCESS) {
+                       wlen = (uint16_t)(ha->fw_transfer_size >> 1);
+                       if (wlen > risc_size)
+                               wlen = risc_size;
+
+                       DEBUG7(printk("scsi(%ld): Loading risc segment@ risc "
+                           "addr %x, number of words 0x%x.\n", ha->host_no,
+                           risc_addr, wlen));
+
+                       for (i = 0; i < wlen; i++)
+                               wcode[i] = swab16(fwcode[i]);
+
+                       rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+                           wlen);
+                       if (rval) {
+                               DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
+                                   "segment %d of firmware\n", ha->host_no,
+                                   fragment));
+                               qla_printk(KERN_WARNING, ha,
+                                   "[ERROR] Failed to load segment %d of "
+                                   "firmware\n", fragment);
+                               break;
+                       }
+
+                       fwcode += wlen;
+                       risc_addr += wlen;
+                       risc_size -= wlen;
+                       fragment++;
+               }
+
+               /* Next segment. */
+               seg++;
+       }
+       return rval;
+
+fail_fw_integrity:
+       return QLA_FUNCTION_FAILED;
+}
+
+int
+qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 {
        int     rval;
        int     segments, fragment;
@@ -3651,14 +3801,13 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
        uint32_t risc_addr;
        uint32_t risc_size;
        uint32_t i;
-       const struct firmware *fw_entry;
+       struct fw_blob *blob;
        uint32_t *fwcode, fwclen;
 
-       if (request_firmware(&fw_entry, ha->brd_info->fw_fname,
-           &ha->pdev->dev)) {
-               qla_printk(KERN_ERR, ha,
-                   "Firmware image file not available: '%s'\n",
-                   ha->brd_info->fw_fname);
+       /* Load firmware blob. */
+       blob = qla2x00_request_firmware(ha);
+       if (!blob) {
+               qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
                return QLA_FUNCTION_FAILED;
        }
 
@@ -3667,14 +3816,14 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
        segments = FA_RISC_CODE_SEGMENTS;
        dcode = (uint32_t *)ha->request_ring;
        *srisc_addr = 0;
-       fwcode = (uint32_t *)fw_entry->data;
+       fwcode = (uint32_t *)blob->fw->data;
        fwclen = 0;
 
        /* Validate firmware image by checking version. */
-       if (fw_entry->size < 8 * sizeof(uint32_t)) {
+       if (blob->fw->size < 8 * sizeof(uint32_t)) {
                qla_printk(KERN_WARNING, ha,
-                   "Unable to verify integrity of flash firmware image "
-                   "(%Zd)!\n", fw_entry->size);
+                   "Unable to verify integrity of firmware image (%Zd)!\n",
+                   blob->fw->size);
                goto fail_fw_integrity;
        }
        for (i = 0; i < 4; i++)
@@ -3684,7 +3833,7 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
            (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
                dcode[3] == 0)) {
                qla_printk(KERN_WARNING, ha,
-                   "Unable to verify integrity of flash firmware image!\n");
+                   "Unable to verify integrity of firmware image!\n");
                qla_printk(KERN_WARNING, ha,
                    "Firmware data: %08x %08x %08x %08x!\n", dcode[0],
                    dcode[1], dcode[2], dcode[3]);
@@ -3698,10 +3847,11 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 
                /* Validate firmware image size. */
                fwclen += risc_size * sizeof(uint32_t);
-               if (fw_entry->size < fwclen) {
+               if (blob->fw->size < fwclen) {
                        qla_printk(KERN_WARNING, ha,
-                           "Unable to verify integrity of flash firmware "
-                           "image (%Zd)!\n", fw_entry->size);
+                           "Unable to verify integrity of firmware image "
+                           "(%Zd)!\n", blob->fw->size);
+
                        goto fail_fw_integrity;
                }
 
@@ -3739,13 +3889,9 @@ qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
                /* Next segment. */
                segments--;
        }
-
-       release_firmware(fw_entry);
        return rval;
 
 fail_fw_integrity:
-
-       release_firmware(fw_entry);
        return QLA_FUNCTION_FAILED;
-
 }
+#endif
index c58c9d9..2430430 100644 (file)
@@ -54,10 +54,12 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xloginretrycount,
                "Specify an alternate value for the NVRAM login retry count.");
 
-int ql2xfwloadbin=1;
-module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(ql2xfwloadbin,
-               "Load ISP2xxx firmware image via hotplug.");
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+int ql2xfwloadflash;
+module_param(ql2xfwloadflash, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xfwloadflash,
+               "Load ISP24xx firmware image from FLASH (onboard memory).");
+#endif
 
 static void qla2x00_free_device(scsi_qla_host_t *);
 
@@ -1261,12 +1263,16 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
        char pci_info[20];
        char fw_str[30];
        fc_port_t *fcport;
+       struct scsi_host_template *sht;
 
        if (pci_enable_device(pdev))
                goto probe_out;
 
-       host = scsi_host_alloc(brd_info->sht ? brd_info->sht:
-           &qla2x00_driver_template, sizeof(scsi_qla_host_t));
+       sht = &qla2x00_driver_template;
+       if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+               sht = &qla24xx_driver_template;
+       host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
        if (host == NULL) {
                printk(KERN_WARNING
                    "qla2xxx: Couldn't allocate host from scsi layer!\n");
@@ -1291,8 +1297,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
                goto probe_failed;
 
        qla_printk(KERN_INFO, ha,
-           "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,
-           pdev->irq, ha->iobase);
+           "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq,
+           ha->iobase);
 
        spin_lock_init(&ha->hardware_lock);
 
@@ -1368,9 +1374,11 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
                ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
                ha->isp_ops.nvram_config = qla24xx_nvram_config;
                ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
-               ha->isp_ops.load_risc = qla24xx_load_risc_flash;
-               if (ql2xfwloadbin)
-                       ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;
+               ha->isp_ops.load_risc = qla24xx_load_risc;
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+               if (ql2xfwloadflash)
+                       ha->isp_ops.load_risc = qla24xx_load_risc_flash;
+#endif
                ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
                ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
                ha->isp_ops.intr_handler = qla24xx_intr_handler;
@@ -1531,11 +1539,12 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
        qla_printk(KERN_INFO, ha, "\n"
            " QLogic Fibre Channel HBA Driver: %s\n"
            "  QLogic %s - %s\n"
-           "  %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str,
-           ha->model_number, ha->model_desc ? ha->model_desc: "",
-           ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info),
-           pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-',
-           ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str));
+           "  ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
+           qla2x00_version_str, ha->model_number,
+           ha->model_desc ? ha->model_desc: "", pdev->device,
+           ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev),
+           ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
+           ha->isp_ops.fw_version_str(ha, fw_str));
 
        /* Go with fc_rport registration. */
        list_for_each_entry(fcport, &ha->fcports, list)
@@ -2483,45 +2492,115 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
        return -ETIMEDOUT;
 }
 
-static struct qla_board_info qla_board_tbl[] = {
-       {
-               .drv_name       = "qla2400",
-               .isp_name       = "ISP2422",
-               .fw_fname       = "ql2400_fw.bin",
-               .sht            = &qla24xx_driver_template,
-       },
-       {
-               .drv_name       = "qla2400",
-               .isp_name       = "ISP2432",
-               .fw_fname       = "ql2400_fw.bin",
-               .sht            = &qla24xx_driver_template,
-       },
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+
+#define qla2x00_release_firmware()     do { } while (0)
+#define qla2x00_pci_module_init()      (0)
+#define qla2x00_pci_module_exit()      do { } while (0)
+
+#else  /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
+/* Firmware interface routines. */
+
+#define FW_BLOBS       6
+#define FW_ISP21XX     0
+#define FW_ISP22XX     1
+#define FW_ISP2300     2
+#define FW_ISP2322     3
+#define FW_ISP63XX     4
+#define FW_ISP24XX     5
+
+static DECLARE_MUTEX(qla_fw_lock);
+
+static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
+       { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, },
+       { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
+       { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
+       { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
+       { .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, },
+       { .name = "ql2400_fw.bin", },
+};
+
+struct fw_blob *
+qla2x00_request_firmware(scsi_qla_host_t *ha)
+{
+       struct fw_blob *blob;
+
+       blob = NULL;
+       if (IS_QLA2100(ha)) {
+               blob = &qla_fw_blobs[FW_ISP21XX];
+       } else if (IS_QLA2200(ha)) {
+               blob = &qla_fw_blobs[FW_ISP22XX];
+       } else if (IS_QLA2300(ha) || IS_QLA2312(ha)) {
+               blob = &qla_fw_blobs[FW_ISP2300];
+       } else if (IS_QLA2322(ha)) {
+               blob = &qla_fw_blobs[FW_ISP2322];
+       } else if (IS_QLA6312(ha) || IS_QLA6322(ha)) {
+               blob = &qla_fw_blobs[FW_ISP63XX];
+       } else if (IS_QLA24XX(ha)) {
+               blob = &qla_fw_blobs[FW_ISP24XX];
+       }
+
+       down(&qla_fw_lock);
+       if (blob->fw)
+               goto out;
+
+       if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
+               DEBUG2(printk("scsi(%ld): Failed to load firmware image "
+                   "(%s).\n", ha->host_no, blob->name));
+               blob->fw = NULL;
+               blob = NULL;
+               goto out;
+       }
+
+out:
+       up(&qla_fw_lock);
+       return blob;
+}
+
+static void
+qla2x00_release_firmware(void)
+{
+       int idx;
+
+       down(&qla_fw_lock);
+       for (idx = 0; idx < FW_BLOBS; idx++)
+               if (qla_fw_blobs[idx].fw)
+                       release_firmware(qla_fw_blobs[idx].fw);
+       up(&qla_fw_lock);
+}
+
+static struct qla_board_info qla_board_tbl = {
+       .drv_name       = "qla2xxx",
 };
 
 static struct pci_device_id qla2xxx_pci_tbl[] = {
-       {
-               .vendor         = PCI_VENDOR_ID_QLOGIC,
-               .device         = PCI_DEVICE_ID_QLOGIC_ISP2422,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = (unsigned long)&qla_board_tbl[0],
-       },
-       {
-               .vendor         = PCI_VENDOR_ID_QLOGIC,
-               .device         = PCI_DEVICE_ID_QLOGIC_ISP2432,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .driver_data    = (unsigned long)&qla_board_tbl[1],
-       },
-       {0, 0},
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
+               PCI_ANY_ID, PCI_ANY_ID, },
+       { 0 },
 };
 MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
 
 static int __devinit
 qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       return qla2x00_probe_one(pdev,
-           (struct qla_board_info *)id->driver_data);
+       return qla2x00_probe_one(pdev, &qla_board_tbl);
 }
 
 static void __devexit
@@ -2532,11 +2611,28 @@ qla2xxx_remove_one(struct pci_dev *pdev)
 
 static struct pci_driver qla2xxx_pci_driver = {
        .name           = "qla2xxx",
+       .driver         = {
+               .owner          = THIS_MODULE,
+       },
        .id_table       = qla2xxx_pci_tbl,
        .probe          = qla2xxx_probe_one,
        .remove         = __devexit_p(qla2xxx_remove_one),
 };
 
+static inline int
+qla2x00_pci_module_init(void)
+{
+       return pci_module_init(&qla2xxx_pci_driver);
+}
+
+static inline void
+qla2x00_pci_module_exit(void)
+{
+       pci_unregister_driver(&qla2xxx_pci_driver);
+}
+
+#endif
+
 /**
  * qla2x00_module_init - Module initialization.
  **/
@@ -2556,6 +2652,9 @@ qla2x00_module_init(void)
 
        /* Derive version string. */
        strcpy(qla2x00_version_str, QLA2XXX_VERSION);
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+       strcat(qla2x00_version_str, "-fw");
+#endif
 #if DEBUG_QLA2100
        strcat(qla2x00_version_str, "-debug");
 #endif
@@ -2565,7 +2664,7 @@ qla2x00_module_init(void)
                return -ENODEV;
 
        printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
-       ret = pci_module_init(&qla2xxx_pci_driver);
+       ret = qla2x00_pci_module_init();
        if (ret) {
                kmem_cache_destroy(srb_cachep);
                fc_release_transport(qla2xxx_transport_template);
@@ -2579,7 +2678,8 @@ qla2x00_module_init(void)
 static void __exit
 qla2x00_module_exit(void)
 {
-       pci_unregister_driver(&qla2xxx_pci_driver);
+       qla2x00_pci_module_exit();
+       qla2x00_release_firmware();
        kmem_cache_destroy(srb_cachep);
        fc_release_transport(qla2xxx_transport_template);
 }
index 5b1c120..5ec5f44 100644 (file)
@@ -115,7 +115,7 @@ static DECLARE_TRANSPORT_CLASS(raid_class,
                               raid_remove,
                               NULL);
 
-static struct {
+static const struct {
        enum raid_state value;
        char            *name;
 } raid_states[] = {
index e69477d..f01ec0a 100644 (file)
@@ -354,8 +354,9 @@ static int scsi_dev_info_list_add_str(char *dev_list)
  *     @model, if found, return the matching flags value, else return
  *     the host or global default settings.
  **/
-int scsi_get_device_flags(struct scsi_device *sdev, unsigned char *vendor,
-                         unsigned char *model)
+int scsi_get_device_flags(struct scsi_device *sdev,
+                         const unsigned char *vendor,
+                         const unsigned char *model)
 {
        struct scsi_dev_info_list *devinfo;
        unsigned int bflags;
index c0ae9e9..a2333d2 100644 (file)
@@ -1319,23 +1319,6 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
        }
 }
 
-/**
- * scsi_eh_lock_done - done function for eh door lock request
- * @scmd:      SCSI command block for the door lock request
- *
- * Notes:
- *     We completed the asynchronous door lock request, and it has either
- *     locked the door or failed.  We must free the command structures
- *     associated with this request.
- **/
-static void scsi_eh_lock_done(struct scsi_cmnd *scmd)
-{
-       struct scsi_request *sreq = scmd->sc_request;
-
-       scsi_release_request(sreq);
-}
-
-
 /**
  * scsi_eh_lock_door - Prevent medium removal for the specified device
  * @sdev:      SCSI device to prevent medium removal
@@ -1358,29 +1341,17 @@ static void scsi_eh_lock_done(struct scsi_cmnd *scmd)
  **/
 static void scsi_eh_lock_door(struct scsi_device *sdev)
 {
-       struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
+       unsigned char cmnd[MAX_COMMAND_SIZE];
 
-       if (unlikely(!sreq)) {
-               printk(KERN_ERR "%s: request allocate failed,"
-                      "prevent media removal cmd not sent\n", __FUNCTION__);
-               return;
-       }
+       cmnd[0] = ALLOW_MEDIUM_REMOVAL;
+       cmnd[1] = 0;
+       cmnd[2] = 0;
+       cmnd[3] = 0;
+       cmnd[4] = SCSI_REMOVAL_PREVENT;
+       cmnd[5] = 0;
 
-       sreq->sr_cmnd[0] = ALLOW_MEDIUM_REMOVAL;
-       sreq->sr_cmnd[1] = 0;
-       sreq->sr_cmnd[2] = 0;
-       sreq->sr_cmnd[3] = 0;
-       sreq->sr_cmnd[4] = SCSI_REMOVAL_PREVENT;
-       sreq->sr_cmnd[5] = 0;
-       sreq->sr_data_direction = DMA_NONE;
-       sreq->sr_bufflen = 0;
-       sreq->sr_buffer = NULL;
-       sreq->sr_allowed = 5;
-       sreq->sr_done = scsi_eh_lock_done;
-       sreq->sr_timeout_per_command = 10 * HZ;
-       sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]);
-
-       scsi_insert_special_req(sreq, 1);
+       scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ,
+                          5, NULL, NULL, GFP_KERNEL);
 }
 
 
index dc249cb..a7f3f0c 100644 (file)
@@ -63,39 +63,6 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = {
 };     
 #undef SP
 
-
-/*
- * Function:    scsi_insert_special_req()
- *
- * Purpose:     Insert pre-formed request into request queue.
- *
- * Arguments:   sreq   - request that is ready to be queued.
- *              at_head        - boolean.  True if we should insert at head
- *                        of queue, false if we should insert at tail.
- *
- * Lock status: Assumed that lock is not held upon entry.
- *
- * Returns:     Nothing
- *
- * Notes:       This function is called from character device and from
- *              ioctl types of functions where the caller knows exactly
- *              what SCSI command needs to be issued.   The idea is that
- *              we merely inject the command into the queue (at the head
- *              for now), and then call the queue request function to actually
- *              process it.
- */
-int scsi_insert_special_req(struct scsi_request *sreq, int at_head)
-{
-       /*
-        * Because users of this function are apt to reuse requests with no
-        * modification, we have to sanitise the request flags here
-        */
-       sreq->sr_request->flags &= ~REQ_DONTPREP;
-       blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
-                          at_head, sreq);
-       return 0;
-}
-
 static void scsi_run_queue(struct request_queue *q);
 
 /*
@@ -249,8 +216,13 @@ void scsi_do_req(struct scsi_request *sreq, const void *cmnd,
 
        /*
         * head injection *required* here otherwise quiesce won't work
+        *
+        * Because users of this function are apt to reuse requests with no
+        * modification, we have to sanitise the request flags here
         */
-       scsi_insert_special_req(sreq, 1);
+       sreq->sr_request->flags &= ~REQ_DONTPREP;
+       blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
+                          1, sreq);
 }
 EXPORT_SYMBOL(scsi_do_req);
 
@@ -287,6 +259,7 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
        memcpy(req->cmd, cmd, req->cmd_len);
        req->sense = sense;
        req->sense_len = 0;
+       req->retries = retries;
        req->timeout = timeout;
        req->flags |= flags | REQ_BLOCK_PC | REQ_SPECIAL | REQ_QUIET;
 
@@ -327,6 +300,200 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
 }
 EXPORT_SYMBOL(scsi_execute_req);
 
+struct scsi_io_context {
+       void *data;
+       void (*done)(void *data, char *sense, int result, int resid);
+       char sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+static kmem_cache_t *scsi_io_context_cache;
+
+static void scsi_end_async(struct request *req)
+{
+       struct scsi_io_context *sioc = req->end_io_data;
+
+       if (sioc->done)
+               sioc->done(sioc->data, sioc->sense, req->errors, req->data_len);
+
+       kmem_cache_free(scsi_io_context_cache, sioc);
+       __blk_put_request(req->q, req);
+}
+
+static int scsi_merge_bio(struct request *rq, struct bio *bio)
+{
+       struct request_queue *q = rq->q;
+
+       bio->bi_flags &= ~(1 << BIO_SEG_VALID);
+       if (rq_data_dir(rq) == WRITE)
+               bio->bi_rw |= (1 << BIO_RW);
+       blk_queue_bounce(q, &bio);
+
+       if (!rq->bio)
+               blk_rq_bio_prep(q, rq, bio);
+       else if (!q->back_merge_fn(q, rq, bio))
+               return -EINVAL;
+       else {
+               rq->biotail->bi_next = bio;
+               rq->biotail = bio;
+               rq->hard_nr_sectors += bio_sectors(bio);
+               rq->nr_sectors = rq->hard_nr_sectors;
+       }
+
+       return 0;
+}
+
+static int scsi_bi_endio(struct bio *bio, unsigned int bytes_done, int error)
+{
+       if (bio->bi_size)
+               return 1;
+
+       bio_put(bio);
+       return 0;
+}
+
+/**
+ * scsi_req_map_sg - map a scatterlist into a request
+ * @rq:                request to fill
+ * @sg:                scatterlist
+ * @nsegs:     number of elements
+ * @bufflen:   len of buffer
+ * @gfp:       memory allocation flags
+ *
+ * scsi_req_map_sg maps a scatterlist into a request so that the
+ * request can be sent to the block layer. We do not trust the scatterlist
+ * sent to use, as some ULDs use that struct to only organize the pages.
+ */
+static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
+                          int nsegs, unsigned bufflen, gfp_t gfp)
+{
+       struct request_queue *q = rq->q;
+       int nr_pages = (bufflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       unsigned int data_len = 0, len, bytes, off;
+       struct page *page;
+       struct bio *bio = NULL;
+       int i, err, nr_vecs = 0;
+
+       for (i = 0; i < nsegs; i++) {
+               page = sgl[i].page;
+               off = sgl[i].offset;
+               len = sgl[i].length;
+               data_len += len;
+
+               while (len > 0) {
+                       bytes = min_t(unsigned int, len, PAGE_SIZE - off);
+
+                       if (!bio) {
+                               nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages);
+                               nr_pages -= nr_vecs;
+
+                               bio = bio_alloc(gfp, nr_vecs);
+                               if (!bio) {
+                                       err = -ENOMEM;
+                                       goto free_bios;
+                               }
+                               bio->bi_end_io = scsi_bi_endio;
+                       }
+
+                       if (bio_add_pc_page(q, bio, page, bytes, off) !=
+                           bytes) {
+                               bio_put(bio);
+                               err = -EINVAL;
+                               goto free_bios;
+                       }
+
+                       if (bio->bi_vcnt >= nr_vecs) {
+                               err = scsi_merge_bio(rq, bio);
+                               if (err) {
+                                       bio_endio(bio, bio->bi_size, 0);
+                                       goto free_bios;
+                               }
+                               bio = NULL;
+                       }
+
+                       page++;
+                       len -= bytes;
+                       off = 0;
+               }
+       }
+
+       rq->buffer = rq->data = NULL;
+       rq->data_len = data_len;
+       return 0;
+
+free_bios:
+       while ((bio = rq->bio) != NULL) {
+               rq->bio = bio->bi_next;
+               /*
+                * call endio instead of bio_put incase it was bounced
+                */
+               bio_endio(bio, bio->bi_size, 0);
+       }
+
+       return err;
+}
+
+/**
+ * scsi_execute_async - insert request
+ * @sdev:      scsi device
+ * @cmd:       scsi command
+ * @data_direction: data direction
+ * @buffer:    data buffer (this can be a kernel buffer or scatterlist)
+ * @bufflen:   len of buffer
+ * @use_sg:    if buffer is a scatterlist this is the number of elements
+ * @timeout:   request timeout in seconds
+ * @retries:   number of times to retry request
+ * @flags:     or into request flags
+ **/
+int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
+                      int data_direction, void *buffer, unsigned bufflen,
+                      int use_sg, int timeout, int retries, void *privdata,
+                      void (*done)(void *, char *, int, int), gfp_t gfp)
+{
+       struct request *req;
+       struct scsi_io_context *sioc;
+       int err = 0;
+       int write = (data_direction == DMA_TO_DEVICE);
+
+       sioc = kmem_cache_alloc(scsi_io_context_cache, gfp);
+       if (!sioc)
+               return DRIVER_ERROR << 24;
+       memset(sioc, 0, sizeof(*sioc));
+
+       req = blk_get_request(sdev->request_queue, write, gfp);
+       if (!req)
+               goto free_sense;
+       req->flags |= REQ_BLOCK_PC | REQ_QUIET;
+
+       if (use_sg)
+               err = scsi_req_map_sg(req, buffer, use_sg, bufflen, gfp);
+       else if (bufflen)
+               err = blk_rq_map_kern(req->q, req, buffer, bufflen, gfp);
+
+       if (err)
+               goto free_req;
+
+       req->cmd_len = COMMAND_SIZE(cmd[0]);
+       memcpy(req->cmd, cmd, req->cmd_len);
+       req->sense = sioc->sense;
+       req->sense_len = 0;
+       req->timeout = timeout;
+       req->retries = retries;
+       req->end_io_data = sioc;
+
+       sioc->data = privdata;
+       sioc->done = done;
+
+       blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async);
+       return 0;
+
+free_req:
+       blk_put_request(req);
+free_sense:
+       kfree(sioc);
+       return DRIVER_ERROR << 24;
+}
+EXPORT_SYMBOL_GPL(scsi_execute_async);
+
 /*
  * Function:    scsi_init_cmd_errh()
  *
@@ -884,7 +1051,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes,
                        * system where READ CAPACITY failed, we may have read
                        * past the end of the disk.
                        */
-                       if (cmd->device->use_10_for_rw &&
+                       if ((cmd->device->use_10_for_rw &&
+                           sshdr.asc == 0x20 && sshdr.ascq == 0x00) &&
                            (cmd->cmnd[0] == READ_10 ||
                             cmd->cmnd[0] == WRITE_10)) {
                                cmd->device->use_10_for_rw = 0;
@@ -1082,10 +1250,16 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
 static void scsi_generic_done(struct scsi_cmnd *cmd)
 {
        BUG_ON(!blk_pc_request(cmd->request));
-       scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0);
+       /*
+        * This will complete the whole command with uptodate=1 so
+        * as far as the block layer is concerned the command completed
+        * successfully. Since this is a REQ_BLOCK_PC command the
+        * caller should check the request's errors value
+        */
+       scsi_io_completion(cmd, cmd->bufflen, 0);
 }
 
-void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries)
+void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
 {
        struct request *req = cmd->request;
 
@@ -1100,7 +1274,7 @@ void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries)
                cmd->sc_data_direction = DMA_FROM_DEVICE;
        
        cmd->transfersize = req->data_len;
-       cmd->allowed = retries;
+       cmd->allowed = req->retries;
        cmd->timeout_per_command = req->timeout;
 }
 EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd);
@@ -1240,7 +1414,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
                                goto kill;
                        }
                } else {
-                       scsi_setup_blk_pc_cmnd(cmd, 3);
+                       scsi_setup_blk_pc_cmnd(cmd);
                        cmd->done = scsi_generic_done;
                }
        }
@@ -1603,6 +1777,14 @@ int __init scsi_init_queue(void)
 {
        int i;
 
+       scsi_io_context_cache = kmem_cache_create("scsi_io_context",
+                                       sizeof(struct scsi_io_context),
+                                       0, 0, NULL, NULL);
+       if (!scsi_io_context_cache) {
+               printk(KERN_ERR "SCSI: can't init scsi io context cache\n");
+               return -ENOMEM;
+       }
+
        for (i = 0; i < SG_MEMPOOL_NR; i++) {
                struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
                int size = sgp->size * sizeof(struct scatterlist);
@@ -1630,6 +1812,8 @@ void scsi_exit_queue(void)
 {
        int i;
 
+       kmem_cache_destroy(scsi_io_context_cache);
+
        for (i = 0; i < SG_MEMPOOL_NR; i++) {
                struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
                mempool_destroy(sgp->pool);
index d632d9e..f04e7e1 100644 (file)
@@ -40,7 +40,6 @@ extern void scsi_exit_hosts(void);
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
-extern int scsi_insert_special_req(struct scsi_request *sreq, int);
 extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
                struct scsi_request *sreq);
 extern void __scsi_release_request(struct scsi_request *sreq);
@@ -57,7 +56,8 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
 
 /* scsi_devinfo.c */
 extern int scsi_get_device_flags(struct scsi_device *sdev,
-                                unsigned char *vendor, unsigned char *model);
+                                const unsigned char *vendor,
+                                const unsigned char *model);
 extern int __init scsi_init_devinfo(void);
 extern void scsi_exit_devinfo(void);
 
index 4e6709f..05ebb9c 100644 (file)
@@ -74,7 +74,7 @@
 #define SCSI_SCAN_TARGET_PRESENT       1
 #define SCSI_SCAN_LUN_PRESENT          2
 
-static char *scsi_null_device_strs = "nullnullnullnull";
+static const char *scsi_null_device_strs = "nullnullnullnull";
 
 #define MAX_SCSI_LUNS  512
 
index 4634929..15842b1 100644 (file)
@@ -21,7 +21,7 @@
 #include "scsi_priv.h"
 #include "scsi_logging.h"
 
-static struct {
+static const struct {
        enum scsi_device_state  value;
        char                    *name;
 } sdev_states[] = {
@@ -48,7 +48,7 @@ const char *scsi_device_state_name(enum scsi_device_state state)
        return name;
 }
 
-static struct {
+static const struct {
        enum scsi_host_state    value;
        char                    *name;
 } shost_states[] = {
index 2a1a99a..685b997 100644 (file)
@@ -112,7 +112,7 @@ fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
 
 
 /* Convert fc_tgtid_binding_type values to ascii string name */
-static struct {
+static const struct {
        enum fc_tgtid_binding_type      value;
        char                            *name;
        int                             matchlen;
@@ -150,7 +150,7 @@ get_fc_##title##_names(u32 table_key, char *buf)            \
 
 
 /* Convert FC_COS bit values to ascii string name */
-static struct {
+static const struct {
        u32                     value;
        char                    *name;
 } fc_cos_names[] = {
@@ -164,7 +164,7 @@ fc_bitfield_name_search(cos, fc_cos_names)
 
 
 /* Convert FC_PORTSPEED bit values to ascii string name */
-static struct {
+static const struct {
        u32                     value;
        char                    *name;
 } fc_port_speed_names[] = {
@@ -190,7 +190,7 @@ show_fc_fc4s (char *buf, u8 *fc4_list)
 
 
 /* Convert FC_RPORT_ROLE bit values to ascii string name */
-static struct {
+static const struct {
        u32                     value;
        char                    *name;
 } fc_remote_port_role_names[] = {
index 38a53b5..46da6fe 100644 (file)
@@ -18,6 +18,7 @@
  *  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/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -378,9 +379,7 @@ static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
 
 /* Translate the period into ns according to the current spec
  * for SDTR/PPR messages */
-static ssize_t
-show_spi_transport_period_helper(struct class_device *cdev, char *buf,
-                                int period)
+static int period_to_str(char *buf, int period)
 {
        int len, picosec;
 
@@ -398,6 +397,14 @@ show_spi_transport_period_helper(struct class_device *cdev, char *buf,
                len = sprint_frac(buf, picosec, 1000);
        }
 
+       return len;
+}
+
+static ssize_t
+show_spi_transport_period_helper(struct class_device *cdev, char *buf,
+                                int period)
+{
+       int len = period_to_str(buf, period);
        buf[len++] = '\n';
        buf[len] = '\0';
        return len;
@@ -1041,12 +1048,133 @@ void spi_display_xfer_agreement(struct scsi_target *starget)
                         tp->hold_mcs ? " HMCS" : "",
                         tmp, tp->offset);
        } else {
-               dev_info(&starget->dev, "%sasynchronous.\n",
+               dev_info(&starget->dev, "%sasynchronous\n",
                                tp->width ? "wide " : "");
        }
 }
 EXPORT_SYMBOL(spi_display_xfer_agreement);
 
+#ifdef CONFIG_SCSI_CONSTANTS
+static const char * const one_byte_msgs[] = {
+/* 0x00 */ "Command Complete", NULL, "Save Pointers",
+/* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
+/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
+/* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
+/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
+/* 0x0f */ "Initiate Recovery", "Release Recovery"
+};
+
+static const char * const two_byte_msgs[] = {
+/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag",
+/* 0x23 */ "Ignore Wide Residue"
+};
+
+static const char * const extended_msgs[] = {
+/* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
+/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request",
+/* 0x04 */ "Parallel Protocol Request"
+};
+
+void print_nego(const unsigned char *msg, int per, int off, int width)
+{
+       if (per) {
+               char buf[20];
+               period_to_str(buf, msg[per]);
+               printk("period = %s ns ", buf);
+       }
+
+       if (off)
+               printk("offset = %d ", msg[off]);
+       if (width)
+               printk("width = %d ", 8 << msg[width]);
+}
+
+int spi_print_msg(const unsigned char *msg)
+{
+       int len = 0, i;
+       if (msg[0] == EXTENDED_MESSAGE) {
+               len = 3 + msg[1];
+               if (msg[2] < ARRAY_SIZE(extended_msgs))
+                       printk ("%s ", extended_msgs[msg[2]]); 
+               else 
+                       printk ("Extended Message, reserved code (0x%02x) ",
+                               (int) msg[2]);
+               switch (msg[2]) {
+               case EXTENDED_MODIFY_DATA_POINTER:
+                       printk("pointer = %d", (int) (msg[3] << 24) |
+                               (msg[4] << 16) | (msg[5] << 8) | msg[6]);
+                       break;
+               case EXTENDED_SDTR:
+                       print_nego(msg, 3, 4, 0);
+                       break;
+               case EXTENDED_WDTR:
+                       print_nego(msg, 0, 0, 3);
+                       break;
+               case EXTENDED_PPR:
+                       print_nego(msg, 3, 5, 6);
+                       break;
+               default:
+               for (i = 2; i < len; ++i) 
+                       printk("%02x ", msg[i]);
+               }
+       /* Identify */
+       } else if (msg[0] & 0x80) {
+               printk("Identify disconnect %sallowed %s %d ",
+                       (msg[0] & 0x40) ? "" : "not ",
+                       (msg[0] & 0x20) ? "target routine" : "lun",
+                       msg[0] & 0x7);
+               len = 1;
+       /* Normal One byte */
+       } else if (msg[0] < 0x1f) {
+               if (msg[0] < ARRAY_SIZE(one_byte_msgs))
+                       printk(one_byte_msgs[msg[0]]);
+               else
+                       printk("reserved (%02x) ", msg[0]);
+               len = 1;
+       /* Two byte */
+       } else if (msg[0] <= 0x2f) {
+               if ((msg[0] - 0x20) < ARRAY_SIZE(two_byte_msgs))
+                       printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
+                               msg[1]);
+               else 
+                       printk("reserved two byte (%02x %02x) ", 
+                               msg[0], msg[1]);
+               len = 2;
+       } else 
+               printk("reserved");
+       return len;
+}
+EXPORT_SYMBOL(spi_print_msg);
+
+#else  /* ifndef CONFIG_SCSI_CONSTANTS */
+
+int spi_print_msg(const unsigned char *msg)
+{
+       int len = 0, i;
+
+       if (msg[0] == EXTENDED_MESSAGE) {
+               len = 3 + msg[1];
+               for (i = 0; i < len; ++i)
+                       printk("%02x ", msg[i]);
+       /* Identify */
+       } else if (msg[0] & 0x80) {
+               printk("%02x ", msg[0]);
+               len = 1;
+       /* Normal One byte */
+       } else if (msg[0] < 0x1f) {
+               printk("%02x ", msg[0]);
+               len = 1;
+       /* Two byte */
+       } else if (msg[0] <= 0x2f) {
+               printk("%02x %02x", msg[0], msg[1]);
+               len = 2;
+       } else 
+               printk("%02x ", msg[0]);
+       return len;
+}
+EXPORT_SYMBOL(spi_print_msg);
+#endif /* ! CONFIG_SCSI_CONSTANTS */
+
 #define SETUP_ATTRIBUTE(field)                                         \
        i->private_attrs[count] = class_device_attr_##field;            \
        if (!i->f->set_##field) {                                       \
index 03fcbab..3d3ad7d 100644 (file)
@@ -245,7 +245,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
         * SG_IO from block layer already setup, just copy cdb basically
         */
        if (blk_pc_request(rq)) {
-               scsi_setup_blk_pc_cmnd(SCpnt, SD_PASSTHROUGH_RETRIES);
+               scsi_setup_blk_pc_cmnd(SCpnt);
                if (rq->timeout)
                        timeout = rq->timeout;
 
@@ -1495,9 +1495,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
         */
        if (sdkp->media_present) {
                sd_read_capacity(sdkp, disk->disk_name, buffer);
-               if (sdp->removable)
-                       sd_read_write_protect_flag(sdkp, disk->disk_name,
-                                                  buffer);
+               sd_read_write_protect_flag(sdkp, disk->disk_name, buffer);
                sd_read_cache_type(sdkp, disk->disk_name, buffer);
        }
                
index b55c2a8..221e96e 100644 (file)
@@ -104,8 +104,6 @@ static int sg_allow_dio = SG_ALLOW_DIO_DEF;
 static int sg_add(struct class_device *, struct class_interface *);
 static void sg_remove(struct class_device *, struct class_interface *);
 
-static Scsi_Request *dummy_cmdp;       /* only used for sizeof */
-
 static DEFINE_RWLOCK(sg_dev_arr_lock); /* Also used to lock
                                                           file descriptor list for device */
 
@@ -119,7 +117,7 @@ typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
        unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */
        unsigned bufflen;       /* Size of (aggregate) data buffer */
        unsigned b_malloc_len;  /* actual len malloc'ed in buffer */
-       void *buffer;           /* Data buffer or scatter list (k_use_sg>0) */
+       struct scatterlist *buffer;/* scatter list */
        char dio_in_use;        /* 0->indirect IO (or mmap), 1->dio */
        unsigned char cmd_opcode; /* first byte of command */
 } Sg_scatter_hold;
@@ -128,12 +126,11 @@ struct sg_device;         /* forward declarations */
 struct sg_fd;
 
 typedef struct sg_request {    /* SG_MAX_QUEUE requests outstanding per file */
-       Scsi_Request *my_cmdp;  /* != 0  when request with lower levels */
        struct sg_request *nextrp;      /* NULL -> tail request (slist) */
        struct sg_fd *parentfp; /* NULL -> not in use */
        Sg_scatter_hold data;   /* hold buffer, perhaps scatter list */
        sg_io_hdr_t header;     /* scsi command+info, see <scsi/sg.h> */
-       unsigned char sense_b[sizeof (dummy_cmdp->sr_sense_buffer)];
+       unsigned char sense_b[SCSI_SENSE_BUFFERSIZE];
        char res_used;          /* 1 -> using reserve buffer, 0 -> not ... */
        char orphan;            /* 1 -> drop on sight, 0 -> normal */
        char sg_io_owned;       /* 1 -> packet belongs to SG_IO */
@@ -174,7 +171,8 @@ typedef struct sg_device { /* holds the state of each scsi generic device */
 } Sg_device;
 
 static int sg_fasync(int fd, struct file *filp, int mode);
-static void sg_cmd_done(Scsi_Cmnd * SCpnt);    /* tasklet or soft irq callback */
+/* tasklet or soft irq callback */
+static void sg_cmd_done(void *data, char *sense, int result, int resid);
 static int sg_start_req(Sg_request * srp);
 static void sg_finish_rem_req(Sg_request * srp);
 static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
@@ -195,8 +193,8 @@ static void sg_remove_scat(Sg_scatter_hold * schp);
 static void sg_build_reserve(Sg_fd * sfp, int req_size);
 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
-static char *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
-static void sg_page_free(char *buff, int size);
+static struct page *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
+static void sg_page_free(struct page *page, int size);
 static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
 static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
 static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
@@ -207,7 +205,6 @@ static int sg_res_in_use(Sg_fd * sfp);
 static int sg_allow_access(unsigned char opcode, char dev_type);
 static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
 static Sg_device *sg_get_dev(int dev);
-static inline unsigned char *sg_scatg2virt(const struct scatterlist *sclp);
 #ifdef CONFIG_SCSI_PROC_FS
 static int sg_last_dev(void);
 #endif
@@ -226,6 +223,7 @@ sg_open(struct inode *inode, struct file *filp)
 {
        int dev = iminor(inode);
        int flags = filp->f_flags;
+       struct request_queue *q;
        Sg_device *sdp;
        Sg_fd *sfp;
        int res;
@@ -287,7 +285,9 @@ sg_open(struct inode *inode, struct file *filp)
        }
        if (!sdp->headfp) {     /* no existing opens on this device */
                sdp->sgdebug = 0;
-               sdp->sg_tablesize = sdp->device->host->sg_tablesize;
+               q = sdp->device->request_queue;
+               sdp->sg_tablesize = min(q->max_hw_segments,
+                                       q->max_phys_segments);
        }
        if ((sfp = sg_add_sfp(sdp, dev)))
                filp->private_data = sfp;
@@ -340,6 +340,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
                return -ENXIO;
        SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n",
                                   sdp->disk->disk_name, (int) count));
+
        if (!access_ok(VERIFY_WRITE, buf, count))
                return -EFAULT;
        if (sfp->force_packid && (count >= SZ_SG_HEADER)) {
@@ -491,7 +492,7 @@ sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp)
        if ((hp->mx_sb_len > 0) && hp->sbp) {
                if ((CHECK_CONDITION & hp->masked_status) ||
                    (DRIVER_SENSE & hp->driver_status)) {
-                       int sb_len = sizeof (dummy_cmdp->sr_sense_buffer);
+                       int sb_len = SCSI_SENSE_BUFFERSIZE;
                        sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
                        len = 8 + (int) srp->sense_b[7];        /* Additional sense length field */
                        len = (len > sb_len) ? sb_len : len;
@@ -525,7 +526,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
        Sg_request *srp;
        struct sg_header old_hdr;
        sg_io_hdr_t *hp;
-       unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];
+       unsigned char cmnd[MAX_COMMAND_SIZE];
 
        if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
                return -ENXIO;
@@ -624,7 +625,7 @@ sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
        int k;
        Sg_request *srp;
        sg_io_hdr_t *hp;
-       unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];
+       unsigned char cmnd[MAX_COMMAND_SIZE];
        int timeout;
        unsigned long ul_timeout;
 
@@ -692,11 +693,9 @@ static int
 sg_common_write(Sg_fd * sfp, Sg_request * srp,
                unsigned char *cmnd, int timeout, int blocking)
 {
-       int k;
-       Scsi_Request *SRpnt;
+       int k, data_dir;
        Sg_device *sdp = sfp->parentdp;
        sg_io_hdr_t *hp = &srp->header;
-       request_queue_t *q;
 
        srp->data.cmd_opcode = cmnd[0]; /* hold opcode of command */
        hp->status = 0;
@@ -723,51 +722,36 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
                sg_finish_rem_req(srp);
                return -ENODEV;
        }
-       SRpnt = scsi_allocate_request(sdp->device, GFP_ATOMIC);
-       if (SRpnt == NULL) {
-               SCSI_LOG_TIMEOUT(1, printk("sg_write: no mem\n"));
-               sg_finish_rem_req(srp);
-               return -ENOMEM;
-       }
 
-       srp->my_cmdp = SRpnt;
-       q = SRpnt->sr_device->request_queue;
-       SRpnt->sr_request->rq_disk = sdp->disk;
-       SRpnt->sr_sense_buffer[0] = 0;
-       SRpnt->sr_cmd_len = hp->cmd_len;
-       SRpnt->sr_use_sg = srp->data.k_use_sg;
-       SRpnt->sr_sglist_len = srp->data.sglist_len;
-       SRpnt->sr_bufflen = srp->data.bufflen;
-       SRpnt->sr_underflow = 0;
-       SRpnt->sr_buffer = srp->data.buffer;
        switch (hp->dxfer_direction) {
        case SG_DXFER_TO_FROM_DEV:
        case SG_DXFER_FROM_DEV:
-               SRpnt->sr_data_direction = DMA_FROM_DEVICE;
+               data_dir = DMA_FROM_DEVICE;
                break;
        case SG_DXFER_TO_DEV:
-               SRpnt->sr_data_direction = DMA_TO_DEVICE;
+               data_dir = DMA_TO_DEVICE;
                break;
        case SG_DXFER_UNKNOWN:
-               SRpnt->sr_data_direction = DMA_BIDIRECTIONAL;
+               data_dir = DMA_BIDIRECTIONAL;
                break;
        default:
-               SRpnt->sr_data_direction = DMA_NONE;
+               data_dir = DMA_NONE;
                break;
        }
-       SRpnt->upper_private_data = srp;
-       srp->data.k_use_sg = 0;
-       srp->data.sglist_len = 0;
-       srp->data.bufflen = 0;
-       srp->data.buffer = NULL;
        hp->duration = jiffies_to_msecs(jiffies);
 /* Now send everything of to mid-level. The next time we hear about this
    packet is when sg_cmd_done() is called (i.e. a callback). */
-       scsi_do_req(SRpnt, (void *) cmnd,
-                   (void *) SRpnt->sr_buffer, hp->dxfer_len,
-                   sg_cmd_done, timeout, SG_DEFAULT_RETRIES);
-       /* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
-       return 0;
+       if (scsi_execute_async(sdp->device, cmnd, data_dir, srp->data.buffer,
+                               hp->dxfer_len, srp->data.k_use_sg, timeout,
+                               SG_DEFAULT_RETRIES, srp, sg_cmd_done,
+                               GFP_ATOMIC)) {
+               SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n"));
+               /*
+                * most likely out of mem, but could also be a bad map
+                */
+               return -ENOMEM;
+       } else
+               return 0;
 }
 
 static int
@@ -1156,45 +1140,22 @@ sg_fasync(int fd, struct file *filp, int mode)
        return (retval < 0) ? retval : 0;
 }
 
-static inline unsigned char *
-sg_scatg2virt(const struct scatterlist *sclp)
-{
-       return (sclp && sclp->page) ?
-           (unsigned char *) page_address(sclp->page) + sclp->offset : NULL;
-}
-
 /* When startFinish==1 increments page counts for pages other than the 
-   first of scatter gather elements obtained from __get_free_pages().
+   first of scatter gather elements obtained from alloc_pages().
    When startFinish==0 decrements ... */
 static void
 sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish)
 {
-       void *page_ptr;
+       struct scatterlist *sg = rsv_schp->buffer;
        struct page *page;
        int k, m;
 
        SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, scatg=%d\n", 
                                   startFinish, rsv_schp->k_use_sg));
        /* N.B. correction _not_ applied to base page of each allocation */
-       if (rsv_schp->k_use_sg) {       /* reserve buffer is a scatter gather list */
-               struct scatterlist *sclp = rsv_schp->buffer;
-
-               for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
-                       for (m = PAGE_SIZE; m < sclp->length; m += PAGE_SIZE) {
-                               page_ptr = sg_scatg2virt(sclp) + m;
-                               page = virt_to_page(page_ptr);
-                               if (startFinish)
-                                       get_page(page);
-                               else {
-                                       if (page_count(page) > 0)
-                                               __put_page(page);
-                               }
-                       }
-               }
-       } else {                /* reserve buffer is just a single allocation */
-               for (m = PAGE_SIZE; m < rsv_schp->bufflen; m += PAGE_SIZE) {
-                       page_ptr = (unsigned char *) rsv_schp->buffer + m;
-                       page = virt_to_page(page_ptr);
+       for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+               for (m = PAGE_SIZE; m < sg->length; m += PAGE_SIZE) {
+                       page = sg->page;
                        if (startFinish)
                                get_page(page);
                        else {
@@ -1210,9 +1171,10 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 {
        Sg_fd *sfp;
        struct page *page = NOPAGE_SIGBUS;
-       void *page_ptr = NULL;
-       unsigned long offset;
+       unsigned long offset, len, sa;
        Sg_scatter_hold *rsv_schp;
+       struct scatterlist *sg;
+       int k;
 
        if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data)))
                return page;
@@ -1222,30 +1184,21 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
                return page;
        SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n",
                                   offset, rsv_schp->k_use_sg));
-       if (rsv_schp->k_use_sg) {       /* reserve buffer is a scatter gather list */
-               int k;
-               unsigned long sa = vma->vm_start;
-               unsigned long len;
-               struct scatterlist *sclp = rsv_schp->buffer;
-
-               for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-                    ++k, ++sclp) {
-                       len = vma->vm_end - sa;
-                       len = (len < sclp->length) ? len : sclp->length;
-                       if (offset < len) {
-                               page_ptr = sg_scatg2virt(sclp) + offset;
-                               page = virt_to_page(page_ptr);
-                               get_page(page); /* increment page count */
-                               break;
-                       }
-                       sa += len;
-                       offset -= len;
+       sg = rsv_schp->buffer;
+       sa = vma->vm_start;
+       for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
+            ++k, ++sg) {
+               len = vma->vm_end - sa;
+               len = (len < sg->length) ? len : sg->length;
+               if (offset < len) {
+                       page = sg->page;
+                       get_page(page); /* increment page count */
+                       break;
                }
-       } else {                /* reserve buffer is just a single allocation */
-               page_ptr = (unsigned char *) rsv_schp->buffer + offset;
-               page = virt_to_page(page_ptr);
-               get_page(page); /* increment page count */
+               sa += len;
+               offset -= len;
        }
+
        if (type)
                *type = VM_FAULT_MINOR;
        return page;
@@ -1259,8 +1212,10 @@ static int
 sg_mmap(struct file *filp, struct vm_area_struct *vma)
 {
        Sg_fd *sfp;
-       unsigned long req_sz;
+       unsigned long req_sz, len, sa;
        Sg_scatter_hold *rsv_schp;
+       int k;
+       struct scatterlist *sg;
 
        if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
                return -ENXIO;
@@ -1273,24 +1228,15 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
        if (req_sz > rsv_schp->bufflen)
                return -ENOMEM; /* cannot map more than reserved buffer */
 
-       if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
-               int k;
-               unsigned long sa = vma->vm_start;
-               unsigned long len;
-               struct scatterlist *sclp = rsv_schp->buffer;
-
-               for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-                    ++k, ++sclp) {
-                       if (0 != sclp->offset)
-                               return -EFAULT; /* non page aligned memory ?? */
-                       len = vma->vm_end - sa;
-                       len = (len < sclp->length) ? len : sclp->length;
-                       sa += len;
-               }
-       } else {        /* reserve buffer is just a single allocation */
-               if ((unsigned long) rsv_schp->buffer & (PAGE_SIZE - 1))
-                       return -EFAULT; /* non page aligned memory ?? */
+       sa = vma->vm_start;
+       sg = rsv_schp->buffer;
+       for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
+            ++k, ++sg) {
+               len = vma->vm_end - sa;
+               len = (len < sg->length) ? len : sg->length;
+               sa += len;
        }
+
        if (0 == sfp->mmap_called) {
                sg_rb_correct4mmap(rsv_schp, 1);        /* do only once per fd lifetime */
                sfp->mmap_called = 1;
@@ -1304,21 +1250,16 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
 /* This function is a "bottom half" handler that is called by the
  * mid level when a command is completed (or has failed). */
 static void
-sg_cmd_done(Scsi_Cmnd * SCpnt)
+sg_cmd_done(void *data, char *sense, int result, int resid)
 {
-       Scsi_Request *SRpnt = NULL;
+       Sg_request *srp = data;
        Sg_device *sdp = NULL;
        Sg_fd *sfp;
-       Sg_request *srp = NULL;
        unsigned long iflags;
        unsigned int ms;
 
-       if (SCpnt && (SRpnt = SCpnt->sc_request))
-               srp = (Sg_request *) SRpnt->upper_private_data;
        if (NULL == srp) {
                printk(KERN_ERR "sg_cmd_done: NULL request\n");
-               if (SRpnt)
-                       scsi_release_request(SRpnt);
                return;
        }
        sfp = srp->parentfp;
@@ -1326,49 +1267,34 @@ sg_cmd_done(Scsi_Cmnd * SCpnt)
                sdp = sfp->parentdp;
        if ((NULL == sdp) || sdp->detached) {
                printk(KERN_INFO "sg_cmd_done: device detached\n");
-               scsi_release_request(SRpnt);
                return;
        }
 
-       /* First transfer ownership of data buffers to sg_device object. */
-       srp->data.k_use_sg = SRpnt->sr_use_sg;
-       srp->data.sglist_len = SRpnt->sr_sglist_len;
-       srp->data.bufflen = SRpnt->sr_bufflen;
-       srp->data.buffer = SRpnt->sr_buffer;
-       /* now clear out request structure */
-       SRpnt->sr_use_sg = 0;
-       SRpnt->sr_sglist_len = 0;
-       SRpnt->sr_bufflen = 0;
-       SRpnt->sr_buffer = NULL;
-       SRpnt->sr_underflow = 0;
-       SRpnt->sr_request->rq_disk = NULL; /* "sg" _disowns_ request blk */
-
-       srp->my_cmdp = NULL;
 
        SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
-               sdp->disk->disk_name, srp->header.pack_id, (int) SRpnt->sr_result));
-       srp->header.resid = SCpnt->resid;
+               sdp->disk->disk_name, srp->header.pack_id, result));
+       srp->header.resid = resid;
        ms = jiffies_to_msecs(jiffies);
        srp->header.duration = (ms > srp->header.duration) ?
                                (ms - srp->header.duration) : 0;
-       if (0 != SRpnt->sr_result) {
+       if (0 != result) {
                struct scsi_sense_hdr sshdr;
 
-               memcpy(srp->sense_b, SRpnt->sr_sense_buffer,
-                      sizeof (srp->sense_b));
-               srp->header.status = 0xff & SRpnt->sr_result;
-               srp->header.masked_status = status_byte(SRpnt->sr_result);
-               srp->header.msg_status = msg_byte(SRpnt->sr_result);
-               srp->header.host_status = host_byte(SRpnt->sr_result);
-               srp->header.driver_status = driver_byte(SRpnt->sr_result);
+               memcpy(srp->sense_b, sense, sizeof (srp->sense_b));
+               srp->header.status = 0xff & result;
+               srp->header.masked_status = status_byte(result);
+               srp->header.msg_status = msg_byte(result);
+               srp->header.host_status = host_byte(result);
+               srp->header.driver_status = driver_byte(result);
                if ((sdp->sgdebug > 0) &&
                    ((CHECK_CONDITION == srp->header.masked_status) ||
                     (COMMAND_TERMINATED == srp->header.masked_status)))
-                       scsi_print_req_sense("sg_cmd_done", SRpnt);
+                       __scsi_print_sense("sg_cmd_done", sense,
+                                          SCSI_SENSE_BUFFERSIZE);
 
                /* Following if statement is a patch supplied by Eric Youngdale */
-               if (driver_byte(SRpnt->sr_result) != 0
-                   && scsi_command_normalize_sense(SCpnt, &sshdr)
+               if (driver_byte(result) != 0
+                   && scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)
                    && !scsi_sense_is_deferred(&sshdr)
                    && sshdr.sense_key == UNIT_ATTENTION
                    && sdp->device->removable) {
@@ -1379,8 +1305,6 @@ sg_cmd_done(Scsi_Cmnd * SCpnt)
        }
        /* Rely on write phase to clean out srp status values, so no "else" */
 
-       scsi_release_request(SRpnt);
-       SRpnt = NULL;
        if (sfp->closed) {      /* whoops this fd already released, cleanup */
                SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, freeing ...\n"));
                sg_finish_rem_req(srp);
@@ -1431,6 +1355,7 @@ static int sg_sysfs_valid = 0;
 
 static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 {
+       struct request_queue *q = scsidp->request_queue;
        Sg_device *sdp;
        unsigned long iflags;
        void *old_sg_dev_arr = NULL;
@@ -1473,7 +1398,7 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
        sdp->disk = disk;
        sdp->device = scsidp;
        init_waitqueue_head(&sdp->o_excl_wait);
-       sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
+       sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments);
 
        sg_nr_dev++;
        sg_dev_arr[k] = sdp;
@@ -1753,36 +1678,35 @@ sg_finish_rem_req(Sg_request * srp)
 static int
 sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
 {
-       int ret_sz;
-       int elem_sz = sizeof (struct scatterlist);
-       int sg_bufflen = tablesize * elem_sz;
-       int mx_sc_elems = tablesize;
+       int sg_bufflen = tablesize * sizeof(struct scatterlist);
+       unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
-       schp->buffer = sg_page_malloc(sg_bufflen, sfp->low_dma, &ret_sz);
+       /*
+        * TODO: test without low_dma, we should not need it since
+        * the block layer will bounce the buffer for us
+        *
+        * XXX(hch): we shouldn't need GFP_DMA for the actual S/G list.
+        */
+       if (sfp->low_dma)
+                gfp_flags |= GFP_DMA;
+       schp->buffer = kzalloc(sg_bufflen, gfp_flags);
        if (!schp->buffer)
                return -ENOMEM;
-       else if (ret_sz != sg_bufflen) {
-               sg_bufflen = ret_sz;
-               mx_sc_elems = sg_bufflen / elem_sz;
-       }
        schp->sglist_len = sg_bufflen;
-       memset(schp->buffer, 0, sg_bufflen);
-       return mx_sc_elems;     /* number of scat_gath elements allocated */
+       return tablesize;       /* number of scat_gath elements allocated */
 }
 
 #ifdef SG_ALLOW_DIO_CODE
 /* vvvvvvvv  following code borrowed from st driver's direct IO vvvvvvvvv */
-       /* hopefully this generic code will moved to a library */
+       /* TODO: hopefully we can use the generic block layer code */
 
 /* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
    - mapping of all pages not successful
-   - any page is above max_pfn
    (i.e., either completely successful or fails)
 */
 static int 
 st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
-                 unsigned long uaddr, size_t count, int rw,
-                 unsigned long max_pfn)
+                 unsigned long uaddr, size_t count, int rw)
 {
        unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
        unsigned long start = uaddr >> PAGE_SHIFT;
@@ -1828,21 +1752,17 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
                  * probably wrong function for rw==WRITE
                  */
                flush_dcache_page(pages[i]);
-               if (page_to_pfn(pages[i]) > max_pfn)
-                       goto out_unlock;
                /* ?? Is locking needed? I don't think so */
                /* if (TestSetPageLocked(pages[i]))
                   goto out_unlock; */
         }
 
-       /* Populate the scatter/gather list */
-       sgl[0].page = pages[0]; 
+       sgl[0].page = pages[0];
        sgl[0].offset = uaddr & ~PAGE_MASK;
        if (nr_pages > 1) {
                sgl[0].length = PAGE_SIZE - sgl[0].offset;
                count -= sgl[0].length;
                for (i=1; i < nr_pages ; i++) {
-                       sgl[i].offset = 0;
                        sgl[i].page = pages[i]; 
                        sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
                        count -= PAGE_SIZE;
@@ -1855,10 +1775,6 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
        kfree(pages);
        return nr_pages;
 
- out_unlock:
-       /* for (j=0; j < i; j++)
-          unlock_page(pages[j]); */
-       res = 0;
  out_unmap:
        if (res > 0) {
                for (j=0; j < res; j++)
@@ -1904,20 +1820,20 @@ sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
        sg_io_hdr_t *hp = &srp->header;
        Sg_scatter_hold *schp = &srp->data;
        int sg_tablesize = sfp->parentdp->sg_tablesize;
-       struct scatterlist *sgl;
        int mx_sc_elems, res;
        struct scsi_device *sdev = sfp->parentdp->device;
 
        if (((unsigned long)hp->dxferp &
                        queue_dma_alignment(sdev->request_queue)) != 0)
                return 1;
+
        mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
         if (mx_sc_elems <= 0) {
                 return 1;
         }
-       sgl = (struct scatterlist *)schp->buffer;
-       res = st_map_user_pages(sgl, mx_sc_elems, (unsigned long)hp->dxferp, dxfer_len, 
-                               (SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0, ULONG_MAX);
+       res = st_map_user_pages(schp->buffer, mx_sc_elems,
+                               (unsigned long)hp->dxferp, dxfer_len, 
+                               (SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0);
        if (res <= 0)
                return 1;
        schp->k_use_sg = res;
@@ -1932,9 +1848,11 @@ sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
 static int
 sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 {
-       int ret_sz;
+       struct scatterlist *sg;
+       int ret_sz = 0, k, rem_sz, num, mx_sc_elems;
+       int sg_tablesize = sfp->parentdp->sg_tablesize;
        int blk_size = buff_size;
-       unsigned char *p = NULL;
+       struct page *p = NULL;
 
        if ((blk_size < 0) || (!sfp))
                return -EFAULT;
@@ -1944,59 +1862,35 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
        blk_size = (blk_size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
        SCSI_LOG_TIMEOUT(4, printk("sg_build_indirect: buff_size=%d, blk_size=%d\n",
                                   buff_size, blk_size));
-       if (blk_size <= SG_SCATTER_SZ) {
-               p = sg_page_malloc(blk_size, sfp->low_dma, &ret_sz);
-               if (!p)
-                       return -ENOMEM;
-               if (blk_size == ret_sz) {       /* got it on the first attempt */
-                       schp->k_use_sg = 0;
-                       schp->buffer = p;
-                       schp->bufflen = blk_size;
-                       schp->b_malloc_len = blk_size;
-                       return 0;
-               }
-       } else {
-               p = sg_page_malloc(SG_SCATTER_SZ, sfp->low_dma, &ret_sz);
+
+       /* N.B. ret_sz carried into this block ... */
+       mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
+       if (mx_sc_elems < 0)
+               return mx_sc_elems;     /* most likely -ENOMEM */
+
+       for (k = 0, sg = schp->buffer, rem_sz = blk_size;
+            (rem_sz > 0) && (k < mx_sc_elems);
+            ++k, rem_sz -= ret_sz, ++sg) {
+               
+               num = (rem_sz > SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
+               p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
                if (!p)
                        return -ENOMEM;
-       }
-/* Want some local declarations, so start new block ... */
-       {                       /* lets try and build a scatter gather list */
-               struct scatterlist *sclp;
-               int k, rem_sz, num;
-               int mx_sc_elems;
-               int sg_tablesize = sfp->parentdp->sg_tablesize;
-               int first = 1;
-
-               /* N.B. ret_sz carried into this block ... */
-               mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
-               if (mx_sc_elems < 0)
-                       return mx_sc_elems;     /* most likely -ENOMEM */
-
-               for (k = 0, sclp = schp->buffer, rem_sz = blk_size;
-                    (rem_sz > 0) && (k < mx_sc_elems);
-                    ++k, rem_sz -= ret_sz, ++sclp) {
-                       if (first)
-                               first = 0;
-                       else {
-                               num =
-                                   (rem_sz >
-                                    SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
-                               p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
-                               if (!p)
-                                       break;
-                       }
-                       sg_set_buf(sclp, p, ret_sz);
-
-                       SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
-                                         k, sg_scatg2virt(sclp), ret_sz));
-               }               /* end of for loop */
-               schp->k_use_sg = k;
-               SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
-               schp->bufflen = blk_size;
-               if (rem_sz > 0) /* must have failed */
-                       return -ENOMEM;
-       }
+
+               sg->page = p;
+               sg->length = ret_sz;
+
+               SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
+                                 k, p, ret_sz));
+       }               /* end of for loop */
+
+       schp->k_use_sg = k;
+       SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
+
+       schp->bufflen = blk_size;
+       if (rem_sz > 0) /* must have failed */
+               return -ENOMEM;
+
        return 0;
 }
 
@@ -2005,6 +1899,7 @@ sg_write_xfer(Sg_request * srp)
 {
        sg_io_hdr_t *hp = &srp->header;
        Sg_scatter_hold *schp = &srp->data;
+       struct scatterlist *sg = schp->buffer;
        int num_xfer = 0;
        int j, k, onum, usglen, ksglen, res;
        int iovec_count = (int) hp->iovec_count;
@@ -2033,63 +1928,45 @@ sg_write_xfer(Sg_request * srp)
        } else
                onum = 1;
 
-       if (0 == schp->k_use_sg) {      /* kernel has single buffer */
-               for (j = 0, p = schp->buffer; j < onum; ++j) {
-                       res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
-                       if (res)
-                               return res;
-                       usglen = (num_xfer > usglen) ? usglen : num_xfer;
-                       if (__copy_from_user(p, up, usglen))
-                               return -EFAULT;
-                       p += usglen;
-                       num_xfer -= usglen;
-                       if (num_xfer <= 0)
-                               return 0;
-               }
-       } else {                /* kernel using scatter gather list */
-               struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
-
-               ksglen = (int) sclp->length;
-               p = sg_scatg2virt(sclp);
-               for (j = 0, k = 0; j < onum; ++j) {
-                       res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
-                       if (res)
-                               return res;
-
-                       for (; p; ++sclp, ksglen = (int) sclp->length,
-                                 p = sg_scatg2virt(sclp)) {
-                               if (usglen <= 0)
-                                       break;
-                               if (ksglen > usglen) {
-                                       if (usglen >= num_xfer) {
-                                               if (__copy_from_user
-                                                   (p, up, num_xfer))
-                                                       return -EFAULT;
-                                               return 0;
-                                       }
-                                       if (__copy_from_user(p, up, usglen))
-                                               return -EFAULT;
-                                       p += usglen;
-                                       ksglen -= usglen;
-                                       break;
-                               } else {
-                                       if (ksglen >= num_xfer) {
-                                               if (__copy_from_user
-                                                   (p, up, num_xfer))
-                                                       return -EFAULT;
-                                               return 0;
-                                       }
-                                       if (__copy_from_user(p, up, ksglen))
+       ksglen = sg->length;
+       p = page_address(sg->page);
+       for (j = 0, k = 0; j < onum; ++j) {
+               res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
+               if (res)
+                       return res;
+
+               for (; p; ++sg, ksglen = sg->length,
+                    p = page_address(sg->page)) {
+                       if (usglen <= 0)
+                               break;
+                       if (ksglen > usglen) {
+                               if (usglen >= num_xfer) {
+                                       if (__copy_from_user(p, up, num_xfer))
                                                return -EFAULT;
-                                       up += ksglen;
-                                       usglen -= ksglen;
+                                       return 0;
                                }
-                               ++k;
-                               if (k >= schp->k_use_sg)
+                               if (__copy_from_user(p, up, usglen))
+                                       return -EFAULT;
+                               p += usglen;
+                               ksglen -= usglen;
+                               break;
+                       } else {
+                               if (ksglen >= num_xfer) {
+                                       if (__copy_from_user(p, up, num_xfer))
+                                               return -EFAULT;
                                        return 0;
+                               }
+                               if (__copy_from_user(p, up, ksglen))
+                                       return -EFAULT;
+                               up += ksglen;
+                               usglen -= ksglen;
                        }
+                       ++k;
+                       if (k >= schp->k_use_sg)
+                               return 0;
                }
        }
+
        return 0;
 }
 
@@ -2127,29 +2004,25 @@ sg_remove_scat(Sg_scatter_hold * schp)
 {
        SCSI_LOG_TIMEOUT(4, printk("sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg));
        if (schp->buffer && (schp->sglist_len > 0)) {
-               struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
+               struct scatterlist *sg = schp->buffer;
 
                if (schp->dio_in_use) {
 #ifdef SG_ALLOW_DIO_CODE
-                       st_unmap_user_pages(sclp, schp->k_use_sg, TRUE);
+                       st_unmap_user_pages(sg, schp->k_use_sg, TRUE);
 #endif
                } else {
                        int k;
 
-                       for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
-                            ++k, ++sclp) {
+                       for (k = 0; (k < schp->k_use_sg) && sg->page;
+                            ++k, ++sg) {
                                SCSI_LOG_TIMEOUT(5, printk(
                                    "sg_remove_scat: k=%d, a=0x%p, len=%d\n",
-                                   k, sg_scatg2virt(sclp), sclp->length));
-                               sg_page_free(sg_scatg2virt(sclp), sclp->length);
-                               sclp->page = NULL;
-                               sclp->offset = 0;
-                               sclp->length = 0;
+                                   k, sg->page, sg->length));
+                               sg_page_free(sg->page, sg->length);
                        }
                }
-               sg_page_free(schp->buffer, schp->sglist_len);
-       } else if (schp->buffer)
-               sg_page_free(schp->buffer, schp->b_malloc_len);
+               kfree(schp->buffer);
+       }
        memset(schp, 0, sizeof (*schp));
 }
 
@@ -2158,6 +2031,7 @@ sg_read_xfer(Sg_request * srp)
 {
        sg_io_hdr_t *hp = &srp->header;
        Sg_scatter_hold *schp = &srp->data;
+       struct scatterlist *sg = schp->buffer;
        int num_xfer = 0;
        int j, k, onum, usglen, ksglen, res;
        int iovec_count = (int) hp->iovec_count;
@@ -2186,63 +2060,45 @@ sg_read_xfer(Sg_request * srp)
        } else
                onum = 1;
 
-       if (0 == schp->k_use_sg) {      /* kernel has single buffer */
-               for (j = 0, p = schp->buffer; j < onum; ++j) {
-                       res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
-                       if (res)
-                               return res;
-                       usglen = (num_xfer > usglen) ? usglen : num_xfer;
-                       if (__copy_to_user(up, p, usglen))
-                               return -EFAULT;
-                       p += usglen;
-                       num_xfer -= usglen;
-                       if (num_xfer <= 0)
-                               return 0;
-               }
-       } else {                /* kernel using scatter gather list */
-               struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
-
-               ksglen = (int) sclp->length;
-               p = sg_scatg2virt(sclp);
-               for (j = 0, k = 0; j < onum; ++j) {
-                       res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
-                       if (res)
-                               return res;
-
-                       for (; p; ++sclp, ksglen = (int) sclp->length,
-                                 p = sg_scatg2virt(sclp)) {
-                               if (usglen <= 0)
-                                       break;
-                               if (ksglen > usglen) {
-                                       if (usglen >= num_xfer) {
-                                               if (__copy_to_user
-                                                   (up, p, num_xfer))
-                                                       return -EFAULT;
-                                               return 0;
-                                       }
-                                       if (__copy_to_user(up, p, usglen))
-                                               return -EFAULT;
-                                       p += usglen;
-                                       ksglen -= usglen;
-                                       break;
-                               } else {
-                                       if (ksglen >= num_xfer) {
-                                               if (__copy_to_user
-                                                   (up, p, num_xfer))
-                                                       return -EFAULT;
-                                               return 0;
-                                       }
-                                       if (__copy_to_user(up, p, ksglen))
+       p = page_address(sg->page);
+       ksglen = sg->length;
+       for (j = 0, k = 0; j < onum; ++j) {
+               res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
+               if (res)
+                       return res;
+
+               for (; p; ++sg, ksglen = sg->length,
+                    p = page_address(sg->page)) {
+                       if (usglen <= 0)
+                               break;
+                       if (ksglen > usglen) {
+                               if (usglen >= num_xfer) {
+                                       if (__copy_to_user(up, p, num_xfer))
                                                return -EFAULT;
-                                       up += ksglen;
-                                       usglen -= ksglen;
+                                       return 0;
                                }
-                               ++k;
-                               if (k >= schp->k_use_sg)
+                               if (__copy_to_user(up, p, usglen))
+                                       return -EFAULT;
+                               p += usglen;
+                               ksglen -= usglen;
+                               break;
+                       } else {
+                               if (ksglen >= num_xfer) {
+                                       if (__copy_to_user(up, p, num_xfer))
+                                               return -EFAULT;
                                        return 0;
+                               }
+                               if (__copy_to_user(up, p, ksglen))
+                                       return -EFAULT;
+                               up += ksglen;
+                               usglen -= ksglen;
                        }
+                       ++k;
+                       if (k >= schp->k_use_sg)
+                               return 0;
                }
        }
+
        return 0;
 }
 
@@ -2250,37 +2106,32 @@ static int
 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 {
        Sg_scatter_hold *schp = &srp->data;
+       struct scatterlist *sg = schp->buffer;
+       int k, num;
 
        SCSI_LOG_TIMEOUT(4, printk("sg_read_oxfer: num_read_xfer=%d\n",
                                   num_read_xfer));
        if ((!outp) || (num_read_xfer <= 0))
                return 0;
-       if (schp->k_use_sg > 0) {
-               int k, num;
-               struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
-
-               for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
-                    ++k, ++sclp) {
-                       num = (int) sclp->length;
-                       if (num > num_read_xfer) {
-                               if (__copy_to_user
-                                   (outp, sg_scatg2virt(sclp), num_read_xfer))
-                                       return -EFAULT;
+
+       for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) {
+               num = sg->length;
+               if (num > num_read_xfer) {
+                       if (__copy_to_user(outp, page_address(sg->page),
+                                          num_read_xfer))
+                               return -EFAULT;
+                       break;
+               } else {
+                       if (__copy_to_user(outp, page_address(sg->page),
+                                          num))
+                               return -EFAULT;
+                       num_read_xfer -= num;
+                       if (num_read_xfer <= 0)
                                break;
-                       } else {
-                               if (__copy_to_user
-                                   (outp, sg_scatg2virt(sclp), num))
-                                       return -EFAULT;
-                               num_read_xfer -= num;
-                               if (num_read_xfer <= 0)
-                                       break;
-                               outp += num;
-                       }
+                       outp += num;
                }
-       } else {
-               if (__copy_to_user(outp, schp->buffer, num_read_xfer))
-                       return -EFAULT;
        }
+
        return 0;
 }
 
@@ -2306,44 +2157,31 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
 {
        Sg_scatter_hold *req_schp = &srp->data;
        Sg_scatter_hold *rsv_schp = &sfp->reserve;
+       struct scatterlist *sg = rsv_schp->buffer;
+       int k, num, rem;
 
        srp->res_used = 1;
        SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
-       size = (size + 1) & (~1);       /* round to even for aha1542 */
-       if (rsv_schp->k_use_sg > 0) {
-               int k, num;
-               int rem = size;
-               struct scatterlist *sclp =
-                   (struct scatterlist *) rsv_schp->buffer;
-
-               for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
-                       num = (int) sclp->length;
-                       if (rem <= num) {
-                               if (0 == k) {
-                                       req_schp->k_use_sg = 0;
-                                       req_schp->buffer = sg_scatg2virt(sclp);
-                               } else {
-                                       sfp->save_scat_len = num;
-                                       sclp->length = (unsigned) rem;
-                                       req_schp->k_use_sg = k + 1;
-                                       req_schp->sglist_len =
-                                           rsv_schp->sglist_len;
-                                       req_schp->buffer = rsv_schp->buffer;
-                               }
-                               req_schp->bufflen = size;
-                               req_schp->b_malloc_len = rsv_schp->b_malloc_len;
-                               break;
-                       } else
-                               rem -= num;
-               }
-               if (k >= rsv_schp->k_use_sg)
-                       SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
-       } else {
-               req_schp->k_use_sg = 0;
-               req_schp->bufflen = size;
-               req_schp->buffer = rsv_schp->buffer;
-               req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+       rem = size = (size + 1) & (~1); /* round to even for aha1542 */
+
+       for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+               num = sg->length;
+               if (rem <= num) {
+                       sfp->save_scat_len = num;
+                       sg->length = rem;
+                       req_schp->k_use_sg = k + 1;
+                       req_schp->sglist_len = rsv_schp->sglist_len;
+                       req_schp->buffer = rsv_schp->buffer;
+
+                       req_schp->bufflen = size;
+                       req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+                       break;
+               } else
+                       rem -= num;
        }
+
+       if (k >= rsv_schp->k_use_sg)
+               SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
 }
 
 static void
@@ -2355,11 +2193,10 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
        SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->k_use_sg=%d\n",
                                   (int) req_schp->k_use_sg));
        if ((rsv_schp->k_use_sg > 0) && (req_schp->k_use_sg > 0)) {
-               struct scatterlist *sclp =
-                   (struct scatterlist *) rsv_schp->buffer;
+               struct scatterlist *sg = rsv_schp->buffer;
 
                if (sfp->save_scat_len > 0)
-                       (sclp + (req_schp->k_use_sg - 1))->length =
+                       (sg + (req_schp->k_use_sg - 1))->length =
                            (unsigned) sfp->save_scat_len;
                else
                        SCSI_LOG_TIMEOUT(1, printk ("sg_unlink_reserve: BAD save_scat_len\n"));
@@ -2445,7 +2282,6 @@ sg_add_request(Sg_fd * sfp)
        if (resp) {
                resp->nextrp = NULL;
                resp->header.duration = jiffies_to_msecs(jiffies);
-               resp->my_cmdp = NULL;
        }
        write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
        return resp;
@@ -2463,8 +2299,6 @@ sg_remove_request(Sg_fd * sfp, Sg_request * srp)
        if ((!sfp) || (!srp) || (!sfp->headrp))
                return res;
        write_lock_irqsave(&sfp->rq_list_lock, iflags);
-       if (srp->my_cmdp)
-               srp->my_cmdp->upper_private_data = NULL;
        prev_rp = sfp->headrp;
        if (srp == prev_rp) {
                sfp->headrp = prev_rp->nextrp;
@@ -2507,10 +2341,10 @@ sg_add_sfp(Sg_device * sdp, int dev)
        Sg_fd *sfp;
        unsigned long iflags;
 
-       sfp = (Sg_fd *) sg_page_malloc(sizeof (Sg_fd), 0, NULL);
+       sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN);
        if (!sfp)
                return NULL;
-       memset(sfp, 0, sizeof (Sg_fd));
+
        init_waitqueue_head(&sfp->read_wait);
        rwlock_init(&sfp->rq_list_lock);
 
@@ -2567,7 +2401,7 @@ __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
        }
        sfp->parentdp = NULL;
        SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp:    sfp=0x%p\n", sfp));
-       sg_page_free((char *) sfp, sizeof (Sg_fd));
+       kfree(sfp);
 }
 
 /* Returns 0 in normal case, 1 when detached and sdp object removed */
@@ -2632,10 +2466,10 @@ sg_res_in_use(Sg_fd * sfp)
 }
 
 /* If retSzp==NULL want exact size or fail */
-static char *
+static struct page *
 sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 {
-       char *resp = NULL;
+       struct page *resp = NULL;
        gfp_t page_mask;
        int order, a_size;
        int resSz = rqSz;
@@ -2650,11 +2484,11 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 
        for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
             order++, a_size <<= 1) ;
-       resp = (char *) __get_free_pages(page_mask, order);
+       resp = alloc_pages(page_mask, order);
        while ((!resp) && order && retSzp) {
                --order;
                a_size >>= 1;   /* divide by 2, until PAGE_SIZE */
-               resp = (char *) __get_free_pages(page_mask, order);     /* try half */
+               resp =  alloc_pages(page_mask, order);  /* try half */
                resSz = a_size;
        }
        if (resp) {
@@ -2667,15 +2501,15 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 }
 
 static void
-sg_page_free(char *buff, int size)
+sg_page_free(struct page *page, int size)
 {
        int order, a_size;
 
-       if (!buff)
+       if (!page)
                return;
        for (order = 0, a_size = PAGE_SIZE; a_size < size;
             order++, a_size <<= 1) ;
-       free_pages((unsigned long) buff, order);
+       __free_pages(page, order);
 }
 
 #ifndef MAINTENANCE_IN_CMD
@@ -3067,13 +2901,11 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
                                        cp = "     ";
                        }
                        seq_printf(s, cp);
-                       blen = srp->my_cmdp ? 
-                               srp->my_cmdp->sr_bufflen : srp->data.bufflen;
-                       usg = srp->my_cmdp ? 
-                               srp->my_cmdp->sr_use_sg : srp->data.k_use_sg;
+                       blen = srp->data.bufflen;
+                       usg = srp->data.k_use_sg;
                        seq_printf(s, srp->done ? 
                                   ((1 == srp->done) ?  "rcv:" : "fin:")
-                                  : (srp->my_cmdp ? "act:" : "prior:"));
+                                  : "act:");
                        seq_printf(s, " id=%d blen=%d",
                                   srp->header.pack_id, blen);
                        if (srp->done)
index fb4012b..a4d9be7 100644 (file)
@@ -320,7 +320,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
         * these are already setup, just copy cdb basically
         */
        if (SCpnt->request->flags & REQ_BLOCK_PC) {
-               scsi_setup_blk_pc_cmnd(SCpnt, MAX_RETRIES);
+               scsi_setup_blk_pc_cmnd(SCpnt);
 
                if (SCpnt->timeout_per_command)
                        timeout = SCpnt->timeout_per_command;
@@ -716,7 +716,7 @@ static void get_capabilities(struct scsi_cd *cd)
        unsigned int the_result;
        int retries, rc, n;
 
-       static char *loadmech[] =
+       static const char *loadmech[] =
        {
                "caddy",
                "tray",
index 78274dc..9dde8df 100644 (file)
@@ -68,8 +68,8 @@ void sr_vendor_init(Scsi_CD *cd)
 #ifndef CONFIG_BLK_DEV_SR_VENDOR
        cd->vendor = VENDOR_SCSI3;
 #else
-       char *vendor = cd->device->vendor;
-       char *model = cd->device->model;
+       const char *vendor = cd->device->vendor;
+       const char *model = cd->device->model;
        
        /* default */
        cd->vendor = VENDOR_SCSI3;
index dd592f6..c4aade8 100644 (file)
@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static char *verstr = "20050830";
+static const char *verstr = "20050830";
 
 #include <linux/module.h>
 
@@ -50,7 +50,6 @@ static char *verstr = "20050830";
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
-#include <scsi/scsi_request.h>
 #include <scsi/sg.h>
 
 
@@ -134,7 +133,7 @@ static struct st_dev_parm {
 #endif
 /* Bit reversed order to get same names for same minors with all
    mode counts */
-static char *st_formats[] = {
+static const char *st_formats[] = {
        "",  "r", "k", "s", "l", "t", "o", "u",
        "m", "v", "p", "x", "a", "y", "q", "z"}; 
 
@@ -188,8 +187,6 @@ static int from_buffer(struct st_buffer *, char __user *, int);
 static void move_buffer_data(struct st_buffer *, int);
 static void buf_to_sg(struct st_buffer *, unsigned int);
 
-static int st_map_user_pages(struct scatterlist *, const unsigned int, 
-                            unsigned long, size_t, int, unsigned long);
 static int sgl_map_user_pages(struct scatterlist *, const unsigned int, 
                              unsigned long, size_t, int);
 static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
@@ -313,12 +310,13 @@ static inline char *tape_name(struct scsi_tape *tape)
 }
 
 
-static void st_analyze_sense(struct scsi_request *SRpnt, struct st_cmdstatus *s)
+static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
 {
        const u8 *ucp;
-       const u8 *sense = SRpnt->sr_sense_buffer;
+       const u8 *sense = SRpnt->sense;
 
-       s->have_sense = scsi_request_normalize_sense(SRpnt, &s->sense_hdr);
+       s->have_sense = scsi_normalize_sense(SRpnt->sense,
+                               SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
        s->flags = 0;
 
        if (s->have_sense) {
@@ -345,9 +343,9 @@ static void st_analyze_sense(struct scsi_request *SRpnt, struct st_cmdstatus *s)
 
 
 /* Convert the result to success code */
-static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
+static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
 {
-       int result = SRpnt->sr_result;
+       int result = SRpnt->result;
        u8 scode;
        DEB(const char *stp;)
        char *name = tape_name(STp);
@@ -366,13 +364,12 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
 
         DEB(
         if (debugging) {
-                printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
+                printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
                       name, result,
-                      SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
-                      SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
-                      SRpnt->sr_bufflen);
+                      SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
+                      SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
                if (cmdstatp->have_sense)
-                       scsi_print_req_sense("st", SRpnt);
+                        __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
        } ) /* end DEB */
        if (!debugging) { /* Abnormal conditions for tape */
                if (!cmdstatp->have_sense)
@@ -386,20 +383,21 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
                         /* scode != UNIT_ATTENTION && */
                         scode != BLANK_CHECK &&
                         scode != VOLUME_OVERFLOW &&
-                        SRpnt->sr_cmnd[0] != MODE_SENSE &&
-                        SRpnt->sr_cmnd[0] != TEST_UNIT_READY) {
+                        SRpnt->cmd[0] != MODE_SENSE &&
+                        SRpnt->cmd[0] != TEST_UNIT_READY) {
                                printk(KERN_WARNING "%s: Error with sense data: ", name);
-                               scsi_print_req_sense("st", SRpnt);
+                               __scsi_print_sense("st", SRpnt->sense,
+                                                  SCSI_SENSE_BUFFERSIZE);
                }
        }
 
        if (cmdstatp->fixed_format &&
            STp->cln_mode >= EXTENDED_SENSE_START) {  /* Only fixed format sense */
                if (STp->cln_sense_value)
-                       STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] &
+                       STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
                                               STp->cln_sense_mask) == STp->cln_sense_value);
                else
-                       STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] &
+                       STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
                                               STp->cln_sense_mask) != 0);
        }
        if (cmdstatp->have_sense &&
@@ -411,8 +409,8 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
        if (cmdstatp->have_sense &&
            scode == RECOVERED_ERROR
 #if ST_RECOVERED_WRITE_FATAL
-           && SRpnt->sr_cmnd[0] != WRITE_6
-           && SRpnt->sr_cmnd[0] != WRITE_FILEMARKS
+           && SRpnt->cmd[0] != WRITE_6
+           && SRpnt->cmd[0] != WRITE_FILEMARKS
 #endif
            ) {
                STp->recover_count++;
@@ -420,9 +418,9 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
 
                 DEB(
                if (debugging) {
-                       if (SRpnt->sr_cmnd[0] == READ_6)
+                       if (SRpnt->cmd[0] == READ_6)
                                stp = "read";
-                       else if (SRpnt->sr_cmnd[0] == WRITE_6)
+                       else if (SRpnt->cmd[0] == WRITE_6)
                                stp = "write";
                        else
                                stp = "ioctl";
@@ -438,28 +436,37 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
 
 
 /* Wakeup from interrupt */
-static void st_sleep_done(struct scsi_cmnd * SCpnt)
+static void st_sleep_done(void *data, char *sense, int result, int resid)
 {
-       struct scsi_tape *STp = container_of(SCpnt->request->rq_disk->private_data,
-                                            struct scsi_tape, driver);
+       struct st_request *SRpnt = data;
+       struct scsi_tape *STp = SRpnt->stp;
 
-       (STp->buffer)->cmdstat.midlevel_result = SCpnt->result;
-       SCpnt->request->rq_status = RQ_SCSI_DONE;
+       memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
+       (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
        DEB( STp->write_pending = 0; )
 
-       if (SCpnt->request->waiting)
-               complete(SCpnt->request->waiting);
+       if (SRpnt->waiting)
+               complete(SRpnt->waiting);
+}
+
+static struct st_request *st_allocate_request(void)
+{
+       return kzalloc(sizeof(struct st_request), GFP_KERNEL);
+}
+
+static void st_release_request(struct st_request *streq)
+{
+       kfree(streq);
 }
 
 /* Do the scsi command. Waits until command performed if do_wait is true.
    Otherwise write_behind_check() is used to check that the command
    has finished. */
-static struct scsi_request *
-st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
+static struct st_request *
+st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
           int bytes, int direction, int timeout, int retries, int do_wait)
 {
        struct completion *waiting;
-       unsigned char *bp;
 
        /* if async, make sure there's no command outstanding */
        if (!do_wait && ((STp->buffer)->last_SRpnt)) {
@@ -473,7 +480,7 @@ st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *c
        }
 
        if (SRpnt == NULL) {
-               SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC);
+               SRpnt = st_allocate_request();
                if (SRpnt == NULL) {
                        DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n",
                                     tape_name(STp)); );
@@ -483,6 +490,7 @@ st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *c
                                (STp->buffer)->syscall_result = (-EBUSY);
                        return NULL;
                }
+               SRpnt->stp = STp;
        }
 
        /* If async IO, set last_SRpnt. This ptr tells write_behind_check
@@ -492,32 +500,28 @@ st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *c
 
        waiting = &STp->wait;
        init_completion(waiting);
-       SRpnt->sr_use_sg = STp->buffer->do_dio || (bytes > (STp->buffer)->frp[0].length);
-       if (SRpnt->sr_use_sg) {
-               if (!STp->buffer->do_dio)
-                       buf_to_sg(STp->buffer, bytes);
-               SRpnt->sr_use_sg = (STp->buffer)->sg_segs;
-               bp = (char *) &((STp->buffer)->sg[0]);
-       } else
-               bp = (STp->buffer)->b_data;
-       SRpnt->sr_data_direction = direction;
-       SRpnt->sr_cmd_len = 0;
-       SRpnt->sr_request->waiting = waiting;
-       SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
-       SRpnt->sr_request->rq_disk = STp->disk;
-       SRpnt->sr_request->end_io = blk_end_sync_rq;
-       STp->buffer->cmdstat.have_sense = 0;
+       SRpnt->waiting = waiting;
 
-       scsi_do_req(SRpnt, (void *) cmd, bp, bytes,
-                   st_sleep_done, timeout, retries);
+       if (!STp->buffer->do_dio)
+               buf_to_sg(STp->buffer, bytes);
 
-       if (do_wait) {
+       memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
+       STp->buffer->cmdstat.have_sense = 0;
+       STp->buffer->syscall_result = 0;
+
+       if (scsi_execute_async(STp->device, cmd, direction,
+                       &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
+                              timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
+               /* could not allocate the buffer or request was too large */
+               (STp->buffer)->syscall_result = (-EBUSY);
+               (STp->buffer)->last_SRpnt = NULL;
+       }
+       else if (do_wait) {
                wait_for_completion(waiting);
-               SRpnt->sr_request->waiting = NULL;
-               if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
-                       SRpnt->sr_result |= (DRIVER_ERROR << 24);
+               SRpnt->waiting = NULL;
                (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
        }
+
        return SRpnt;
 }
 
@@ -532,7 +536,7 @@ static int write_behind_check(struct scsi_tape * STp)
        struct st_buffer *STbuffer;
        struct st_partstat *STps;
        struct st_cmdstatus *cmdstatp;
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
 
        STbuffer = STp->buffer;
        if (!STbuffer->writing)
@@ -548,12 +552,10 @@ static int write_behind_check(struct scsi_tape * STp)
        wait_for_completion(&(STp->wait));
        SRpnt = STbuffer->last_SRpnt;
        STbuffer->last_SRpnt = NULL;
-       SRpnt->sr_request->waiting = NULL;
-       if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
-               SRpnt->sr_result |= (DRIVER_ERROR << 24);
+       SRpnt->waiting = NULL;
 
        (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
 
        STbuffer->buffer_bytes -= STbuffer->writing;
        STps = &(STp->ps[STp->partition]);
@@ -593,7 +595,7 @@ static int write_behind_check(struct scsi_tape * STp)
    it messes up the block number). */
 static int cross_eof(struct scsi_tape * STp, int forward)
 {
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
        unsigned char cmd[MAX_COMMAND_SIZE];
 
        cmd[0] = SPACE;
@@ -613,7 +615,7 @@ static int cross_eof(struct scsi_tape * STp, int forward)
        if (!SRpnt)
                return (STp->buffer)->syscall_result;
 
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
        SRpnt = NULL;
 
        if ((STp->buffer)->cmdstat.midlevel_result != 0)
@@ -630,7 +632,7 @@ static int flush_write_buffer(struct scsi_tape * STp)
        int offset, transfer, blks;
        int result;
        unsigned char cmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
        struct st_partstat *STps;
 
        result = write_behind_check(STp);
@@ -688,7 +690,7 @@ static int flush_write_buffer(struct scsi_tape * STp)
                        STp->dirty = 0;
                        (STp->buffer)->buffer_bytes = 0;
                }
-               scsi_release_request(SRpnt);
+               st_release_request(SRpnt);
                SRpnt = NULL;
        }
        return result;
@@ -785,7 +787,7 @@ static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
 }
 
 
-/* Lock or unlock the drive door. Don't use when scsi_request allocated. */
+/* Lock or unlock the drive door. Don't use when st_request allocated. */
 static int do_door_lock(struct scsi_tape * STp, int do_lock)
 {
        int retval, cmd;
@@ -844,7 +846,7 @@ static int test_ready(struct scsi_tape *STp, int do_wait)
        int attentions, waits, max_wait, scode;
        int retval = CHKRES_READY, new_session = 0;
        unsigned char cmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt = NULL;
+       struct st_request *SRpnt = NULL;
        struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
 
        max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
@@ -903,7 +905,7 @@ static int test_ready(struct scsi_tape *STp, int do_wait)
        }
 
        if (SRpnt != NULL)
-               scsi_release_request(SRpnt);
+               st_release_request(SRpnt);
        return retval;
 }
 
@@ -918,7 +920,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
        int i, retval, new_session = 0, do_wait;
        unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
        unsigned short st_flags = filp->f_flags;
-       struct scsi_request *SRpnt = NULL;
+       struct st_request *SRpnt = NULL;
        struct st_modedef *STm;
        struct st_partstat *STps;
        char *name = tape_name(STp);
@@ -993,7 +995,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
                        goto err_out;
                }
 
-               if (!SRpnt->sr_result && !STp->buffer->cmdstat.have_sense) {
+               if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
                        STp->max_block = ((STp->buffer)->b_data[1] << 16) |
                            ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
                        STp->min_block = ((STp->buffer)->b_data[4] << 8) |
@@ -1045,7 +1047,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
                }
                STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
        }
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
        SRpnt = NULL;
         STp->inited = 1;
 
@@ -1196,7 +1198,7 @@ static int st_flush(struct file *filp)
 {
        int result = 0, result2;
        unsigned char cmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
        struct scsi_tape *STp = filp->private_data;
        struct st_modedef *STm = &(STp->modes[STp->current_mode]);
        struct st_partstat *STps = &(STp->ps[STp->partition]);
@@ -1249,7 +1251,7 @@ static int st_flush(struct file *filp)
                      cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
                     (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
                        /* Write successful at EOM */
-                       scsi_release_request(SRpnt);
+                       st_release_request(SRpnt);
                        SRpnt = NULL;
                        if (STps->drv_file >= 0)
                                STps->drv_file++;
@@ -1259,7 +1261,7 @@ static int st_flush(struct file *filp)
                        STps->eof = ST_FM;
                }
                else { /* Write error */
-                       scsi_release_request(SRpnt);
+                       st_release_request(SRpnt);
                        SRpnt = NULL;
                        printk(KERN_ERR "%s: Error on write filemark.\n", name);
                        if (result == 0)
@@ -1400,11 +1402,11 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
                i = STp->try_dio && try_rdio;
        else
                i = STp->try_dio && try_wdio;
+
        if (i && ((unsigned long)buf & queue_dma_alignment(
                                        STp->device->request_queue)) == 0) {
-               i = st_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
-                                     (unsigned long)buf, count, (is_read ? READ : WRITE),
-                                     STp->max_pfn);
+               i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
+                                     (unsigned long)buf, count, (is_read ? READ : WRITE));
                if (i > 0) {
                        STbp->do_dio = i;
                        STbp->buffer_bytes = 0;   /* can be used as transfer counter */
@@ -1449,14 +1451,15 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
 
 
 /* Can be called more than once after each setup_buffer() */
-static void release_buffering(struct scsi_tape *STp)
+static void release_buffering(struct scsi_tape *STp, int is_read)
 {
        struct st_buffer *STbp;
 
        STbp = STp->buffer;
        if (STbp->do_dio) {
-               sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, 0);
+               sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
                STbp->do_dio = 0;
+               STbp->sg_segs = 0;
        }
 }
 
@@ -1472,7 +1475,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
        int async_write;
        unsigned char cmd[MAX_COMMAND_SIZE];
        const char __user *b_point;
-       struct scsi_request *SRpnt = NULL;
+       struct st_request *SRpnt = NULL;
        struct scsi_tape *STp = filp->private_data;
        struct st_modedef *STm;
        struct st_partstat *STps;
@@ -1624,7 +1627,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
                        retval = STbp->syscall_result;
                        goto out;
                }
-               if (async_write) {
+               if (async_write && !STbp->syscall_result) {
                        STbp->writing = transfer;
                        STp->dirty = !(STbp->writing ==
                                       STbp->buffer_bytes);
@@ -1698,7 +1701,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
                        } else {
                                count += do_count;
                                STps->drv_block = (-1);         /* Too cautious? */
-                               retval = (-EIO);
+                               retval = STbp->syscall_result;
                        }
 
                }
@@ -1728,8 +1731,8 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
 
  out:
        if (SRpnt != NULL)
-               scsi_release_request(SRpnt);
-       release_buffering(STp);
+               st_release_request(SRpnt);
+       release_buffering(STp, 0);
        up(&STp->lock);
 
        return retval;
@@ -1742,11 +1745,11 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
    Does release user buffer mapping if it is set.
 */
 static long read_tape(struct scsi_tape *STp, long count,
-                     struct scsi_request ** aSRpnt)
+                     struct st_request ** aSRpnt)
 {
        int transfer, blks, bytes;
        unsigned char cmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
        struct st_modedef *STm;
        struct st_partstat *STps;
        struct st_buffer *STbp;
@@ -1787,7 +1790,7 @@ static long read_tape(struct scsi_tape *STp, long count,
        SRpnt = *aSRpnt;
        SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
                           STp->device->timeout, MAX_RETRIES, 1);
-       release_buffering(STp);
+       release_buffering(STp, 1);
        *aSRpnt = SRpnt;
        if (!SRpnt)
                return STbp->syscall_result;
@@ -1802,10 +1805,10 @@ static long read_tape(struct scsi_tape *STp, long count,
                retval = 1;
                DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
                             name,
-                            SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
-                            SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
-                            SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
-                            SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]));
+                            SRpnt->sense[0], SRpnt->sense[1],
+                            SRpnt->sense[2], SRpnt->sense[3],
+                            SRpnt->sense[4], SRpnt->sense[5],
+                            SRpnt->sense[6], SRpnt->sense[7]));
                if (cmdstatp->have_sense) {
 
                        if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
@@ -1835,7 +1838,7 @@ static long read_tape(struct scsi_tape *STp, long count,
                                                }
                                                STbp->buffer_bytes = bytes - transfer;
                                        } else {
-                                               scsi_release_request(SRpnt);
+                                               st_release_request(SRpnt);
                                                SRpnt = *aSRpnt = NULL;
                                                if (transfer == blks) { /* We did not get anything, error */
                                                        printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
@@ -1929,7 +1932,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
        ssize_t retval = 0;
        ssize_t i, transfer;
        int special, do_dio = 0;
-       struct scsi_request *SRpnt = NULL;
+       struct st_request *SRpnt = NULL;
        struct scsi_tape *STp = filp->private_data;
        struct st_modedef *STm;
        struct st_partstat *STps;
@@ -2054,11 +2057,11 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
 
  out:
        if (SRpnt != NULL) {
-               scsi_release_request(SRpnt);
+               st_release_request(SRpnt);
                SRpnt = NULL;
        }
        if (do_dio) {
-               release_buffering(STp);
+               release_buffering(STp, 1);
                STbp->buffer_bytes = 0;
        }
        up(&STp->lock);
@@ -2284,7 +2287,7 @@ static int st_set_options(struct scsi_tape *STp, long options)
 static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
 {
        unsigned char cmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt = NULL;
+       struct st_request *SRpnt = NULL;
 
        memset(cmd, 0, MAX_COMMAND_SIZE);
        cmd[0] = MODE_SENSE;
@@ -2298,7 +2301,7 @@ static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
        if (SRpnt == NULL)
                return (STp->buffer)->syscall_result;
 
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
 
        return (STp->buffer)->syscall_result;
 }
@@ -2310,7 +2313,7 @@ static int write_mode_page(struct scsi_tape *STp, int page, int slow)
 {
        int pgo;
        unsigned char cmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt = NULL;
+       struct st_request *SRpnt = NULL;
 
        memset(cmd, 0, MAX_COMMAND_SIZE);
        cmd[0] = MODE_SELECT;
@@ -2329,7 +2332,7 @@ static int write_mode_page(struct scsi_tape *STp, int page, int slow)
        if (SRpnt == NULL)
                return (STp->buffer)->syscall_result;
 
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
 
        return (STp->buffer)->syscall_result;
 }
@@ -2412,7 +2415,7 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod
        DEB( char *name = tape_name(STp); )
        unsigned char cmd[MAX_COMMAND_SIZE];
        struct st_partstat *STps;
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
 
        if (STp->ready != ST_READY && !load_code) {
                if (STp->ready == ST_NO_TAPE)
@@ -2455,7 +2458,7 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod
                return (STp->buffer)->syscall_result;
 
        retval = (STp->buffer)->syscall_result;
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
 
        if (!retval) {  /* SCSI command successful */
 
@@ -2503,7 +2506,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
        int ioctl_result;
        int chg_eof = 1;
        unsigned char cmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
        struct st_partstat *STps;
        int fileno, blkno, at_sm, undone;
        int datalen = 0, direction = DMA_NONE;
@@ -2757,7 +2760,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
        ioctl_result = (STp->buffer)->syscall_result;
 
        if (!ioctl_result) {    /* SCSI command successful */
-               scsi_release_request(SRpnt);
+               st_release_request(SRpnt);
                SRpnt = NULL;
                STps->drv_block = blkno;
                STps->drv_file = fileno;
@@ -2872,7 +2875,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
                                /* Try the other possible state of Page Format if not
                                   already tried */
                                STp->use_pf = !STp->use_pf | PF_TESTED;
-                               scsi_release_request(SRpnt);
+                               st_release_request(SRpnt);
                                SRpnt = NULL;
                                return st_int_ioctl(STp, cmd_in, arg);
                        }
@@ -2882,7 +2885,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
                if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
                        STps->eof = ST_EOD;
 
-               scsi_release_request(SRpnt);
+               st_release_request(SRpnt);
                SRpnt = NULL;
        }
 
@@ -2898,7 +2901,7 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti
 {
        int result;
        unsigned char scmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
        DEB( char *name = tape_name(STp); )
 
        if (STp->ready != ST_READY)
@@ -2944,7 +2947,7 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti
                 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
                             *block, *partition));
        }
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
        SRpnt = NULL;
 
        return result;
@@ -2961,7 +2964,7 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition
        unsigned int blk;
        int timeout;
        unsigned char scmd[MAX_COMMAND_SIZE];
-       struct scsi_request *SRpnt;
+       struct st_request *SRpnt;
        DEB( char *name = tape_name(STp); )
 
        if (STp->ready != ST_READY)
@@ -3047,7 +3050,7 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition
                result = 0;
        }
 
-       scsi_release_request(SRpnt);
+       st_release_request(SRpnt);
        SRpnt = NULL;
 
        return result;
@@ -3577,7 +3580,7 @@ static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
 static struct st_buffer *
  new_tape_buffer(int from_initialization, int need_dma, int max_sg)
 {
-       int i, got = 0, segs = 0;
+       int i, got = 0;
        gfp_t priority;
        struct st_buffer *tb;
 
@@ -3594,10 +3597,8 @@ static struct st_buffer *
                return NULL;
        }
        memset(tb, 0, i);
-       tb->frp_segs = tb->orig_frp_segs = segs;
+       tb->frp_segs = tb->orig_frp_segs = 0;
        tb->use_sg = max_sg;
-       if (segs > 0)
-               tb->b_data = page_address(tb->sg[0].page);
        tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
 
        tb->in_use = 1;
@@ -3628,7 +3629,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
        priority = GFP_KERNEL | __GFP_NOWARN;
        if (need_dma)
                priority |= GFP_DMA;
-       for (b_size = PAGE_SIZE, order=0;
+       for (b_size = PAGE_SIZE, order=0; order <= 6 &&
             b_size < new_size - STbuffer->buffer_size;
             order++, b_size *= 2)
                ;  /* empty */
@@ -3670,6 +3671,7 @@ static void normalize_buffer(struct st_buffer * STbuffer)
        }
        STbuffer->frp_segs = STbuffer->orig_frp_segs;
        STbuffer->frp_sg_current = 0;
+       STbuffer->sg_segs = 0;
 }
 
 
@@ -3882,7 +3884,6 @@ static int st_probe(struct device *dev)
        struct st_buffer *buffer;
        int i, j, mode, dev_num, error;
        char *stp;
-       u64 bounce_limit;
 
        if (SDp->type != TYPE_TAPE)
                return -ENODEV;
@@ -3892,7 +3893,8 @@ static int st_probe(struct device *dev)
                return -ENODEV;
        }
 
-       i = SDp->host->sg_tablesize;
+       i = min(SDp->request_queue->max_hw_segments,
+               SDp->request_queue->max_phys_segments);
        if (st_max_sg_segs < i)
                i = st_max_sg_segs;
        buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
@@ -3994,11 +3996,6 @@ static int st_probe(struct device *dev)
        tpnt->long_timeout = ST_LONG_TIMEOUT;
        tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
 
-       bounce_limit = scsi_calculate_bounce_limit(SDp->host) >> PAGE_SHIFT;
-       if (bounce_limit > ULONG_MAX)
-               bounce_limit = ULONG_MAX;
-       tpnt->max_pfn = bounce_limit;
-
        for (i = 0; i < ST_NBR_MODES; i++) {
                STm = &(tpnt->modes[i]);
                STm->defined = 0;
@@ -4077,9 +4074,9 @@ static int st_probe(struct device *dev)
 
        sdev_printk(KERN_WARNING, SDp,
                    "Attached scsi tape %s", tape_name(tpnt));
-       printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n",
+       printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
               tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
-              queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn);
+              queue_dma_alignment(SDp->request_queue) + 1);
 
        return 0;
 
@@ -4185,7 +4182,11 @@ static void scsi_tape_release(struct kref *kref)
 
 static void st_intr(struct scsi_cmnd *SCpnt)
 {
-       scsi_io_completion(SCpnt, (SCpnt->result ? 0: SCpnt->bufflen), 1);
+       /*
+        * The caller should be checking the request's errors
+        * value.
+        */
+       scsi_io_completion(SCpnt, SCpnt->bufflen, 0);
 }
 
 /*
@@ -4197,7 +4198,7 @@ static int st_init_command(struct scsi_cmnd *SCpnt)
        if (!(SCpnt->request->flags & REQ_BLOCK_PC))
                return 0;
 
-       scsi_setup_blk_pc_cmnd(SCpnt, 0);
+       scsi_setup_blk_pc_cmnd(SCpnt);
        SCpnt->done = st_intr;
        return 1;
 }
@@ -4390,34 +4391,6 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
        return;
 }
 
-
-/* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
-   - mapping of all pages not successful
-   - any page is above max_pfn
-   (i.e., either completely successful or fails)
-*/
-static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
-                            unsigned long uaddr, size_t count, int rw,
-                            unsigned long max_pfn)
-{
-       int i, nr_pages;
-
-       nr_pages = sgl_map_user_pages(sgl, max_pages, uaddr, count, rw);
-       if (nr_pages <= 0)
-               return nr_pages;
-
-       for (i=0; i < nr_pages; i++) {
-               if (page_to_pfn(sgl[i].page) > max_pfn)
-                       goto out_unmap;
-       }
-       return nr_pages;
-
- out_unmap:
-       sgl_unmap_user_pages(sgl, nr_pages, 0);
-       return 0;
-}
-
-
 /* The following functions may be useful for a larger audience. */
 static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
                              unsigned long uaddr, size_t count, int rw)
index 790acac..4112090 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/completion.h>
 #include <linux/kref.h>
+#include <scsi/scsi_cmnd.h>
 
 /* Descriptor for analyzed sense data */
 struct st_cmdstatus {
@@ -17,6 +18,17 @@ struct st_cmdstatus {
        u8 deferred;
 };
 
+struct scsi_tape;
+
+/* scsi tape command */
+struct st_request {
+       unsigned char cmd[MAX_COMMAND_SIZE];
+       unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+       int result;
+       struct scsi_tape *stp;
+       struct completion *waiting;
+};
+
 /* The tape buffer descriptor. */
 struct st_buffer {
        unsigned char in_use;
@@ -28,7 +40,7 @@ struct st_buffer {
        int read_pointer;
        int writing;
        int syscall_result;
-       struct scsi_request *last_SRpnt;
+       struct st_request *last_SRpnt;
        struct st_cmdstatus cmdstat;
        unsigned char *b_data;
        unsigned short use_sg;  /* zero or max number of s/g segments for this adapter */
index c041bfd..25cced9 100644 (file)
@@ -70,6 +70,7 @@
  *
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 /*
  * Further development / testing that should be done : 
@@ -2378,7 +2379,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
  * 3..length+1 arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
                    extended_msg[0] = EXTENDED_MESSAGE;
                    /* Accept first byte by clearing ACK */
@@ -2431,7 +2432,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
                default:
                    if (!tmp) {
                        printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-                       scsi_print_msg (extended_msg);
+                       spi_print_msg(extended_msg);
                        printk("\n");
                    } else if (tmp != EXTENDED_MESSAGE)
                        printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2566,7 +2567,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
 
     if (!(msg[0] & 0x80)) {
        printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-       scsi_print_msg(msg);
+       spi_print_msg(msg);
        do_abort(instance);
        return;
     }
index 2d9437d..3659dd7 100644 (file)
@@ -40,7 +40,7 @@
 #ifndef SYM_DEFS_H
 #define SYM_DEFS_H
 
-#define SYM_VERSION "2.2.1"
+#define SYM_VERSION "2.2.2"
 #define SYM_DRIVER_NAME        "sym-" SYM_VERSION
 
 /*
index fd36cf9..9916a2a 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef __FreeBSD__
-#include <dev/sym/sym_glue.h>
-#else
 #include "sym_glue.h"
-#endif
 
 /*
  *  Macros used for all firmwares.
 #define        SYM_FWA_SCR             sym_fw1a_scr
 #define        SYM_FWB_SCR             sym_fw1b_scr
 #define        SYM_FWZ_SCR             sym_fw1z_scr
-#ifdef __FreeBSD__
-#include <dev/sym/sym_fw1.h>
-#else
 #include "sym_fw1.h"
-#endif
 static struct sym_fwa_ofs sym_fw1a_ofs = {
        SYM_GEN_FW_A(struct SYM_FWA_SCR)
 };
 static struct sym_fwb_ofs sym_fw1b_ofs = {
        SYM_GEN_FW_B(struct SYM_FWB_SCR)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       SYM_GEN_B(struct SYM_FWB_SCR, data_io)
-#endif
 };
 static struct sym_fwz_ofs sym_fw1z_ofs = {
        SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
@@ -88,19 +77,12 @@ static struct sym_fwz_ofs sym_fw1z_ofs = {
 #define        SYM_FWA_SCR             sym_fw2a_scr
 #define        SYM_FWB_SCR             sym_fw2b_scr
 #define        SYM_FWZ_SCR             sym_fw2z_scr
-#ifdef __FreeBSD__
-#include <dev/sym/sym_fw2.h>
-#else
 #include "sym_fw2.h"
-#endif
 static struct sym_fwa_ofs sym_fw2a_ofs = {
        SYM_GEN_FW_A(struct SYM_FWA_SCR)
 };
 static struct sym_fwb_ofs sym_fw2b_ofs = {
        SYM_GEN_FW_B(struct SYM_FWB_SCR)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       SYM_GEN_B(struct SYM_FWB_SCR, data_io)
-#endif
        SYM_GEN_B(struct SYM_FWB_SCR, start64)
        SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
 };
index 43f6810..66ec35b 100644 (file)
@@ -92,9 +92,6 @@ struct sym_fwa_ofs {
 };
 struct sym_fwb_ofs {
        SYM_GEN_FW_B(u_short)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       SYM_GEN_B(u_short, data_io)
-#endif
        SYM_GEN_B(u_short, start64)
        SYM_GEN_B(u_short, pm_handle)
 };
@@ -111,9 +108,6 @@ struct sym_fwa_ba {
 };
 struct sym_fwb_ba {
        SYM_GEN_FW_B(u32)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       SYM_GEN_B(u32, data_io)
-#endif
        SYM_GEN_B(u32, start64);
        SYM_GEN_B(u32, pm_handle);
 };
index cdd92d8..7b39f4a 100644 (file)
@@ -197,12 +197,6 @@ struct SYM_FWB_SCR {
        u32 bad_status          [  7];
        u32 wsr_ma_helper       [  4];
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       /* Unknown direction handling */
-       u32 data_io             [  2];
-       u32 data_io_com         [  8];
-       u32 data_io_out         [  7];
-#endif
        /* Data area */
        u32 zero                [  1];
        u32 scratch             [  1];
@@ -1747,48 +1741,6 @@ static struct SYM_FWB_SCR SYM_FWB_SCR = {
        SCR_JUMP,
                PADDR_A (dispatch),
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-}/*-------------------------< DATA_IO >--------------------------*/,{
-       /*
-        *  We jump here if the data direction was unknown at the 
-        *  time we had to queue the command to the scripts processor.
-        *  Pointers had been set as follow in this situation:
-        *    savep   -->   DATA_IO
-        *    lastp   -->   start pointer when DATA_IN
-        *    wlastp  -->   start pointer when DATA_OUT
-        *  This script sets savep and lastp according to the 
-        *  direction chosen by the target.
-        */
-       SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
-               PADDR_B (data_io_out),
-}/*-------------------------< DATA_IO_COM >----------------------*/,{
-       /*
-        *  Direction is DATA IN.
-        */
-       SCR_COPY  (4),
-               HADDR_1 (ccb_head.lastp),
-               HADDR_1 (ccb_head.savep),
-       /*
-        *  Jump to the SCRIPTS according to actual direction.
-        */
-       SCR_COPY  (4),
-               HADDR_1 (ccb_head.savep),
-               RADDR_1 (temp),
-       SCR_RETURN,
-               0,
-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
-       /*
-        *  Direction is DATA OUT.
-        */
-       SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
-               0,
-       SCR_COPY  (4),
-               HADDR_1 (ccb_head.wlastp),
-               HADDR_1 (ccb_head.lastp),
-       SCR_JUMP,
-               PADDR_B(data_io_com),
-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
-
 }/*-------------------------< ZERO >-----------------------------*/,{
        SCR_DATA_ZERO,
 }/*-------------------------< SCRATCH >--------------------------*/,{
index 7ea7151..851f270 100644 (file)
@@ -191,13 +191,6 @@ struct SYM_FWB_SCR {
        u32 pm_wsr_handle       [ 38];
        u32 wsr_ma_helper       [  4];
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       /* Unknown direction handling */
-       u32 data_io             [  2];
-       u32 data_io_in          [  2];
-       u32 data_io_com         [  6];
-       u32 data_io_out         [  8];
-#endif
        /* Data area */
        u32 zero                [  1];
        u32 scratch             [  1];
@@ -1838,51 +1831,6 @@ static struct SYM_FWB_SCR SYM_FWB_SCR = {
        SCR_JUMP,
                PADDR_A (dispatch),
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-}/*-------------------------< DATA_IO >--------------------------*/,{
-       /*
-        *  We jump here if the data direction was unknown at the 
-        *  time we had to queue the command to the scripts processor.
-        *  Pointers had been set as follow in this situation:
-        *    savep   -->   DATA_IO
-        *    lastp   -->   start pointer when DATA_IN
-        *    wlastp  -->   start pointer when DATA_OUT
-        *  This script sets savep and lastp according to the 
-        *  direction chosen by the target.
-        */
-       SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
-               PADDR_B (data_io_out),
-}/*-------------------------< DATA_IO_IN >-----------------------*/,{
-       /*
-        *  Direction is DATA IN.
-        */
-       SCR_LOAD_REL  (scratcha, 4),
-               offsetof (struct sym_ccb, phys.head.lastp),
-}/*-------------------------< DATA_IO_COM >----------------------*/,{
-       SCR_STORE_REL (scratcha, 4),
-               offsetof (struct sym_ccb, phys.head.savep),
-
-       /*
-        *  Jump to the SCRIPTS according to actual direction.
-        */
-       SCR_LOAD_REL  (temp, 4),
-               offsetof (struct sym_ccb, phys.head.savep),
-       SCR_RETURN,
-               0,
-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
-       /*
-        *  Direction is DATA OUT.
-        */
-       SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
-               0,
-       SCR_LOAD_REL  (scratcha, 4),
-               offsetof (struct sym_ccb, phys.head.wlastp),
-       SCR_STORE_REL (scratcha, 4),
-               offsetof (struct sym_ccb, phys.head.lastp),
-       SCR_JUMP,
-               PADDR_B(data_io_com),
-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
-
 }/*-------------------------< ZERO >-----------------------------*/,{
        SCR_DATA_ZERO,
 }/*-------------------------< SCRATCH >--------------------------*/,{
index 7fc0b97..1fffd2b 100644 (file)
@@ -514,9 +514,10 @@ static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struc
  */
 int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
 {
-       int dir;
        struct sym_tcb *tp = &np->target[cp->target];
        struct sym_lcb *lp = sym_lp(tp, cp->lun);
+       u32 lastp, goalp;
+       int dir;
 
        /*
         *  Build the CDB.
@@ -534,15 +535,47 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
                        sym_set_cam_status(cmd, DID_ERROR);
                        goto out_abort;
                }
+
+               /*
+                *  No segments means no data.
+                */
+               if (!cp->segments)
+                       dir = DMA_NONE;
        } else {
                cp->data_len = 0;
                cp->segments = 0;
        }
 
        /*
-        *  Set data pointers.
+        *  Set the data pointer.
         */
-       sym_setup_data_pointers(np, cp, dir);
+       switch (dir) {
+       case DMA_BIDIRECTIONAL:
+               printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np));
+               sym_set_cam_status(cmd, DID_ERROR);
+               goto out_abort;
+       case DMA_TO_DEVICE:
+               goalp = SCRIPTA_BA(np, data_out2) + 8;
+               lastp = goalp - 8 - (cp->segments * (2*4));
+               break;
+       case DMA_FROM_DEVICE:
+               cp->host_flags |= HF_DATA_IN;
+               goalp = SCRIPTA_BA(np, data_in2) + 8;
+               lastp = goalp - 8 - (cp->segments * (2*4));
+               break;
+       case DMA_NONE:
+       default:
+               lastp = goalp = SCRIPTB_BA(np, no_data);
+               break;
+       }
+
+       /*
+        *  Set all pointers values needed by SCRIPTS.
+        */
+       cp->phys.head.lastp = cpu_to_scr(lastp);
+       cp->phys.head.savep = cpu_to_scr(lastp);
+       cp->startp          = cp->phys.head.savep;
+       cp->goalp           = cpu_to_scr(goalp);
 
        /*
         *  When `#ifed 1', the code below makes the driver 
@@ -563,10 +596,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
        /*
         *      activate this job.
         */
-       if (lp)
-               sym_start_next_ccbs(np, lp, 2);
-       else
-               sym_put_start_queue(np, cp);
+       sym_start_next_ccbs(np, lp, 2);
        return 0;
 
 out_abort:
@@ -981,15 +1011,14 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun)
 
 static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
 {
-       struct sym_hcb *np;
-       struct sym_tcb *tp;
+       struct sym_hcb *np = sym_get_hcb(sdev->host);
+       struct sym_tcb *tp = &np->target[sdev->id];
+       struct sym_lcb *lp;
 
        if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
                return -ENXIO;
 
-       np = sym_get_hcb(sdev->host);
-       tp = &np->target[sdev->id];
-
+       tp->starget = sdev->sdev_target;
        /*
         * Fail the device init if the device is flagged NOSCAN at BOOT in
         * the NVRAM.  This may speed up boot and maintain coherency with
@@ -999,34 +1028,40 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
         * lun devices behave badly when asked for a non zero LUN.
         */
 
-       if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
-           ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) {
+       if (tp->usrflags & SYM_SCAN_BOOT_DISABLED) {
                tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
+               starget_printk(KERN_INFO, tp->starget,
+                               "Scan at boot disabled in NVRAM\n");
                return -ENXIO;
        }
 
-       tp->starget = sdev->sdev_target;
+       if (tp->usrflags & SYM_SCAN_LUNS_DISABLED) {
+               if (sdev->lun != 0)
+                       return -ENXIO;
+               starget_printk(KERN_INFO, tp->starget,
+                               "Multiple LUNs disabled in NVRAM\n");
+       }
+
+       lp = sym_alloc_lcb(np, sdev->id, sdev->lun);
+       if (!lp)
+               return -ENOMEM;
+
+       spi_min_period(tp->starget) = tp->usr_period;
+       spi_max_width(tp->starget) = tp->usr_width;
+
        return 0;
 }
 
 /*
  * Linux entry point for device queue sizing.
  */
-static int sym53c8xx_slave_configure(struct scsi_device *device)
+static int sym53c8xx_slave_configure(struct scsi_device *sdev)
 {
-       struct sym_hcb *np = sym_get_hcb(device->host);
-       struct sym_tcb *tp = &np->target[device->id];
-       struct sym_lcb *lp;
+       struct sym_hcb *np = sym_get_hcb(sdev->host);
+       struct sym_tcb *tp = &np->target[sdev->id];
+       struct sym_lcb *lp = sym_lp(tp, sdev->lun);
        int reqtags, depth_to_use;
 
-       /*
-        *  Allocate the LCB if not yet.
-        *  If it fail, we may well be in the sh*t. :)
-        */
-       lp = sym_alloc_lcb(np, device->id, device->lun);
-       if (!lp)
-               return -ENOMEM;
-
        /*
         *  Get user flags.
         */
@@ -1038,10 +1073,10 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
         *  Use at least 2.
         *  Donnot use more than our maximum.
         */
-       reqtags = device_queue_depth(np, device->id, device->lun);
+       reqtags = device_queue_depth(np, sdev->id, sdev->lun);
        if (reqtags > tp->usrtags)
                reqtags = tp->usrtags;
-       if (!device->tagged_supported)
+       if (!sdev->tagged_supported)
                reqtags = 0;
 #if 1 /* Avoid to locally queue commands for no good reasons */
        if (reqtags > SYM_CONF_MAX_TAG)
@@ -1050,19 +1085,30 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
 #else
        depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2);
 #endif
-       scsi_adjust_queue_depth(device,
-                               (device->tagged_supported ?
+       scsi_adjust_queue_depth(sdev,
+                               (sdev->tagged_supported ?
                                 MSG_SIMPLE_TAG : 0),
                                depth_to_use);
        lp->s.scdev_depth = depth_to_use;
-       sym_tune_dev_queuing(tp, device->lun, reqtags);
+       sym_tune_dev_queuing(tp, sdev->lun, reqtags);
 
-       if (!spi_initial_dv(device->sdev_target))
-               spi_dv_device(device);
+       if (!spi_initial_dv(sdev->sdev_target))
+               spi_dv_device(sdev);
 
        return 0;
 }
 
+static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
+{
+       struct sym_hcb *np = sym_get_hcb(sdev->host);
+       struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun);
+
+       if (lp->itlq_tbl)
+               sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL");
+       kfree(lp->cb_tags);
+       sym_mfree_dma(lp, sizeof(*lp), "LCB");
+}
+
 /*
  *  Linux entry point for info() function
  */
@@ -1497,7 +1543,7 @@ static int sym_setup_bus_dma_mask(struct sym_hcb *np)
 {
 #if SYM_CONF_DMA_ADDRESSING_MODE > 0
 #if   SYM_CONF_DMA_ADDRESSING_MODE == 1
-#define        DMA_DAC_MASK    0x000000ffffffffffULL /* 40-bit */
+#define        DMA_DAC_MASK    DMA_40BIT_MASK
 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
 #define        DMA_DAC_MASK    DMA_64BIT_MASK
 #endif
@@ -1926,6 +1972,7 @@ static struct scsi_host_template sym2_template = {
        .queuecommand           = sym53c8xx_queue_command,
        .slave_alloc            = sym53c8xx_slave_alloc,
        .slave_configure        = sym53c8xx_slave_configure,
+       .slave_destroy          = sym53c8xx_slave_destroy,
        .eh_abort_handler       = sym53c8xx_eh_abort_handler,
        .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
        .eh_bus_reset_handler   = sym53c8xx_eh_bus_reset_handler,
index d3d52f1..cc92d0c 100644 (file)
@@ -68,7 +68,6 @@
  */
 #define        SYM_CONF_TIMER_INTERVAL         ((HZ+1)/2)
 
-#define SYM_OPT_HANDLE_DIR_UNKNOWN
 #define SYM_OPT_HANDLE_DEVICE_QUEUEING
 #define SYM_OPT_LIMIT_COMMAND_REORDERING
 
@@ -268,6 +267,5 @@ void sym_xpt_async_bus_reset(struct sym_hcb *np);
 void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target);
 int  sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp);
 void sym_log_bus_error(struct sym_hcb *np);
-void sym_sniff_inquiry(struct sym_hcb *np, struct scsi_cmnd *cmd, int resid);
 
 #endif /* SYM_GLUE_H */
index 1564ca2..8260f04 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <linux/slab.h>
 #include <asm/param.h>         /* for timeouts in units of HZ */
+#include <scsi/scsi_dbg.h>
 
 #include "sym_glue.h"
 #include "sym_nvram.h"
@@ -70,32 +71,12 @@ static void sym_printl_hex(u_char *p, int n)
        printf (".\n");
 }
 
-/*
- *  Print out the content of a SCSI message.
- */
-static int sym_show_msg (u_char * msg)
-{
-       u_char i;
-       printf ("%x",*msg);
-       if (*msg==M_EXTENDED) {
-               for (i=1;i<8;i++) {
-                       if (i-1>msg[1]) break;
-                       printf ("-%x",msg[i]);
-               }
-               return (i+1);
-       } else if ((*msg & 0xf0) == 0x20) {
-               printf ("-%x",msg[1]);
-               return (2);
-       }
-       return (1);
-}
-
 static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
 {
        sym_print_addr(cp->cmd, "%s: ", label);
 
-       sym_show_msg(msg);
-       printf(".\n");
+       spi_print_msg(msg);
+       printf("\n");
 }
 
 static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
@@ -103,8 +84,8 @@ static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_ch
        struct sym_tcb *tp = &np->target[target];
        dev_info(&tp->starget->dev, "%s: ", label);
 
-       sym_show_msg(msg);
-       printf(".\n");
+       spi_print_msg(msg);
+       printf("\n");
 }
 
 /*
@@ -635,29 +616,6 @@ static __inline void sym_init_burst(struct sym_hcb *np, u_char bc)
        }
 }
 
-
-/*
- * Print out the list of targets that have some flag disabled by user.
- */
-static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg)
-{
-       int cnt;
-       int i;
-
-       for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
-               if (i == np->myaddr)
-                       continue;
-               if (np->target[i].usrflags & mask) {
-                       if (!cnt++)
-                               printf("%s: %s disabled for targets",
-                                       sym_name(np), msg);
-                       printf(" %d", i);
-               }
-       }
-       if (cnt)
-               printf(".\n");
-}
-
 /*
  *  Save initial settings of some IO registers.
  *  Assumed to have been set by BIOS.
@@ -962,7 +920,7 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru
                tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
                tp->usrtags = SYM_SETUP_MAX_TAG;
 
-               sym_nvram_setup_target(np, i, nvram);
+               sym_nvram_setup_target(tp, i, nvram);
 
                if (!tp->usrtags)
                        tp->usrflags &= ~SYM_TAGS_ENABLED;
@@ -1005,13 +963,6 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru
                        sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
                        np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
        }
-       /*
-        *  Let user be aware of targets that have some disable flags set.
-        */
-       sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT");
-       if (sym_verbose)
-               sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED,
-                                      "SCAN FOR LUNS");
 
        return 0;
 }
@@ -1523,7 +1474,7 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
 /*
  *  Insert a job into the start queue.
  */
-void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
+static void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
 {
        u_short qidx;
 
@@ -3654,7 +3605,7 @@ static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int
         *  If result is dp_sg = SYM_CONF_MAX_SG, then we are at the 
         *  end of the data.
         */
-       tmp = scr_to_cpu(sym_goalp(cp));
+       tmp = scr_to_cpu(cp->goalp);
        dp_sg = SYM_CONF_MAX_SG;
        if (dp_scr != tmp)
                dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4);
@@ -3761,7 +3712,7 @@ static void sym_modify_dp(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb
         *  And our alchemy:) allows to easily calculate the data 
         *  script address we want to return for the next data phase.
         */
-       dp_ret = cpu_to_scr(sym_goalp(cp));
+       dp_ret = cpu_to_scr(cp->goalp);
        dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4);
 
        /*
@@ -3857,7 +3808,7 @@ int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp)
         *  If all data has been transferred,
         *  there is no residual.
         */
-       if (cp->phys.head.lastp == sym_goalp(cp))
+       if (cp->phys.head.lastp == cp->goalp)
                return resid;
 
        /*
@@ -4664,30 +4615,7 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
                goto out;
        cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
 
-#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
-       /*
-        *  If the LCB is not yet available and the LUN
-        *  has been probed ok, try to allocate the LCB.
-        */
-       if (!lp && sym_is_bit(tp->lun_map, ln)) {
-               lp = sym_alloc_lcb(np, tn, ln);
-               if (!lp)
-                       goto out_free;
-       }
-#endif
-
-       /*
-        *  If the LCB is not available here, then the 
-        *  logical unit is not yet discovered. For those 
-        *  ones only accept 1 SCSI IO per logical unit, 
-        *  since we cannot allow disconnections.
-        */
-       if (!lp) {
-               if (!sym_is_bit(tp->busy0_map, ln))
-                       sym_set_bit(tp->busy0_map, ln);
-               else
-                       goto out_free;
-       } else {
+       {
                /*
                 *  If we have been asked for a tagged command.
                 */
@@ -4840,12 +4768,6 @@ void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp)
                        lp->head.resel_sa =
                                cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
        }
-       /*
-        *  Otherwise, we only accept 1 IO per LUN.
-        *  Clear the bit that keeps track of this IO.
-        */
-       else
-               sym_clr_bit(tp->busy0_map, cp->lun);
 
        /*
         *  We donnot queue more than 1 ccb per target 
@@ -4997,20 +4919,7 @@ static void sym_init_tcb (struct sym_hcb *np, u_char tn)
 struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
 {
        struct sym_tcb *tp = &np->target[tn];
-       struct sym_lcb *lp = sym_lp(tp, ln);
-
-       /*
-        *  Already done, just return.
-        */
-       if (lp)
-               return lp;
-
-       /*
-        *  Donnot allow LUN control block 
-        *  allocation for not probed LUNs.
-        */
-       if (!sym_is_bit(tp->lun_map, ln))
-               return NULL;
+       struct sym_lcb *lp = NULL;
 
        /*
         *  Initialize the target control block if not yet.
@@ -5082,13 +4991,7 @@ struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
        lp->started_max   = SYM_CONF_MAX_TASK;
        lp->started_limit = SYM_CONF_MAX_TASK;
 #endif
-       /*
-        *  If we are busy, count the IO.
-        */
-       if (sym_is_bit(tp->busy0_map, ln)) {
-               lp->busy_itl = 1;
-               sym_clr_bit(tp->busy0_map, ln);
-       }
+
 fail:
        return lp;
 }
@@ -5102,12 +5005,6 @@ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
        struct sym_lcb *lp = sym_lp(tp, ln);
        int i;
 
-       /*
-        *  If LCB not available, try to allocate it.
-        */
-       if (!lp && !(lp = sym_alloc_lcb(np, tn, ln)))
-               goto fail;
-
        /*
         *  Allocate the task table and and the tag allocation 
         *  circular buffer. We want both or none.
@@ -5481,8 +5378,7 @@ finish:
        /*
         *  Donnot start more than 1 command after an error.
         */
-       if (lp)
-               sym_start_next_ccbs(np, lp, 1);
+       sym_start_next_ccbs(np, lp, 1);
 #endif
 }
 
@@ -5520,18 +5416,12 @@ void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
        tp = &np->target[cp->target];
        lp = sym_lp(tp, cp->lun);
 
-       /*
-        *  Assume device discovered on first success.
-        */
-       if (!lp)
-               sym_set_bit(tp->lun_map, cp->lun);
-
        /*
         *  If all data have been transferred, given than no
         *  extended error did occur, there is no residual.
         */
        resid = 0;
-       if (cp->phys.head.lastp != sym_goalp(cp))
+       if (cp->phys.head.lastp != cp->goalp)
                resid = sym_compute_residual(np, cp);
 
        /*
@@ -5551,15 +5441,6 @@ if (resid)
         */
        sym_set_cam_result_ok(cp, cmd, resid);
 
-#ifdef SYM_OPT_SNIFF_INQUIRY
-       /*
-        *  On standard INQUIRY response (EVPD and CmDt 
-        *  not set), sniff out device capabilities.
-        */
-       if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3))
-               sym_sniff_inquiry(np, cmd, resid);
-#endif
-
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
        /*
         *  If max number of started ccbs had been reduced,
@@ -5587,7 +5468,7 @@ if (resid)
        /*
         *  Requeue a couple of awaiting scsi commands.
         */
-       if (lp && !sym_que_empty(&lp->waiting_ccbq))
+       if (!sym_que_empty(&lp->waiting_ccbq))
                sym_start_next_ccbs(np, lp, 2);
 #endif
        /*
@@ -5830,8 +5711,7 @@ void sym_hcb_free(struct sym_hcb *np)
        SYM_QUEHEAD *qp;
        struct sym_ccb *cp;
        struct sym_tcb *tp;
-       struct sym_lcb *lp;
-       int target, lun;
+       int target;
 
        if (np->scriptz0)
                sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
@@ -5857,16 +5737,6 @@ void sym_hcb_free(struct sym_hcb *np)
 
        for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
                tp = &np->target[target];
-               for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) {
-                       lp = sym_lp(tp, lun);
-                       if (!lp)
-                               continue;
-                       if (lp->itlq_tbl)
-                               sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
-                                      "ITLQ_TBL");
-                       kfree(lp->cb_tags);
-                       sym_mfree_dma(lp, sizeof(*lp), "LCB");
-               }
 #if SYM_CONF_MAX_LUN > 1
                kfree(tp->lunmp);
 #endif 
index 3a264a4..2456090 100644 (file)
  *  They may be defined in platform specific headers, if they 
  *  are useful.
  *
- *    SYM_OPT_HANDLE_DIR_UNKNOWN
- *        When this option is set, the SCRIPTS used by the driver 
- *        are able to handle SCSI transfers with direction not 
- *        supplied by user.
- *        (set for Linux-2.0.X)
- *
  *    SYM_OPT_HANDLE_DEVICE_QUEUEING
  *        When this option is set, the driver will use a queue per 
  *        device and handle QUEUE FULL status requeuing internally.
@@ -64,7 +58,6 @@
  *        (set for Linux)
  */
 #if 0
-#define SYM_OPT_HANDLE_DIR_UNKNOWN
 #define SYM_OPT_HANDLE_DEVICE_QUEUEING
 #define SYM_OPT_LIMIT_COMMAND_REORDERING
 #endif
@@ -416,19 +409,6 @@ struct sym_tcb {
        struct sym_lcb **lunmp;         /* Other LCBs [1..MAX_LUN]      */
 #endif
 
-       /*
-        *  Bitmap that tells about LUNs that succeeded at least 
-        *  1 IO and therefore assumed to be a real device.
-        *  Avoid useless allocation of the LCB structure.
-        */
-       u32     lun_map[(SYM_CONF_MAX_LUN+31)/32];
-
-       /*
-        *  Bitmap that tells about LUNs that haven't yet an LCB 
-        *  allocated (not discovered or LCB allocation failed).
-        */
-       u32     busy0_map[(SYM_CONF_MAX_LUN+31)/32];
-
 #ifdef SYM_HAVE_STCB
        /*
         *  O/S specific data structure.
@@ -454,8 +434,10 @@ struct sym_tcb {
         *  Other user settable limits and options.
         *  These limits are read from the NVRAM if present.
         */
-       u_char  usrflags;
-       u_short usrtags;
+       unsigned char   usrflags;
+       unsigned char   usr_period;
+       unsigned char   usr_width;
+       unsigned short  usrtags;
        struct scsi_target *starget;
 };
 
@@ -672,9 +654,6 @@ struct sym_ccbh {
         */
        u32     savep;          /* Jump address to saved data pointer   */
        u32     lastp;          /* SCRIPTS address at end of data       */
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       u32     wlastp;
-#endif
 
        /*
         *  Status fields.
@@ -804,9 +783,6 @@ struct sym_ccb {
        SYM_QUEHEAD link_ccbq;  /* Link to free/busy CCB queue  */
        u32     startp;         /* Initial data pointer         */
        u32     goalp;          /* Expected last data pointer   */
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       u32     wgoalp;
-#endif
        int     ext_sg;         /* Extreme data pointer, used   */
        int     ext_ofs;        /*  to calculate the residual.  */
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
@@ -821,12 +797,6 @@ struct sym_ccb {
 
 #define CCB_BA(cp,lbl) cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-#define        sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp)
-#else
-#define        sym_goalp(cp) (cp->goalp)
-#endif
-
 typedef struct device *m_pool_ident_t;
 
 /*
@@ -1077,7 +1047,6 @@ char *sym_driver_name(void);
 void sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
 int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
 struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision);
-void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
 #endif
@@ -1135,71 +1104,6 @@ bad:
 #error "Unsupported DMA addressing mode"
 #endif
 
-/*
- *  Set up data pointers used by SCRIPTS.
- *  Called from O/S specific code.
- */
-static inline void sym_setup_data_pointers(struct sym_hcb *np,
-               struct sym_ccb *cp, int dir)
-{
-       u32 lastp, goalp;
-
-       /*
-        *  No segments means no data.
-        */
-       if (!cp->segments)
-               dir = DMA_NONE;
-
-       /*
-        *  Set the data pointer.
-        */
-       switch(dir) {
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       case DMA_BIDIRECTIONAL:
-#endif
-       case DMA_TO_DEVICE:
-               goalp = SCRIPTA_BA(np, data_out2) + 8;
-               lastp = goalp - 8 - (cp->segments * (2*4));
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-               cp->wgoalp = cpu_to_scr(goalp);
-               if (dir != DMA_BIDIRECTIONAL)
-                       break;
-               cp->phys.head.wlastp = cpu_to_scr(lastp);
-               /* fall through */
-#else
-               break;
-#endif
-       case DMA_FROM_DEVICE:
-               cp->host_flags |= HF_DATA_IN;
-               goalp = SCRIPTA_BA(np, data_in2) + 8;
-               lastp = goalp - 8 - (cp->segments * (2*4));
-               break;
-       case DMA_NONE:
-       default:
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-               cp->host_flags |= HF_DATA_IN;
-#endif
-               lastp = goalp = SCRIPTB_BA(np, no_data);
-               break;
-       }
-
-       /*
-        *  Set all pointers values needed by SCRIPTS.
-        */
-       cp->phys.head.lastp = cpu_to_scr(lastp);
-       cp->phys.head.savep = cpu_to_scr(lastp);
-       cp->startp          = cp->phys.head.savep;
-       cp->goalp           = cpu_to_scr(goalp);
-
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-       /*
-        *  If direction is unknown, start at data_io.
-        */
-       if (dir == DMA_BIDIRECTIONAL)
-               cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
-#endif
-}
-
 /*
  *  MEMORY ALLOCATOR.
  */
index a34d403..92bf9b1 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef __FreeBSD__
-#include <dev/sym/sym_glue.h>
-#else
 #include "sym_glue.h"
-#endif
 
 /*
  *  Simple power of two buddy-like generic allocator.
index 994b756..15d6929 100644 (file)
@@ -92,29 +92,32 @@ void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sy
  *  Get target set-up from Symbios format NVRAM.
  */
 static void
-sym_Symbios_setup_target(struct sym_hcb *np, int target, Symbios_nvram *nvram)
+sym_Symbios_setup_target(struct sym_tcb *tp, int target, Symbios_nvram *nvram)
 {
-       struct sym_tcb *tp = &np->target[target];
        Symbios_target *tn = &nvram->target[target];
 
-       tp->usrtags =
-               (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SYM_SETUP_MAX_TAG : 0;
-
+       if (!(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED))
+               tp->usrtags = 0;
        if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
                tp->usrflags &= ~SYM_DISC_ENABLED;
        if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
                tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
        if (!(tn->flags & SYMBIOS_SCAN_LUNS))
                tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
+       tp->usr_period = (tn->sync_period + 3) / 4;
+       tp->usr_width = (tn->bus_width == 0x8) ? 0 : 1;
 }
 
+static const unsigned char Tekram_sync[16] = {
+       25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21, 6, 7, 9, 10
+};
+
 /*
  *  Get target set-up from Tekram format NVRAM.
  */
 static void
-sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
+sym_Tekram_setup_target(struct sym_tcb *tp, int target, Tekram_nvram *nvram)
 {
-       struct sym_tcb *tp = &np->target[target];
        struct Tekram_target *tn = &nvram->target[target];
 
        if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
@@ -124,22 +127,22 @@ sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
        if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
                tp->usrflags |= SYM_DISC_ENABLED;
  
-       /* If any device does not support parity, we will not use this option */
-       if (!(tn->flags & TEKRAM_PARITY_CHECK))
-               np->rv_scntl0  &= ~0x0a; /* SCSI parity checking disabled */
+       if (tn->flags & TEKRAM_SYNC_NEGO)
+               tp->usr_period = Tekram_sync[tn->sync_index & 0xf];
+       tp->usr_width = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
 }
 
 /*
  *  Get target setup from NVRAM.
  */
-void sym_nvram_setup_target(struct sym_hcb *np, int target, struct sym_nvram *nvp)
+void sym_nvram_setup_target(struct sym_tcb *tp, int target, struct sym_nvram *nvp)
 {
        switch (nvp->type) {
        case SYM_SYMBIOS_NVRAM:
-               sym_Symbios_setup_target(np, target, &nvp->data.Symbios);
+               sym_Symbios_setup_target(tp, target, &nvp->data.Symbios);
                break;
        case SYM_TEKRAM_NVRAM:
-               sym_Tekram_setup_target(np, target, &nvp->data.Tekram);
+               sym_Tekram_setup_target(tp, target, &nvp->data.Tekram);
                break;
        default:
                break;
index 1538bed..bdfbbb0 100644 (file)
@@ -194,12 +194,12 @@ struct sym_nvram {
 
 #if SYM_CONF_NVRAM_SUPPORT
 void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram);
-void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp);
+void sym_nvram_setup_target (struct sym_tcb *tp, int target, struct sym_nvram *nvp);
 int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp);
 char *sym_nvram_type(struct sym_nvram *nvp);
 #else
 static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { }
-static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { }
+static inline void sym_nvram_setup_target(struct sym_tcb *tp, struct sym_nvram *nvram) { }
 static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
 {
        nvp->type = 0;
diff --git a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h
deleted file mode 100644 (file)
index 20ae2b1..0000000
+++ /dev/null
@@ -1,792 +0,0 @@
-/******************************************************************************
-**  High Performance device driver for the Symbios 53C896 controller.
-**
-**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
-**
-**  This driver also supports all the Symbios 53C8XX controller family, 
-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
-**  revisions of 53C815 controllers.
-**
-**  This driver is based on the Linux port of the FreeBSD ncr driver.
-** 
-**  Copyright (C) 1994  Wolfgang Stanglmeier
-**  
-**-----------------------------------------------------------------------------
-**  
-**  This program is free software; you can redistribute it and/or modify
-**  it under the terms of the GNU General Public License as published by
-**  the Free Software Foundation; either version 2 of the License, or
-**  (at your option) any later version.
-**
-**  This program is distributed in the hope that it will be useful,
-**  but WITHOUT ANY WARRANTY; without even the implied warranty of
-**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-**  GNU General Public License for more details.
-**
-**  You should have received a copy of the GNU General Public License
-**  along with this program; if not, write to the Free Software
-**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-**-----------------------------------------------------------------------------
-**
-**  The Linux port of the FreeBSD ncr driver has been achieved in 
-**  november 1995 by:
-**
-**          Gerard Roudier              <groudier@free.fr>
-**
-**  Being given that this driver originates from the FreeBSD version, and
-**  in order to keep synergy on both, any suggested enhancements and corrections
-**  received on Linux are automatically a potential candidate for the FreeBSD 
-**  version.
-**
-**  The original driver has been written for 386bsd and FreeBSD by
-**          Wolfgang Stanglmeier        <wolf@cologne.de>
-**          Stefan Esser                <se@mi.Uni-Koeln.de>
-**
-**-----------------------------------------------------------------------------
-**
-**  Major contributions:
-**  --------------------
-**
-**  NVRAM detection and reading.
-**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
-**
-*******************************************************************************
-*/
-
-/*==========================================================
-**
-**     Debugging tags
-**
-**==========================================================
-*/
-
-#define DEBUG_ALLOC    (0x0001)
-#define DEBUG_PHASE    (0x0002)
-#define DEBUG_QUEUE    (0x0008)
-#define DEBUG_RESULT   (0x0010)
-#define DEBUG_POINTER  (0x0020)
-#define DEBUG_SCRIPT   (0x0040)
-#define DEBUG_TINY     (0x0080)
-#define DEBUG_TIMING   (0x0100)
-#define DEBUG_NEGO     (0x0200)
-#define DEBUG_TAGS     (0x0400)
-#define DEBUG_SCATTER  (0x0800)
-#define DEBUG_IC        (0x1000)
-
-/*
-**    Enable/Disable debug messages.
-**    Can be changed at runtime too.
-*/
-
-#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
-static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
-       #define DEBUG_FLAGS ncr_debug
-#else
-       #define DEBUG_FLAGS     SCSI_NCR_DEBUG_FLAGS
-#endif
-
-static inline struct list_head *ncr_list_pop(struct list_head *head)
-{
-       if (!list_empty(head)) {
-               struct list_head *elem = head->next;
-
-               list_del(elem);
-               return elem;
-       }
-
-       return NULL;
-}
-
-#ifdef __sparc__
-#include <asm/irq.h>
-#endif
-
-/*==========================================================
-**
-**     Simple power of two buddy-like allocator.
-**
-**     This simple code is not intended to be fast, but to 
-**     provide power of 2 aligned memory allocations.
-**     Since the SCRIPTS processor only supplies 8 bit 
-**     arithmetic, this allocator allows simple and fast 
-**     address calculations  from the SCRIPTS code.
-**     In addition, cache line alignment is guaranteed for 
-**     power of 2 cache line size.
-**     Enhanced in linux-2.3.44 to provide a memory pool 
-**     per pcidev to support dynamic dma mapping. (I would 
-**     have preferred a real bus astraction, btw).
-**
-**==========================================================
-*/
-
-#define MEMO_SHIFT     4       /* 16 bytes minimum memory chunk */
-#if PAGE_SIZE >= 8192
-#define MEMO_PAGE_ORDER        0       /* 1 PAGE  maximum */
-#else
-#define MEMO_PAGE_ORDER        1       /* 2 PAGES maximum */
-#endif
-#define MEMO_FREE_UNUSED       /* Free unused pages immediately */
-#define MEMO_WARN      1
-#define MEMO_GFP_FLAGS GFP_ATOMIC
-#define MEMO_CLUSTER_SHIFT     (PAGE_SHIFT+MEMO_PAGE_ORDER)
-#define MEMO_CLUSTER_SIZE      (1UL << MEMO_CLUSTER_SHIFT)
-#define MEMO_CLUSTER_MASK      (MEMO_CLUSTER_SIZE-1)
-
-typedef u_long m_addr_t;       /* Enough bits to bit-hack addresses */
-typedef struct device *m_bush_t;       /* Something that addresses DMAable */
-
-typedef struct m_link {                /* Link between free memory chunks */
-       struct m_link *next;
-} m_link_s;
-
-typedef struct m_vtob {                /* Virtual to Bus address translation */
-       struct m_vtob *next;
-       m_addr_t vaddr;
-       m_addr_t baddr;
-} m_vtob_s;
-#define VTOB_HASH_SHIFT                5
-#define VTOB_HASH_SIZE         (1UL << VTOB_HASH_SHIFT)
-#define VTOB_HASH_MASK         (VTOB_HASH_SIZE-1)
-#define VTOB_HASH_CODE(m)      \
-       ((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
-
-typedef struct m_pool {                /* Memory pool of a given kind */
-       m_bush_t bush;
-       m_addr_t (*getp)(struct m_pool *);
-       void (*freep)(struct m_pool *, m_addr_t);
-       int nump;
-       m_vtob_s *(vtob[VTOB_HASH_SIZE]);
-       struct m_pool *next;
-       struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
-} m_pool_s;
-
-static void *___m_alloc(m_pool_s *mp, int size)
-{
-       int i = 0;
-       int s = (1 << MEMO_SHIFT);
-       int j;
-       m_addr_t a;
-       m_link_s *h = mp->h;
-
-       if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
-               return NULL;
-
-       while (size > s) {
-               s <<= 1;
-               ++i;
-       }
-
-       j = i;
-       while (!h[j].next) {
-               if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-                       h[j].next = (m_link_s *)mp->getp(mp);
-                       if (h[j].next)
-                               h[j].next->next = NULL;
-                       break;
-               }
-               ++j;
-               s <<= 1;
-       }
-       a = (m_addr_t) h[j].next;
-       if (a) {
-               h[j].next = h[j].next->next;
-               while (j > i) {
-                       j -= 1;
-                       s >>= 1;
-                       h[j].next = (m_link_s *) (a+s);
-                       h[j].next->next = NULL;
-               }
-       }
-#ifdef DEBUG
-       printk("___m_alloc(%d) = %p\n", size, (void *) a);
-#endif
-       return (void *) a;
-}
-
-static void ___m_free(m_pool_s *mp, void *ptr, int size)
-{
-       int i = 0;
-       int s = (1 << MEMO_SHIFT);
-       m_link_s *q;
-       m_addr_t a, b;
-       m_link_s *h = mp->h;
-
-#ifdef DEBUG
-       printk("___m_free(%p, %d)\n", ptr, size);
-#endif
-
-       if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
-               return;
-
-       while (size > s) {
-               s <<= 1;
-               ++i;
-       }
-
-       a = (m_addr_t) ptr;
-
-       while (1) {
-#ifdef MEMO_FREE_UNUSED
-               if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-                       mp->freep(mp, a);
-                       break;
-               }
-#endif
-               b = a ^ s;
-               q = &h[i];
-               while (q->next && q->next != (m_link_s *) b) {
-                       q = q->next;
-               }
-               if (!q->next) {
-                       ((m_link_s *) a)->next = h[i].next;
-                       h[i].next = (m_link_s *) a;
-                       break;
-               }
-               q->next = q->next->next;
-               a = a & b;
-               s <<= 1;
-               ++i;
-       }
-}
-
-static DEFINE_SPINLOCK(ncr53c8xx_lock);
-
-static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
-{
-       void *p;
-
-       p = ___m_alloc(mp, size);
-
-       if (DEBUG_FLAGS & DEBUG_ALLOC)
-               printk ("new %-10s[%4d] @%p.\n", name, size, p);
-
-       if (p)
-               memset(p, 0, size);
-       else if (uflags & MEMO_WARN)
-               printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
-
-       return p;
-}
-
-#define __m_calloc(mp, s, n)   __m_calloc2(mp, s, n, MEMO_WARN)
-
-static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
-{
-       if (DEBUG_FLAGS & DEBUG_ALLOC)
-               printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
-
-       ___m_free(mp, ptr, size);
-
-}
-
-/*
- * With pci bus iommu support, we use a default pool of unmapped memory 
- * for memory we donnot need to DMA from/to and one pool per pcidev for 
- * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
- */
-
-static m_addr_t ___mp0_getp(m_pool_s *mp)
-{
-       m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
-       if (m)
-               ++mp->nump;
-       return m;
-}
-
-static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
-{
-       free_pages(m, MEMO_PAGE_ORDER);
-       --mp->nump;
-}
-
-static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
-
-/*
- * DMAable pools.
- */
-
-/*
- * With pci bus iommu support, we maintain one pool per pcidev and a 
- * hashed reverse table for virtual to bus physical address translations.
- */
-static m_addr_t ___dma_getp(m_pool_s *mp)
-{
-       m_addr_t vp;
-       m_vtob_s *vbp;
-
-       vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
-       if (vbp) {
-               dma_addr_t daddr;
-               vp = (m_addr_t) dma_alloc_coherent(mp->bush,
-                                               PAGE_SIZE<<MEMO_PAGE_ORDER,
-                                               &daddr, GFP_ATOMIC);
-               if (vp) {
-                       int hc = VTOB_HASH_CODE(vp);
-                       vbp->vaddr = vp;
-                       vbp->baddr = daddr;
-                       vbp->next = mp->vtob[hc];
-                       mp->vtob[hc] = vbp;
-                       ++mp->nump;
-                       return vp;
-               }
-       }
-       if (vbp)
-               __m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
-       return 0;
-}
-
-static void ___dma_freep(m_pool_s *mp, m_addr_t m)
-{
-       m_vtob_s **vbpp, *vbp;
-       int hc = VTOB_HASH_CODE(m);
-
-       vbpp = &mp->vtob[hc];
-       while (*vbpp && (*vbpp)->vaddr != m)
-               vbpp = &(*vbpp)->next;
-       if (*vbpp) {
-               vbp = *vbpp;
-               *vbpp = (*vbpp)->next;
-               dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
-                                 (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
-               __m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
-               --mp->nump;
-       }
-}
-
-static inline m_pool_s *___get_dma_pool(m_bush_t bush)
-{
-       m_pool_s *mp;
-       for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
-       return mp;
-}
-
-static m_pool_s *___cre_dma_pool(m_bush_t bush)
-{
-       m_pool_s *mp;
-       mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
-       if (mp) {
-               memset(mp, 0, sizeof(*mp));
-               mp->bush = bush;
-               mp->getp = ___dma_getp;
-               mp->freep = ___dma_freep;
-               mp->next = mp0.next;
-               mp0.next = mp;
-       }
-       return mp;
-}
-
-static void ___del_dma_pool(m_pool_s *p)
-{
-       struct m_pool **pp = &mp0.next;
-
-       while (*pp && *pp != p)
-               pp = &(*pp)->next;
-       if (*pp) {
-               *pp = (*pp)->next;
-               __m_free(&mp0, p, sizeof(*p), "MPOOL");
-       }
-}
-
-static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
-{
-       u_long flags;
-       struct m_pool *mp;
-       void *m = NULL;
-
-       spin_lock_irqsave(&ncr53c8xx_lock, flags);
-       mp = ___get_dma_pool(bush);
-       if (!mp)
-               mp = ___cre_dma_pool(bush);
-       if (mp)
-               m = __m_calloc(mp, size, name);
-       if (mp && !mp->nump)
-               ___del_dma_pool(mp);
-       spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-
-       return m;
-}
-
-static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
-{
-       u_long flags;
-       struct m_pool *mp;
-
-       spin_lock_irqsave(&ncr53c8xx_lock, flags);
-       mp = ___get_dma_pool(bush);
-       if (mp)
-               __m_free(mp, m, size, name);
-       if (mp && !mp->nump)
-               ___del_dma_pool(mp);
-       spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-}
-
-static m_addr_t __vtobus(m_bush_t bush, void *m)
-{
-       u_long flags;
-       m_pool_s *mp;
-       int hc = VTOB_HASH_CODE(m);
-       m_vtob_s *vp = NULL;
-       m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
-
-       spin_lock_irqsave(&ncr53c8xx_lock, flags);
-       mp = ___get_dma_pool(bush);
-       if (mp) {
-               vp = mp->vtob[hc];
-               while (vp && (m_addr_t) vp->vaddr != a)
-                       vp = vp->next;
-       }
-       spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-       return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
-}
-
-#define _m_calloc_dma(np, s, n)                __m_calloc_dma(np->dev, s, n)
-#define _m_free_dma(np, p, s, n)       __m_free_dma(np->dev, p, s, n)
-#define m_calloc_dma(s, n)             _m_calloc_dma(np, s, n)
-#define m_free_dma(p, s, n)            _m_free_dma(np, p, s, n)
-#define _vtobus(np, p)                 __vtobus(np->dev, p)
-#define vtobus(p)                      _vtobus(np, p)
-
-/*
- *  Deal with DMA mapping/unmapping.
- */
-
-/* To keep track of the dma mapping (sg/single) that has been set */
-#define __data_mapped  SCp.phase
-#define __data_mapping SCp.have_data_in
-
-static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-       switch(cmd->__data_mapped) {
-       case 2:
-               dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
-                               cmd->sc_data_direction);
-               break;
-       case 1:
-               dma_unmap_single(dev, cmd->__data_mapping,
-                                cmd->request_bufflen,
-                                cmd->sc_data_direction);
-               break;
-       }
-       cmd->__data_mapped = 0;
-}
-
-static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-       dma_addr_t mapping;
-
-       if (cmd->request_bufflen == 0)
-               return 0;
-
-       mapping = dma_map_single(dev, cmd->request_buffer,
-                                cmd->request_bufflen,
-                                cmd->sc_data_direction);
-       cmd->__data_mapped = 1;
-       cmd->__data_mapping = mapping;
-
-       return mapping;
-}
-
-static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-       int use_sg;
-
-       if (cmd->use_sg == 0)
-               return 0;
-
-       use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
-                       cmd->sc_data_direction);
-       cmd->__data_mapped = 2;
-       cmd->__data_mapping = use_sg;
-
-       return use_sg;
-}
-
-#define unmap_scsi_data(np, cmd)       __unmap_scsi_data(np->dev, cmd)
-#define map_scsi_single_data(np, cmd)  __map_scsi_single_data(np->dev, cmd)
-#define map_scsi_sg_data(np, cmd)      __map_scsi_sg_data(np->dev, cmd)
-
-/*==========================================================
-**
-**     Driver setup.
-**
-**     This structure is initialized from linux config 
-**     options. It can be overridden at boot-up by the boot 
-**     command line.
-**
-**==========================================================
-*/
-static struct ncr_driver_setup
-       driver_setup                    = SCSI_NCR_DRIVER_SETUP;
-
-#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-static struct ncr_driver_setup
-       driver_safe_setup __initdata    = SCSI_NCR_DRIVER_SAFE_SETUP;
-#endif
-
-#define initverbose (driver_setup.verbose)
-#define bootverbose (np->verbose)
-
-
-/*===================================================================
-**
-**     Driver setup from the boot command line
-**
-**===================================================================
-*/
-
-#ifdef MODULE
-#define        ARG_SEP ' '
-#else
-#define        ARG_SEP ','
-#endif
-
-#define OPT_TAGS               1
-#define OPT_MASTER_PARITY      2
-#define OPT_SCSI_PARITY                3
-#define OPT_DISCONNECTION      4
-#define OPT_SPECIAL_FEATURES   5
-#define OPT_UNUSED_1           6
-#define OPT_FORCE_SYNC_NEGO    7
-#define OPT_REVERSE_PROBE      8
-#define OPT_DEFAULT_SYNC       9
-#define OPT_VERBOSE            10
-#define OPT_DEBUG              11
-#define OPT_BURST_MAX          12
-#define OPT_LED_PIN            13
-#define OPT_MAX_WIDE           14
-#define OPT_SETTLE_DELAY       15
-#define OPT_DIFF_SUPPORT       16
-#define OPT_IRQM               17
-#define OPT_PCI_FIX_UP         18
-#define OPT_BUS_CHECK          19
-#define OPT_OPTIMIZE           20
-#define OPT_RECOVERY           21
-#define OPT_SAFE_SETUP         22
-#define OPT_USE_NVRAM          23
-#define OPT_EXCLUDE            24
-#define OPT_HOST_ID            25
-
-#ifdef SCSI_NCR_IARB_SUPPORT
-#define OPT_IARB               26
-#endif
-
-static char setup_token[] __initdata = 
-       "tags:"   "mpar:"
-       "spar:"   "disc:"
-       "specf:"  "ultra:"
-       "fsn:"    "revprob:"
-       "sync:"   "verb:"
-       "debug:"  "burst:"
-       "led:"    "wide:"
-       "settle:" "diff:"
-       "irqm:"   "pcifix:"
-       "buschk:" "optim:"
-       "recovery:"
-       "safe:"   "nvram:"
-       "excl:"   "hostid:"
-#ifdef SCSI_NCR_IARB_SUPPORT
-       "iarb:"
-#endif
-       ;       /* DONNOT REMOVE THIS ';' */
-
-#ifdef MODULE
-#define        ARG_SEP ' '
-#else
-#define        ARG_SEP ','
-#endif
-
-static int __init get_setup_token(char *p)
-{
-       char *cur = setup_token;
-       char *pc;
-       int i = 0;
-
-       while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
-               ++pc;
-               ++i;
-               if (!strncmp(p, cur, pc - cur))
-                       return i;
-               cur = pc;
-       }
-       return 0;
-}
-
-
-static int __init sym53c8xx__setup(char *str)
-{
-#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-       char *cur = str;
-       char *pc, *pv;
-       int i, val, c;
-       int xi = 0;
-
-       while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
-               char *pe;
-
-               val = 0;
-               pv = pc;
-               c = *++pv;
-
-               if      (c == 'n')
-                       val = 0;
-               else if (c == 'y')
-                       val = 1;
-               else
-                       val = (int) simple_strtoul(pv, &pe, 0);
-
-               switch (get_setup_token(cur)) {
-               case OPT_TAGS:
-                       driver_setup.default_tags = val;
-                       if (pe && *pe == '/') {
-                               i = 0;
-                               while (*pe && *pe != ARG_SEP && 
-                                       i < sizeof(driver_setup.tag_ctrl)-1) {
-                                       driver_setup.tag_ctrl[i++] = *pe++;
-                               }
-                               driver_setup.tag_ctrl[i] = '\0';
-                       }
-                       break;
-               case OPT_MASTER_PARITY:
-                       driver_setup.master_parity = val;
-                       break;
-               case OPT_SCSI_PARITY:
-                       driver_setup.scsi_parity = val;
-                       break;
-               case OPT_DISCONNECTION:
-                       driver_setup.disconnection = val;
-                       break;
-               case OPT_SPECIAL_FEATURES:
-                       driver_setup.special_features = val;
-                       break;
-               case OPT_FORCE_SYNC_NEGO:
-                       driver_setup.force_sync_nego = val;
-                       break;
-               case OPT_REVERSE_PROBE:
-                       driver_setup.reverse_probe = val;
-                       break;
-               case OPT_DEFAULT_SYNC:
-                       driver_setup.default_sync = val;
-                       break;
-               case OPT_VERBOSE:
-                       driver_setup.verbose = val;
-                       break;
-               case OPT_DEBUG:
-                       driver_setup.debug = val;
-                       break;
-               case OPT_BURST_MAX:
-                       driver_setup.burst_max = val;
-                       break;
-               case OPT_LED_PIN:
-                       driver_setup.led_pin = val;
-                       break;
-               case OPT_MAX_WIDE:
-                       driver_setup.max_wide = val? 1:0;
-                       break;
-               case OPT_SETTLE_DELAY:
-                       driver_setup.settle_delay = val;
-                       break;
-               case OPT_DIFF_SUPPORT:
-                       driver_setup.diff_support = val;
-                       break;
-               case OPT_IRQM:
-                       driver_setup.irqm = val;
-                       break;
-               case OPT_PCI_FIX_UP:
-                       driver_setup.pci_fix_up = val;
-                       break;
-               case OPT_BUS_CHECK:
-                       driver_setup.bus_check = val;
-                       break;
-               case OPT_OPTIMIZE:
-                       driver_setup.optimize = val;
-                       break;
-               case OPT_RECOVERY:
-                       driver_setup.recovery = val;
-                       break;
-               case OPT_USE_NVRAM:
-                       driver_setup.use_nvram = val;
-                       break;
-               case OPT_SAFE_SETUP:
-                       memcpy(&driver_setup, &driver_safe_setup,
-                               sizeof(driver_setup));
-                       break;
-               case OPT_EXCLUDE:
-                       if (xi < SCSI_NCR_MAX_EXCLUDES)
-                               driver_setup.excludes[xi++] = val;
-                       break;
-               case OPT_HOST_ID:
-                       driver_setup.host_id = val;
-                       break;
-#ifdef SCSI_NCR_IARB_SUPPORT
-               case OPT_IARB:
-                       driver_setup.iarb = val;
-                       break;
-#endif
-               default:
-                       printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
-                       break;
-               }
-
-               if ((cur = strchr(cur, ARG_SEP)) != NULL)
-                       ++cur;
-       }
-#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
-       return 1;
-}
-
-/*===================================================================
-**
-**     Get device queue depth from boot command line.
-**
-**===================================================================
-*/
-#define DEF_DEPTH      (driver_setup.default_tags)
-#define ALL_TARGETS    -2
-#define NO_TARGET      -1
-#define ALL_LUNS       -2
-#define NO_LUN         -1
-
-static int device_queue_depth(int unit, int target, int lun)
-{
-       int c, h, t, u, v;
-       char *p = driver_setup.tag_ctrl;
-       char *ep;
-
-       h = -1;
-       t = NO_TARGET;
-       u = NO_LUN;
-       while ((c = *p++) != 0) {
-               v = simple_strtoul(p, &ep, 0);
-               switch(c) {
-               case '/':
-                       ++h;
-                       t = ALL_TARGETS;
-                       u = ALL_LUNS;
-                       break;
-               case 't':
-                       if (t != target)
-                               t = (target == v) ? v : NO_TARGET;
-                       u = ALL_LUNS;
-                       break;
-               case 'u':
-                       if (u != lun)
-                               u = (lun == v) ? v : NO_LUN;
-                       break;
-               case 'q':
-                       if (h == unit &&
-                               (t == ALL_TARGETS || t == target) &&
-                               (u == ALL_LUNS    || u == lun))
-                               return v;
-                       break;
-               case '-':
-                       t = ALL_TARGETS;
-                       u = ALL_LUNS;
-                       break;
-               default:
-                       break;
-               }
-               p = ep;
-       }
-       return DEF_DEPTH;
-}
diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h
deleted file mode 100644 (file)
index 139cd0e..0000000
+++ /dev/null
@@ -1,1320 +0,0 @@
-/******************************************************************************
-**  High Performance device driver for the Symbios 53C896 controller.
-**
-**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
-**
-**  This driver also supports all the Symbios 53C8XX controller family, 
-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
-**  revisions of 53C815 controllers.
-**
-**  This driver is based on the Linux port of the FreeBSD ncr driver.
-** 
-**  Copyright (C) 1994  Wolfgang Stanglmeier
-**  
-**-----------------------------------------------------------------------------
-**  
-**  This program is free software; you can redistribute it and/or modify
-**  it under the terms of the GNU General Public License as published by
-**  the Free Software Foundation; either version 2 of the License, or
-**  (at your option) any later version.
-**
-**  This program is distributed in the hope that it will be useful,
-**  but WITHOUT ANY WARRANTY; without even the implied warranty of
-**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-**  GNU General Public License for more details.
-**
-**  You should have received a copy of the GNU General Public License
-**  along with this program; if not, write to the Free Software
-**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-**-----------------------------------------------------------------------------
-**
-**  The Linux port of the FreeBSD ncr driver has been achieved in 
-**  november 1995 by:
-**
-**          Gerard Roudier              <groudier@free.fr>
-**
-**  Being given that this driver originates from the FreeBSD version, and
-**  in order to keep synergy on both, any suggested enhancements and corrections
-**  received on Linux are automatically a potential candidate for the FreeBSD 
-**  version.
-**
-**  The original driver has been written for 386bsd and FreeBSD by
-**          Wolfgang Stanglmeier        <wolf@cologne.de>
-**          Stefan Esser                <se@mi.Uni-Koeln.de>
-**
-**-----------------------------------------------------------------------------
-**
-**  Major contributions:
-**  --------------------
-**
-**  NVRAM detection and reading.
-**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
-**
-**  Added support for MIPS big endian systems.
-**    Carsten Langgaard, carstenl@mips.com
-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-**
-**  Added support for HP PARISC big endian systems.
-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-**
-*******************************************************************************
-*/
-
-#ifndef SYM53C8XX_DEFS_H
-#define SYM53C8XX_DEFS_H
-
-#include <linux/config.h>
-
-/*
-**     If you want a driver as small as possible, donnot define the 
-**     following options.
-*/
-#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-#define SCSI_NCR_DEBUG_INFO_SUPPORT
-
-/*
-**     To disable integrity checking, do not define the 
-**     following option.
-*/
-#ifdef CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
-#      define SCSI_NCR_ENABLE_INTEGRITY_CHECK
-#endif
-
-/* ---------------------------------------------------------------------
-** Take into account kernel configured parameters.
-** Most of these options can be overridden at startup by a command line.
-** ---------------------------------------------------------------------
-*/
-
-/*
- * For Ultra2 and Ultra3 SCSI support option, use special features. 
- *
- * Value (default) means:
- *     bit 0 : all features enabled, except:
- *             bit 1 : PCI Write And Invalidate.
- *             bit 2 : Data Phase Mismatch handling from SCRIPTS.
- *
- * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
- * enabled by the driver.
- */
-#define        SCSI_NCR_SETUP_SPECIAL_FEATURES         (3)
-
-#define SCSI_NCR_MAX_SYNC                      (80)
-
-/*
- * Allow tags from 2 to 256, default 8
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_MAX_TAGS
-#if    CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
-#define SCSI_NCR_MAX_TAGS      (2)
-#elif  CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
-#define SCSI_NCR_MAX_TAGS      (256)
-#else
-#define        SCSI_NCR_MAX_TAGS       CONFIG_SCSI_NCR53C8XX_MAX_TAGS
-#endif
-#else
-#define SCSI_NCR_MAX_TAGS      (8)
-#endif
-
-/*
- * Allow tagged command queuing support if configured with default number 
- * of tags set to max (see above).
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
-#define        SCSI_NCR_SETUP_DEFAULT_TAGS     CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
-#elif  defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
-#define        SCSI_NCR_SETUP_DEFAULT_TAGS     SCSI_NCR_MAX_TAGS
-#else
-#define        SCSI_NCR_SETUP_DEFAULT_TAGS     (0)
-#endif
-
-/*
- * Immediate arbitration
- */
-#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
-#define SCSI_NCR_IARB_SUPPORT
-#endif
-
-/*
- * Sync transfer frequency at startup.
- * Allow from 5Mhz to 80Mhz default 20 Mhz.
- */
-#ifndef        CONFIG_SCSI_NCR53C8XX_SYNC
-#define        CONFIG_SCSI_NCR53C8XX_SYNC      (20)
-#elif  CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
-#undef CONFIG_SCSI_NCR53C8XX_SYNC
-#define        CONFIG_SCSI_NCR53C8XX_SYNC      SCSI_NCR_MAX_SYNC
-#endif
-
-#if    CONFIG_SCSI_NCR53C8XX_SYNC == 0
-#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (255)
-#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 5
-#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (50)
-#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 20
-#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (250/(CONFIG_SCSI_NCR53C8XX_SYNC))
-#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 33
-#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (11)
-#elif  CONFIG_SCSI_NCR53C8XX_SYNC <= 40
-#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (10)
-#else
-#define        SCSI_NCR_SETUP_DEFAULT_SYNC     (9)
-#endif
-
-/*
- * Disallow disconnections at boot-up
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
-#define SCSI_NCR_SETUP_DISCONNECTION   (0)
-#else
-#define SCSI_NCR_SETUP_DISCONNECTION   (1)
-#endif
-
-/*
- * Force synchronous negotiation for all targets
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (1)
-#else
-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (0)
-#endif
-
-/*
- * Disable master parity checking (flawed hardwares need that)
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
-#define SCSI_NCR_SETUP_MASTER_PARITY   (0)
-#else
-#define SCSI_NCR_SETUP_MASTER_PARITY   (1)
-#endif
-
-/*
- * Disable scsi parity checking (flawed devices may need that)
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
-#define SCSI_NCR_SETUP_SCSI_PARITY     (0)
-#else
-#define SCSI_NCR_SETUP_SCSI_PARITY     (1)
-#endif
-
-/*
- * Settle time after reset at boot-up
- */
-#define SCSI_NCR_SETUP_SETTLE_TIME     (2)
-
-/*
-**     Bridge quirks work-around option defaulted to 1.
-*/
-#ifndef        SCSI_NCR_PCIQ_WORK_AROUND_OPT
-#define        SCSI_NCR_PCIQ_WORK_AROUND_OPT   1
-#endif
-
-/*
-**     Work-around common bridge misbehaviour.
-**
-**     - Do not flush posted writes in the opposite 
-**       direction on read.
-**     - May reorder DMA writes to memory.
-**
-**     This option should not affect performances 
-**     significantly, so it is the default.
-*/
-#if    SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
-#define        SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
-#define        SCSI_NCR_PCIQ_MAY_REORDER_WRITES
-#define        SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
-
-/*
-**     Same as option 1, but also deal with 
-**     misconfigured interrupts.
-**
-**     - Edge triggerred instead of level sensitive.
-**     - No interrupt line connected.
-**     - IRQ number misconfigured.
-**     
-**     If no interrupt is delivered, the driver will 
-**     catch the interrupt conditions 10 times per 
-**     second. No need to say that this option is 
-**     not recommended.
-*/
-#elif  SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
-#define        SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
-#define        SCSI_NCR_PCIQ_MAY_REORDER_WRITES
-#define        SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
-#define        SCSI_NCR_PCIQ_BROKEN_INTR
-
-/*
-**     Some bridge designers decided to flush 
-**     everything prior to deliver the interrupt.
-**     This option tries to deal with such a 
-**     behaviour.
-*/
-#elif  SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
-#define        SCSI_NCR_PCIQ_SYNC_ON_INTR
-#endif
-
-/*
-**     Other parameters not configurable with "make config"
-**     Avoid to change these constants, unless you know what you are doing.
-*/
-
-#define SCSI_NCR_ALWAYS_SIMPLE_TAG
-#define SCSI_NCR_MAX_SCATTER   (127)
-#define SCSI_NCR_MAX_TARGET    (16)
-
-/*
-**   Compute some desirable value for CAN_QUEUE 
-**   and CMD_PER_LUN.
-**   The driver will use lower values if these 
-**   ones appear to be too large.
-*/
-#define SCSI_NCR_CAN_QUEUE     (8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
-#define SCSI_NCR_CMD_PER_LUN   (SCSI_NCR_MAX_TAGS)
-
-#define SCSI_NCR_SG_TABLESIZE  (SCSI_NCR_MAX_SCATTER)
-#define SCSI_NCR_TIMER_INTERVAL        (HZ)
-
-#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
-#define SCSI_NCR_MAX_LUN       (16)
-#else
-#define SCSI_NCR_MAX_LUN       (1)
-#endif
-
-/*
- *  IO functions definition for big/little endian CPU support.
- *  For now, the NCR is only supported in little endian addressing mode, 
- */
-
-#ifdef __BIG_ENDIAN
-
-#define        inw_l2b         inw
-#define        inl_l2b         inl
-#define        outw_b2l        outw
-#define        outl_b2l        outl
-
-#define        readb_raw       readb
-#define        writeb_raw      writeb
-
-#if defined(SCSI_NCR_BIG_ENDIAN)
-#define        readw_l2b       __raw_readw
-#define        readl_l2b       __raw_readl
-#define        writew_b2l      __raw_writew
-#define        writel_b2l      __raw_writel
-#define        readw_raw       __raw_readw
-#define        readl_raw       __raw_readl
-#define        writew_raw      __raw_writew
-#define        writel_raw      __raw_writel
-#else  /* Other big-endian */
-#define        readw_l2b       readw
-#define        readl_l2b       readl
-#define        writew_b2l      writew
-#define        writel_b2l      writel
-#define        readw_raw       readw
-#define        readl_raw       readl
-#define        writew_raw      writew
-#define        writel_raw      writel
-#endif
-
-#else  /* little endian */
-
-#define        inw_raw         inw
-#define        inl_raw         inl
-#define        outw_raw        outw
-#define        outl_raw        outl
-
-#define        readb_raw       readb
-#define        readw_raw       readw
-#define        readl_raw       readl
-#define        writeb_raw      writeb
-#define        writew_raw      writew
-#define        writel_raw      writel
-
-#endif
-
-#if !defined(__hppa__) && !defined(__mips__)
-#ifdef SCSI_NCR_BIG_ENDIAN
-#error "The NCR in BIG ENDIAN addressing mode is not (yet) supported"
-#endif
-#endif
-
-#define MEMORY_BARRIER()       mb()
-
-
-/*
- *  If the NCR uses big endian addressing mode over the 
- *  PCI, actual io register addresses for byte and word 
- *  accesses must be changed according to lane routing.
- *  Btw, ncr_offb() and ncr_offw() macros only apply to 
- *  constants and so donnot generate bloated code.
- */
-
-#if    defined(SCSI_NCR_BIG_ENDIAN)
-
-#define ncr_offb(o)    (((o)&~3)+((~((o)&3))&3))
-#define ncr_offw(o)    (((o)&~3)+((~((o)&3))&2))
-
-#else
-
-#define ncr_offb(o)    (o)
-#define ncr_offw(o)    (o)
-
-#endif
-
-/*
- *  If the CPU and the NCR use same endian-ness addressing,
- *  no byte reordering is needed for script patching.
- *  Macro cpu_to_scr() is to be used for script patching.
- *  Macro scr_to_cpu() is to be used for getting a DWORD 
- *  from the script.
- */
-
-#if    defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
-
-#define cpu_to_scr(dw) cpu_to_le32(dw)
-#define scr_to_cpu(dw) le32_to_cpu(dw)
-
-#elif  defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
-
-#define cpu_to_scr(dw) cpu_to_be32(dw)
-#define scr_to_cpu(dw) be32_to_cpu(dw)
-
-#else
-
-#define cpu_to_scr(dw) (dw)
-#define scr_to_cpu(dw) (dw)
-
-#endif
-
-/*
- *  Access to the controller chip.
- *
- *  If the CPU and the NCR use same endian-ness addressing,
- *  no byte reordering is needed for accessing chip io 
- *  registers. Functions suffixed by '_raw' are assumed 
- *  to access the chip over the PCI without doing byte 
- *  reordering. Functions suffixed by '_l2b' are 
- *  assumed to perform little-endian to big-endian byte 
- *  reordering, those suffixed by '_b2l' blah, blah,
- *  blah, ...
- */
-
-/*
- *  MEMORY mapped IO input / output
- */
-
-#define INB_OFF(o)             readb_raw((char __iomem *)np->reg + ncr_offb(o))
-#define OUTB_OFF(o, val)       writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
-
-#if    defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
-
-#define INW_OFF(o)             readw_l2b((char __iomem *)np->reg + ncr_offw(o))
-#define INL_OFF(o)             readl_l2b((char __iomem *)np->reg + (o))
-
-#define OUTW_OFF(o, val)       writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
-#define OUTL_OFF(o, val)       writel_b2l((val), (char __iomem *)np->reg + (o))
-
-#elif  defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
-
-#define INW_OFF(o)             readw_b2l((char __iomem *)np->reg + ncr_offw(o))
-#define INL_OFF(o)             readl_b2l((char __iomem *)np->reg + (o))
-
-#define OUTW_OFF(o, val)       writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
-#define OUTL_OFF(o, val)       writel_l2b((val), (char __iomem *)np->reg + (o))
-
-#else
-
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
-/* Only 8 or 32 bit transfers allowed */
-#define INW_OFF(o)             (readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
-#else
-#define INW_OFF(o)             readw_raw((char __iomem *)np->reg + ncr_offw(o))
-#endif
-#define INL_OFF(o)             readl_raw((char __iomem *)np->reg + (o))
-
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
-/* Only 8 or 32 bit transfers allowed */
-#define OUTW_OFF(o, val)       do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
-#else
-#define OUTW_OFF(o, val)       writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
-#endif
-#define OUTL_OFF(o, val)       writel_raw((val), (char __iomem *)np->reg + (o))
-
-#endif
-
-#define INB(r)         INB_OFF (offsetof(struct ncr_reg,r))
-#define INW(r)         INW_OFF (offsetof(struct ncr_reg,r))
-#define INL(r)         INL_OFF (offsetof(struct ncr_reg,r))
-
-#define OUTB(r, val)   OUTB_OFF (offsetof(struct ncr_reg,r), (val))
-#define OUTW(r, val)   OUTW_OFF (offsetof(struct ncr_reg,r), (val))
-#define OUTL(r, val)   OUTL_OFF (offsetof(struct ncr_reg,r), (val))
-
-/*
- *  Set bit field ON, OFF 
- */
-
-#define OUTONB(r, m)   OUTB(r, INB(r) | (m))
-#define OUTOFFB(r, m)  OUTB(r, INB(r) & ~(m))
-#define OUTONW(r, m)   OUTW(r, INW(r) | (m))
-#define OUTOFFW(r, m)  OUTW(r, INW(r) & ~(m))
-#define OUTONL(r, m)   OUTL(r, INL(r) | (m))
-#define OUTOFFL(r, m)  OUTL(r, INL(r) & ~(m))
-
-/*
- *  We normally want the chip to have a consistent view
- *  of driver internal data structures when we restart it.
- *  Thus these macros.
- */
-#define OUTL_DSP(v)                            \
-       do {                                    \
-               MEMORY_BARRIER();               \
-               OUTL (nc_dsp, (v));             \
-       } while (0)
-
-#define OUTONB_STD()                           \
-       do {                                    \
-               MEMORY_BARRIER();               \
-               OUTONB (nc_dcntl, (STD|NOCOM)); \
-       } while (0)
-
-
-/*
-**   NCR53C8XX devices features table.
-*/
-struct ncr_chip {
-       unsigned short  revision_id;
-       unsigned char   burst_max;      /* log-base-2 of max burst */
-       unsigned char   offset_max;
-       unsigned char   nr_divisor;
-       unsigned int    features;
-#define FE_LED0                (1<<0)
-#define FE_WIDE                (1<<1)    /* Wide data transfers */
-#define FE_ULTRA       (1<<2)    /* Ultra speed 20Mtrans/sec */
-#define FE_DBLR                (1<<4)    /* Clock doubler present */
-#define FE_QUAD                (1<<5)    /* Clock quadrupler present */
-#define FE_ERL         (1<<6)    /* Enable read line */
-#define FE_CLSE                (1<<7)    /* Cache line size enable */
-#define FE_WRIE                (1<<8)    /* Write & Invalidate enable */
-#define FE_ERMP                (1<<9)    /* Enable read multiple */
-#define FE_BOF         (1<<10)   /* Burst opcode fetch */
-#define FE_DFS         (1<<11)   /* DMA fifo size */
-#define FE_PFEN                (1<<12)   /* Prefetch enable */
-#define FE_LDSTR       (1<<13)   /* Load/Store supported */
-#define FE_RAM         (1<<14)   /* On chip RAM present */
-#define FE_VARCLK      (1<<15)   /* SCSI clock may vary */
-#define FE_RAM8K       (1<<16)   /* On chip RAM sized 8Kb */
-#define FE_64BIT       (1<<17)   /* Have a 64-bit PCI interface */
-#define FE_IO256       (1<<18)   /* Requires full 256 bytes in PCI space */
-#define FE_NOPM                (1<<19)   /* Scripts handles phase mismatch */
-#define FE_LEDC                (1<<20)   /* Hardware control of LED */
-#define FE_DIFF                (1<<21)   /* Support Differential SCSI */
-#define FE_66MHZ       (1<<23)   /* 66MHz PCI Support */
-#define FE_DAC         (1<<24)   /* Support DAC cycles (64 bit addressing) */
-#define FE_ISTAT1      (1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
-#define FE_DAC_IN_USE  (1<<26)   /* Platform does DAC cycles */
-#define FE_EHP         (1<<27)   /* 720: Even host parity */
-#define FE_MUX         (1<<28)   /* 720: Multiplexed bus */
-#define FE_EA          (1<<29)   /* 720: Enable Ack */
-
-#define FE_CACHE_SET   (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
-#define FE_SCSI_SET    (FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
-#define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
-};
-
-
-/*
-**     Driver setup structure.
-**
-**     This structure is initialized from linux config options.
-**     It can be overridden at boot-up by the boot command line.
-*/
-#define SCSI_NCR_MAX_EXCLUDES 8
-struct ncr_driver_setup {
-       u8      master_parity;
-       u8      scsi_parity;
-       u8      disconnection;
-       u8      special_features;
-       u8      force_sync_nego;
-       u8      reverse_probe;
-       u8      pci_fix_up;
-       u8      use_nvram;
-       u8      verbose;
-       u8      default_tags;
-       u16     default_sync;
-       u16     debug;
-       u8      burst_max;
-       u8      led_pin;
-       u8      max_wide;
-       u8      settle_delay;
-       u8      diff_support;
-       u8      irqm;
-       u8      bus_check;
-       u8      optimize;
-       u8      recovery;
-       u8      host_id;
-       u16     iarb;
-       u32     excludes[SCSI_NCR_MAX_EXCLUDES];
-       char    tag_ctrl[100];
-};
-
-/*
-**     Initial setup.
-**     Can be overriden at startup by a command line.
-*/
-#define SCSI_NCR_DRIVER_SETUP                  \
-{                                              \
-       SCSI_NCR_SETUP_MASTER_PARITY,           \
-       SCSI_NCR_SETUP_SCSI_PARITY,             \
-       SCSI_NCR_SETUP_DISCONNECTION,           \
-       SCSI_NCR_SETUP_SPECIAL_FEATURES,        \
-       SCSI_NCR_SETUP_FORCE_SYNC_NEGO,         \
-       0,                                      \
-       0,                                      \
-       1,                                      \
-       0,                                      \
-       SCSI_NCR_SETUP_DEFAULT_TAGS,            \
-       SCSI_NCR_SETUP_DEFAULT_SYNC,            \
-       0x00,                                   \
-       7,                                      \
-       0,                                      \
-       1,                                      \
-       SCSI_NCR_SETUP_SETTLE_TIME,             \
-       0,                                      \
-       0,                                      \
-       1,                                      \
-       0,                                      \
-       0,                                      \
-       255,                                    \
-       0x00                                    \
-}
-
-/*
-**     Boot fail safe setup.
-**     Override initial setup from boot command line:
-**     ncr53c8xx=safe:y
-*/
-#define SCSI_NCR_DRIVER_SAFE_SETUP             \
-{                                              \
-       0,                                      \
-       1,                                      \
-       0,                                      \
-       0,                                      \
-       0,                                      \
-       0,                                      \
-       0,                                      \
-       1,                                      \
-       2,                                      \
-       0,                                      \
-       255,                                    \
-       0x00,                                   \
-       255,                                    \
-       0,                                      \
-       0,                                      \
-       10,                                     \
-       1,                                      \
-       1,                                      \
-       1,                                      \
-       0,                                      \
-       0,                                      \
-       255                                     \
-}
-
-/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
-
-/*-----------------------------------------------------------------
-**
-**     The ncr 53c810 register structure.
-**
-**-----------------------------------------------------------------
-*/
-
-struct ncr_reg {
-/*00*/  u8     nc_scntl0;    /* full arb., ena parity, par->ATN  */
-
-/*01*/  u8     nc_scntl1;    /* no reset                         */
-        #define   ISCON   0x10  /* connected to scsi               */
-        #define   CRST    0x08  /* force reset                      */
-        #define   IARB    0x02  /* immediate arbitration            */
-
-/*02*/  u8     nc_scntl2;    /* no disconnect expected           */
-       #define   SDU     0x80  /* cmd: disconnect will raise error */
-       #define   CHM     0x40  /* sta: chained mode                */
-       #define   WSS     0x08  /* sta: wide scsi send           [W]*/
-       #define   WSR     0x01  /* sta: wide scsi received       [W]*/
-
-/*03*/  u8     nc_scntl3;    /* cnf system clock dependent       */
-       #define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
-       #define   ULTRA   0x80  /* cmd: ULTRA enable                */
-                               /* bits 0-2, 7 rsvd for C1010       */
-
-/*04*/  u8     nc_scid;        /* cnf host adapter scsi address    */
-       #define   RRE     0x40  /* r/w:e enable response to resel.  */
-       #define   SRE     0x20  /* r/w:e enable response to select  */
-
-/*05*/  u8     nc_sxfer;       /* ### Sync speed and count         */
-                               /* bits 6-7 rsvd for C1010          */
-
-/*06*/  u8     nc_sdid;        /* ### Destination-ID               */
-
-/*07*/  u8     nc_gpreg;       /* ??? IO-Pins                      */
-
-/*08*/  u8     nc_sfbr;        /* ### First byte in phase          */
-
-/*09*/  u8     nc_socl;
-       #define   CREQ    0x80  /* r/w: SCSI-REQ                    */
-       #define   CACK    0x40  /* r/w: SCSI-ACK                    */
-       #define   CBSY    0x20  /* r/w: SCSI-BSY                    */
-       #define   CSEL    0x10  /* r/w: SCSI-SEL                    */
-       #define   CATN    0x08  /* r/w: SCSI-ATN                    */
-       #define   CMSG    0x04  /* r/w: SCSI-MSG                    */
-       #define   CC_D    0x02  /* r/w: SCSI-C_D                    */
-       #define   CI_O    0x01  /* r/w: SCSI-I_O                    */
-
-/*0a*/  u8     nc_ssid;
-
-/*0b*/  u8     nc_sbcl;
-
-/*0c*/  u8     nc_dstat;
-        #define   DFE     0x80  /* sta: dma fifo empty              */
-        #define   MDPE    0x40  /* int: master data parity error    */
-        #define   BF      0x20  /* int: script: bus fault           */
-        #define   ABRT    0x10  /* int: script: command aborted     */
-        #define   SSI     0x08  /* int: script: single step         */
-        #define   SIR     0x04  /* int: script: interrupt instruct. */
-        #define   IID     0x01  /* int: script: illegal instruct.   */
-
-/*0d*/  u8     nc_sstat0;
-        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
-        #define   ORF     0x40  /* sta: data in SODR register lsb   */
-        #define   OLF     0x20  /* sta: data in SODL register lsb   */
-        #define   AIP     0x10  /* sta: arbitration in progress     */
-        #define   LOA     0x08  /* sta: arbitration lost            */
-        #define   WOA     0x04  /* sta: arbitration won             */
-        #define   IRST    0x02  /* sta: scsi reset signal           */
-        #define   SDP     0x01  /* sta: scsi parity signal          */
-
-/*0e*/  u8     nc_sstat1;
-       #define   FF3210  0xf0  /* sta: bytes in the scsi fifo      */
-
-/*0f*/  u8     nc_sstat2;
-        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
-        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
-        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
-        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
-        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
-
-/*10*/  u8     nc_dsa; /* --> Base page                    */
-/*11*/  u8     nc_dsa1;
-/*12*/  u8     nc_dsa2;
-/*13*/  u8     nc_dsa3;
-
-/*14*/  u8     nc_istat;       /* --> Main Command and status      */
-        #define   CABRT   0x80  /* cmd: abort current operation     */
-        #define   SRST    0x40  /* mod: reset chip                  */
-        #define   SIGP    0x20  /* r/w: message from host to ncr    */
-        #define   SEM     0x10  /* r/w: message between host + ncr  */
-        #define   CON     0x08  /* sta: connected to scsi           */
-        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
-        #define   SIP     0x02  /* sta: scsi-interrupt              */
-        #define   DIP     0x01  /* sta: host/script interrupt       */
-
-/*15*/  u8     nc_istat1;      /* 896 and later cores only */
-        #define   FLSH    0x04  /* sta: chip is flushing            */
-        #define   SRUN    0x02  /* sta: scripts are running         */
-        #define   SIRQD   0x01  /* r/w: disable INT pin             */
-
-/*16*/  u8     nc_mbox0;       /* 896 and later cores only */
-/*17*/  u8     nc_mbox1;       /* 896 and later cores only */
-
-/*18*/ u8      nc_ctest0;
-       #define   EHP     0x04  /* 720 even host parity             */
-/*19*/  u8     nc_ctest1;
-
-/*1a*/  u8     nc_ctest2;
-       #define   CSIGP   0x40
-                               /* bits 0-2,7 rsvd for C1010        */
-
-/*1b*/  u8     nc_ctest3;
-       #define   FLF     0x08  /* cmd: flush dma fifo              */
-       #define   CLF     0x04  /* cmd: clear dma fifo              */
-       #define   FM      0x02  /* mod: fetch pin mode              */
-       #define   WRIE    0x01  /* mod: write and invalidate enable */
-                               /* bits 4-7 rsvd for C1010          */
-
-/*1c*/  u32    nc_temp;        /* ### Temporary stack              */
-
-/*20*/ u8      nc_dfifo;
-/*21*/  u8     nc_ctest4;
-       #define   MUX     0x80  /* 720 host bus multiplex mode      */
-       #define   BDIS    0x80  /* mod: burst disable               */
-       #define   MPEE    0x08  /* mod: master parity error enable  */
-
-/*22*/  u8     nc_ctest5;
-       #define   DFS     0x20  /* mod: dma fifo size               */
-                               /* bits 0-1, 3-7 rsvd for C1010          */
-/*23*/  u8     nc_ctest6;
-
-/*24*/  u32    nc_dbc; /* ### Byte count and command       */
-/*28*/  u32    nc_dnad;        /* ### Next command register        */
-/*2c*/  u32    nc_dsp; /* --> Script Pointer               */
-/*30*/  u32    nc_dsps;        /* --> Script pointer save/opcode#2 */
-
-/*34*/  u8     nc_scratcha;  /* Temporary register a            */
-/*35*/  u8     nc_scratcha1;
-/*36*/  u8     nc_scratcha2;
-/*37*/  u8     nc_scratcha3;
-
-/*38*/  u8     nc_dmode;
-       #define   BL_2    0x80  /* mod: burst length shift value +2 */
-       #define   BL_1    0x40  /* mod: burst length shift value +1 */
-       #define   ERL     0x08  /* mod: enable read line            */
-       #define   ERMP    0x04  /* mod: enable read multiple        */
-       #define   BOF     0x02  /* mod: burst op code fetch         */
-
-/*39*/  u8     nc_dien;
-/*3a*/  u8     nc_sbr;
-
-/*3b*/  u8     nc_dcntl;       /* --> Script execution control     */
-       #define   CLSE    0x80  /* mod: cache line size enable      */
-       #define   PFF     0x40  /* cmd: pre-fetch flush             */
-       #define   PFEN    0x20  /* mod: pre-fetch enable            */
-       #define   EA      0x20  /* mod: 720 enable-ack              */
-       #define   SSM     0x10  /* mod: single step mode            */
-       #define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
-       #define   STD     0x04  /* cmd: start dma mode              */
-       #define   IRQD    0x02  /* mod: irq disable                 */
-       #define   NOCOM   0x01  /* cmd: protect sfbr while reselect */
-                               /* bits 0-1 rsvd for C1010          */
-
-/*3c*/  u32    nc_adder;
-
-/*40*/  u16    nc_sien;        /* -->: interrupt enable            */
-/*42*/  u16    nc_sist;        /* <--: interrupt status            */
-        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
-        #define   STO     0x0400/* sta: timeout (select)            */
-        #define   GEN     0x0200/* sta: timeout (general)           */
-        #define   HTH     0x0100/* sta: timeout (handshake)         */
-        #define   MA      0x80  /* sta: phase mismatch              */
-        #define   CMP     0x40  /* sta: arbitration complete        */
-        #define   SEL     0x20  /* sta: selected by another device  */
-        #define   RSL     0x10  /* sta: reselected by another device*/
-        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
-        #define   UDC     0x04  /* sta: unexpected disconnect       */
-        #define   RST     0x02  /* sta: scsi bus reset detected     */
-        #define   PAR     0x01  /* sta: scsi parity error           */
-
-/*44*/  u8     nc_slpar;
-/*45*/  u8     nc_swide;
-/*46*/  u8     nc_macntl;
-/*47*/  u8     nc_gpcntl;
-/*48*/  u8     nc_stime0;    /* cmd: timeout for select&handshake*/
-/*49*/  u8     nc_stime1;    /* cmd: timeout user defined        */
-/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
-
-/*4c*/  u8     nc_stest0;
-
-/*4d*/  u8     nc_stest1;
-       #define   SCLK    0x80  /* Use the PCI clock as SCSI clock      */
-       #define   DBLEN   0x08  /* clock doubler running                */
-       #define   DBLSEL  0x04  /* clock doubler selected               */
-  
-
-/*4e*/  u8     nc_stest2;
-       #define   ROF     0x40  /* reset scsi offset (after gross error!) */
-       #define   DIF     0x20  /* 720 SCSI differential mode             */
-       #define   EXT     0x02  /* extended filtering                     */
-
-/*4f*/  u8     nc_stest3;
-       #define   TE     0x80   /* c: tolerAnt enable */
-       #define   HSC    0x20   /* c: Halt SCSI Clock */
-       #define   CSF    0x02   /* c: clear scsi fifo */
-
-/*50*/  u16   nc_sidl; /* Lowlevel: latched from scsi data */
-/*52*/  u8     nc_stest4;
-       #define   SMODE  0xc0   /* SCSI bus mode      (895/6 only) */
-       #define    SMODE_HVD 0x40       /* High Voltage Differential       */
-       #define    SMODE_SE  0x80       /* Single Ended                    */
-       #define    SMODE_LVD 0xc0       /* Low Voltage Differential        */
-       #define   LCKFRQ 0x20   /* Frequency Lock (895/6 only)     */
-                               /* bits 0-5 rsvd for C1010          */
-
-/*53*/  u8     nc_53_;
-/*54*/  u16    nc_sodl;        /* Lowlevel: data out to scsi data  */
-/*56*/ u8      nc_ccntl0;      /* Chip Control 0 (896)             */
-       #define   ENPMJ  0x80   /* Enable Phase Mismatch Jump       */
-       #define   PMJCTL 0x40   /* Phase Mismatch Jump Control      */
-       #define   ENNDJ  0x20   /* Enable Non Data PM Jump          */
-       #define   DISFC  0x10   /* Disable Auto FIFO Clear          */
-       #define   DILS   0x02   /* Disable Internal Load/Store      */
-       #define   DPR    0x01   /* Disable Pipe Req                 */
-
-/*57*/ u8      nc_ccntl1;      /* Chip Control 1 (896)             */
-       #define   ZMOD   0x80   /* High Impedance Mode              */
-       #define   DIC    0x10   /* Disable Internal Cycles          */
-       #define   DDAC   0x08   /* Disable Dual Address Cycle       */
-       #define   XTIMOD 0x04   /* 64-bit Table Ind. Indexing Mode  */
-       #define   EXTIBMV 0x02  /* Enable 64-bit Table Ind. BMOV    */
-       #define   EXDBMV 0x01   /* Enable 64-bit Direct BMOV        */
-
-/*58*/  u16    nc_sbdl;        /* Lowlevel: data from scsi data    */
-/*5a*/  u16    nc_5a_;
-
-/*5c*/  u8     nc_scr0;        /* Working register B               */
-/*5d*/  u8     nc_scr1;        /*                                  */
-/*5e*/  u8     nc_scr2;        /*                                  */
-/*5f*/  u8     nc_scr3;        /*                                  */
-
-/*60*/  u8     nc_scrx[64];    /* Working register C-R             */
-/*a0*/ u32     nc_mmrs;        /* Memory Move Read Selector        */
-/*a4*/ u32     nc_mmws;        /* Memory Move Write Selector       */
-/*a8*/ u32     nc_sfs;         /* Script Fetch Selector            */
-/*ac*/ u32     nc_drs;         /* DSA Relative Selector            */
-/*b0*/ u32     nc_sbms;        /* Static Block Move Selector       */
-/*b4*/ u32     nc_dbms;        /* Dynamic Block Move Selector      */
-/*b8*/ u32     nc_dnad64;      /* DMA Next Address 64              */
-/*bc*/ u16     nc_scntl4;      /* C1010 only                       */
-       #define   U3EN   0x80   /* Enable Ultra 3                   */
-       #define   AIPEN  0x40   /* Allow check upper byte lanes     */
-       #define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
-                                       transfer edge               */
-       #define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
-                                       transfer edge               */
-
-/*be*/  u8     nc_aipcntl0;    /* Epat Control 1 C1010 only        */
-/*bf*/  u8     nc_aipcntl1;    /* AIP Control C1010_66 Only        */
-
-/*c0*/ u32     nc_pmjad1;      /* Phase Mismatch Jump Address 1    */
-/*c4*/ u32     nc_pmjad2;      /* Phase Mismatch Jump Address 2    */
-/*c8*/ u8      nc_rbc;         /* Remaining Byte Count             */
-/*c9*/ u8      nc_rbc1;        /*                                  */
-/*ca*/ u8      nc_rbc2;        /*                                  */
-/*cb*/ u8      nc_rbc3;        /*                                  */
-
-/*cc*/ u8      nc_ua;          /* Updated Address                  */
-/*cd*/ u8      nc_ua1;         /*                                  */
-/*ce*/ u8      nc_ua2;         /*                                  */
-/*cf*/ u8      nc_ua3;         /*                                  */
-/*d0*/ u32     nc_esa;         /* Entry Storage Address            */
-/*d4*/ u8      nc_ia;          /* Instruction Address              */
-/*d5*/ u8      nc_ia1;
-/*d6*/ u8      nc_ia2;
-/*d7*/ u8      nc_ia3;
-/*d8*/ u32     nc_sbc;         /* SCSI Byte Count (3 bytes only)   */
-/*dc*/ u32     nc_csbc;        /* Cumulative SCSI Byte Count       */
-
-                               /* Following for C1010 only         */
-/*e0*/  u16    nc_crcpad;      /* CRC Value                        */
-/*e2*/  u8     nc_crccntl0;    /* CRC control register             */
-       #define   SNDCRC  0x10  /* Send CRC Request                 */
-/*e3*/  u8     nc_crccntl1;    /* CRC control register             */
-/*e4*/  u32    nc_crcdata;     /* CRC data register                */ 
-/*e8*/  u32    nc_e8_;         /* rsvd                             */
-/*ec*/  u32    nc_ec_;         /* rsvd                             */
-/*f0*/  u16    nc_dfbc;        /* DMA FIFO byte count              */ 
-
-};
-
-/*-----------------------------------------------------------
-**
-**     Utility macros for the script.
-**
-**-----------------------------------------------------------
-*/
-
-#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
-#define REG(r) REGJ (nc_, r)
-
-typedef u32 ncrcmd;
-
-/*-----------------------------------------------------------
-**
-**     SCSI phases
-**
-**     DT phases illegal for ncr driver.
-**
-**-----------------------------------------------------------
-*/
-
-#define        SCR_DATA_OUT    0x00000000
-#define        SCR_DATA_IN     0x01000000
-#define        SCR_COMMAND     0x02000000
-#define        SCR_STATUS      0x03000000
-#define SCR_DT_DATA_OUT        0x04000000
-#define SCR_DT_DATA_IN 0x05000000
-#define SCR_MSG_OUT    0x06000000
-#define SCR_MSG_IN      0x07000000
-
-#define SCR_ILG_OUT    0x04000000
-#define SCR_ILG_IN     0x05000000
-
-/*-----------------------------------------------------------
-**
-**     Data transfer via SCSI.
-**
-**-----------------------------------------------------------
-**
-**     MOVE_ABS (LEN)
-**     <<start address>>
-**
-**     MOVE_IND (LEN)
-**     <<dnad_offset>>
-**
-**     MOVE_TBL
-**     <<dnad_offset>>
-**
-**-----------------------------------------------------------
-*/
-
-#define OPC_MOVE          0x08000000
-
-#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
-#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
-#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
-
-#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
-#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
-#define SCR_CHMOV_TBL     (0x10000000)
-
-struct scr_tblmove {
-        u32  size;
-        u32  addr;
-};
-
-/*-----------------------------------------------------------
-**
-**     Selection
-**
-**-----------------------------------------------------------
-**
-**     SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
-**     <<alternate_address>>
-**
-**     SEL_TBL | << dnad_offset>>  [ | REL_JMP]
-**     <<alternate_address>>
-**
-**-----------------------------------------------------------
-*/
-
-#define        SCR_SEL_ABS     0x40000000
-#define        SCR_SEL_ABS_ATN 0x41000000
-#define        SCR_SEL_TBL     0x42000000
-#define        SCR_SEL_TBL_ATN 0x43000000
-
-
-#ifdef SCSI_NCR_BIG_ENDIAN
-struct scr_tblsel {
-        u8     sel_scntl3;
-        u8     sel_id;
-        u8     sel_sxfer;
-        u8     sel_scntl4;     
-};
-#else
-struct scr_tblsel {
-        u8     sel_scntl4;     
-        u8     sel_sxfer;
-        u8     sel_id;
-        u8     sel_scntl3;
-};
-#endif
-
-#define SCR_JMP_REL     0x04000000
-#define SCR_ID(id)     (((u32)(id)) << 16)
-
-/*-----------------------------------------------------------
-**
-**     Waiting for Disconnect or Reselect
-**
-**-----------------------------------------------------------
-**
-**     WAIT_DISC
-**     dummy: <<alternate_address>>
-**
-**     WAIT_RESEL
-**     <<alternate_address>>
-**
-**-----------------------------------------------------------
-*/
-
-#define        SCR_WAIT_DISC   0x48000000
-#define SCR_WAIT_RESEL  0x50000000
-
-/*-----------------------------------------------------------
-**
-**     Bit Set / Reset
-**
-**-----------------------------------------------------------
-**
-**     SET (flags {|.. })
-**
-**     CLR (flags {|.. })
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_SET(f)     (0x58000000 | (f))
-#define SCR_CLR(f)     (0x60000000 | (f))
-
-#define        SCR_CARRY       0x00000400
-#define        SCR_TRG         0x00000200
-#define        SCR_ACK         0x00000040
-#define        SCR_ATN         0x00000008
-
-
-
-
-/*-----------------------------------------------------------
-**
-**     Memory to memory move
-**
-**-----------------------------------------------------------
-**
-**     COPY (bytecount)
-**     << source_address >>
-**     << destination_address >>
-**
-**     SCR_COPY   sets the NO FLUSH option by default.
-**     SCR_COPY_F does not set this option.
-**
-**     For chips which do not support this option,
-**     ncr_copy_and_bind() will remove this bit.
-**-----------------------------------------------------------
-*/
-
-#define SCR_NO_FLUSH 0x01000000
-
-#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
-#define SCR_COPY_F(n) (0xc0000000 | (n))
-
-/*-----------------------------------------------------------
-**
-**     Register move and binary operations
-**
-**-----------------------------------------------------------
-**
-**     SFBR_REG (reg, op, data)        reg  = SFBR op data
-**     << 0 >>
-**
-**     REG_SFBR (reg, op, data)        SFBR = reg op data
-**     << 0 >>
-**
-**     REG_REG  (reg, op, data)        reg  = reg op data
-**     << 0 >>
-**
-**-----------------------------------------------------------
-**     On 810A, 860, 825A, 875, 895 and 896 chips the content 
-**     of SFBR register can be used as data (SCR_SFBR_DATA).
-**     The 896 has additionnal IO registers starting at 
-**     offset 0x80. Bit 7 of register offset is stored in 
-**     bit 7 of the SCRIPTS instruction first DWORD.
-**-----------------------------------------------------------
-*/
-
-#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
-
-#define SCR_SFBR_REG(reg,op,data) \
-        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-#define SCR_REG_SFBR(reg,op,data) \
-        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-#define SCR_REG_REG(reg,op,data) \
-        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-
-#define      SCR_LOAD   0x00000000
-#define      SCR_SHL    0x01000000
-#define      SCR_OR     0x02000000
-#define      SCR_XOR    0x03000000
-#define      SCR_AND    0x04000000
-#define      SCR_SHR    0x05000000
-#define      SCR_ADD    0x06000000
-#define      SCR_ADDC   0x07000000
-
-#define      SCR_SFBR_DATA   (0x00800000>>8ul) /* Use SFBR as data */
-
-/*-----------------------------------------------------------
-**
-**     FROM_REG (reg)            SFBR = reg
-**     << 0 >>
-**
-**     TO_REG   (reg)            reg  = SFBR
-**     << 0 >>
-**
-**     LOAD_REG (reg, data)      reg  = <data>
-**     << 0 >>
-**
-**     LOAD_SFBR(data)           SFBR = <data>
-**     << 0 >>
-**
-**-----------------------------------------------------------
-*/
-
-#define        SCR_FROM_REG(reg) \
-       SCR_REG_SFBR(reg,SCR_OR,0)
-
-#define        SCR_TO_REG(reg) \
-       SCR_SFBR_REG(reg,SCR_OR,0)
-
-#define        SCR_LOAD_REG(reg,data) \
-       SCR_REG_REG(reg,SCR_LOAD,data)
-
-#define SCR_LOAD_SFBR(data) \
-        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
-
-/*-----------------------------------------------------------
-**
-**     LOAD  from memory   to register.
-**     STORE from register to memory.
-**
-**     Only supported by 810A, 860, 825A, 875, 895 and 896.
-**
-**-----------------------------------------------------------
-**
-**     LOAD_ABS (LEN)
-**     <<start address>>
-**
-**     LOAD_REL (LEN)        (DSA relative)
-**     <<dsa_offset>>
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
-#define SCR_NO_FLUSH2  0x02000000
-#define SCR_DSA_REL2   0x10000000
-
-#define SCR_LOAD_R(reg, how, n) \
-        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
-
-#define SCR_STORE_R(reg, how, n) \
-        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
-
-#define SCR_LOAD_ABS(reg, n)   SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
-#define SCR_LOAD_REL(reg, n)   SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
-#define SCR_LOAD_ABS_F(reg, n) SCR_LOAD_R(reg, 0, n)
-#define SCR_LOAD_REL_F(reg, n) SCR_LOAD_R(reg, SCR_DSA_REL2, n)
-
-#define SCR_STORE_ABS(reg, n)  SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
-#define SCR_STORE_REL(reg, n)  SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
-#define SCR_STORE_ABS_F(reg, n)        SCR_STORE_R(reg, 0, n)
-#define SCR_STORE_REL_F(reg, n)        SCR_STORE_R(reg, SCR_DSA_REL2, n)
-
-
-/*-----------------------------------------------------------
-**
-**     Waiting for Disconnect or Reselect
-**
-**-----------------------------------------------------------
-**
-**     JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
-**     <<address>>
-**
-**     JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
-**     <<distance>>
-**
-**     CALL            [ | IFTRUE/IFFALSE ( ... ) ]
-**     <<address>>
-**
-**     CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
-**     <<distance>>
-**
-**     RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
-**     <<dummy>>
-**
-**     INT             [ | IFTRUE/IFFALSE ( ... ) ]
-**     <<ident>>
-**
-**     INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
-**     <<ident>>
-**
-**     Conditions:
-**          WHEN (phase)
-**          IF   (phase)
-**          CARRYSET
-**          DATA (data, mask)
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_NO_OP       0x80000000
-#define SCR_JUMP        0x80080000
-#define SCR_JUMP64      0x80480000
-#define SCR_JUMPR       0x80880000
-#define SCR_CALL        0x88080000
-#define SCR_CALLR       0x88880000
-#define SCR_RETURN      0x90080000
-#define SCR_INT         0x98080000
-#define SCR_INT_FLY     0x98180000
-
-#define IFFALSE(arg)   (0x00080000 | (arg))
-#define IFTRUE(arg)    (0x00000000 | (arg))
-
-#define WHEN(phase)    (0x00030000 | (phase))
-#define IF(phase)      (0x00020000 | (phase))
-
-#define DATA(D)        (0x00040000 | ((D) & 0xff))
-#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
-
-#define CARRYSET       (0x00200000)
-
-/*-----------------------------------------------------------
-**
-**     SCSI  constants.
-**
-**-----------------------------------------------------------
-*/
-
-/*
-**     Messages
-*/
-
-#define        M_COMPLETE      COMMAND_COMPLETE
-#define        M_EXTENDED      EXTENDED_MESSAGE
-#define        M_SAVE_DP       SAVE_POINTERS
-#define        M_RESTORE_DP    RESTORE_POINTERS
-#define        M_DISCONNECT    DISCONNECT
-#define        M_ID_ERROR      INITIATOR_ERROR
-#define        M_ABORT         ABORT_TASK_SET
-#define        M_REJECT        MESSAGE_REJECT
-#define        M_NOOP          NOP
-#define        M_PARITY        MSG_PARITY_ERROR
-#define        M_LCOMPLETE     LINKED_CMD_COMPLETE
-#define        M_FCOMPLETE     LINKED_FLG_CMD_COMPLETE
-#define        M_RESET         TARGET_RESET
-#define        M_ABORT_TAG     ABORT_TASK
-#define        M_CLEAR_QUEUE   CLEAR_TASK_SET
-#define        M_INIT_REC      INITIATE_RECOVERY
-#define        M_REL_REC       RELEASE_RECOVERY
-#define        M_TERMINATE     (0x11)
-#define        M_SIMPLE_TAG    SIMPLE_QUEUE_TAG
-#define        M_HEAD_TAG      HEAD_OF_QUEUE_TAG
-#define        M_ORDERED_TAG   ORDERED_QUEUE_TAG
-#define        M_IGN_RESIDUE   IGNORE_WIDE_RESIDUE
-#define        M_IDENTIFY      (0x80)
-
-#define        M_X_MODIFY_DP   EXTENDED_MODIFY_DATA_POINTER
-#define        M_X_SYNC_REQ    EXTENDED_SDTR
-#define        M_X_WIDE_REQ    EXTENDED_WDTR
-#define        M_X_PPR_REQ     EXTENDED_PPR
-
-/*
-**     Status
-*/
-
-#define        S_GOOD          (0x00)
-#define        S_CHECK_COND    (0x02)
-#define        S_COND_MET      (0x04)
-#define        S_BUSY          (0x08)
-#define        S_INT           (0x10)
-#define        S_INT_COND_MET  (0x14)
-#define        S_CONFLICT      (0x18)
-#define        S_TERMINATED    (0x20)
-#define        S_QUEUE_FULL    (0x28)
-#define        S_ILLEGAL       (0xff)
-#define        S_SENSE         (0x80)
-
-/*
- * End of ncrreg from FreeBSD
- */
-
-#endif /* defined SYM53C8XX_DEFS_H */
index a50c2bc..3639c3f 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_MIDI)                += class/
 obj-$(CONFIG_USB_PRINTER)      += class/
 
 obj-$(CONFIG_USB_STORAGE)      += storage/
+obj-$(CONFIG_USB)              += storage/
 
 obj-$(CONFIG_USB_AIPTEK)       += input/
 obj-$(CONFIG_USB_ATI_REMOTE)   += input/
index f429862..550ddfa 100644 (file)
@@ -44,6 +44,19 @@ config USB_CXACRU
          To compile this driver as a module, choose M here: the
          module will be called cxacru.
 
+config USB_UEAGLEATM
+       tristate "ADI 930 and eagle USB DSL modem"
+       depends on USB_ATM
+       select FW_LOADER
+       help
+         Say Y here if you have an ADSL USB modem based on the ADI 930
+         or eagle chipset. In order to use your modem you will need to
+         install firmwares and CMV (Command Management Variables); see
+         <https://gna.org/projects/ueagleatm/> for details.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ueagle-atm.
+
 config USB_XUSBATM
        tristate "Other USB DSL modem support"
        depends on USB_ATM
index 8509971..4c4a776 100644 (file)
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_USB_CXACRU)       += cxacru.o
 obj-$(CONFIG_USB_SPEEDTOUCH)   += speedtch.o
+obj-$(CONFIG_USB_UEAGLEATM)    += ueagle-atm.o
 obj-$(CONFIG_USB_ATM)          += usbatm.o
 obj-$(CONFIG_USB_XUSBATM)      += xusbatm.o
 
index 9d59dc6..af0a41e 100644 (file)
@@ -853,7 +853,6 @@ static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_
 }
 
 static struct usb_driver cxacru_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = cxacru_driver_name,
        .probe          = cxacru_usb_probe,
        .disconnect     = usbatm_usb_disconnect,
index d0cbbb7..b283361 100644 (file)
@@ -659,7 +659,6 @@ MODULE_DEVICE_TABLE(usb, speedtch_usb_ids);
 static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *);
 
 static struct usb_driver speedtch_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = speedtch_driver_name,
        .probe          = speedtch_usb_probe,
        .disconnect     = usbatm_usb_disconnect,
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
new file mode 100644 (file)
index 0000000..7d2a679
--- /dev/null
@@ -0,0 +1,1820 @@
+/*-
+ * Copyright (c) 2003, 2004
+ *     Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
+ *
+ * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr>
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * GPL license :
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *
+ * HISTORY : some part of the code was base on ueagle 1.3 BSD driver,
+ * Damien Bergamini agree to put his code under a DUAL GPL/BSD license.
+ *
+ * The rest of the code was was rewritten from scratch.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+#include <linux/kthread.h>
+#include <linux/version.h>
+#include <asm/unaligned.h>
+
+#include "usbatm.h"
+
+#define EAGLEUSBVERSION "ueagle 1.1"
+
+
+/*
+ * Debug macros
+ */
+#define uea_dbg(usb_dev, format, args...)      \
+       do { \
+               if (debug >= 1) \
+                       dev_dbg(&(usb_dev)->dev, \
+                               "[ueagle-atm dbg] %s: " format, \
+                                       __FUNCTION__, ##args); \
+       } while (0)
+
+#define uea_vdbg(usb_dev, format, args...)     \
+       do { \
+               if (debug >= 2) \
+                       dev_dbg(&(usb_dev)->dev, \
+                               "[ueagle-atm vdbg]  " format, ##args); \
+       } while (0)
+
+#define uea_enters(usb_dev) \
+       uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)
+
+#define uea_leaves(usb_dev) \
+       uea_vdbg(usb_dev, "leaving  %s\n", __FUNCTION__)
+
+#define uea_err(usb_dev, format,args...) \
+       dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)
+
+#define uea_warn(usb_dev, format,args...) \
+       dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args)
+
+#define uea_info(usb_dev, format,args...) \
+       dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args)
+
+struct uea_cmvs {
+       u32 address;
+       u16 offset;
+       u32 data;
+} __attribute__ ((packed));
+
+struct uea_softc {
+       struct usb_device *usb_dev;
+       struct usbatm_data *usbatm;
+
+       int modem_index;
+       unsigned int driver_info;
+
+       int booting;
+       int reset;
+
+       wait_queue_head_t sync_q;
+
+       struct task_struct *kthread;
+       u32 data;
+       wait_queue_head_t cmv_ack_wait;
+       int cmv_ack;
+
+       struct work_struct task;
+       u16 pageno;
+       u16 ovl;
+
+       const struct firmware *dsp_firm;
+       struct urb *urb_int;
+
+       u8 cmv_function;
+       u16 cmv_idx;
+       u32 cmv_address;
+       u16 cmv_offset;
+
+       /* keep in sync with eaglectl */
+       struct uea_stats {
+               struct {
+                       u32 state;
+                       u32 flags;
+                       u32 mflags;
+                       u32 vidcpe;
+                       u32 vidco;
+                       u32 dsrate;
+                       u32 usrate;
+                       u32 dsunc;
+                       u32 usunc;
+                       u32 dscorr;
+                       u32 uscorr;
+                       u32 txflow;
+                       u32 rxflow;
+                       u32 usattenuation;
+                       u32 dsattenuation;
+                       u32 dsmargin;
+                       u32 usmargin;
+                       u32 firmid;
+               } phy;
+       } stats;
+};
+
+/*
+ * Elsa IDs
+ */
+#define ELSA_VID               0x05CC
+#define ELSA_PID_PSTFIRM       0x3350
+#define ELSA_PID_PREFIRM       0x3351
+
+/*
+ * Sagem USB IDs
+ */
+#define EAGLE_VID              0x1110
+#define EAGLE_I_PID_PREFIRM    0x9010  /* Eagle I */
+#define EAGLE_I_PID_PSTFIRM    0x900F  /* Eagle I */
+
+#define EAGLE_IIC_PID_PREFIRM  0x9024  /* Eagle IIC */
+#define EAGLE_IIC_PID_PSTFIRM  0x9023  /* Eagle IIC */
+
+#define EAGLE_II_PID_PREFIRM   0x9022  /* Eagle II */
+#define EAGLE_II_PID_PSTFIRM   0x9021  /* Eagle II */
+
+/*
+ *  Eagle III Pid
+ */
+#define EAGLE_III_PID_PREFIRM  0x9032  /* Eagle III */
+#define EAGLE_III_PID_PSTFIRM  0x9031  /* Eagle III */
+
+/*
+ * USR USB IDs
+ */
+#define USR_VID                        0x0BAF
+#define MILLER_A_PID_PREFIRM   0x00F2
+#define MILLER_A_PID_PSTFIRM   0x00F1
+#define MILLER_B_PID_PREFIRM   0x00FA
+#define MILLER_B_PID_PSTFIRM   0x00F9
+#define HEINEKEN_A_PID_PREFIRM 0x00F6
+#define HEINEKEN_A_PID_PSTFIRM 0x00F5
+#define HEINEKEN_B_PID_PREFIRM 0x00F8
+#define HEINEKEN_B_PID_PSTFIRM 0x00F7
+
+#define PREFIRM 0
+#define PSTFIRM (1<<7)
+enum {
+       ADI930 = 0,
+       EAGLE_I,
+       EAGLE_II,
+       EAGLE_III
+};
+
+/* macros for both struct usb_device_id and struct uea_softc */
+#define UEA_IS_PREFIRM(x) \
+       (!((x)->driver_info & PSTFIRM))
+#define UEA_CHIP_VERSION(x) \
+       ((x)->driver_info & 0xf)
+
+#define IS_ISDN(sc) \
+       (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)
+
+#define INS_TO_USBDEV(ins) ins->usb_dev
+
+#define GET_STATUS(data) \
+       ((data >> 8) & 0xf)
+#define IS_OPERATIONAL(sc) \
+       (GET_STATUS(sc->stats.phy.state) == 2)
+
+/*
+ * Set of macros to handle unaligned data in the firmware blob.
+ * The FW_GET_BYTE() macro is provided only for consistency.
+ */
+
+#define FW_GET_BYTE(p) *((__u8 *) (p))
+#define FW_GET_WORD(p) le16_to_cpu(get_unaligned((__le16 *) (p)))
+#define FW_GET_LONG(p) le32_to_cpu(get_unaligned((__le32 *) (p)))
+
+#define FW_DIR "ueagle-atm/"
+#define NB_MODEM 4
+
+#define BULK_TIMEOUT 300
+#define CTRL_TIMEOUT 1000
+
+#define ACK_TIMEOUT msecs_to_jiffies(1500)
+
+#define UEA_INTR_IFACE_NO      0
+#define UEA_US_IFACE_NO                1
+#define UEA_DS_IFACE_NO                2
+
+#define FASTEST_ISO_INTF       8
+
+#define UEA_BULK_DATA_PIPE     0x02
+#define UEA_IDMA_PIPE          0x04
+#define UEA_INTR_PIPE          0x04
+#define UEA_ISO_DATA_PIPE      0x08
+
+#define UEA_SET_BLOCK          0x0001
+#define UEA_SET_MODE           0x0003
+#define UEA_SET_2183_DATA      0x0004
+#define UEA_SET_TIMEOUT                0x0011
+
+#define UEA_LOOPBACK_OFF       0x0002
+#define UEA_LOOPBACK_ON                0x0003
+#define UEA_BOOT_IDMA          0x0006
+#define UEA_START_RESET                0x0007
+#define UEA_END_RESET          0x0008
+
+#define UEA_SWAP_MAILBOX       (0x3fcd | 0x4000)
+#define UEA_MPTX_START         (0x3fce | 0x4000)
+#define UEA_MPTX_MAILBOX       (0x3fd6 | 0x4000)
+#define UEA_MPRX_MAILBOX       (0x3fdf | 0x4000)
+
+/* structure describing a block within a DSP page */
+struct block_info {
+       __le16 wHdr;
+#define UEA_BIHDR 0xabcd
+       __le16 wAddress;
+       __le16 wSize;
+       __le16 wOvlOffset;
+       __le16 wOvl;            /* overlay */
+       __le16 wLast;
+} __attribute__ ((packed));
+#define BLOCK_INFO_SIZE 12
+
+/* structure representing a CMV (Configuration and Management Variable) */
+struct cmv {
+       __le16 wPreamble;
+#define PREAMBLE 0x535c
+       __u8 bDirection;
+#define MODEMTOHOST 0x01
+#define HOSTTOMODEM 0x10
+       __u8 bFunction;
+#define FUNCTION_TYPE(f)    ((f) >> 4)
+#define MEMACCESS      0x1
+#define ADSLDIRECTIVE  0x7
+
+#define FUNCTION_SUBTYPE(f) ((f) & 0x0f)
+/* for MEMACCESS */
+#define REQUESTREAD    0x0
+#define REQUESTWRITE   0x1
+#define REPLYREAD      0x2
+#define REPLYWRITE     0x3
+/* for ADSLDIRECTIVE */
+#define KERNELREADY    0x0
+#define MODEMREADY     0x1
+
+#define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf))
+       __le16 wIndex;
+       __le32 dwSymbolicAddress;
+#define MAKESA(a, b, c, d)                                             \
+       (((c) & 0xff) << 24 |                                           \
+        ((d) & 0xff) << 16 |                                           \
+        ((a) & 0xff) << 8  |                                           \
+        ((b) & 0xff))
+
+#define SA_CNTL MAKESA('C', 'N', 'T', 'L')
+#define SA_DIAG MAKESA('D', 'I', 'A', 'G')
+#define SA_INFO MAKESA('I', 'N', 'F', 'O')
+#define SA_OPTN MAKESA('O', 'P', 'T', 'N')
+#define SA_RATE MAKESA('R', 'A', 'T', 'E')
+#define SA_STAT MAKESA('S', 'T', 'A', 'T')
+       __le16 wOffsetAddress;
+       __le32 dwData;
+} __attribute__ ((packed));
+#define CMV_SIZE 16
+
+/* structure representing swap information */
+struct swap_info {
+       __u8 bSwapPageNo;
+       __u8 bOvl;              /* overlay */
+} __attribute__ ((packed));
+
+/* structure representing interrupt data */
+struct intr_pkt {
+       __u8 bType;
+       __u8 bNotification;
+       __le16 wValue;
+       __le16 wIndex;
+       __le16 wLength;
+       __le16 wInterrupt;
+#define INT_LOADSWAPPAGE 0x0001
+#define INT_INCOMINGCMV  0x0002
+       union {
+               struct {
+                       struct swap_info swapinfo;
+                       __le16 wDataSize;
+               } __attribute__ ((packed)) s1;
+
+               struct {
+                       struct cmv cmv;
+                       __le16 wDataSize;
+               } __attribute__ ((packed)) s2;
+       } __attribute__ ((packed)) u;
+#define bSwapPageNo    u.s1.swapinfo.bSwapPageNo
+#define bOvl           u.s1.swapinfo.bOvl
+} __attribute__ ((packed));
+#define INTR_PKT_SIZE 28
+
+static struct usb_driver uea_driver;
+static DECLARE_MUTEX(uea_semaphore);
+static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};
+
+static int modem_index;
+static unsigned int debug;
+static int sync_wait[NB_MODEM];
+static char *cmv_file[NB_MODEM];
+
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
+module_param_array(sync_wait, bool, NULL, 0644);
+MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM");
+module_param_array(cmv_file, charp, NULL, 0644);
+MODULE_PARM_DESC(cmv_file,
+               "file name with configuration and management variables");
+
+#define UPDATE_ATM_STAT(type, val) \
+       do { \
+               if (sc->usbatm->atm_dev) \
+                       sc->usbatm->atm_dev->type = val; \
+       } while (0)
+
+/* Firmware loading */
+#define LOAD_INTERNAL     0xA0
+#define F8051_USBCS       0x7f92
+
+/**
+ * uea_send_modem_cmd - Send a command for pre-firmware devices.
+ */
+static int uea_send_modem_cmd(struct usb_device *usb,
+               u16 addr, u16 size, u8 * buff)
+{
+       int ret = -ENOMEM;
+       u8 *xfer_buff;
+
+       xfer_buff = kmalloc(size, GFP_KERNEL);
+       if (xfer_buff) {
+               memcpy(xfer_buff, buff, size);
+               ret = usb_control_msg(usb,
+                                     usb_sndctrlpipe(usb, 0),
+                                     LOAD_INTERNAL,
+                                     USB_DIR_OUT | USB_TYPE_VENDOR |
+                                     USB_RECIP_DEVICE, addr, 0, xfer_buff,
+                                     size, CTRL_TIMEOUT);
+               kfree(xfer_buff);
+       }
+
+       if (ret < 0)
+               return ret;
+
+       return (ret == size) ? 0 : -EIO;
+}
+
+static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context)
+{
+       struct usb_device *usb = context;
+       u8 *pfw, value;
+       u32 crc = 0;
+       int ret, size;
+
+       uea_enters(usb);
+       if (!fw_entry) {
+               uea_err(usb, "firmware is not available\n");
+               goto err;
+       }
+
+       pfw = fw_entry->data;
+       size = fw_entry->size;
+       if (size < 4)
+               goto err_fw_corrupted;
+
+       crc = FW_GET_LONG(pfw);
+       pfw += 4;
+       size -= 4;
+       if (crc32_be(0, pfw, size) != crc)
+               goto err_fw_corrupted;
+
+       /*
+        * Start to upload formware : send reset
+        */
+       value = 1;
+       ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
+
+       if (ret < 0) {
+               uea_err(usb, "modem reset failed with error %d\n", ret);
+               goto err;
+       }
+
+       while (size > 3) {
+               u8 len = FW_GET_BYTE(pfw);
+               u16 add = FW_GET_WORD(pfw + 1);
+
+               size -= len + 3;
+               if (size < 0)
+                       goto err_fw_corrupted;
+
+               ret = uea_send_modem_cmd(usb, add, len, pfw + 3);
+               if (ret < 0) {
+                       uea_err(usb, "uploading firmware data failed "
+                                       "with error %d\n", ret);
+                       goto err;
+               }
+               pfw += len + 3;
+       }
+
+       if (size != 0)
+               goto err_fw_corrupted;
+
+       /*
+        * Tell the modem we finish : de-assert reset
+        */
+       value = 0;
+       ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value);
+       if (ret < 0)
+               uea_err(usb, "modem de-assert failed with error %d\n", ret);
+       else
+               uea_info(usb, "firmware uploaded\n");
+
+       uea_leaves(usb);
+       return;
+
+err_fw_corrupted:
+       uea_err(usb, "firmware is corrupted\n");
+err:
+       uea_leaves(usb);
+}
+
+/**
+ * uea_load_firmware - Load usb firmware for pre-firmware devices.
+ */
+static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
+{
+       int ret;
+       char *fw_name = FW_DIR "eagle.fw";
+
+       uea_enters(usb);
+       uea_info(usb, "pre-firmware device, uploading firmware\n");
+
+       switch (ver) {
+       case ADI930:
+               fw_name = FW_DIR "adi930.fw";
+               break;
+       case EAGLE_I:
+               fw_name = FW_DIR "eagleI.fw";
+               break;
+       case EAGLE_II:
+               fw_name = FW_DIR "eagleII.fw";
+               break;
+       case EAGLE_III:
+               fw_name = FW_DIR "eagleIII.fw";
+               break;
+       }
+
+       ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
+       if (ret)
+               uea_err(usb, "firmware %s is not available\n", fw_name);
+       else
+               uea_info(usb, "loading firmware %s\n", fw_name);
+
+       uea_leaves(usb);
+       return ret;
+}
+
+/* modem management : dsp firmware, send/read CMV, monitoring statistic
+ */
+
+/*
+ * Make sure that the DSP code provided is safe to use.
+ */
+static int check_dsp(u8 *dsp, unsigned int len)
+{
+       u8 pagecount, blockcount;
+       u16 blocksize;
+       u32 pageoffset;
+       unsigned int i, j, p, pp;
+
+       pagecount = FW_GET_BYTE(dsp);
+       p = 1;
+
+       /* enough space for page offsets? */
+       if (p + 4 * pagecount > len)
+               return 1;
+
+       for (i = 0; i < pagecount; i++) {
+
+               pageoffset = FW_GET_LONG(dsp + p);
+               p += 4;
+
+               if (pageoffset == 0)
+                       continue;
+
+               /* enough space for blockcount? */
+               if (pageoffset >= len)
+                       return 1;
+
+               pp = pageoffset;
+               blockcount = FW_GET_BYTE(dsp + pp);
+               pp += 1;
+
+               for (j = 0; j < blockcount; j++) {
+
+                       /* enough space for block header? */
+                       if (pp + 4 > len)
+                               return 1;
+
+                       pp += 2;        /* skip blockaddr */
+                       blocksize = FW_GET_WORD(dsp + pp);
+                       pp += 2;
+
+                       /* enough space for block data? */
+                       if (pp + blocksize > len)
+                               return 1;
+
+                       pp += blocksize;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * send data to the idma pipe
+ * */
+static int uea_idma_write(struct uea_softc *sc, void *data, u32 size)
+{
+       int ret = -ENOMEM;
+       u8 *xfer_buff;
+       int bytes_read;
+
+       xfer_buff = kmalloc(size, GFP_KERNEL);
+       if (!xfer_buff) {
+               uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
+               return ret;
+       }
+
+       memcpy(xfer_buff, data, size);
+
+       ret = usb_bulk_msg(sc->usb_dev,
+                        usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE),
+                        xfer_buff, size, &bytes_read, BULK_TIMEOUT);
+
+       kfree(xfer_buff);
+       if (ret < 0)
+               return ret;
+       if (size != bytes_read) {
+               uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size,
+                      bytes_read);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int request_dsp(struct uea_softc *sc)
+{
+       int ret;
+       char *dsp_name;
+
+       if (UEA_CHIP_VERSION(sc) == ADI930) {
+               if (IS_ISDN(sc))
+                       dsp_name = FW_DIR "DSP9i.bin";
+               else
+                       dsp_name = FW_DIR "DSP9p.bin";
+       } else {
+               if (IS_ISDN(sc))
+                       dsp_name = FW_DIR "DSPei.bin";
+               else
+                       dsp_name = FW_DIR "DSPep.bin";
+       }
+
+       ret = request_firmware(&sc->dsp_firm,
+                               dsp_name, &sc->usb_dev->dev);
+       if (ret < 0) {
+               uea_err(INS_TO_USBDEV(sc),
+                      "requesting firmware %s failed with error %d\n",
+                      dsp_name, ret);
+               return ret;
+       }
+
+       if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) {
+               uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+                      dsp_name);
+               release_firmware(sc->dsp_firm);
+               sc->dsp_firm = NULL;
+               return -EILSEQ;
+       }
+
+       return 0;
+}
+
+/*
+ * The uea_load_page() function must be called within a process context
+ */
+static void uea_load_page(void *xsc)
+{
+       struct uea_softc *sc = xsc;
+       u16 pageno = sc->pageno;
+       u16 ovl = sc->ovl;
+       struct block_info bi;
+
+       u8 *p;
+       u8 pagecount, blockcount;
+       u16 blockaddr, blocksize;
+       u32 pageoffset;
+       int i;
+
+       /* reload firmware when reboot start and it's loaded already */
+       if (ovl == 0 && pageno == 0 && sc->dsp_firm) {
+               release_firmware(sc->dsp_firm);
+               sc->dsp_firm = NULL;
+       }
+
+       if (sc->dsp_firm == NULL && request_dsp(sc) < 0)
+               return;
+
+       p = sc->dsp_firm->data;
+       pagecount = FW_GET_BYTE(p);
+       p += 1;
+
+       if (pageno >= pagecount)
+               goto bad1;
+
+       p += 4 * pageno;
+       pageoffset = FW_GET_LONG(p);
+
+       if (pageoffset == 0)
+               goto bad1;
+
+       p = sc->dsp_firm->data + pageoffset;
+       blockcount = FW_GET_BYTE(p);
+       p += 1;
+
+       uea_dbg(INS_TO_USBDEV(sc),
+              "sending %u blocks for DSP page %u\n", blockcount, pageno);
+
+       bi.wHdr = cpu_to_le16(UEA_BIHDR);
+       bi.wOvl = cpu_to_le16(ovl);
+       bi.wOvlOffset = cpu_to_le16(ovl | 0x8000);
+
+       for (i = 0; i < blockcount; i++) {
+               blockaddr = FW_GET_WORD(p);
+               p += 2;
+
+               blocksize = FW_GET_WORD(p);
+               p += 2;
+
+               bi.wSize = cpu_to_le16(blocksize);
+               bi.wAddress = cpu_to_le16(blockaddr);
+               bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0);
+
+               /* send block info through the IDMA pipe */
+               if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE))
+                       goto bad2;
+
+               /* send block data through the IDMA pipe */
+               if (uea_idma_write(sc, p, blocksize))
+                       goto bad2;
+
+               p += blocksize;
+       }
+
+       return;
+
+bad2:
+       uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i);
+       return;
+bad1:
+       uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno);
+}
+
+static inline void wake_up_cmv_ack(struct uea_softc *sc)
+{
+       sc->cmv_ack = 1;
+       wake_up(&sc->cmv_ack_wait);
+}
+
+static inline int wait_cmv_ack(struct uea_softc *sc)
+{
+       int ret = wait_event_timeout(sc->cmv_ack_wait,
+                                                  sc->cmv_ack, ACK_TIMEOUT);
+       sc->cmv_ack = 0;
+
+       if (ret < 0)
+               return ret;
+
+       return (ret == 0) ? -ETIMEDOUT : 0;
+
+}
+
+#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
+
+static int uea_request(struct uea_softc *sc,
+               u16 value, u16 index, u16 size, void *data)
+{
+       u8 *xfer_buff;
+       int ret = -ENOMEM;
+
+       xfer_buff = kmalloc(size, GFP_KERNEL);
+       if (!xfer_buff) {
+               uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
+               return ret;
+       }
+       memcpy(xfer_buff, data, size);
+
+       ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0),
+                             UCDC_SEND_ENCAPSULATED_COMMAND,
+                             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                             value, index, xfer_buff, size, CTRL_TIMEOUT);
+
+       kfree(xfer_buff);
+       if (ret < 0) {
+               uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret);
+               return ret;
+       }
+
+       if (ret != size) {
+               uea_err(INS_TO_USBDEV(sc),
+                      "usb_control_msg send only %d bytes (instead of %d)\n",
+                      ret, size);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int uea_cmv(struct uea_softc *sc,
+               u8 function, u32 address, u16 offset, u32 data)
+{
+       struct cmv cmv;
+       int ret;
+
+       /* we send a request, but we expect a reply */
+       sc->cmv_function = function | 0x2;
+       sc->cmv_idx++;
+       sc->cmv_address = address;
+       sc->cmv_offset = offset;
+
+       cmv.wPreamble = cpu_to_le16(PREAMBLE);
+       cmv.bDirection = HOSTTOMODEM;
+       cmv.bFunction = function;
+       cmv.wIndex = cpu_to_le16(sc->cmv_idx);
+       put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress);
+       cmv.wOffsetAddress = cpu_to_le16(offset);
+       put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData);
+
+       ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv);
+       if (ret < 0)
+               return ret;
+       return wait_cmv_ack(sc);
+}
+
+static inline int uea_read_cmv(struct uea_softc *sc,
+               u32 address, u16 offset, u32 *data)
+{
+       int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD),
+                         address, offset, 0);
+       if (ret < 0)
+               uea_err(INS_TO_USBDEV(sc),
+                       "reading cmv failed with error %d\n", ret);
+       else
+               *data = sc->data;
+
+       return ret;
+}
+
+static inline int uea_write_cmv(struct uea_softc *sc,
+               u32 address, u16 offset, u32 data)
+{
+       int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE),
+                         address, offset, data);
+       if (ret < 0)
+               uea_err(INS_TO_USBDEV(sc),
+                       "writing cmv failed with error %d\n", ret);
+
+       return ret;
+}
+
+/*
+ * Monitor the modem and update the stat
+ * return 0 if everything is ok
+ * return < 0 if an error occurs (-EAGAIN reboot needed)
+ */
+static int uea_stat(struct uea_softc *sc)
+{
+       u32 data;
+       int ret;
+
+       uea_enters(INS_TO_USBDEV(sc));
+       data = sc->stats.phy.state;
+
+       ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state);
+       if (ret < 0)
+               return ret;
+
+       switch (GET_STATUS(sc->stats.phy.state)) {
+       case 0:         /* not yet synchronized */
+               uea_dbg(INS_TO_USBDEV(sc),
+                      "modem not yet synchronized\n");
+               return 0;
+
+       case 1:         /* initialization */
+               uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");
+               return 0;
+
+       case 2:         /* operational */
+               uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n");
+               break;
+
+       case 3:         /* fail ... */
+               uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n");
+               return -EAGAIN;
+
+       case 4 ... 6:   /* test state */
+               uea_warn(INS_TO_USBDEV(sc),
+                               "modem in test mode - not supported\n");
+               return -EAGAIN;
+
+       case 7:         /* fast-retain ... */
+               uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n");
+               return 0;
+       default:
+               uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n",
+                       GET_STATUS(sc->stats.phy.state));
+               return -EAGAIN;
+       }
+
+       if (GET_STATUS(data) != 2) {
+               uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);
+               uea_info(INS_TO_USBDEV(sc), "modem operational\n");
+
+               /* release the dsp firmware as it is not needed until
+                * the next failure
+                */
+               if (sc->dsp_firm) {
+                       release_firmware(sc->dsp_firm);
+                       sc->dsp_firm = NULL;
+               }
+
+               ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid);
+               if (ret < 0)
+                       return ret;
+               uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
+                               sc->stats.phy.firmid);
+       }
+
+       /* always update it as atm layer could not be init when we switch to
+        * operational state
+        */
+       UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND);
+
+       /* wake up processes waiting for synchronization */
+       wake_up(&sc->sync_q);
+
+       ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags);
+       if (ret < 0)
+               return ret;
+       sc->stats.phy.mflags |= sc->stats.phy.flags;
+
+       /* in case of a flags ( for example delineation LOSS (& 0x10)),
+        * we check the status again in order to detect the failure earlier
+        */
+       if (sc->stats.phy.flags) {
+               uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n",
+                      sc->stats.phy.flags);
+               return 0;
+       }
+
+       ret = uea_read_cmv(sc, SA_RATE, 0, &data);
+       if (ret < 0)
+               return ret;
+
+       /* in bulk mode the modem have problem with high rate
+        * changing internal timing could improve things, but the
+        * value is misterious.
+        * ADI930 don't support it (-EPIPE error).
+        */
+       if (UEA_CHIP_VERSION(sc) != ADI930
+                   && sc->stats.phy.dsrate != (data >> 16) * 32) {
+               /* Original timming from ADI(used in windows driver)
+                * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits
+                */
+               u16 timeout = (data <= 0x20ffff) ? 0 : 1;
+               ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL);
+               uea_info(INS_TO_USBDEV(sc),
+                               "setting new timeout %d%s\n", timeout,
+                               ret < 0?" failed":"");
+       }
+       sc->stats.phy.dsrate = (data >> 16) * 32;
+       sc->stats.phy.usrate = (data & 0xffff) * 32;
+       UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);
+
+       ret = uea_read_cmv(sc, SA_DIAG, 23, &data);
+       if (ret < 0)
+               return ret;
+       sc->stats.phy.dsattenuation = (data & 0xff) / 2;
+
+       ret = uea_read_cmv(sc, SA_DIAG, 47, &data);
+       if (ret < 0)
+               return ret;
+       sc->stats.phy.usattenuation = (data & 0xff) / 2;
+
+       ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin);
+       if (ret < 0)
+               return ret;
+
+       ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin);
+       if (ret < 0)
+               return ret;
+
+       ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow);
+       if (ret < 0)
+               return ret;
+
+       ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow);
+       if (ret < 0)
+               return ret;
+
+       ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc);
+       if (ret < 0)
+               return ret;
+
+       /* only for atu-c */
+       ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc);
+       if (ret < 0)
+               return ret;
+
+       ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr);
+       if (ret < 0)
+               return ret;
+
+       /* only for atu-c */
+       ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr);
+       if (ret < 0)
+               return ret;
+
+       ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco);
+       if (ret < 0)
+               return ret;
+
+       ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int request_cmvs(struct uea_softc *sc,
+                struct uea_cmvs **cmvs, const struct firmware **fw)
+{
+       int ret, size;
+       u8 *data;
+       char *file;
+       static char cmv_name[256] = FW_DIR;
+
+       if (cmv_file[sc->modem_index] == NULL) {
+               if (UEA_CHIP_VERSION(sc) == ADI930)
+                       file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin";
+               else
+                       file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin";
+       } else
+               file = cmv_file[sc->modem_index];
+
+       strcpy(cmv_name, FW_DIR);
+       strlcat(cmv_name, file, sizeof(cmv_name));
+
+       ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev);
+       if (ret < 0) {
+               uea_err(INS_TO_USBDEV(sc),
+                      "requesting firmware %s failed with error %d\n",
+                      cmv_name, ret);
+               return ret;
+       }
+
+       data = (u8 *) (*fw)->data;
+       size = *data * sizeof(struct uea_cmvs) + 1;
+       if (size != (*fw)->size) {
+               uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+                      cmv_name);
+               release_firmware(*fw);
+               return -EILSEQ;
+       }
+
+       *cmvs = (struct uea_cmvs *)(data + 1);
+       return *data;
+}
+
+/* Start boot post firmware modem:
+ * - send reset commands through usb control pipe
+ * - start workqueue for DSP loading
+ * - send CMV options to modem
+ */
+
+static int uea_start_reset(struct uea_softc *sc)
+{
+       u16 zero = 0;   /* ;-) */
+       int i, len, ret;
+       struct uea_cmvs *cmvs;
+       const struct firmware *cmvs_fw;
+
+       uea_enters(INS_TO_USBDEV(sc));
+       uea_info(INS_TO_USBDEV(sc), "(re)booting started\n");
+
+       sc->booting = 1;
+       UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST);
+
+       /* reset statistics */
+       memset(&sc->stats, 0, sizeof(struct uea_stats));
+
+       /* tell the modem that we want to boot in IDMA mode */
+       uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
+       uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL);
+
+       /* enter reset mode */
+       uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL);
+
+       /* original driver use 200ms, but windows driver use 100ms */
+       msleep(100);
+
+       /* leave reset mode */
+       uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL);
+
+       /* clear tx and rx mailboxes */
+       uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero);
+       uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero);
+       uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero);
+
+       msleep(1000);
+       sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY);
+       sc->booting = 0;
+
+       /* start loading DSP */
+       sc->pageno = 0;
+       sc->ovl = 0;
+       schedule_work(&sc->task);
+
+       /* wait for modem ready CMV */
+       ret = wait_cmv_ack(sc);
+       if (ret < 0)
+               return ret;
+
+       /* Enter in R-IDLE (cmv) until instructed otherwise */
+       ret = uea_write_cmv(sc, SA_CNTL, 0, 1);
+       if (ret < 0)
+               return ret;
+
+       /* get options */
+       ret = len = request_cmvs(sc, &cmvs, &cmvs_fw);
+       if (ret < 0)
+               return ret;
+
+       /* send options */
+       for (i = 0; i < len; i++) {
+               ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address),
+                                       FW_GET_WORD(&cmvs[i].offset),
+                                       FW_GET_LONG(&cmvs[i].data));
+               if (ret < 0)
+                       goto out;
+       }
+       /* Enter in R-ACT-REQ */
+       ret = uea_write_cmv(sc, SA_CNTL, 0, 2);
+out:
+       release_firmware(cmvs_fw);
+       sc->reset = 0;
+       uea_leaves(INS_TO_USBDEV(sc));
+       return ret;
+}
+
+/*
+ * In case of an error wait 1s before rebooting the modem
+ * if the modem don't request reboot (-EAGAIN).
+ * Monitor the modem every 1s.
+ */
+
+static int uea_kthread(void *data)
+{
+       struct uea_softc *sc = data;
+       int ret = -EAGAIN;
+
+       uea_enters(INS_TO_USBDEV(sc));
+       while (!kthread_should_stop()) {
+               if (ret < 0 || sc->reset)
+                       ret = uea_start_reset(sc);
+               if (!ret)
+                       ret = uea_stat(sc);
+               if (ret != -EAGAIN)
+                       msleep(1000);
+       }
+       uea_leaves(INS_TO_USBDEV(sc));
+       return ret;
+}
+
+/* Load second usb firmware for ADI930 chip */
+static int load_XILINX_firmware(struct uea_softc *sc)
+{
+       const struct firmware *fw_entry;
+       int ret, size, u, ln;
+       u8 *pfw, value;
+       char *fw_name = FW_DIR "930-fpga.bin";
+
+       uea_enters(INS_TO_USBDEV(sc));
+
+       ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev);
+       if (ret) {
+               uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n",
+                      fw_name);
+               goto err0;
+       }
+
+       pfw = fw_entry->data;
+       size = fw_entry->size;
+       if (size != 0x577B) {
+               uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+                      fw_name);
+               ret = -EILSEQ;
+               goto err1;
+       }
+       for (u = 0; u < size; u += ln) {
+               ln = min(size - u, 64);
+               ret = uea_request(sc, 0xe, 0, ln, pfw + u);
+               if (ret < 0) {
+                       uea_err(INS_TO_USBDEV(sc),
+                              "elsa download data failed (%d)\n", ret);
+                       goto err1;
+               }
+       }
+
+       /* finish to send the fpga
+        */
+       ret = uea_request(sc, 0xe, 1, 0, NULL);
+       if (ret < 0) {
+               uea_err(INS_TO_USBDEV(sc),
+                               "elsa download data failed (%d)\n", ret);
+               goto err1;
+       }
+
+       /*
+        * Tell the modem we finish : de-assert reset
+        */
+       value = 0;
+       ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value);
+       if (ret < 0)
+               uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret);
+
+
+err1:
+       release_firmware(fw_entry);
+err0:
+       uea_leaves(INS_TO_USBDEV(sc));
+       return ret;
+}
+
+static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv)
+{
+       uea_enters(INS_TO_USBDEV(sc));
+       if (le16_to_cpu(cmv->wPreamble) != PREAMBLE)
+               goto bad1;
+
+       if (cmv->bDirection != MODEMTOHOST)
+               goto bad1;
+
+       /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to
+        * the first MEMACESS cmv. Ignore it...
+        */
+       if (cmv->bFunction != sc->cmv_function) {
+               if (UEA_CHIP_VERSION(sc) == ADI930
+                               && cmv->bFunction ==  MAKEFUNCTION(2, 2)) {
+                       cmv->wIndex = cpu_to_le16(sc->cmv_idx);
+                       put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress);
+                       cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset);
+               }
+               else
+                       goto bad2;
+       }
+
+       if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) {
+               wake_up_cmv_ack(sc);
+               return;
+       }
+
+       /* in case of MEMACCESS */
+       if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx ||
+           le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) !=
+           sc->cmv_address
+           || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset)
+               goto bad2;
+
+       sc->data = le32_to_cpu(get_unaligned(&cmv->dwData));
+       sc->data = sc->data << 16 | sc->data >> 16;
+
+       wake_up_cmv_ack(sc);
+       return;
+
+bad2:
+       uea_err(INS_TO_USBDEV(sc), "unexpected cmv received,"
+                       "Function : %d, Subfunction : %d\n",
+                       FUNCTION_TYPE(cmv->bFunction),
+                       FUNCTION_SUBTYPE(cmv->bFunction));
+       return;
+
+bad1:
+       uea_err(INS_TO_USBDEV(sc), "invalid cmv received, "
+                       "wPreamble %d, bDirection %d\n",
+                       le16_to_cpu(cmv->wPreamble), cmv->bDirection);
+}
+
+/*
+ * interrupt handler
+ */
+static void uea_intr(struct urb *urb, struct pt_regs *regs)
+{
+       struct uea_softc *sc = (struct uea_softc *)urb->context;
+       struct intr_pkt *intr;
+       uea_enters(INS_TO_USBDEV(sc));
+
+       if (urb->status < 0) {
+               uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n",
+                      urb->status);
+               return;
+       }
+
+       intr = (struct intr_pkt *) urb->transfer_buffer;
+
+       /* device-to-host interrupt */
+       if (intr->bType != 0x08 || sc->booting) {
+               uea_err(INS_TO_USBDEV(sc), "wrong intr\n");
+               // rebooting ?
+               // sc->reset = 1;
+               goto resubmit;
+       }
+
+       switch (le16_to_cpu(intr->wInterrupt)) {
+       case INT_LOADSWAPPAGE:
+               sc->pageno = intr->bSwapPageNo;
+               sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4;
+               schedule_work(&sc->task);
+               break;
+
+       case INT_INCOMINGCMV:
+               uea_dispatch_cmv(sc, &intr->u.s2.cmv);
+               break;
+
+       default:
+               uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n",
+                      le16_to_cpu(intr->wInterrupt));
+       }
+
+resubmit:
+       usb_submit_urb(sc->urb_int, GFP_ATOMIC);
+}
+
+/*
+ * Start the modem : init the data and start kernel thread
+ */
+static int uea_boot(struct uea_softc *sc)
+{
+       int ret;
+       struct intr_pkt *intr;
+
+       uea_enters(INS_TO_USBDEV(sc));
+
+       INIT_WORK(&sc->task, uea_load_page, sc);
+       init_waitqueue_head(&sc->sync_q);
+       init_waitqueue_head(&sc->cmv_ack_wait);
+
+       if (UEA_CHIP_VERSION(sc) == ADI930)
+               load_XILINX_firmware(sc);
+
+       intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL);
+       if (!intr) {
+               uea_err(INS_TO_USBDEV(sc),
+                      "cannot allocate interrupt package\n");
+               uea_leaves(INS_TO_USBDEV(sc));
+               return -ENOMEM;
+       }
+
+       sc->urb_int = usb_alloc_urb(0, GFP_KERNEL);
+       if (!sc->urb_int) {
+               uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n");
+               goto err;
+       }
+
+       usb_fill_int_urb(sc->urb_int, sc->usb_dev,
+                        usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
+                        intr, INTR_PKT_SIZE, uea_intr, sc,
+                        sc->usb_dev->actconfig->interface[0]->altsetting[0].
+                        endpoint[0].desc.bInterval);
+
+       ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
+       if (ret < 0) {
+               uea_err(INS_TO_USBDEV(sc),
+                      "urb submition failed with error %d\n", ret);
+               goto err1;
+       }
+
+       sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
+       if (sc->kthread == ERR_PTR(-ENOMEM)) {
+               uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
+               goto err2;
+       }
+
+       uea_leaves(INS_TO_USBDEV(sc));
+       return 0;
+
+err2:
+       usb_kill_urb(sc->urb_int);
+err1:
+       kfree(intr);
+err:
+       usb_free_urb(sc->urb_int);
+       uea_leaves(INS_TO_USBDEV(sc));
+       return -ENOMEM;
+}
+
+/*
+ * Stop the modem : kill kernel thread and free data
+ */
+static void uea_stop(struct uea_softc *sc)
+{
+       int ret;
+       uea_enters(INS_TO_USBDEV(sc));
+       ret = kthread_stop(sc->kthread);
+       uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
+
+       /* stop any pending boot process */
+       flush_scheduled_work();
+
+       uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
+
+       usb_kill_urb(sc->urb_int);
+       kfree(sc->urb_int->transfer_buffer);
+       usb_free_urb(sc->urb_int);
+
+       if (sc->dsp_firm)
+               release_firmware(sc->dsp_firm);
+       uea_leaves(INS_TO_USBDEV(sc));
+}
+
+/* syfs interface */
+static struct uea_softc *dev_to_uea(struct device *dev)
+{
+       struct usb_interface *intf;
+       struct usbatm_data *usbatm;
+
+       intf = to_usb_interface(dev);
+       if (!intf)
+               return NULL;
+
+       usbatm = usb_get_intfdata(intf);
+       if (!usbatm)
+               return NULL;
+
+       return usbatm->driver_data;
+}
+
+static ssize_t read_status(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       int ret = -ENODEV;
+       struct uea_softc *sc;
+
+       down(&uea_semaphore);
+       sc = dev_to_uea(dev);
+       if (!sc)
+               goto out;
+       ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state);
+out:
+       up(&uea_semaphore);
+       return ret;
+}
+
+static ssize_t reboot(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       int ret = -ENODEV;
+       struct uea_softc *sc;
+
+       down(&uea_semaphore);
+       sc = dev_to_uea(dev);
+       if (!sc)
+               goto out;
+       sc->reset = 1;
+       ret = count;
+out:
+       up(&uea_semaphore);
+       return ret;
+}
+
+static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);
+
+static ssize_t read_human_status(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       int ret = -ENODEV;
+       struct uea_softc *sc;
+
+       down(&uea_semaphore);
+       sc = dev_to_uea(dev);
+       if (!sc)
+               goto out;
+
+       switch (GET_STATUS(sc->stats.phy.state)) {
+       case 0:
+               ret = sprintf(buf, "Modem is booting\n");
+               break;
+       case 1:
+               ret = sprintf(buf, "Modem is initializing\n");
+               break;
+       case 2:
+               ret = sprintf(buf, "Modem is operational\n");
+               break;
+       default:
+               ret = sprintf(buf, "Modem synchronization failed\n");
+               break;
+       }
+out:
+       up(&uea_semaphore);
+       return ret;
+}
+
+static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL);
+
+static ssize_t read_delin(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       int ret = -ENODEV;
+       struct uea_softc *sc;
+
+       down(&uea_semaphore);
+       sc = dev_to_uea(dev);
+       if (!sc)
+               goto out;
+
+       if (sc->stats.phy.flags & 0x0C00)
+               ret = sprintf(buf, "ERROR\n");
+       else if (sc->stats.phy.flags & 0x0030)
+               ret = sprintf(buf, "LOSS\n");
+       else
+               ret = sprintf(buf, "GOOD\n");
+out:
+       up(&uea_semaphore);
+       return ret;
+}
+
+static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);
+
+#define UEA_ATTR(name, reset)                                  \
+                                                               \
+static ssize_t read_##name(struct device *dev,                         \
+               struct device_attribute *attr, char *buf)       \
+{                                                              \
+       int ret = -ENODEV;                                      \
+       struct uea_softc *sc;                                   \
+                                                               \
+       down(&uea_semaphore);                                   \
+       sc = dev_to_uea(dev);                                   \
+       if (!sc)                                                \
+               goto out;                                       \
+       ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name);  \
+       if (reset)                                              \
+               sc->stats.phy.name = 0;                         \
+out:                                                           \
+       up(&uea_semaphore);                                     \
+       return ret;                                             \
+}                                                              \
+                                                               \
+static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL)
+
+UEA_ATTR(mflags, 1);
+UEA_ATTR(vidcpe, 0);
+UEA_ATTR(usrate, 0);
+UEA_ATTR(dsrate, 0);
+UEA_ATTR(usattenuation, 0);
+UEA_ATTR(dsattenuation, 0);
+UEA_ATTR(usmargin, 0);
+UEA_ATTR(dsmargin, 0);
+UEA_ATTR(txflow, 0);
+UEA_ATTR(rxflow, 0);
+UEA_ATTR(uscorr, 0);
+UEA_ATTR(dscorr, 0);
+UEA_ATTR(usunc, 0);
+UEA_ATTR(dsunc, 0);
+
+/* Retrieve the device End System Identifier (MAC) */
+
+#define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10)
+static int uea_getesi(struct uea_softc *sc, u_char * esi)
+{
+       unsigned char mac_str[2 * ETH_ALEN + 1];
+       int i;
+       if (usb_string
+           (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str,
+            sizeof(mac_str)) != 2 * ETH_ALEN)
+               return 1;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]);
+
+       return 0;
+}
+
+/* ATM stuff */
+static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
+{
+       struct uea_softc *sc = usbatm->driver_data;
+
+       return uea_getesi(sc, atm_dev->esi);
+}
+
+static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf)
+{
+       struct uea_softc *sc = usbatm->driver_data;
+
+       wait_event(sc->sync_q, IS_OPERATIONAL(sc));
+
+       return 0;
+
+}
+
+static int claim_interface(struct usb_device *usb_dev,
+                          struct usbatm_data *usbatm, int ifnum)
+{
+       int ret;
+       struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum);
+
+       if (!intf) {
+               uea_err(usb_dev, "interface %d not found\n", ifnum);
+               return -ENODEV;
+       }
+
+       ret = usb_driver_claim_interface(&uea_driver, intf, usbatm);
+       if (ret != 0)
+               uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum,
+                      ret);
+       return ret;
+}
+
+static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
+{
+       /* sysfs interface */
+       device_create_file(&intf->dev, &dev_attr_stat_status);
+       device_create_file(&intf->dev, &dev_attr_stat_mflags);
+       device_create_file(&intf->dev, &dev_attr_stat_human_status);
+       device_create_file(&intf->dev, &dev_attr_stat_delin);
+       device_create_file(&intf->dev, &dev_attr_stat_vidcpe);
+       device_create_file(&intf->dev, &dev_attr_stat_usrate);
+       device_create_file(&intf->dev, &dev_attr_stat_dsrate);
+       device_create_file(&intf->dev, &dev_attr_stat_usattenuation);
+       device_create_file(&intf->dev, &dev_attr_stat_dsattenuation);
+       device_create_file(&intf->dev, &dev_attr_stat_usmargin);
+       device_create_file(&intf->dev, &dev_attr_stat_dsmargin);
+       device_create_file(&intf->dev, &dev_attr_stat_txflow);
+       device_create_file(&intf->dev, &dev_attr_stat_rxflow);
+       device_create_file(&intf->dev, &dev_attr_stat_uscorr);
+       device_create_file(&intf->dev, &dev_attr_stat_dscorr);
+       device_create_file(&intf->dev, &dev_attr_stat_usunc);
+       device_create_file(&intf->dev, &dev_attr_stat_dsunc);
+}
+
+static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
+                  const struct usb_device_id *id, int *heavy)
+{
+       struct usb_device *usb = interface_to_usbdev(intf);
+       struct uea_softc *sc;
+       int ret, ifnum = intf->altsetting->desc.bInterfaceNumber;
+
+       uea_enters(usb);
+
+       /* interface 0 is for firmware/monitoring */
+       if (ifnum != UEA_INTR_IFACE_NO)
+               return -ENODEV;
+
+       *heavy = sync_wait[modem_index];
+
+       /* interface 1 is for outbound traffic */
+       ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO);
+       if (ret < 0)
+               return ret;
+
+       /* ADI930 has only 2 interfaces and inbound traffic
+        * is on interface 1
+        */
+       if (UEA_CHIP_VERSION(id) != ADI930) {
+               /* interface 2 is for inbound traffic */
+               ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO);
+               if (ret < 0)
+                       return ret;
+       }
+
+       sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL);
+       if (!sc) {
+               uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n");
+               return -ENOMEM;
+       }
+
+       sc->usb_dev = usb;
+       usbatm->driver_data = sc;
+       sc->usbatm = usbatm;
+       sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0;
+       sc->driver_info = id->driver_info;
+
+       ret = uea_boot(sc);
+       if (ret < 0) {
+               kfree(sc);
+               return ret;
+       }
+
+       create_fs_entries(sc, intf);
+       return 0;
+}
+
+static void destroy_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
+{
+       /* sysfs interface */
+       device_remove_file(&intf->dev, &dev_attr_stat_status);
+       device_remove_file(&intf->dev, &dev_attr_stat_mflags);
+       device_remove_file(&intf->dev, &dev_attr_stat_human_status);
+       device_remove_file(&intf->dev, &dev_attr_stat_delin);
+       device_remove_file(&intf->dev, &dev_attr_stat_vidcpe);
+       device_remove_file(&intf->dev, &dev_attr_stat_usrate);
+       device_remove_file(&intf->dev, &dev_attr_stat_dsrate);
+       device_remove_file(&intf->dev, &dev_attr_stat_usattenuation);
+       device_remove_file(&intf->dev, &dev_attr_stat_dsattenuation);
+       device_remove_file(&intf->dev, &dev_attr_stat_usmargin);
+       device_remove_file(&intf->dev, &dev_attr_stat_dsmargin);
+       device_remove_file(&intf->dev, &dev_attr_stat_txflow);
+       device_remove_file(&intf->dev, &dev_attr_stat_rxflow);
+       device_remove_file(&intf->dev, &dev_attr_stat_uscorr);
+       device_remove_file(&intf->dev, &dev_attr_stat_dscorr);
+       device_remove_file(&intf->dev, &dev_attr_stat_usunc);
+       device_remove_file(&intf->dev, &dev_attr_stat_dsunc);
+}
+
+static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
+{
+       struct uea_softc *sc = usbatm->driver_data;
+
+       destroy_fs_entries(sc, intf);
+       uea_stop(sc);
+       kfree(sc);
+}
+
+static struct usbatm_driver uea_usbatm_driver = {
+       .driver_name = "ueagle-atm",
+       .owner = THIS_MODULE,
+       .bind = uea_bind,
+       .atm_start = uea_atm_open,
+       .unbind = uea_unbind,
+       .heavy_init = uea_heavy,
+       .in = UEA_BULK_DATA_PIPE,
+       .out = UEA_BULK_DATA_PIPE,
+};
+
+static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+       struct usb_device *usb = interface_to_usbdev(intf);
+
+       uea_enters(usb);
+       uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n",
+              le16_to_cpu(usb->descriptor.idVendor),
+              le16_to_cpu(usb->descriptor.idProduct),
+              chip_name[UEA_CHIP_VERSION(id)]);
+
+       usb_reset_device(usb);
+
+       if (UEA_IS_PREFIRM(id))
+               return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
+
+       return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+}
+
+static void uea_disconnect(struct usb_interface *intf)
+{
+       struct usb_device *usb = interface_to_usbdev(intf);
+       int ifnum = intf->altsetting->desc.bInterfaceNumber;
+       uea_enters(usb);
+
+       /* ADI930 has 2 interfaces and eagle 3 interfaces.
+        * Pre-firmware device has one interface
+        */
+       if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) {
+               down(&uea_semaphore);
+               usbatm_usb_disconnect(intf);
+               up(&uea_semaphore);
+               uea_info(usb, "ADSL device removed\n");
+       }
+
+       uea_leaves(usb);
+}
+
+/*
+ * List of supported VID/PID
+ */
+static const struct usb_device_id uea_ids[] = {
+       {USB_DEVICE(ELSA_VID,   ELSA_PID_PREFIRM),      .driver_info = ADI930 | PREFIRM},
+       {USB_DEVICE(ELSA_VID,   ELSA_PID_PSTFIRM),      .driver_info = ADI930 | PSTFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_I_PID_PREFIRM),   .driver_info = EAGLE_I | PREFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_I_PID_PSTFIRM),   .driver_info = EAGLE_I | PSTFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_II_PID_PREFIRM),  .driver_info = EAGLE_II | PREFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_II_PID_PSTFIRM),  .driver_info = EAGLE_II | PSTFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM},
+       {USB_DEVICE(EAGLE_VID,  EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM},
+       {USB_DEVICE(USR_VID,    MILLER_A_PID_PREFIRM),  .driver_info = EAGLE_I | PREFIRM},
+       {USB_DEVICE(USR_VID,    MILLER_A_PID_PSTFIRM),  .driver_info = EAGLE_I | PSTFIRM},
+       {USB_DEVICE(USR_VID,    MILLER_B_PID_PREFIRM),  .driver_info = EAGLE_I | PREFIRM},
+       {USB_DEVICE(USR_VID,    MILLER_B_PID_PSTFIRM),  .driver_info = EAGLE_I | PSTFIRM},
+       {USB_DEVICE(USR_VID,    HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
+       {USB_DEVICE(USR_VID,    HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
+       {USB_DEVICE(USR_VID,    HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
+       {USB_DEVICE(USR_VID,    HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
+       {}
+};
+
+/*
+ * USB driver descriptor
+ */
+static struct usb_driver uea_driver = {
+       .name = "ueagle-atm",
+       .id_table = uea_ids,
+       .probe = uea_probe,
+       .disconnect = uea_disconnect,
+};
+
+MODULE_DEVICE_TABLE(usb, uea_ids);
+
+/**
+ * uea_init - Initialize the module.
+ *      Register to USB subsystem
+ */
+static int __init uea_init(void)
+{
+       printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n");
+
+       usb_register(&uea_driver);
+
+       return 0;
+}
+
+module_init(uea_init);
+
+/**
+ * uea_exit  -  Destroy module
+ *    Deregister with USB subsystem
+ */
+static void __exit uea_exit(void)
+{
+       /*
+        * This calls automatically the uea_disconnect method if necessary:
+        */
+       usb_deregister(&uea_driver);
+
+       printk(KERN_INFO "[ueagle-atm] driver unloaded\n");
+}
+
+module_exit(uea_exit);
+
+MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka");
+MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver");
+MODULE_LICENSE("Dual BSD/GPL");
index 2e6593e..9baa629 100644 (file)
@@ -646,14 +646,14 @@ static void usbatm_destroy_instance(struct kref *kref)
        kfree(instance);
 }
 
-void usbatm_get_instance(struct usbatm_data *instance)
+static void usbatm_get_instance(struct usbatm_data *instance)
 {
        dbg("%s", __func__);
 
        kref_get(&instance->refcount);
 }
 
-void usbatm_put_instance(struct usbatm_data *instance)
+static void usbatm_put_instance(struct usbatm_data *instance)
 {
        dbg("%s", __func__);
 
index 7fe7fb4..5c76e3a 100644 (file)
@@ -140,7 +140,6 @@ static int xusbatm_usb_probe(struct usb_interface *intf,
 }
 
 static struct usb_driver xusbatm_usb_driver = {
-       .owner          = THIS_MODULE,
        .name           = xusbatm_driver_name,
        .probe          = xusbatm_usb_probe,
        .disconnect     = usbatm_usb_disconnect,
index 5085827..3ad9ee8 100644 (file)
@@ -2732,7 +2732,6 @@ static struct usb_device_id usb_audio_ids [] = {
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
-       .owner =        THIS_MODULE,
        .name =         "audio",
        .probe =        usb_audio_probe,
        .disconnect =   usb_audio_disconnect,
index 1b47514..248279e 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com>
  * Copyright (c) 2000 Vojtech Pavlik   <vojtech@suse.cz>
  * Copyright (c) 2004 Oliver Neukum    <oliver@neukum.name>
+ * Copyright (c) 2005 David Kubicek    <dave@awk.cz>
  *
  * USB Abstract Control Model driver for USB modems and ISDN adapters
  *
@@ -29,6 +30,7 @@
  *             config we want, sysadmin changes bConfigurationValue in sysfs.
  *     v0.23 - use softirq for rx processing, as needed by tty layer
  *     v0.24 - change probe method to evaluate CDC union descriptor
+ *     v0.25 - downstream tasks paralelized to maximize throughput
  */
 
 /*
 #include <linux/usb_cdc.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
+#include <linux/list.h>
 
 #include "cdc-acm.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.23"
-#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
+#define DRIVER_VERSION "v0.25"
+#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
 
 static struct usb_driver acm_driver;
@@ -284,7 +287,9 @@ exit:
 /* data interface returns incoming bytes, or we got unthrottled */
 static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
 {
-       struct acm *acm = urb->context;
+       struct acm_rb *buf;
+       struct acm_ru *rcv = urb->context;
+       struct acm *acm = rcv->instance;
        dbg("Entering acm_read_bulk with status %d\n", urb->status);
 
        if (!ACM_READY(acm))
@@ -293,49 +298,109 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
        if (urb->status)
                dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status);
 
-       /* calling tty_flip_buffer_push() in_irq() isn't allowed */
-       tasklet_schedule(&acm->bh);
+       buf = rcv->buffer;
+       buf->size = urb->actual_length;
+
+       spin_lock(&acm->read_lock);
+       list_add_tail(&rcv->list, &acm->spare_read_urbs);
+       list_add_tail(&buf->list, &acm->filled_read_bufs);
+       spin_unlock(&acm->read_lock);
+
+       tasklet_schedule(&acm->urb_task);
 }
 
 static void acm_rx_tasklet(unsigned long _acm)
 {
        struct acm *acm = (void *)_acm;
-       struct urb *urb = acm->readurb;
+       struct acm_rb *buf;
        struct tty_struct *tty = acm->tty;
-       unsigned char *data = urb->transfer_buffer;
+       struct acm_ru *rcv;
+       //unsigned long flags;
        int i = 0;
        dbg("Entering acm_rx_tasklet");
 
-       if (urb->actual_length > 0 && !acm->throttle)  {
-               for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters,
-                        * we drop them. */
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
-               dbg("Handed %d bytes to tty layer", i+1);
-               tty_flip_buffer_push(tty);
+       if (!ACM_READY(acm) || acm->throttle)
+               return;
+
+next_buffer:
+       spin_lock(&acm->read_lock);
+       if (list_empty(&acm->filled_read_bufs)) {
+               spin_unlock(&acm->read_lock);
+               goto urbs;
        }
+       buf = list_entry(acm->filled_read_bufs.next,
+                        struct acm_rb, list);
+       list_del(&buf->list);
+       spin_unlock(&acm->read_lock);
+
+       dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
+
+       for (i = 0; i < buf->size && !acm->throttle; i++) {
+               /* if we insert more than TTY_FLIPBUF_SIZE characters,
+                  we drop them. */
+               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+                       tty_flip_buffer_push(tty);
+               }
+               tty_insert_flip_char(tty, buf->base[i], 0);
+       }
+       tty_flip_buffer_push(tty);
 
        spin_lock(&acm->throttle_lock);
        if (acm->throttle) {
                dbg("Throtteling noticed");
-               memmove(data, data + i, urb->actual_length - i);
-               urb->actual_length -= i;
-               acm->resubmit_to_unthrottle = 1;
+               memmove(buf->base, buf->base + i, buf->size - i);
+               buf->size -= i;
                spin_unlock(&acm->throttle_lock);
+               spin_lock(&acm->read_lock);
+               list_add(&buf->list, &acm->filled_read_bufs);
+               spin_unlock(&acm->read_lock);
                return;
        }
        spin_unlock(&acm->throttle_lock);
 
-       urb->actual_length = 0;
-       urb->dev = acm->dev;
-
-       i = usb_submit_urb(urb, GFP_ATOMIC);
-       if (i)
-               dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i);
+       spin_lock(&acm->read_lock);
+       list_add(&buf->list, &acm->spare_read_bufs);
+       spin_unlock(&acm->read_lock);
+       goto next_buffer;
+
+urbs:
+       while (!list_empty(&acm->spare_read_bufs)) {
+               spin_lock(&acm->read_lock);
+               if (list_empty(&acm->spare_read_urbs)) {
+                       spin_unlock(&acm->read_lock);
+                       return;
+               }
+               rcv = list_entry(acm->spare_read_urbs.next,
+                                struct acm_ru, list);
+               list_del(&rcv->list);
+               spin_unlock(&acm->read_lock);
+
+               buf = list_entry(acm->spare_read_bufs.next,
+                                struct acm_rb, list);
+               list_del(&buf->list);
+
+               rcv->buffer = buf;
+
+               usb_fill_bulk_urb(rcv->urb, acm->dev,
+                                 acm->rx_endpoint,
+                                 buf->base,
+                                 acm->readsize,
+                                 acm_read_bulk, rcv);
+               rcv->urb->transfer_dma = buf->dma;
+               rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+               dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf);
+
+               /* This shouldn't kill the driver as unsuccessful URBs are returned to the
+                  free-urbs-pool and resubmited ASAP */
+               if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
+                       list_add(&buf->list, &acm->spare_read_bufs);
+                       spin_lock(&acm->read_lock);
+                       list_add(&rcv->list, &acm->spare_read_urbs);
+                       spin_unlock(&acm->read_lock);
+                       return;
+               }
+       }
 }
 
 /* data interface wrote those outgoing bytes */
@@ -369,6 +434,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
 {
        struct acm *acm;
        int rv = -EINVAL;
+       int i;
        dbg("Entering acm_tty_open.\n");
        
        down(&open_sem);
@@ -382,7 +448,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
        tty->driver_data = acm;
        acm->tty = tty;
 
-
+       /* force low_latency on so that our tty_push actually forces the data through,
+          otherwise it is scheduled, and with high data rates data can get lost. */
+       tty->low_latency = 1;
 
        if (acm->used++) {
                goto done;
@@ -394,18 +462,20 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
                goto bail_out;
        }
 
-       acm->readurb->dev = acm->dev;
-       if (usb_submit_urb(acm->readurb, GFP_KERNEL)) {
-               dbg("usb_submit_urb(read bulk) failed");
-               goto bail_out_and_unlink;
-       }
-
        if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS))
                goto full_bailout;
 
-       /* force low_latency on so that our tty_push actually forces the data through, 
-          otherwise it is scheduled, and with high data rates data can get lost. */
-       tty->low_latency = 1;
+       INIT_LIST_HEAD(&acm->spare_read_urbs);
+       INIT_LIST_HEAD(&acm->spare_read_bufs);
+       INIT_LIST_HEAD(&acm->filled_read_bufs);
+       for (i = 0; i < ACM_NRU; i++) {
+               list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
+       }
+       for (i = 0; i < ACM_NRB; i++) {
+               list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
+       }
+
+       tasklet_schedule(&acm->urb_task);
 
 done:
 err_out:
@@ -413,8 +483,6 @@ err_out:
        return rv;
 
 full_bailout:
-       usb_kill_urb(acm->readurb);
-bail_out_and_unlink:
        usb_kill_urb(acm->ctrlurb);
 bail_out:
        acm->used--;
@@ -424,18 +492,22 @@ bail_out:
 
 static void acm_tty_unregister(struct acm *acm)
 {
+       int i;
+
        tty_unregister_device(acm_tty_driver, acm->minor);
        usb_put_intf(acm->control);
        acm_table[acm->minor] = NULL;
        usb_free_urb(acm->ctrlurb);
-       usb_free_urb(acm->readurb);
        usb_free_urb(acm->writeurb);
+       for (i = 0; i < ACM_NRU; i++)
+               usb_free_urb(acm->ru[i].urb);
        kfree(acm);
 }
 
 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
 {
        struct acm *acm = tty->driver_data;
+       int i;
 
        if (!acm || !acm->used)
                return;
@@ -446,7 +518,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
                        acm_set_control(acm, acm->ctrlout = 0);
                        usb_kill_urb(acm->ctrlurb);
                        usb_kill_urb(acm->writeurb);
-                       usb_kill_urb(acm->readurb);
+                       for (i = 0; i < ACM_NRU; i++)
+                               usb_kill_urb(acm->ru[i].urb);
                } else
                        acm_tty_unregister(acm);
        }
@@ -528,10 +601,7 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
        spin_lock_bh(&acm->throttle_lock);
        acm->throttle = 0;
        spin_unlock_bh(&acm->throttle_lock);
-       if (acm->resubmit_to_unthrottle) {
-               acm->resubmit_to_unthrottle = 0;
-               acm_read_bulk(acm->readurb, NULL);
-       }
+       tasklet_schedule(&acm->urb_task);
 }
 
 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
@@ -588,7 +658,7 @@ static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int
        return -ENOIOCTLCMD;
 }
 
-static __u32 acm_tty_speed[] = {
+static const __u32 acm_tty_speed[] = {
        0, 50, 75, 110, 134, 150, 200, 300, 600,
        1200, 1800, 2400, 4800, 9600, 19200, 38400,
        57600, 115200, 230400, 460800, 500000, 576000,
@@ -596,7 +666,7 @@ static __u32 acm_tty_speed[] = {
        2500000, 3000000, 3500000, 4000000
 };
 
-static __u8 acm_tty_size[] = {
+static const __u8 acm_tty_size[] = {
        5, 6, 7, 8
 };
 
@@ -694,6 +764,7 @@ static int acm_probe (struct usb_interface *intf,
        int call_interface_num = -1;
        int data_interface_num;
        unsigned long quirks;
+       int i;
 
        /* handle quirks deadly to normal probing*/
        quirks = (unsigned long)id->driver_info;
@@ -833,7 +904,7 @@ skip_normal_probe:
        }
 
        ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
-       readsize = le16_to_cpu(epread->wMaxPacketSize);
+       readsize = le16_to_cpu(epread->wMaxPacketSize)*2;
        acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
        acm->control = control_interface;
        acm->data = data_interface;
@@ -842,12 +913,14 @@ skip_normal_probe:
        acm->ctrl_caps = ac_management_function;
        acm->ctrlsize = ctrlsize;
        acm->readsize = readsize;
-       acm->bh.func = acm_rx_tasklet;
-       acm->bh.data = (unsigned long) acm;
+       acm->urb_task.func = acm_rx_tasklet;
+       acm->urb_task.data = (unsigned long) acm;
        INIT_WORK(&acm->work, acm_softint, acm);
        spin_lock_init(&acm->throttle_lock);
        spin_lock_init(&acm->write_lock);
+       spin_lock_init(&acm->read_lock);
        acm->write_ready = 1;
+       acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
 
        buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
        if (!buf) {
@@ -856,13 +929,6 @@ skip_normal_probe:
        }
        acm->ctrl_buffer = buf;
 
-       buf = usb_buffer_alloc(usb_dev, readsize, GFP_KERNEL, &acm->read_dma);
-       if (!buf) {
-               dev_dbg(&intf->dev, "out of memory (read buffer alloc)\n");
-               goto alloc_fail3;
-       }
-       acm->read_buffer = buf;
-
        if (acm_write_buffers_alloc(acm) < 0) {
                dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
                goto alloc_fail4;
@@ -873,10 +939,25 @@ skip_normal_probe:
                dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
                goto alloc_fail5;
        }
-       acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!acm->readurb) {
-               dev_dbg(&intf->dev, "out of memory (readurb kmalloc)\n");
-               goto alloc_fail6;
+       for (i = 0; i < ACM_NRU; i++) {
+               struct acm_ru *rcv = &(acm->ru[i]);
+
+               if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
+                       dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
+                       goto alloc_fail7;
+               }
+
+               rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+               rcv->instance = acm;
+       }
+       for (i = 0; i < ACM_NRB; i++) {
+               struct acm_rb *buf = &(acm->rb[i]);
+
+               // Using usb_buffer_alloc instead of kmalloc as Oliver suggested
+               if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
+                       dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
+                       goto alloc_fail7;
+               }
        }
        acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
        if (!acm->writeurb) {
@@ -889,15 +970,9 @@ skip_normal_probe:
        acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        acm->ctrlurb->transfer_dma = acm->ctrl_dma;
 
-       usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
-                         acm->read_buffer, readsize, acm_read_bulk, acm);
-       acm->readurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
-       acm->readurb->transfer_dma = acm->read_dma;
-
        usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
                          NULL, acm->writesize, acm_write_bulk, acm);
        acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
-       /* acm->writeurb->transfer_dma = 0; */
 
        dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
 
@@ -917,14 +992,14 @@ skip_normal_probe:
        return 0;
 
 alloc_fail7:
-       usb_free_urb(acm->readurb);
-alloc_fail6:
+       for (i = 0; i < ACM_NRB; i++)
+               usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+       for (i = 0; i < ACM_NRU; i++)
+               usb_free_urb(acm->ru[i].urb);
        usb_free_urb(acm->ctrlurb);
 alloc_fail5:
        acm_write_buffers_free(acm);
 alloc_fail4:
-       usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma);
-alloc_fail3:
        usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
 alloc_fail2:
        kfree(acm);
@@ -936,6 +1011,7 @@ static void acm_disconnect(struct usb_interface *intf)
 {
        struct acm *acm = usb_get_intfdata (intf);
        struct usb_device *usb_dev = interface_to_usbdev(intf);
+       int i;
 
        if (!acm || !acm->dev) {
                dbg("disconnect on nonexisting interface");
@@ -946,15 +1022,24 @@ static void acm_disconnect(struct usb_interface *intf)
        acm->dev = NULL;
        usb_set_intfdata (intf, NULL);
 
+       tasklet_disable(&acm->urb_task);
+
        usb_kill_urb(acm->ctrlurb);
-       usb_kill_urb(acm->readurb);
        usb_kill_urb(acm->writeurb);
+       for (i = 0; i < ACM_NRU; i++)
+               usb_kill_urb(acm->ru[i].urb);
+
+       INIT_LIST_HEAD(&acm->filled_read_bufs);
+       INIT_LIST_HEAD(&acm->spare_read_bufs);
+
+       tasklet_enable(&acm->urb_task);
 
        flush_scheduled_work(); /* wait for acm_softint */
 
        acm_write_buffers_free(acm);
-       usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma);
        usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
+       for (i = 0; i < ACM_NRB; i++)
+               usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
 
        usb_driver_release_interface(&acm_driver, acm->data);
 
@@ -1003,7 +1088,6 @@ static struct usb_device_id acm_ids[] = {
 MODULE_DEVICE_TABLE (usb, acm_ids);
 
 static struct usb_driver acm_driver = {
-       .owner =        THIS_MODULE,
        .name =         "cdc_acm",
        .probe =        acm_probe,
        .disconnect =   acm_disconnect,
index 963a5df..fd2aacc 100644 (file)
@@ -59,6 +59,9 @@
  * when processing onlcr, so we only need 2 buffers.
  */
 #define ACM_NWB  2
+#define ACM_NRU  16
+#define ACM_NRB  16
+
 struct acm_wb {
        unsigned char *buf;
        dma_addr_t dmah;
@@ -66,22 +69,43 @@ struct acm_wb {
        int use;
 };
 
+struct acm_rb {
+       struct list_head        list;
+       int                     size;
+       unsigned char           *base;
+       dma_addr_t              dma;
+};
+
+struct acm_ru {
+       struct list_head        list;
+       struct acm_rb           *buffer;
+       struct urb              *urb;
+       struct acm              *instance;
+};
+
 struct acm {
        struct usb_device *dev;                         /* the corresponding usb device */
        struct usb_interface *control;                  /* control interface */
        struct usb_interface *data;                     /* data interface */
        struct tty_struct *tty;                         /* the corresponding tty */
-       struct urb *ctrlurb, *readurb, *writeurb;       /* urbs */
-       u8 *ctrl_buffer, *read_buffer;                  /* buffers of urbs */
-       dma_addr_t ctrl_dma, read_dma;                  /* dma handles of buffers */
+       struct urb *ctrlurb, *writeurb;                 /* urbs */
+       u8 *ctrl_buffer;                                /* buffers of urbs */
+       dma_addr_t ctrl_dma;                            /* dma handles of buffers */
        struct acm_wb wb[ACM_NWB];
+       struct acm_ru ru[ACM_NRU];
+       struct acm_rb rb[ACM_NRB];
+       int rx_endpoint;
+       spinlock_t read_lock;
+       struct list_head spare_read_urbs;
+       struct list_head spare_read_bufs;
+       struct list_head filled_read_bufs;
        int write_current;                              /* current write buffer */
        int write_used;                                 /* number of non-empty write buffers */
        int write_ready;                                /* write urb is not running */
        spinlock_t write_lock;
        struct usb_cdc_line_coding line;                /* bits, stop, parity */
        struct work_struct work;                        /* work queue entry for line discipline waking up */
-       struct tasklet_struct bh;                       /* rx processing */
+       struct tasklet_struct urb_task;                 /* rx processing */
        spinlock_t throttle_lock;                       /* synchronize throtteling and read callback */
        unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
        unsigned int ctrlout;                           /* output control lines (DTR, RTS) */
@@ -91,7 +115,6 @@ struct acm {
        unsigned int minor;                             /* acm minor number */
        unsigned char throttle;                         /* throttled by tty layer */
        unsigned char clocal;                           /* termios CLOCAL */
-       unsigned char resubmit_to_unthrottle;           /* throtteling has disabled the read urb */
        unsigned int ctrl_caps;                         /* control capabilities from the class specific header */
 };
 
index 5f8af35..f13f004 100644 (file)
@@ -2027,7 +2027,6 @@ static struct usb_device_id id_table[] = {
 };
 
 static struct usb_driver usb_midi_driver = {
-       .owner =        THIS_MODULE,
        .name =         "midi",
        .probe =        usb_midi_probe,
        .disconnect =   usb_midi_disconnect,
index 357e753..27e9404 100644 (file)
@@ -199,7 +199,7 @@ struct quirk_printer_struct {
 #define USBLP_QUIRK_BIDIR      0x1     /* reports bidir but requires unidirectional mode (no INs/reads) */
 #define USBLP_QUIRK_USB_INIT   0x2     /* needs vendor USB init string */
 
-static struct quirk_printer_struct quirk_printers[] = {
+static const struct quirk_printer_struct quirk_printers[] = {
        { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
        { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */
        { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
@@ -301,7 +301,7 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs)
  * Get and print printer errors.
  */
 
-static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
+static const char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
 
 static int usblp_check_status(struct usblp *usblp, int err)
 {
@@ -438,7 +438,7 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait
                               | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
 }
 
-static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct usblp *usblp = file->private_data;
        int length, err, i;
@@ -838,7 +838,8 @@ static struct file_operations usblp_fops = {
        .read =         usblp_read,
        .write =        usblp_write,
        .poll =         usblp_poll,
-       .ioctl =        usblp_ioctl,
+       .unlocked_ioctl =       usblp_ioctl,
+       .compat_ioctl =         usblp_ioctl,
        .open =         usblp_open,
        .release =      usblp_release,
 };
@@ -849,6 +850,20 @@ static struct usb_class_driver usblp_class = {
        .minor_base =   USBLP_MINOR_BASE,
 };
 
+static ssize_t usblp_show_ieee1284_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct usb_interface *intf = to_usb_interface(dev);
+       struct usblp *usblp = usb_get_intfdata (intf);
+
+       if (usblp->device_id_string[0] == 0 &&
+           usblp->device_id_string[1] == 0)
+               return 0;
+
+       return sprintf(buf, "%s", usblp->device_id_string+2);
+}
+
+static DEVICE_ATTR(ieee1284_id, S_IRUGO, usblp_show_ieee1284_id, NULL);
+
 static int usblp_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
 {
@@ -933,20 +948,12 @@ static int usblp_probe(struct usb_interface *intf,
 
        /* Retrieve and store the device ID string. */
        usblp_cache_device_id_string(usblp);
+       device_create_file(&intf->dev, &dev_attr_ieee1284_id);
 
 #ifdef DEBUG
        usblp_check_status(usblp, 0);
 #endif
 
-       info("usblp%d: USB %sdirectional printer dev %d "
-               "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
-               usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
-               usblp->ifnum,
-               usblp->protocol[usblp->current_protocol].alt_setting,
-               usblp->current_protocol,
-               le16_to_cpu(usblp->dev->descriptor.idVendor),
-               le16_to_cpu(usblp->dev->descriptor.idProduct));
-
        usb_set_intfdata (intf, usblp);
 
        usblp->present = 1;
@@ -957,11 +964,20 @@ static int usblp_probe(struct usb_interface *intf,
                goto abort_intfdata;
        }
        usblp->minor = intf->minor;
+       info("usblp%d: USB %sdirectional printer dev %d "
+               "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
+               usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
+               usblp->ifnum,
+               usblp->protocol[usblp->current_protocol].alt_setting,
+               usblp->current_protocol,
+               le16_to_cpu(usblp->dev->descriptor.idVendor),
+               le16_to_cpu(usblp->dev->descriptor.idProduct));
 
        return 0;
 
 abort_intfdata:
        usb_set_intfdata (intf, NULL);
+       device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 abort:
        if (usblp) {
                if (usblp->writebuf)
@@ -1156,6 +1172,8 @@ static void usblp_disconnect(struct usb_interface *intf)
                BUG ();
        }
 
+       device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
+
        down (&usblp_sem);
        down (&usblp->sem);
        usblp->present = 0;
@@ -1186,7 +1204,6 @@ static struct usb_device_id usblp_ids [] = {
 MODULE_DEVICE_TABLE (usb, usblp_ids);
 
 static struct usb_driver usblp_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usblp",
        .probe =        usblp_probe,
        .disconnect =   usblp_disconnect,
index 86d5c38..28329dd 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for USB Core files and filesystem
 #
 
-usbcore-objs   := usb.o hub.o hcd.o urb.o message.o \
+usbcore-objs   := usb.o hub.o hcd.o urb.o message.o driver.o \
                        config.o file.o buffer.o sysfs.o devio.o notify.o
 
 ifeq ($(CONFIG_PCI),y)
index 419c994..ad742ce 100644 (file)
@@ -55,6 +55,9 @@ int hcd_buffer_create (struct usb_hcd *hcd)
        char            name [16];
        int             i, size;
 
+       if (!hcd->self.controller->dma_mask)
+               return 0;
+
        for (i = 0; i < HCD_BUFFER_POOLS; i++) { 
                if (!(size = pool_max [i]))
                        continue;
index 83e815d..2684e15 100644 (file)
 /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
 #define ALLOW_SERIAL_NUMBER
 
-static char *format_topo =
+static const char *format_topo =
 /* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
 "\nT:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
 
-static char *format_string_manufacturer =
+static const char *format_string_manufacturer =
 /* S:  Manufacturer=xxxx */
   "S:  Manufacturer=%.100s\n";
 
-static char *format_string_product =
+static const char *format_string_product =
 /* S:  Product=xxxx */
   "S:  Product=%.100s\n";
 
 #ifdef ALLOW_SERIAL_NUMBER
-static char *format_string_serialnumber =
+static const char *format_string_serialnumber =
 /* S:  SerialNumber=xxxx */
   "S:  SerialNumber=%.100s\n";
 #endif
 
-static char *format_bandwidth =
+static const char *format_bandwidth =
 /* B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */
   "B:  Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n";
   
-static char *format_device1 =
+static const char *format_device1 =
 /* D:  Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */
   "D:  Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n";
 
-static char *format_device2 =
+static const char *format_device2 =
 /* P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx */
   "P:  Vendor=%04x ProdID=%04x Rev=%2x.%02x\n";
 
-static char *format_config =
+static const char *format_config =
 /* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
   "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
   
-static char *format_iface =
+static const char *format_iface =
 /* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
   "I:  If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
 
-static char *format_endpt =
+static const char *format_endpt =
 /* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */
   "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n";
 
@@ -545,10 +545,10 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
                struct usb_device *childdev = usbdev->children[chix];
 
                if (childdev) {
-                       down(&childdev->serialize);
+                       usb_lock_device(childdev);
                        ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev,
                                        bus, level + 1, chix, ++cnt);
-                       up(&childdev->serialize);
+                       usb_unlock_device(childdev);
                        if (ret == -EFAULT)
                                return total_written;
                        total_written += ret;
index b1d6e9a..2b68998 100644 (file)
@@ -402,7 +402,6 @@ static void driver_disconnect(struct usb_interface *intf)
 }
 
 struct usb_driver usbfs_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbfs",
        .probe =        driver_probe,
        .disconnect =   driver_disconnect,
@@ -1350,9 +1349,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
        /* let kernel drivers try to (re)bind to the interface */
        case USBDEVFS_CONNECT:
                usb_unlock_device(ps->dev);
-               usb_lock_all_devices();
                bus_rescan_devices(intf->dev.bus);
-               usb_unlock_all_devices();
                usb_lock_device(ps->dev);
                break;
 
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
new file mode 100644 (file)
index 0000000..076462c
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * drivers/usb/driver.c - most of the driver model stuff for usb
+ *
+ * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * based on drivers/usb/usb.c which had the following copyrights:
+ *     (C) Copyright Linus Torvalds 1999
+ *     (C) Copyright Johannes Erdfelt 1999-2001
+ *     (C) Copyright Andreas Gal 1999
+ *     (C) Copyright Gregory P. Smith 1999
+ *     (C) Copyright Deti Fliegl 1999 (new USB architecture)
+ *     (C) Copyright Randy Dunlap 2000
+ *     (C) Copyright David Brownell 2000-2004
+ *     (C) Copyright Yggdrasil Computing, Inc. 2000
+ *             (usb_device_id matching changes by Adam J. Richter)
+ *     (C) Copyright Greg Kroah-Hartman 2002-2003
+ *
+ * NOTE! This is not actually a driver at all, rather this is
+ * just a collection of helper routines that implement the
+ * generic USB things that the real drivers can use..
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/device.h>
+#include <linux/usb.h>
+#include "hcd.h"
+#include "usb.h"
+
+static int usb_match_one_id(struct usb_interface *interface,
+                           const struct usb_device_id *id);
+
+struct usb_dynid {
+       struct list_head node;
+       struct usb_device_id id;
+};
+
+
+static int generic_probe(struct device *dev)
+{
+       return 0;
+}
+static int generic_remove(struct device *dev)
+{
+       struct usb_device *udev = to_usb_device(dev);
+
+       /* if this is only an unbind, not a physical disconnect, then
+        * unconfigure the device */
+       if (udev->state == USB_STATE_CONFIGURED)
+               usb_set_configuration(udev, 0);
+
+       /* in case the call failed or the device was suspended */
+       if (udev->state >= USB_STATE_CONFIGURED)
+               usb_disable_device(udev, 0);
+       return 0;
+}
+
+struct device_driver usb_generic_driver = {
+       .owner = THIS_MODULE,
+       .name = "usb",
+       .bus = &usb_bus_type,
+       .probe = generic_probe,
+       .remove = generic_remove,
+};
+
+/* Fun hack to determine if the struct device is a
+ * usb device or a usb interface. */
+int usb_generic_driver_data;
+
+#ifdef CONFIG_HOTPLUG
+
+/*
+ * Adds a new dynamic USBdevice ID to this driver,
+ * and cause the driver to probe for all devices again.
+ */
+static ssize_t store_new_id(struct device_driver *driver,
+                           const char *buf, size_t count)
+{
+       struct usb_driver *usb_drv = to_usb_driver(driver);
+       struct usb_dynid *dynid;
+       u32 idVendor = 0;
+       u32 idProduct = 0;
+       int fields = 0;
+
+       fields = sscanf(buf, "%x %x", &idVendor, &idProduct);
+       if (fields < 2)
+               return -EINVAL;
+
+       dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
+       if (!dynid)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&dynid->node);
+       dynid->id.idVendor = idVendor;
+       dynid->id.idProduct = idProduct;
+       dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+
+       spin_lock(&usb_drv->dynids.lock);
+       list_add_tail(&usb_drv->dynids.list, &dynid->node);
+       spin_unlock(&usb_drv->dynids.lock);
+
+       if (get_driver(driver)) {
+               driver_attach(driver);
+               put_driver(driver);
+       }
+
+       return count;
+}
+static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+
+static int usb_create_newid_file(struct usb_driver *usb_drv)
+{
+       int error = 0;
+
+       if (usb_drv->no_dynamic_id)
+               goto exit;
+
+       if (usb_drv->probe != NULL)
+               error = sysfs_create_file(&usb_drv->driver.kobj,
+                                         &driver_attr_new_id.attr);
+exit:
+       return error;
+}
+
+static void usb_remove_newid_file(struct usb_driver *usb_drv)
+{
+       if (usb_drv->no_dynamic_id)
+               return;
+
+       if (usb_drv->probe != NULL)
+               sysfs_remove_file(&usb_drv->driver.kobj,
+                                 &driver_attr_new_id.attr);
+}
+
+static void usb_free_dynids(struct usb_driver *usb_drv)
+{
+       struct usb_dynid *dynid, *n;
+
+       spin_lock(&usb_drv->dynids.lock);
+       list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) {
+               list_del(&dynid->node);
+               kfree(dynid);
+       }
+       spin_unlock(&usb_drv->dynids.lock);
+}
+#else
+static inline int usb_create_newid_file(struct usb_driver *usb_drv)
+{
+       return 0;
+}
+
+static void usb_remove_newid_file(struct usb_driver *usb_drv)
+{
+}
+
+static inline void usb_free_dynids(struct usb_driver *usb_drv)
+{
+}
+#endif
+
+static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
+                                                       struct usb_driver *drv)
+{
+       struct usb_dynid *dynid;
+
+       spin_lock(&drv->dynids.lock);
+       list_for_each_entry(dynid, &drv->dynids.list, node) {
+               if (usb_match_one_id(intf, &dynid->id)) {
+                       spin_unlock(&drv->dynids.lock);
+                       return &dynid->id;
+               }
+       }
+       spin_unlock(&drv->dynids.lock);
+       return NULL;
+}
+
+
+/* called from driver core with usb_bus_type.subsys writelock */
+static int usb_probe_interface(struct device *dev)
+{
+       struct usb_interface * intf = to_usb_interface(dev);
+       struct usb_driver * driver = to_usb_driver(dev->driver);
+       const struct usb_device_id *id;
+       int error = -ENODEV;
+
+       dev_dbg(dev, "%s\n", __FUNCTION__);
+
+       if (!driver->probe)
+               return error;
+       /* FIXME we'd much prefer to just resume it ... */
+       if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED)
+               return -EHOSTUNREACH;
+
+       id = usb_match_id(intf, driver->id_table);
+       if (!id)
+               id = usb_match_dynamic_id(intf, driver);
+       if (id) {
+               dev_dbg(dev, "%s - got id\n", __FUNCTION__);
+
+               /* Interface "power state" doesn't correspond to any hardware
+                * state whatsoever.  We use it to record when it's bound to
+                * a driver that may start I/0:  it's not frozen/quiesced.
+                */
+               mark_active(intf);
+               intf->condition = USB_INTERFACE_BINDING;
+               error = driver->probe(intf, id);
+               if (error) {
+                       mark_quiesced(intf);
+                       intf->condition = USB_INTERFACE_UNBOUND;
+               } else
+                       intf->condition = USB_INTERFACE_BOUND;
+       }
+
+       return error;
+}
+
+/* called from driver core with usb_bus_type.subsys writelock */
+static int usb_unbind_interface(struct device *dev)
+{
+       struct usb_interface *intf = to_usb_interface(dev);
+       struct usb_driver *driver = to_usb_driver(intf->dev.driver);
+
+       intf->condition = USB_INTERFACE_UNBINDING;
+
+       /* release all urbs for this interface */
+       usb_disable_interface(interface_to_usbdev(intf), intf);
+
+       if (driver && driver->disconnect)
+               driver->disconnect(intf);
+
+       /* reset other interface state */
+       usb_set_interface(interface_to_usbdev(intf),
+                       intf->altsetting[0].desc.bInterfaceNumber,
+                       0);
+       usb_set_intfdata(intf, NULL);
+       intf->condition = USB_INTERFACE_UNBOUND;
+       mark_quiesced(intf);
+
+       return 0;
+}
+
+/* returns 0 if no match, 1 if match */
+static int usb_match_one_id(struct usb_interface *interface,
+                           const struct usb_device_id *id)
+{
+       struct usb_host_interface *intf;
+       struct usb_device *dev;
+
+       /* proc_connectinfo in devio.c may call us with id == NULL. */
+       if (id == NULL)
+               return 0;
+
+       intf = interface->cur_altsetting;
+       dev = interface_to_usbdev(interface);
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+           id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+           id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
+               return 0;
+
+       /* No need to test id->bcdDevice_lo != 0, since 0 is never
+          greater than any unsigned number. */
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
+           (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
+           (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+           (id->bDeviceClass != dev->descriptor.bDeviceClass))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
+           (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
+           (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+           (id->bInterfaceClass != intf->desc.bInterfaceClass))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+           (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
+               return 0;
+
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+           (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
+               return 0;
+
+       return 1;
+}
+/**
+ * usb_match_id - find first usb_device_id matching device or interface
+ * @interface: the interface of interest
+ * @id: array of usb_device_id structures, terminated by zero entry
+ *
+ * usb_match_id searches an array of usb_device_id's and returns
+ * the first one matching the device or interface, or null.
+ * This is used when binding (or rebinding) a driver to an interface.
+ * Most USB device drivers will use this indirectly, through the usb core,
+ * but some layered driver frameworks use it directly.
+ * These device tables are exported with MODULE_DEVICE_TABLE, through
+ * modutils, to support the driver loading functionality of USB hotplugging.
+ *
+ * What Matches:
+ *
+ * The "match_flags" element in a usb_device_id controls which
+ * members are used.  If the corresponding bit is set, the
+ * value in the device_id must match its corresponding member
+ * in the device or interface descriptor, or else the device_id
+ * does not match.
+ *
+ * "driver_info" is normally used only by device drivers,
+ * but you can create a wildcard "matches anything" usb_device_id
+ * as a driver's "modules.usbmap" entry if you provide an id with
+ * only a nonzero "driver_info" field.  If you do this, the USB device
+ * driver's probe() routine should use additional intelligence to
+ * decide whether to bind to the specified interface.
+ *
+ * What Makes Good usb_device_id Tables:
+ *
+ * The match algorithm is very simple, so that intelligence in
+ * driver selection must come from smart driver id records.
+ * Unless you have good reasons to use another selection policy,
+ * provide match elements only in related groups, and order match
+ * specifiers from specific to general.  Use the macros provided
+ * for that purpose if you can.
+ *
+ * The most specific match specifiers use device descriptor
+ * data.  These are commonly used with product-specific matches;
+ * the USB_DEVICE macro lets you provide vendor and product IDs,
+ * and you can also match against ranges of product revisions.
+ * These are widely used for devices with application or vendor
+ * specific bDeviceClass values.
+ *
+ * Matches based on device class/subclass/protocol specifications
+ * are slightly more general; use the USB_DEVICE_INFO macro, or
+ * its siblings.  These are used with single-function devices
+ * where bDeviceClass doesn't specify that each interface has
+ * its own class.
+ *
+ * Matches based on interface class/subclass/protocol are the
+ * most general; they let drivers bind to any interface on a
+ * multiple-function device.  Use the USB_INTERFACE_INFO
+ * macro, or its siblings, to match class-per-interface style
+ * devices (as recorded in bDeviceClass).
+ *
+ * Within those groups, remember that not all combinations are
+ * meaningful.  For example, don't give a product version range
+ * without vendor and product IDs; or specify a protocol without
+ * its associated class and subclass.
+ */
+const struct usb_device_id *usb_match_id(struct usb_interface *interface,
+                                        const struct usb_device_id *id)
+{
+       /* proc_connectinfo in devio.c may call us with id == NULL. */
+       if (id == NULL)
+               return NULL;
+
+       /* It is important to check that id->driver_info is nonzero,
+          since an entry that is all zeroes except for a nonzero
+          id->driver_info is the way to create an entry that
+          indicates that the driver want to examine every
+          device and interface. */
+       for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+              id->driver_info; id++) {
+               if (usb_match_one_id(interface, id))
+                       return id;
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(usb_match_id);
+
+int usb_device_match(struct device *dev, struct device_driver *drv)
+{
+       struct usb_interface *intf;
+       struct usb_driver *usb_drv;
+       const struct usb_device_id *id;
+
+       /* check for generic driver, which we don't match any device with */
+       if (drv == &usb_generic_driver)
+               return 0;
+
+       intf = to_usb_interface(dev);
+       usb_drv = to_usb_driver(drv);
+
+       id = usb_match_id(intf, usb_drv->id_table);
+       if (id)
+               return 1;
+
+       id = usb_match_dynamic_id(intf, usb_drv);
+       if (id)
+               return 1;
+       return 0;
+}
+
+/**
+ * usb_register_driver - register a USB driver
+ * @new_driver: USB operations for the driver
+ * @owner: module owner of this driver.
+ *
+ * Registers a USB driver with the USB core.  The list of unattached
+ * interfaces will be rescanned whenever a new driver is added, allowing
+ * the new driver to attach to any recognized devices.
+ * Returns a negative error code on failure and 0 on success.
+ *
+ * NOTE: if you want your driver to use the USB major number, you must call
+ * usb_register_dev() to enable that functionality.  This function no longer
+ * takes care of that.
+ */
+int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
+{
+       int retval = 0;
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       new_driver->driver.name = (char *)new_driver->name;
+       new_driver->driver.bus = &usb_bus_type;
+       new_driver->driver.probe = usb_probe_interface;
+       new_driver->driver.remove = usb_unbind_interface;
+       new_driver->driver.owner = owner;
+       spin_lock_init(&new_driver->dynids.lock);
+       INIT_LIST_HEAD(&new_driver->dynids.list);
+
+       retval = driver_register(&new_driver->driver);
+
+       if (!retval) {
+               pr_info("%s: registered new driver %s\n",
+                       usbcore_name, new_driver->name);
+               usbfs_update_special();
+               usb_create_newid_file(new_driver);
+       } else {
+               printk(KERN_ERR "%s: error %d registering driver %s\n",
+                       usbcore_name, retval, new_driver->name);
+       }
+
+       return retval;
+}
+EXPORT_SYMBOL_GPL(usb_register_driver);
+
+/**
+ * usb_deregister - unregister a USB driver
+ * @driver: USB operations of the driver to unregister
+ * Context: must be able to sleep
+ *
+ * Unlinks the specified driver from the internal USB driver list.
+ *
+ * NOTE: If you called usb_register_dev(), you still need to call
+ * usb_deregister_dev() to clean up your driver's allocated minor numbers,
+ * this * call will no longer do it for you.
+ */
+void usb_deregister(struct usb_driver *driver)
+{
+       pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name);
+
+       usb_remove_newid_file(driver);
+       usb_free_dynids(driver);
+       driver_unregister(&driver->driver);
+
+       usbfs_update_special();
+}
+EXPORT_SYMBOL_GPL(usb_deregister);
index da24c31..0018bbc 100644 (file)
@@ -857,9 +857,7 @@ static int register_root_hub (struct usb_device *usb_dev,
                return (retval < 0) ? retval : -EMSGSIZE;
        }
 
-       usb_lock_device (usb_dev);
        retval = usb_new_device (usb_dev);
-       usb_unlock_device (usb_dev);
        if (retval) {
                usb_dev->bus->root_hub = NULL;
                dev_err (parent_dev, "can't register root hub for %s, %d\n",
@@ -1827,8 +1825,6 @@ int usb_add_hcd(struct usb_hcd *hcd,
                retval = -ENOMEM;
                goto err_allocate_root_hub;
        }
-       rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
-                       USB_SPEED_FULL;
 
        /* Although in principle hcd->driver->start() might need to use rhdev,
         * none of the current drivers do.
@@ -1846,6 +1842,9 @@ int usb_add_hcd(struct usb_hcd *hcd,
                dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
        hcd->remote_wakeup = hcd->can_wakeup;
 
+       rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
+                       USB_SPEED_FULL;
+       rhdev->bus_mA = min(500u, hcd->power_budget);
        if ((retval = register_root_hub(rhdev, hcd)) != 0)
                goto err_register_root_hub;
 
@@ -1891,7 +1890,10 @@ void usb_remove_hcd(struct usb_hcd *hcd)
        spin_lock_irq (&hcd_root_hub_lock);
        hcd->rh_registered = 0;
        spin_unlock_irq (&hcd_root_hub_lock);
+
+       down(&usb_bus_list_lock);
        usb_disconnect(&hcd->self.root_hub);
+       up(&usb_bus_list_lock);
 
        hcd->poll_rh = 0;
        del_timer_sync(&hcd->rh_timer);
index c8a1b35..591b5aa 100644 (file)
@@ -380,6 +380,7 @@ extern int usb_find_interface_driver (struct usb_device *dev,
 #ifdef CONFIG_PM
 extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd);
 extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
+extern void usb_root_hub_lost_power (struct usb_device *rhdev);
 extern int hcd_bus_suspend (struct usb_bus *bus);
 extern int hcd_bus_resume (struct usb_bus *bus);
 #else
index f78bd12..650d5ee 100644 (file)
@@ -32,7 +32,7 @@
 #include "hub.h"
 
 /* Protect struct usb_device->state and ->children members
- * Note: Both are also protected by ->serialize, except that ->state can
+ * Note: Both are also protected by ->dev.sem, except that ->state can
  * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
 static DEFINE_SPINLOCK(device_state_lock);
 
@@ -515,6 +515,31 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
        return ret;
 }
 
+
+/* caller has locked the hub device */
+static void hub_pre_reset(struct usb_hub *hub, int disable_ports)
+{
+       struct usb_device *hdev = hub->hdev;
+       int port1;
+
+       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+               if (hdev->children[port1 - 1]) {
+                       usb_disconnect(&hdev->children[port1 - 1]);
+                       if (disable_ports)
+                               hub_port_disable(hub, port1, 0);
+               }
+       }
+       hub_quiesce(hub);
+}
+
+/* caller has locked the hub device */
+static void hub_post_reset(struct usb_hub *hub)
+{
+       hub_activate(hub);
+       hub_power_on(hub);
+}
+
+
 static int hub_configure(struct usb_hub *hub,
        struct usb_endpoint_descriptor *endpoint)
 {
@@ -677,26 +702,40 @@ static int hub_configure(struct usb_hub *hub,
         * and battery-powered root hubs (may provide just 8 mA).
         */
        ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus);
-       if (ret < 0) {
+       if (ret < 2) {
                message = "can't get hub status";
                goto fail;
        }
        le16_to_cpus(&hubstatus);
        if (hdev == hdev->bus->root_hub) {
-               struct usb_hcd *hcd =
-                               container_of(hdev->bus, struct usb_hcd, self);
-
-               hub->power_budget = min(500u, hcd->power_budget) / 2;
+               if (hdev->bus_mA == 0 || hdev->bus_mA >= 500)
+                       hub->mA_per_port = 500;
+               else {
+                       hub->mA_per_port = hdev->bus_mA;
+                       hub->limited_power = 1;
+               }
        } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
                dev_dbg(hub_dev, "hub controller current requirement: %dmA\n",
                        hub->descriptor->bHubContrCurrent);
-               hub->power_budget = (501 - hub->descriptor->bHubContrCurrent)
-                                       / 2;
+               hub->limited_power = 1;
+               if (hdev->maxchild > 0) {
+                       int remaining = hdev->bus_mA -
+                                       hub->descriptor->bHubContrCurrent;
+
+                       if (remaining < hdev->maxchild * 100)
+                               dev_warn(hub_dev,
+                                       "insufficient power available "
+                                       "to use all downstream ports\n");
+                       hub->mA_per_port = 100;         /* 7.2.1.1 */
+               }
+       } else {        /* Self-powered external hub */
+               /* FIXME: What about battery-powered external hubs that
+                * provide less current per port? */
+               hub->mA_per_port = 500;
        }
-       if (hub->power_budget)
-               dev_dbg(hub_dev, "%dmA bus power budget for children\n",
-                       hub->power_budget * 2);
-
+       if (hub->mA_per_port < 500)
+               dev_dbg(hub_dev, "%umA bus power budget for each child\n",
+                               hub->mA_per_port);
 
        ret = hub_hub_status(hub, &hubstatus, &hubchange);
        if (ret < 0) {
@@ -750,29 +789,10 @@ fail:
 
 static unsigned highspeed_hubs;
 
-/* Called after the hub driver is unbound from a hub with children */
-static void hub_remove_children_work(void *__hub)
-{
-       struct usb_hub          *hub = __hub;
-       struct usb_device       *hdev = hub->hdev;
-       int                     i;
-
-       kfree(hub);
-
-       usb_lock_device(hdev);
-       for (i = 0; i < hdev->maxchild; ++i) {
-               if (hdev->children[i])
-                       usb_disconnect(&hdev->children[i]);
-       }
-       usb_unlock_device(hdev);
-       usb_put_dev(hdev);
-}
-
 static void hub_disconnect(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata (intf);
        struct usb_device *hdev;
-       int n, port1;
 
        usb_set_intfdata (intf, NULL);
        hdev = hub->hdev;
@@ -780,7 +800,9 @@ static void hub_disconnect(struct usb_interface *intf)
        if (hdev->speed == USB_SPEED_HIGH)
                highspeed_hubs--;
 
-       hub_quiesce(hub);
+       /* Disconnect all children and quiesce the hub */
+       hub_pre_reset(hub, 1);
+
        usb_free_urb(hub->urb);
        hub->urb = NULL;
 
@@ -800,27 +822,7 @@ static void hub_disconnect(struct usb_interface *intf)
                hub->buffer = NULL;
        }
 
-       /* If there are any children then this is an unbind only, not a
-        * physical disconnection.  The active ports must be disabled
-        * and later on we must call usb_disconnect().  We can't call
-        * it now because we may not hold the hub's device lock.
-        */
-       n = 0;
-       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-               if (hdev->children[port1 - 1]) {
-                       ++n;
-                       hub_port_disable(hub, port1, 1);
-               }
-       }
-
-       if (n == 0)
-               kfree(hub);
-       else {
-               /* Reuse the hub->leds work_struct for our own purposes */
-               INIT_WORK(&hub->leds, hub_remove_children_work, hub);
-               schedule_work(&hub->leds);
-               usb_get_dev(hdev);
-       }
+       kfree(hub);
 }
 
 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -917,26 +919,6 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
        }
 }
 
-/* caller has locked the hub device */
-static void hub_pre_reset(struct usb_hub *hub)
-{
-       struct usb_device *hdev = hub->hdev;
-       int i;
-
-       for (i = 0; i < hdev->maxchild; ++i) {
-               if (hdev->children[i])
-                       usb_disconnect(&hdev->children[i]);
-       }
-       hub_quiesce(hub);
-}
-
-/* caller has locked the hub device */
-static void hub_post_reset(struct usb_hub *hub)
-{
-       hub_activate(hub);
-       hub_power_on(hub);
-}
-
 
 /* grab device/port lock, returning index of that port (zero based).
  * protects the upstream link used by this device from concurrent
@@ -964,24 +946,21 @@ static int locktree(struct usb_device *udev)
        t = locktree(hdev);
        if (t < 0)
                return t;
-       for (t = 0; t < hdev->maxchild; t++) {
-               if (hdev->children[t] == udev) {
-                       /* everything is fail-fast once disconnect
-                        * processing starts
-                        */
-                       if (udev->state == USB_STATE_NOTATTACHED)
-                               break;
 
-                       /* when everyone grabs locks top->bottom,
-                        * non-overlapping work may be concurrent
-                        */
-                       down(&udev->serialize);
-                       up(&hdev->serialize);
-                       return t + 1;
-               }
+       /* everything is fail-fast once disconnect
+        * processing starts
+        */
+       if (udev->state == USB_STATE_NOTATTACHED) {
+               usb_unlock_device(hdev);
+               return -ENODEV;
        }
+
+       /* when everyone grabs locks top->bottom,
+        * non-overlapping work may be concurrent
+        */
+       usb_lock_device(udev);
        usb_unlock_device(hdev);
-       return -ENODEV;
+       return udev->portnum;
 }
 
 static void recursively_mark_NOTATTACHED(struct usb_device *udev)
@@ -1039,6 +1018,39 @@ void usb_set_device_state(struct usb_device *udev,
 EXPORT_SYMBOL(usb_set_device_state);
 
 
+#ifdef CONFIG_PM
+
+/**
+ * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power
+ * @rhdev: struct usb_device for the root hub
+ *
+ * The USB host controller driver calls this function when its root hub
+ * is resumed and Vbus power has been interrupted or the controller
+ * has been reset.  The routine marks all the children of the root hub
+ * as NOTATTACHED and marks logical connect-change events on their ports.
+ */
+void usb_root_hub_lost_power(struct usb_device *rhdev)
+{
+       struct usb_hub *hub;
+       int port1;
+       unsigned long flags;
+
+       dev_warn(&rhdev->dev, "root hub lost power or was reset\n");
+       spin_lock_irqsave(&device_state_lock, flags);
+       hub = hdev_to_hub(rhdev);
+       for (port1 = 1; port1 <= rhdev->maxchild; ++port1) {
+               if (rhdev->children[port1 - 1]) {
+                       recursively_mark_NOTATTACHED(
+                                       rhdev->children[port1 - 1]);
+                       set_bit(port1, hub->change_bits);
+               }
+       }
+       spin_unlock_irqrestore(&device_state_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_root_hub_lost_power);
+
+#endif
+
 static void choose_address(struct usb_device *udev)
 {
        int             devnum;
@@ -1099,16 +1111,10 @@ void usb_disconnect(struct usb_device **pdev)
         * this quiesces everyting except pending urbs.
         */
        usb_set_device_state(udev, USB_STATE_NOTATTACHED);
-
-       /* lock the bus list on behalf of HCDs unregistering their root hubs */
-       if (!udev->parent) {
-               down(&usb_bus_list_lock);
-               usb_lock_device(udev);
-       } else
-               down(&udev->serialize);
-
        dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum);
 
+       usb_lock_device(udev);
+
        /* Free up all the children before we remove this device */
        for (i = 0; i < USB_MAXCHILDREN; i++) {
                if (udev->children[i])
@@ -1136,54 +1142,112 @@ void usb_disconnect(struct usb_device **pdev)
        *pdev = NULL;
        spin_unlock_irq(&device_state_lock);
 
-       if (!udev->parent) {
-               usb_unlock_device(udev);
-               up(&usb_bus_list_lock);
-       } else
-               up(&udev->serialize);
+       usb_unlock_device(udev);
 
        device_unregister(&udev->dev);
 }
 
+static inline const char *plural(int n)
+{
+       return (n == 1 ? "" : "s");
+}
+
 static int choose_configuration(struct usb_device *udev)
 {
-       int c, i;
+       int i;
+       u16 devstatus;
+       int bus_powered;
+       int num_configs;
+       struct usb_host_config *c, *best;
+
+       /* If this fails, assume the device is bus-powered */
+       devstatus = 0;
+       usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
+       le16_to_cpus(&devstatus);
+       bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0);
+       dev_dbg(&udev->dev, "device is %s-powered\n",
+                       bus_powered ? "bus" : "self");
+
+       best = NULL;
+       c = udev->config;
+       num_configs = udev->descriptor.bNumConfigurations;
+       for (i = 0; i < num_configs; (i++, c++)) {
+               struct usb_interface_descriptor *desc =
+                               &c->intf_cache[0]->altsetting->desc;
+
+               /*
+                * HP's USB bus-powered keyboard has only one configuration
+                * and it claims to be self-powered; other devices may have
+                * similar errors in their descriptors.  If the next test
+                * were allowed to execute, such configurations would always
+                * be rejected and the devices would not work as expected.
+                */
+#if 0
+               /* Rule out self-powered configs for a bus-powered device */
+               if (bus_powered && (c->desc.bmAttributes &
+                                       USB_CONFIG_ATT_SELFPOWER))
+                       continue;
+#endif
 
-       /* NOTE: this should interact with hub power budgeting */
+               /*
+                * The next test may not be as effective as it should be.
+                * Some hubs have errors in their descriptor, claiming
+                * to be self-powered when they are really bus-powered.
+                * We will overestimate the amount of current such hubs
+                * make available for each port.
+                *
+                * This is a fairly benign sort of failure.  It won't
+                * cause us to reject configurations that we should have
+                * accepted.
+                */
 
-       c = udev->config[0].desc.bConfigurationValue;
-       if (udev->descriptor.bNumConfigurations != 1) {
-               for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
-                       struct usb_interface_descriptor *desc;
+               /* Rule out configs that draw too much bus current */
+               if (c->desc.bMaxPower * 2 > udev->bus_mA)
+                       continue;
 
-                       /* heuristic:  Linux is more likely to have class
-                        * drivers, so avoid vendor-specific interfaces.
-                        */
-                       desc = &udev->config[i].intf_cache[0]
-                                       ->altsetting->desc;
-                       if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
-                               continue;
-                       /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS.
-                        * MSFT needs this to be the first config; never use
-                        * it as the default unless Linux has host-side RNDIS.
-                        * A second config would ideally be CDC-Ethernet, but
-                        * may instead be the "vendor specific" CDC subset
-                        * long used by ARM Linux for sa1100 or pxa255.
-                        */
-                       if (desc->bInterfaceClass == USB_CLASS_COMM
-                                       && desc->bInterfaceSubClass == 2
-                                       && desc->bInterfaceProtocol == 0xff) {
-                               c = udev->config[1].desc.bConfigurationValue;
-                               continue;
-                       }
-                       c = udev->config[i].desc.bConfigurationValue;
+               /* If the first config's first interface is COMM/2/0xff
+                * (MSFT RNDIS), rule it out unless Linux has host-side
+                * RNDIS support. */
+               if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM
+                               && desc->bInterfaceSubClass == 2
+                               && desc->bInterfaceProtocol == 0xff) {
+#ifndef CONFIG_USB_NET_RNDIS
+                       continue;
+#else
+                       best = c;
+#endif
+               }
+
+               /* From the remaining configs, choose the first one whose
+                * first interface is for a non-vendor-specific class.
+                * Reason: Linux is more likely to have a class driver
+                * than a vendor-specific driver. */
+               else if (udev->descriptor.bDeviceClass !=
+                                               USB_CLASS_VENDOR_SPEC &&
+                               desc->bInterfaceClass !=
+                                               USB_CLASS_VENDOR_SPEC) {
+                       best = c;
                        break;
                }
+
+               /* If all the remaining configs are vendor-specific,
+                * choose the first one. */
+               else if (!best)
+                       best = c;
+       }
+
+       if (best) {
+               i = best->desc.bConfigurationValue;
                dev_info(&udev->dev,
-                       "configuration #%d chosen from %d choices\n",
-                       c, udev->descriptor.bNumConfigurations);
+                       "configuration #%d chosen from %d choice%s\n",
+                       i, num_configs, plural(num_configs));
+       } else {
+               i = -1;
+               dev_warn(&udev->dev,
+                       "no configuration chosen from %d choice%s\n",
+                       num_configs, plural(num_configs));
        }
-       return c;
+       return i;
 }
 
 #ifdef DEBUG
@@ -1210,8 +1274,8 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
  *
  * This is called with devices which have been enumerated, but not yet
  * configured.  The device descriptor is available, but not descriptors
- * for any device configuration.  The caller must have locked udev and
- * either the parent hub (if udev is a normal device) or else the
+ * for any device configuration.  The caller must have locked either
+ * the parent hub (if udev is a normal device) or else the
  * usb_bus_list_lock (if udev is a root hub).  The parent's pointer to
  * udev has already been installed, but udev is not yet visible through
  * sysfs or other filesystem code.
@@ -1221,8 +1285,7 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
  *
  * This call is synchronous, and may not be used in an interrupt context.
  *
- * Only the hub driver should ever call this; root hub registration
- * uses it indirectly.
+ * Only the hub driver or root-hub registrar should ever call this.
  */
 int usb_new_device(struct usb_device *udev)
 {
@@ -1269,15 +1332,9 @@ int usb_new_device(struct usb_device *udev)
                                        le16_to_cpu(udev->config[0].desc.wTotalLength),
                                        USB_DT_OTG, (void **) &desc) == 0) {
                        if (desc->bmAttributes & USB_OTG_HNP) {
-                               unsigned                port1;
+                               unsigned                port1 = udev->portnum;
                                struct usb_device       *root = udev->parent;
                                
-                               for (port1 = 1; port1 <= root->maxchild;
-                                               port1++) {
-                                       if (root->children[port1-1] == udev)
-                                               break;
-                               }
-
                                dev_info(&udev->dev,
                                        "Dual-Role OTG device on %sHNP port\n",
                                        (port1 == bus->otg_port)
@@ -1331,27 +1388,27 @@ int usb_new_device(struct usb_device *udev)
        }
        usb_create_sysfs_dev_files (udev);
 
+       usb_lock_device(udev);
+
        /* choose and set the configuration. that registers the interfaces
         * with the driver core, and lets usb device drivers bind to them.
         */
        c = choose_configuration(udev);
-       if (c < 0)
-               dev_warn(&udev->dev,
-                               "can't choose an initial configuration\n");
-       else {
+       if (c >= 0) {
                err = usb_set_configuration(udev, c);
                if (err) {
                        dev_err(&udev->dev, "can't set config #%d, error %d\n",
                                        c, err);
-                       usb_remove_sysfs_dev_files(udev);
-                       device_del(&udev->dev);
-                       goto fail;
+                       /* This need not be fatal.  The user can try to
+                        * set other configurations. */
                }
        }
 
        /* USB device state == configured ... usable */
        usb_notify_add_device(udev);
 
+       usb_unlock_device(udev);
+
        return 0;
 
 fail:
@@ -1654,15 +1711,9 @@ static int __usb_suspend_device (struct usb_device *udev, int port1)
 int usb_suspend_device(struct usb_device *udev)
 {
 #ifdef CONFIG_USB_SUSPEND
-       int     port1, status;
-
-       port1 = locktree(udev);
-       if (port1 < 0)
-               return port1;
-
-       status = __usb_suspend_device(udev, port1);
-       usb_unlock_device(udev);
-       return status;
+       if (udev->state == USB_STATE_NOTATTACHED)
+               return -ENODEV;
+       return __usb_suspend_device(udev, udev->portnum);
 #else
        /* NOTE:  udev->state unchanged, it's not lying ... */
        udev->dev.power.power_state = PMSG_SUSPEND;
@@ -1694,13 +1745,14 @@ static int finish_device_resume(struct usb_device *udev)
        usb_set_device_state(udev, udev->actconfig
                        ? USB_STATE_CONFIGURED
                        : USB_STATE_ADDRESS);
+       udev->dev.power.power_state = PMSG_ON;
 
        /* 10.5.4.5 says be sure devices in the tree are still there.
         * For now let's assume the device didn't go crazy on resume,
         * and device drivers will know about any resume quirks.
         */
        status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
-       if (status < 0)
+       if (status < 2)
                dev_dbg(&udev->dev,
                        "gone after usb resume? status %d\n",
                        status);
@@ -1709,7 +1761,7 @@ static int finish_device_resume(struct usb_device *udev)
                int             (*resume)(struct device *);
 
                le16_to_cpus(&devstatus);
-               if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)
+               if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
                                && udev->parent) {
                        status = usb_control_msg(udev,
                                        usb_sndctrlpipe(udev, 0),
@@ -1729,8 +1781,14 @@ static int finish_device_resume(struct usb_device *udev)
                 * may have a child resume event to deal with soon
                 */
                resume = udev->dev.bus->resume;
-               for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++)
-                       (void) resume(&udev->actconfig->interface[i]->dev);
+               for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+                       struct device *dev =
+                                       &udev->actconfig->interface[i]->dev;
+
+                       down(&dev->sem);
+                       (void) resume(dev);
+                       up(&dev->sem);
+               }
                status = 0;
 
        } else if (udev->devnum <= 0) {
@@ -1813,11 +1871,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
  */
 int usb_resume_device(struct usb_device *udev)
 {
-       int     port1, status;
+       int     status;
 
-       port1 = locktree(udev);
-       if (port1 < 0)
-               return port1;
+       if (udev->state == USB_STATE_NOTATTACHED)
+               return -ENODEV;
 
 #ifdef CONFIG_USB_SUSPEND
        /* selective resume of one downstream hub-to-device port */
@@ -1826,7 +1883,7 @@ int usb_resume_device(struct usb_device *udev)
                        // NOTE swsusp may bork us, device state being wrong...
                        // NOTE this fails if parent is also suspended...
                        status = hub_port_resume(hdev_to_hub(udev->parent),
-                                       port1, udev);
+                                       udev->portnum, udev);
                } else
                        status = 0;
        } else
@@ -1836,13 +1893,11 @@ int usb_resume_device(struct usb_device *udev)
                dev_dbg(&udev->dev, "can't resume, status %d\n",
                        status);
 
-       usb_unlock_device(udev);
-
        /* rebind drivers that had no suspend() */
        if (status == 0) {
-               usb_lock_all_devices();
+               usb_unlock_device(udev);
                bus_rescan_devices(&usb_bus_type);
-               usb_unlock_all_devices();
+               usb_lock_device(udev);
        }
        return status;
 }
@@ -1856,14 +1911,14 @@ static int remote_wakeup(struct usb_device *udev)
        /* don't repeat RESUME sequence if this device
         * was already woken up by some other task
         */
-       down(&udev->serialize);
+       usb_lock_device(udev);
        if (udev->state == USB_STATE_SUSPENDED) {
                dev_dbg(&udev->dev, "RESUME (wakeup)\n");
                /* TRSMRCY = 10 msec */
                msleep(10);
                status = finish_device_resume(udev);
        }
-       up(&udev->serialize);
+       usb_unlock_device(udev);
 #endif
        return status;
 }
@@ -1964,7 +2019,7 @@ static int hub_resume(struct usb_interface *intf)
 
                if (!udev || status < 0)
                        continue;
-               down (&udev->serialize);
+               usb_lock_device(udev);
                if (portstat & USB_PORT_STAT_SUSPEND)
                        status = hub_port_resume(hub, port1, udev);
                else {
@@ -1975,7 +2030,7 @@ static int hub_resume(struct usb_interface *intf)
                                hub_port_logical_disconnect(hub, port1);
                        }
                }
-               up(&udev->serialize);
+               usb_unlock_device(udev);
        }
        }
 #endif
@@ -2359,39 +2414,36 @@ hub_power_remaining (struct usb_hub *hub)
 {
        struct usb_device *hdev = hub->hdev;
        int remaining;
-       unsigned i;
+       int port1;
 
-       remaining = hub->power_budget;
-       if (!remaining)         /* self-powered */
+       if (!hub->limited_power)
                return 0;
 
-       for (i = 0; i < hdev->maxchild; i++) {
-               struct usb_device       *udev = hdev->children[i];
-               int                     delta, ceiling;
+       remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
+       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+               struct usb_device       *udev = hdev->children[port1 - 1];
+               int                     delta;
 
                if (!udev)
                        continue;
 
-               /* 100mA per-port ceiling, or 8mA for OTG ports */
-               if (i != (udev->bus->otg_port - 1) || hdev->parent)
-                       ceiling = 50;
-               else
-                       ceiling = 4;
-
+               /* Unconfigured devices may not use more than 100mA,
+                * or 8mA for OTG ports */
                if (udev->actconfig)
-                       delta = udev->actconfig->desc.bMaxPower;
+                       delta = udev->actconfig->desc.bMaxPower * 2;
+               else if (port1 != udev->bus->otg_port || hdev->parent)
+                       delta = 100;
                else
-                       delta = ceiling;
-               // dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta);
-               if (delta > ceiling)
-                       dev_warn(&udev->dev, "%dmA over %dmA budget!\n",
-                               2 * (delta - ceiling), 2 * ceiling);
+                       delta = 8;
+               if (delta > hub->mA_per_port)
+                       dev_warn(&udev->dev, "%dmA is over %umA budget "
+                                       "for port %d!\n",
+                                       delta, hub->mA_per_port, port1);
                remaining -= delta;
        }
        if (remaining < 0) {
-               dev_warn(hub->intfdev,
-                       "%dmA over power budget!\n",
-                       -2 * remaining);
+               dev_warn(hub->intfdev, "%dmA over power budget!\n",
+                       - remaining);
                remaining = 0;
        }
        return remaining;
@@ -2486,7 +2538,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 
                usb_set_device_state(udev, USB_STATE_POWERED);
                udev->speed = USB_SPEED_UNKNOWN;
+               udev->bus_mA = hub->mA_per_port;
+
                /* set the address */
                choose_address(udev);
                if (udev->devnum <= 0) {
@@ -2506,16 +2559,16 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                 * on the parent.
                 */
                if (udev->descriptor.bDeviceClass == USB_CLASS_HUB
-                               && hub->power_budget) {
+                               && udev->bus_mA <= 100) {
                        u16     devstat;
 
                        status = usb_get_status(udev, USB_RECIP_DEVICE, 0,
                                        &devstat);
-                       if (status < 0) {
+                       if (status < 2) {
                                dev_dbg(&udev->dev, "get status %d ?\n", status);
                                goto loop_disable;
                        }
-                       cpu_to_le16s(&devstat);
+                       le16_to_cpus(&devstat);
                        if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
                                dev_err(&udev->dev,
                                        "can't connect bus-powered hub "
@@ -2540,7 +2593,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                 * udev becomes globally accessible, although presumably
                 * no one will look at it until hdev is unlocked.
                 */
-               down (&udev->serialize);
                status = 0;
 
                /* We mustn't add new devices if the parent hub has
@@ -2564,15 +2616,12 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                        }
                }
 
-               up (&udev->serialize);
                if (status)
                        goto loop_disable;
 
                status = hub_power_remaining(hub);
                if (status)
-                       dev_dbg(hub_dev,
-                               "%dmA power budget left\n",
-                               2 * status);
+                       dev_dbg(hub_dev, "%dmA power budget left\n", status);
 
                return;
 
@@ -2648,6 +2697,8 @@ static void hub_events(void)
                if (i) {
                        dpm_runtime_resume(&hdev->dev);
                        dpm_runtime_resume(&intf->dev);
+                       usb_put_intf(intf);
+                       continue;
                }
 
                /* Lock the device, then check to see if we were
@@ -2661,7 +2712,7 @@ static void hub_events(void)
 
                /* If the hub has died, clean up after it */
                if (hdev->state == USB_STATE_NOTATTACHED) {
-                       hub_pre_reset(hub);
+                       hub_pre_reset(hub, 0);
                        goto loop;
                }
 
@@ -2784,6 +2835,11 @@ static void hub_events(void)
                        if (hubchange & HUB_CHANGE_LOCAL_POWER) {
                                dev_dbg (hub_dev, "power change\n");
                                clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
+                               if (hubstatus & HUB_STATUS_LOCAL_POWER)
+                                       /* FIXME: Is this always true? */
+                                       hub->limited_power = 0;
+                               else
+                                       hub->limited_power = 1;
                        }
                        if (hubchange & HUB_CHANGE_OVERCURRENT) {
                                dev_dbg (hub_dev, "overcurrent change\n");
@@ -2832,7 +2888,6 @@ static struct usb_device_id hub_id_table [] = {
 MODULE_DEVICE_TABLE (usb, hub_id_table);
 
 static struct usb_driver hub_driver = {
-       .owner =        THIS_MODULE,
        .name =         "hub",
        .probe =        hub_probe,
        .disconnect =   hub_disconnect,
@@ -2944,7 +2999,8 @@ int usb_reset_device(struct usb_device *udev)
        struct usb_hub                  *parent_hub;
        struct usb_device_descriptor    descriptor = udev->descriptor;
        struct usb_hub                  *hub = NULL;
-       int                             i, ret = 0, port1 = -1;
+       int                             i, ret = 0;
+       int                             port1 = udev->portnum;
 
        if (udev->state == USB_STATE_NOTATTACHED ||
                        udev->state == USB_STATE_SUSPENDED) {
@@ -2958,18 +3014,6 @@ int usb_reset_device(struct usb_device *udev)
                dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
                return -EISDIR;
        }
-
-       for (i = 0; i < parent_hdev->maxchild; i++)
-               if (parent_hdev->children[i] == udev) {
-                       port1 = i + 1;
-                       break;
-               }
-
-       if (port1 < 0) {
-               /* If this ever happens, it's very bad */
-               dev_err(&udev->dev, "Can't locate device's port!\n");
-               return -ENOENT;
-       }
        parent_hub = hdev_to_hub(parent_hdev);
 
        /* If we're resetting an active hub, take some special actions */
@@ -2977,7 +3021,7 @@ int usb_reset_device(struct usb_device *udev)
                        udev->actconfig->interface[0]->dev.driver ==
                                &hub_driver.driver &&
                        (hub = hdev_to_hub(udev)) != NULL) {
-               hub_pre_reset(hub);
+               hub_pre_reset(hub, 0);
        }
 
        set_bit(port1, parent_hub->busy_bits);
index bf23f89..29d5f45 100644 (file)
@@ -220,8 +220,9 @@ struct usb_hub {
        struct usb_hub_descriptor *descriptor;  /* class descriptor */
        struct usb_tt           tt;             /* Transaction Translator */
 
-       u8                      power_budget;   /* in 2mA units; or zero */
+       unsigned                mA_per_port;    /* current for each child */
 
+       unsigned                limited_power:1;
        unsigned                quiescing:1;
        unsigned                activating:1;
        unsigned                resume_root_hub:1;
index fe74f99..319de03 100644 (file)
@@ -1387,6 +1387,12 @@ free_interfaces:
        if (dev->state != USB_STATE_ADDRESS)
                usb_disable_device (dev, 1);    // Skip ep0
 
+       i = dev->bus_mA - cp->desc.bMaxPower * 2;
+       if (i < 0)
+               dev_warn(&dev->dev, "new config #%d exceeds power "
+                               "limit by %dmA\n",
+                               configuration, -i);
+
        if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                        USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
                        NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0)
index e80ef94..56a3520 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/smp_lock.h>
-#include <linux/rwsem.h>
 #include <linux/usb.h>
 
 #include <asm/io.h>
 const char *usbcore_name = "usbcore";
 
 static int nousb;      /* Disable USB when built into kernel image */
-                       /* Not honored on modular build */
 
-static DECLARE_RWSEM(usb_all_devices_rwsem);
-
-
-static int generic_probe (struct device *dev)
-{
-       return 0;
-}
-static int generic_remove (struct device *dev)
-{
-       struct usb_device *udev = to_usb_device(dev);
-
-       /* if this is only an unbind, not a physical disconnect, then
-        * unconfigure the device */
-       if (udev->state == USB_STATE_CONFIGURED)
-               usb_set_configuration(udev, 0);
-
-       /* in case the call failed or the device was suspended */
-       if (udev->state >= USB_STATE_CONFIGURED)
-               usb_disable_device(udev, 0);
-       return 0;
-}
-
-static struct device_driver usb_generic_driver = {
-       .owner = THIS_MODULE,
-       .name = "usb",
-       .bus = &usb_bus_type,
-       .probe = generic_probe,
-       .remove = generic_remove,
-};
-
-static int usb_generic_driver_data;
-
-/* called from driver core with usb_bus_type.subsys writelock */
-static int usb_probe_interface(struct device *dev)
-{
-       struct usb_interface * intf = to_usb_interface(dev);
-       struct usb_driver * driver = to_usb_driver(dev->driver);
-       const struct usb_device_id *id;
-       int error = -ENODEV;
-
-       dev_dbg(dev, "%s\n", __FUNCTION__);
-
-       if (!driver->probe)
-               return error;
-       /* FIXME we'd much prefer to just resume it ... */
-       if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED)
-               return -EHOSTUNREACH;
-
-       id = usb_match_id (intf, driver->id_table);
-       if (id) {
-               dev_dbg (dev, "%s - got id\n", __FUNCTION__);
-
-               /* Interface "power state" doesn't correspond to any hardware
-                * state whatsoever.  We use it to record when it's bound to
-                * a driver that may start I/0:  it's not frozen/quiesced.
-                */
-               mark_active(intf);
-               intf->condition = USB_INTERFACE_BINDING;
-               error = driver->probe (intf, id);
-               if (error) {
-                       mark_quiesced(intf);
-                       intf->condition = USB_INTERFACE_UNBOUND;
-               } else
-                       intf->condition = USB_INTERFACE_BOUND;
-       }
-
-       return error;
-}
-
-/* called from driver core with usb_bus_type.subsys writelock */
-static int usb_unbind_interface(struct device *dev)
-{
-       struct usb_interface *intf = to_usb_interface(dev);
-       struct usb_driver *driver = to_usb_driver(intf->dev.driver);
-
-       intf->condition = USB_INTERFACE_UNBINDING;
-
-       /* release all urbs for this interface */
-       usb_disable_interface(interface_to_usbdev(intf), intf);
-
-       if (driver && driver->disconnect)
-               driver->disconnect(intf);
-
-       /* reset other interface state */
-       usb_set_interface(interface_to_usbdev(intf),
-                       intf->altsetting[0].desc.bInterfaceNumber,
-                       0);
-       usb_set_intfdata(intf, NULL);
-       intf->condition = USB_INTERFACE_UNBOUND;
-       mark_quiesced(intf);
-
-       return 0;
-}
-
-/**
- * usb_register - register a USB driver
- * @new_driver: USB operations for the driver
- *
- * Registers a USB driver with the USB core.  The list of unattached
- * interfaces will be rescanned whenever a new driver is added, allowing
- * the new driver to attach to any recognized devices.
- * Returns a negative error code on failure and 0 on success.
- * 
- * NOTE: if you want your driver to use the USB major number, you must call
- * usb_register_dev() to enable that functionality.  This function no longer
- * takes care of that.
- */
-int usb_register(struct usb_driver *new_driver)
-{
-       int retval = 0;
-
-       if (nousb)
-               return -ENODEV;
-
-       new_driver->driver.name = (char *)new_driver->name;
-       new_driver->driver.bus = &usb_bus_type;
-       new_driver->driver.probe = usb_probe_interface;
-       new_driver->driver.remove = usb_unbind_interface;
-       new_driver->driver.owner = new_driver->owner;
-
-       usb_lock_all_devices();
-       retval = driver_register(&new_driver->driver);
-       usb_unlock_all_devices();
-
-       if (!retval) {
-               pr_info("%s: registered new driver %s\n",
-                       usbcore_name, new_driver->name);
-               usbfs_update_special();
-       } else {
-               printk(KERN_ERR "%s: error %d registering driver %s\n",
-                       usbcore_name, retval, new_driver->name);
-       }
-
-       return retval;
-}
-
-/**
- * usb_deregister - unregister a USB driver
- * @driver: USB operations of the driver to unregister
- * Context: must be able to sleep
- *
- * Unlinks the specified driver from the internal USB driver list.
- * 
- * NOTE: If you called usb_register_dev(), you still need to call
- * usb_deregister_dev() to clean up your driver's allocated minor numbers,
- * this * call will no longer do it for you.
- */
-void usb_deregister(struct usb_driver *driver)
-{
-       pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name);
-
-       usb_lock_all_devices();
-       driver_unregister (&driver->driver);
-       usb_unlock_all_devices();
-
-       usbfs_update_special();
-}
 
 /**
  * usb_ifnum_to_if - get the interface object with a given interface number
@@ -351,152 +192,23 @@ void usb_driver_release_interface(struct usb_driver *driver,
        iface->condition = USB_INTERFACE_UNBOUND;
        mark_quiesced(iface);
 }
-
-/**
- * usb_match_id - find first usb_device_id matching device or interface
- * @interface: the interface of interest
- * @id: array of usb_device_id structures, terminated by zero entry
- *
- * usb_match_id searches an array of usb_device_id's and returns
- * the first one matching the device or interface, or null.
- * This is used when binding (or rebinding) a driver to an interface.
- * Most USB device drivers will use this indirectly, through the usb core,
- * but some layered driver frameworks use it directly.
- * These device tables are exported with MODULE_DEVICE_TABLE, through
- * modutils and "modules.usbmap", to support the driver loading
- * functionality of USB hotplugging.
- *
- * What Matches:
- *
- * The "match_flags" element in a usb_device_id controls which
- * members are used.  If the corresponding bit is set, the
- * value in the device_id must match its corresponding member
- * in the device or interface descriptor, or else the device_id
- * does not match.
- *
- * "driver_info" is normally used only by device drivers,
- * but you can create a wildcard "matches anything" usb_device_id
- * as a driver's "modules.usbmap" entry if you provide an id with
- * only a nonzero "driver_info" field.  If you do this, the USB device
- * driver's probe() routine should use additional intelligence to
- * decide whether to bind to the specified interface.
- * 
- * What Makes Good usb_device_id Tables:
- *
- * The match algorithm is very simple, so that intelligence in
- * driver selection must come from smart driver id records.
- * Unless you have good reasons to use another selection policy,
- * provide match elements only in related groups, and order match
- * specifiers from specific to general.  Use the macros provided
- * for that purpose if you can.
- *
- * The most specific match specifiers use device descriptor
- * data.  These are commonly used with product-specific matches;
- * the USB_DEVICE macro lets you provide vendor and product IDs,
- * and you can also match against ranges of product revisions.
- * These are widely used for devices with application or vendor
- * specific bDeviceClass values.
- *
- * Matches based on device class/subclass/protocol specifications
- * are slightly more general; use the USB_DEVICE_INFO macro, or
- * its siblings.  These are used with single-function devices
- * where bDeviceClass doesn't specify that each interface has
- * its own class. 
- *
- * Matches based on interface class/subclass/protocol are the
- * most general; they let drivers bind to any interface on a
- * multiple-function device.  Use the USB_INTERFACE_INFO
- * macro, or its siblings, to match class-per-interface style 
- * devices (as recorded in bDeviceClass).
- *  
- * Within those groups, remember that not all combinations are
- * meaningful.  For example, don't give a product version range
- * without vendor and product IDs; or specify a protocol without
- * its associated class and subclass.
- */   
-const struct usb_device_id *
-usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
-{
-       struct usb_host_interface *intf;
-       struct usb_device *dev;
-
-       /* proc_connectinfo in devio.c may call us with id == NULL. */
-       if (id == NULL)
-               return NULL;
-
-       intf = interface->cur_altsetting;
-       dev = interface_to_usbdev(interface);
-
-       /* It is important to check that id->driver_info is nonzero,
-          since an entry that is all zeroes except for a nonzero
-          id->driver_info is the way to create an entry that
-          indicates that the driver want to examine every
-          device and interface. */
-       for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
-              id->driver_info; id++) {
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-                   id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-                   id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
-                       continue;
-
-               /* No need to test id->bcdDevice_lo != 0, since 0 is never
-                  greater than any unsigned number. */
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
-                   (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
-                   (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
-                   (id->bDeviceClass != dev->descriptor.bDeviceClass))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
-                   (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
-                   (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
-                   (id->bInterfaceClass != intf->desc.bInterfaceClass))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
-                   (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
-                       continue;
-
-               if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
-                   (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
-                       continue;
-
-               return id;
-       }
-
-       return NULL;
-}
-
+struct find_interface_arg {
+       int minor;
+       struct usb_interface *interface;
+};
 
 static int __find_interface(struct device * dev, void * data)
 {
-       struct usb_interface ** ret = (struct usb_interface **)data;
-       struct usb_interface * intf = *ret;
-       int *minor = (int *)data;
+       struct find_interface_arg *arg = data;
+       struct usb_interface *intf;
 
        /* can't look at usb devices, only interfaces */
        if (dev->driver == &usb_generic_driver)
                return 0;
 
        intf = to_usb_interface(dev);
-       if (intf->minor != -1 && intf->minor == *minor) {
-               *ret = intf;
+       if (intf->minor != -1 && intf->minor == arg->minor) {
+               arg->interface = intf;
                return 1;
        }
        return 0;
@@ -513,35 +225,14 @@ static int __find_interface(struct device * dev, void * data)
  */
 struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
 {
-       struct usb_interface *intf = (struct usb_interface *)(long)minor;
-       int ret;
-
-       ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);
-
-       return ret ? intf : NULL;
-}
-
-static int usb_device_match (struct device *dev, struct device_driver *drv)
-{
-       struct usb_interface *intf;
-       struct usb_driver *usb_drv;
-       const struct usb_device_id *id;
-
-       /* check for generic driver, which we don't match any device with */
-       if (drv == &usb_generic_driver)
-               return 0;
-
-       intf = to_usb_interface(dev);
-       usb_drv = to_usb_driver(drv);
-       
-       id = usb_match_id (intf, usb_drv->id_table);
-       if (id)
-               return 1;
+       struct find_interface_arg argb;
 
-       return 0;
+       argb.minor = minor;
+       argb.interface = NULL;
+       driver_for_each_device(&drv->driver, NULL, &argb, __find_interface);
+       return argb.interface;
 }
 
-
 #ifdef CONFIG_HOTPLUG
 
 /*
@@ -750,12 +441,11 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
                /* hub driver sets up TT records */
        }
 
+       dev->portnum = port1;
        dev->bus = bus;
        dev->parent = parent;
        INIT_LIST_HEAD(&dev->filelist);
 
-       init_MUTEX(&dev->serialize);
-
        return dev;
 }
 
@@ -828,75 +518,20 @@ void usb_put_intf(struct usb_interface *intf)
 
 /*                     USB device locking
  *
- * Although locking USB devices should be straightforward, it is
- * complicated by the way the driver-model core works.  When a new USB
- * driver is registered or unregistered, the core will automatically
- * probe or disconnect all matching interfaces on all USB devices while
- * holding the USB subsystem writelock.  There's no good way for us to
- * tell which devices will be used or to lock them beforehand; our only
- * option is to effectively lock all the USB devices.
- *
- * We do that by using a private rw-semaphore, usb_all_devices_rwsem.
- * When locking an individual device you must first acquire the rwsem's
- * readlock.  When a driver is registered or unregistered the writelock
- * must be held.  These actions are encapsulated in the subroutines
- * below, so all a driver needs to do is call usb_lock_device() and
- * usb_unlock_device().
+ * USB devices and interfaces are locked using the semaphore in their
+ * embedded struct device.  The hub driver guarantees that whenever a
+ * device is connected or disconnected, drivers are called with the
+ * USB device locked as well as their particular interface.
  *
  * Complications arise when several devices are to be locked at the same
  * time.  Only hub-aware drivers that are part of usbcore ever have to
- * do this; nobody else needs to worry about it.  The problem is that
- * usb_lock_device() must not be called to lock a second device since it
- * would acquire the rwsem's readlock reentrantly, leading to deadlock if
- * another thread was waiting for the writelock.  The solution is simple:
- *
- *     When locking more than one device, call usb_lock_device()
- *     to lock the first one.  Lock the others by calling
- *     down(&udev->serialize) directly.
- *
- *     When unlocking multiple devices, use up(&udev->serialize)
- *     to unlock all but the last one.  Unlock the last one by
- *     calling usb_unlock_device().
+ * do this; nobody else needs to worry about it.  The rule for locking
+ * is simple:
  *
  *     When locking both a device and its parent, always lock the
  *     the parent first.
  */
 
-/**
- * usb_lock_device - acquire the lock for a usb device structure
- * @udev: device that's being locked
- *
- * Use this routine when you don't hold any other device locks;
- * to acquire nested inner locks call down(&udev->serialize) directly.
- * This is necessary for proper interaction with usb_lock_all_devices().
- */
-void usb_lock_device(struct usb_device *udev)
-{
-       down_read(&usb_all_devices_rwsem);
-       down(&udev->serialize);
-}
-
-/**
- * usb_trylock_device - attempt to acquire the lock for a usb device structure
- * @udev: device that's being locked
- *
- * Don't use this routine if you already hold a device lock;
- * use down_trylock(&udev->serialize) instead.
- * This is necessary for proper interaction with usb_lock_all_devices().
- *
- * Returns 1 if successful, 0 if contention.
- */
-int usb_trylock_device(struct usb_device *udev)
-{
-       if (!down_read_trylock(&usb_all_devices_rwsem))
-               return 0;
-       if (down_trylock(&udev->serialize)) {
-               up_read(&usb_all_devices_rwsem);
-               return 0;
-       }
-       return 1;
-}
-
 /**
  * usb_lock_device_for_reset - cautiously acquire the lock for a
  *     usb device structure
@@ -935,7 +570,7 @@ int usb_lock_device_for_reset(struct usb_device *udev,
                }
        }
 
-       while (!usb_trylock_device(udev)) {
+       while (usb_trylock_device(udev) != 0) {
 
                /* If we can't acquire the lock after waiting one second,
                 * we're probably deadlocked */
@@ -953,39 +588,6 @@ int usb_lock_device_for_reset(struct usb_device *udev,
        return 1;
 }
 
-/**
- * usb_unlock_device - release the lock for a usb device structure
- * @udev: device that's being unlocked
- *
- * Use this routine when releasing the only device lock you hold;
- * to release inner nested locks call up(&udev->serialize) directly.
- * This is necessary for proper interaction with usb_lock_all_devices().
- */
-void usb_unlock_device(struct usb_device *udev)
-{
-       up(&udev->serialize);
-       up_read(&usb_all_devices_rwsem);
-}
-
-/**
- * usb_lock_all_devices - acquire the lock for all usb device structures
- *
- * This is necessary when registering a new driver or probing a bus,
- * since the driver-model core may try to use any usb_device.
- */
-void usb_lock_all_devices(void)
-{
-       down_write(&usb_all_devices_rwsem);
-}
-
-/**
- * usb_unlock_all_devices - release the lock for all usb device structures
- */
-void usb_unlock_all_devices(void)
-{
-       up_write(&usb_all_devices_rwsem);
-}
-
 
 static struct usb_device *match_device(struct usb_device *dev,
                                       u16 vendor_id, u16 product_id)
@@ -1008,10 +610,10 @@ static struct usb_device *match_device(struct usb_device *dev,
        /* look through all of the children of this device */
        for (child = 0; child < dev->maxchild; ++child) {
                if (dev->children[child]) {
-                       down(&dev->children[child]->serialize);
+                       usb_lock_device(dev->children[child]);
                        ret_dev = match_device(dev->children[child],
                                               vendor_id, product_id);
-                       up(&dev->children[child]->serialize);
+                       usb_unlock_device(dev->children[child]);
                        if (ret_dev)
                                goto exit;
                }
@@ -1496,18 +1098,8 @@ struct bus_type usb_bus_type = {
        .resume =       usb_generic_resume,
 };
 
-#ifndef MODULE
-
-static int __init usb_setup_disable(char *str)
-{
-       nousb = 1;
-       return 1;
-}
-
 /* format to disable USB on kernel command line is: nousb */
-__setup("nousb", usb_setup_disable);
-
-#endif
+__module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444);
 
 /*
  * for external read access to <nousb>
@@ -1598,8 +1190,6 @@ module_exit(usb_exit);
  * driver modules to use.
  */
 
-EXPORT_SYMBOL(usb_register);
-EXPORT_SYMBOL(usb_deregister);
 EXPORT_SYMBOL(usb_disabled);
 
 EXPORT_SYMBOL_GPL(usb_get_intf);
@@ -1610,14 +1200,10 @@ EXPORT_SYMBOL(usb_put_dev);
 EXPORT_SYMBOL(usb_get_dev);
 EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
 
-EXPORT_SYMBOL(usb_lock_device);
-EXPORT_SYMBOL(usb_trylock_device);
 EXPORT_SYMBOL(usb_lock_device_for_reset);
-EXPORT_SYMBOL(usb_unlock_device);
 
 EXPORT_SYMBOL(usb_driver_claim_interface);
 EXPORT_SYMBOL(usb_driver_release_interface);
-EXPORT_SYMBOL(usb_match_id);
 EXPORT_SYMBOL(usb_find_interface);
 EXPORT_SYMBOL(usb_ifnum_to_if);
 EXPORT_SYMBOL(usb_altnum_to_altsetting);
index 1c4a684..4647e1e 100644 (file)
@@ -16,9 +16,6 @@ extern int usb_get_device_descriptor(struct usb_device *dev,
 extern char *usb_cache_string(struct usb_device *udev, int index);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 
-extern void usb_lock_all_devices(void);
-extern void usb_unlock_all_devices(void);
-
 extern void usb_kick_khubd(struct usb_device *dev);
 extern void usb_suspend_root_hub(struct usb_device *hdev);
 extern void usb_resume_root_hub(struct usb_device *dev);
@@ -33,6 +30,9 @@ extern void usb_host_cleanup(void);
 extern int usb_suspend_device(struct usb_device *dev);
 extern int usb_resume_device(struct usb_device *dev);
 
+extern struct device_driver usb_generic_driver;
+extern int usb_generic_driver_data;
+extern int usb_device_match(struct device *dev, struct device_driver *drv);
 
 /* Interfaces and their "power state" are owned by usbcore */
 
index c655d46..9734cb7 100644 (file)
@@ -138,7 +138,7 @@ static const char *const ep_name [] = {
        /* or like sa1100: two fixed function endpoints */
        "ep1out-bulk", "ep2in-bulk",
 };
-#define DUMMY_ENDPOINTS        (sizeof(ep_name)/sizeof(char *))
+#define DUMMY_ENDPOINTS        ARRAY_SIZE(ep_name)
 
 /*-------------------------------------------------------------------------*/
 
@@ -896,7 +896,7 @@ dummy_gadget_release (struct device *dev)
 #endif
 }
 
-static int dummy_udc_probe (struct platform_device *dev)
+static int dummy_udc_probe (struct platform_device *pdev)
 {
        struct dummy    *dum = the_controller;
        int             rc;
@@ -909,7 +909,7 @@ static int dummy_udc_probe (struct platform_device *dev)
        dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
 
        strcpy (dum->gadget.dev.bus_id, "gadget");
-       dum->gadget.dev.parent = &dev->dev;
+       dum->gadget.dev.parent = &pdev->dev;
        dum->gadget.dev.release = dummy_gadget_release;
        rc = device_register (&dum->gadget.dev);
        if (rc < 0)
@@ -919,47 +919,47 @@ static int dummy_udc_probe (struct platform_device *dev)
        usb_bus_get (&dummy_to_hcd (dum)->self);
 #endif
 
-       platform_set_drvdata (dev, dum);
+       platform_set_drvdata (pdev, dum);
        device_create_file (&dum->gadget.dev, &dev_attr_function);
        return rc;
 }
 
-static int dummy_udc_remove (struct platform_device *dev)
+static int dummy_udc_remove (struct platform_device *pdev)
 {
-       struct dummy    *dum = platform_get_drvdata (dev);
+       struct dummy    *dum = platform_get_drvdata (pdev);
 
-       platform_set_drvdata (dev, NULL);
+       platform_set_drvdata (pdev, NULL);
        device_remove_file (&dum->gadget.dev, &dev_attr_function);
        device_unregister (&dum->gadget.dev);
        return 0;
 }
 
-static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state)
+static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state)
 {
-       struct dummy    *dum = platform_get_drvdata(dev);
+       struct dummy    *dum = platform_get_drvdata(pdev);
 
-       dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+       dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
        spin_lock_irq (&dum->lock);
        dum->udc_suspended = 1;
        set_link_state (dum);
        spin_unlock_irq (&dum->lock);
 
-       dev->dev.power.power_state = state;
+       pdev->dev.power.power_state = state;
        usb_hcd_poll_rh_status (dummy_to_hcd (dum));
        return 0;
 }
 
-static int dummy_udc_resume (struct platform_device *dev)
+static int dummy_udc_resume (struct platform_device *pdev)
 {
-       struct dummy    *dum = platform_get_drvdata(dev);
+       struct dummy    *dum = platform_get_drvdata(pdev);
 
-       dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+       dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
        spin_lock_irq (&dum->lock);
        dum->udc_suspended = 0;
        set_link_state (dum);
        spin_unlock_irq (&dum->lock);
 
-       dev->dev.power.power_state = PMSG_ON;
+       pdev->dev.power.power_state = PMSG_ON;
        usb_hcd_poll_rh_status (dummy_to_hcd (dum));
        return 0;
 }
@@ -1576,7 +1576,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf)
        dum = hcd_to_dummy (hcd);
 
        spin_lock_irqsave (&dum->lock, flags);
-       if (hcd->state != HC_STATE_RUNNING)
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
                goto done;
 
        if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) {
@@ -1623,7 +1623,7 @@ static int dummy_hub_control (
        int             retval = 0;
        unsigned long   flags;
 
-       if (hcd->state != HC_STATE_RUNNING)
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
                return -ETIMEDOUT;
 
        dum = hcd_to_dummy (hcd);
@@ -1756,9 +1756,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd)
 {
        struct dummy *dum = hcd_to_dummy (hcd);
 
+       dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
+
        spin_lock_irq (&dum->lock);
        dum->rh_state = DUMMY_RH_SUSPENDED;
        set_link_state (dum);
+       hcd->state = HC_STATE_SUSPENDED;
        spin_unlock_irq (&dum->lock);
        return 0;
 }
@@ -1766,14 +1769,23 @@ static int dummy_bus_suspend (struct usb_hcd *hcd)
 static int dummy_bus_resume (struct usb_hcd *hcd)
 {
        struct dummy *dum = hcd_to_dummy (hcd);
+       int rc = 0;
+
+       dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
 
        spin_lock_irq (&dum->lock);
-       dum->rh_state = DUMMY_RH_RUNNING;
-       set_link_state (dum);
-       if (!list_empty(&dum->urbp_list))
-               mod_timer (&dum->timer, jiffies);
+       if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+               dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n");
+               rc = -ENODEV;
+       } else {
+               dum->rh_state = DUMMY_RH_RUNNING;
+               set_link_state (dum);
+               if (!list_empty(&dum->urbp_list))
+                       mod_timer (&dum->timer, jiffies);
+               hcd->state = HC_STATE_RUNNING;
+       }
        spin_unlock_irq (&dum->lock);
-       return 0;
+       return rc;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1899,14 +1911,14 @@ static const struct hc_driver dummy_hcd = {
        .bus_resume =           dummy_bus_resume,
 };
 
-static int dummy_hcd_probe (struct platform_device *dev)
+static int dummy_hcd_probe(struct platform_device *pdev)
 {
        struct usb_hcd          *hcd;
        int                     retval;
 
-       dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
+       dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
 
-       hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id);
+       hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id);
        if (!hcd)
                return -ENOMEM;
        the_controller = hcd_to_dummy (hcd);
@@ -1919,36 +1931,43 @@ static int dummy_hcd_probe (struct platform_device *dev)
        return retval;
 }
 
-static int dummy_hcd_remove (struct platform_device *dev)
+static int dummy_hcd_remove (struct platform_device *pdev)
 {
        struct usb_hcd          *hcd;
 
-       hcd = platform_get_drvdata (dev);
+       hcd = platform_get_drvdata (pdev);
        usb_remove_hcd (hcd);
        usb_put_hcd (hcd);
        the_controller = NULL;
        return 0;
 }
 
-static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state)
+static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state)
 {
        struct usb_hcd          *hcd;
+       struct dummy            *dum;
+       int                     rc = 0;
 
-       dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
-       hcd = platform_get_drvdata (dev);
+       dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 
-       hcd->state = HC_STATE_SUSPENDED;
-       return 0;
+       hcd = platform_get_drvdata (pdev);
+       dum = hcd_to_dummy (hcd);
+       if (dum->rh_state == DUMMY_RH_RUNNING) {
+               dev_warn(&pdev->dev, "Root hub isn't suspended!\n");
+               rc = -EBUSY;
+       } else
+               clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+       return rc;
 }
 
-static int dummy_hcd_resume (struct platform_device *dev)
+static int dummy_hcd_resume (struct platform_device *pdev)
 {
        struct usb_hcd          *hcd;
 
-       dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
-       hcd = platform_get_drvdata (dev);
-       hcd->state = HC_STATE_RUNNING;
+       dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 
+       hcd = platform_get_drvdata (pdev);
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
        usb_hcd_poll_rh_status (hcd);
        return 0;
 }
index ea09aaa..0cea978 100644 (file)
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/kthread.h>
 #include <linux/limits.h>
 #include <linux/list.h>
 #include <linux/string.h>
 #include <linux/suspend.h>
 #include <linux/utsname.h>
-#include <linux/wait.h>
 
 #include <linux/usb_ch9.h>
 #include <linux/usb_gadget.h>
 
 #define DRIVER_DESC            "File-backed Storage Gadget"
 #define DRIVER_NAME            "g_file_storage"
-#define DRIVER_VERSION         "20 October 2004"
+#define DRIVER_VERSION         "28 November 2005"
 
 static const char longname[] = DRIVER_DESC;
 static const char shortname[] = DRIVER_NAME;
@@ -335,8 +335,8 @@ MODULE_LICENSE("Dual BSD/GPL");
 #define MAX_LUNS       8
 
        /* Arggh!  There should be a module_param_array_named macro! */
-static char            *file[MAX_LUNS] = {NULL, };
-static int             ro[MAX_LUNS] = {0, };
+static char            *file[MAX_LUNS];
+static int             ro[MAX_LUNS];
 
 static struct {
        int             num_filenames;
@@ -587,7 +587,7 @@ enum fsg_buffer_state {
 struct fsg_buffhd {
        void                            *buf;
        dma_addr_t                      dma;
-       volatile enum fsg_buffer_state  state;
+       enum fsg_buffer_state           state;
        struct fsg_buffhd               *next;
 
        /* The NetChip 2280 is faster, and handles some protocol faults
@@ -596,9 +596,9 @@ struct fsg_buffhd {
        unsigned int                    bulk_out_intended_length;
 
        struct usb_request              *inreq;
-       volatile int                    inreq_busy;
+       int                             inreq_busy;
        struct usb_request              *outreq;
-       volatile int                    outreq_busy;
+       int                             outreq_busy;
 };
 
 enum fsg_state {
@@ -631,13 +631,16 @@ struct fsg_dev {
        /* filesem protects: backing files in use */
        struct rw_semaphore     filesem;
 
+       /* reference counting: wait until all LUNs are released */
+       struct kref             ref;
+
        struct usb_ep           *ep0;           // Handy copy of gadget->ep0
        struct usb_request      *ep0req;        // For control responses
-       volatile unsigned int   ep0_req_tag;
+       unsigned int            ep0_req_tag;
        const char              *ep0req_name;
 
        struct usb_request      *intreq;        // For interrupt responses
-       volatile int            intreq_busy;
+       int                     intreq_busy;
        struct fsg_buffhd       *intr_buffhd;
 
        unsigned int            bulk_out_maxpacket;
@@ -667,7 +670,6 @@ struct fsg_dev {
        struct fsg_buffhd       *next_buffhd_to_drain;
        struct fsg_buffhd       buffhds[NUM_BUFFERS];
 
-       wait_queue_head_t       thread_wqh;
        int                     thread_wakeup_needed;
        struct completion       thread_notifier;
        struct task_struct      *thread_task;
@@ -694,7 +696,6 @@ struct fsg_dev {
        unsigned int            nluns;
        struct lun              *luns;
        struct lun              *curlun;
-       struct completion       lun_released;
 };
 
 typedef void (*fsg_routine_t)(struct fsg_dev *);
@@ -1073,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget,
 
 /* These routines may be called in process context or in_irq */
 
+/* Caller must hold fsg->lock */
 static void wakeup_thread(struct fsg_dev *fsg)
 {
        /* Tell the main thread that something has happened */
        fsg->thread_wakeup_needed = 1;
-       wake_up_all(&fsg->thread_wqh);
+       if (fsg->thread_task)
+               wake_up_process(fsg->thread_task);
 }
 
 
@@ -1164,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
                usb_ep_fifo_flush(ep);
 
        /* Hold the lock while we update the request and buffer states */
+       smp_wmb();
        spin_lock(&fsg->lock);
        bh->inreq_busy = 0;
        bh->state = BUF_STATE_EMPTY;
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
+       spin_unlock(&fsg->lock);
 }
 
 static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
@@ -1185,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
                usb_ep_fifo_flush(ep);
 
        /* Hold the lock while we update the request and buffer states */
+       smp_wmb();
        spin_lock(&fsg->lock);
        bh->outreq_busy = 0;
        bh->state = BUF_STATE_FULL;
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
+       spin_unlock(&fsg->lock);
 }
 
 
@@ -1206,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
                usb_ep_fifo_flush(ep);
 
        /* Hold the lock while we update the request and buffer states */
+       smp_wmb();
        spin_lock(&fsg->lock);
        fsg->intreq_busy = 0;
        bh->state = BUF_STATE_EMPTY;
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
+       spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1261,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        fsg->cbbuf_cmnd_size = req->actual;
        memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
 
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
+       spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1514,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget,
 
 /* Use this for bulk or interrupt transfers, not ep0 */
 static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
-               struct usb_request *req, volatile int *pbusy,
-               volatile enum fsg_buffer_state *state)
+               struct usb_request *req, int *pbusy,
+               enum fsg_buffer_state *state)
 {
        int     rc;
 
@@ -1523,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
                dump_msg(fsg, "bulk-in", req->buf, req->length);
        else if (ep == fsg->intr_in)
                dump_msg(fsg, "intr-in", req->buf, req->length);
+
+       spin_lock_irq(&fsg->lock);
        *pbusy = 1;
        *state = BUF_STATE_BUSY;
+       spin_unlock_irq(&fsg->lock);
        rc = usb_ep_queue(ep, req, GFP_KERNEL);
        if (rc != 0) {
                *pbusy = 0;
@@ -1544,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
 
 static int sleep_thread(struct fsg_dev *fsg)
 {
-       int     rc;
+       int     rc = 0;
 
        /* Wait until a signal arrives or we are woken up */
-       rc = wait_event_interruptible(fsg->thread_wqh,
-                       fsg->thread_wakeup_needed);
+       for (;;) {
+               try_to_freeze();
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (signal_pending(current)) {
+                       rc = -EINTR;
+                       break;
+               }
+               if (fsg->thread_wakeup_needed)
+                       break;
+               schedule();
+       }
+       __set_current_state(TASK_RUNNING);
        fsg->thread_wakeup_needed = 0;
-       try_to_freeze();
-       return (rc ? -EINTR : 0);
+       return rc;
 }
 
 
@@ -1788,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg)
                if (bh->state == BUF_STATE_EMPTY && !get_some_more)
                        break;                  // We stopped early
                if (bh->state == BUF_STATE_FULL) {
+                       smp_rmb();
                        fsg->next_buffhd_to_drain = bh->next;
                        bh->state = BUF_STATE_EMPTY;
 
@@ -2356,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg)
 
                /* Throw away the data in a filled buffer */
                if (bh->state == BUF_STATE_FULL) {
+                       smp_rmb();
                        bh->state = BUF_STATE_EMPTY;
                        fsg->next_buffhd_to_drain = bh->next;
 
@@ -3021,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg)
                        if ((rc = sleep_thread(fsg)) != 0)
                                return rc;
                        }
+               smp_rmb();
                rc = received_cbw(fsg, bh);
                bh->state = BUF_STATE_EMPTY;
 
@@ -3642,11 +3663,19 @@ static DEVICE_ATTR(file, 0444, show_file, NULL);
 
 /*-------------------------------------------------------------------------*/
 
+static void fsg_release(struct kref *ref)
+{
+       struct fsg_dev  *fsg = container_of(ref, struct fsg_dev, ref);
+
+       kfree(fsg->luns);
+       kfree(fsg);
+}
+
 static void lun_release(struct device *dev)
 {
        struct fsg_dev  *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
 
-       complete(&fsg->lun_released);
+       kref_put(&fsg->ref, fsg_release);
 }
 
 static void fsg_unbind(struct usb_gadget *gadget)
@@ -3660,14 +3689,12 @@ static void fsg_unbind(struct usb_gadget *gadget)
        clear_bit(REGISTERED, &fsg->atomic_bitflags);
 
        /* Unregister the sysfs attribute files and the LUNs */
-       init_completion(&fsg->lun_released);
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
                if (curlun->registered) {
                        device_remove_file(&curlun->dev, &dev_attr_ro);
                        device_remove_file(&curlun->dev, &dev_attr_file);
                        device_unregister(&curlun->dev);
-                       wait_for_completion(&fsg->lun_released);
                        curlun->registered = 0;
                }
        }
@@ -3846,6 +3873,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                        curlun->dev.release = lun_release;
                        device_create_file(&curlun->dev, &dev_attr_ro);
                        device_create_file(&curlun->dev, &dev_attr_file);
+                       kref_get(&fsg->ref);
                }
 
                if (file[i] && *file[i]) {
@@ -4061,7 +4089,7 @@ static int __init fsg_alloc(void)
                return -ENOMEM;
        spin_lock_init(&fsg->lock);
        init_rwsem(&fsg->filesem);
-       init_waitqueue_head(&fsg->thread_wqh);
+       kref_init(&fsg->ref);
        init_completion(&fsg->thread_notifier);
 
        the_fsg = fsg;
@@ -4069,13 +4097,6 @@ static int __init fsg_alloc(void)
 }
 
 
-static void fsg_free(struct fsg_dev *fsg)
-{
-       kfree(fsg->luns);
-       kfree(fsg);
-}
-
-
 static int __init fsg_init(void)
 {
        int             rc;
@@ -4085,7 +4106,7 @@ static int __init fsg_init(void)
                return rc;
        fsg = the_fsg;
        if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
-               fsg_free(fsg);
+               kref_put(&fsg->ref, fsg_release);
        return rc;
 }
 module_init(fsg_init);
@@ -4103,6 +4124,6 @@ static void __exit fsg_cleanup(void)
        wait_for_completion(&fsg->thread_notifier);
 
        close_all_backing_files(fsg);
-       fsg_free(fsg);
+       kref_put(&fsg->ref, fsg_release);
 }
 module_exit(fsg_cleanup);
index b35ac6d..65e084a 100644 (file)
@@ -890,10 +890,12 @@ static void gs_close(struct tty_struct *tty, struct file *file)
        /* wait for write buffer to drain, or */
        /* at most GS_CLOSE_TIMEOUT seconds */
        if (gs_buf_data_avail(port->port_write_buf) > 0) {
+               spin_unlock_irqrestore(&port->port_lock, flags);
                wait_cond_interruptible_timeout(port->port_write_wait,
                port->port_dev == NULL
                || gs_buf_data_avail(port->port_write_buf) == 0,
                &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
+               spin_lock_irqsave(&port->port_lock, flags);
        }
 
        /* free disconnected port on final close */
index 58321d3..e3020f4 100644 (file)
@@ -2,6 +2,10 @@
 # Makefile for USB Host Controller Drivers
 #
 
+ifeq ($(CONFIG_USB_DEBUG),y)
+       EXTRA_CFLAGS            += -DDEBUG
+endif
+
 obj-$(CONFIG_PCI)              += pci-quirks.o
 
 obj-$(CONFIG_USB_EHCI_HCD)     += ehci-hcd.o
index 29f52a4..9dd3d14 100644 (file)
  */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-       #define DEBUG
-#else
-       #undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dmapool.h>
@@ -624,7 +617,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
        }
 
        /* remote wakeup [4.3.1] */
-       if ((status & STS_PCD) && hcd->remote_wakeup) {
+       if (status & STS_PCD) {
                unsigned        i = HCS_N_PORTS (ehci->hcs_params);
 
                /* resume root hub? */
index 82caf33..69b0b9b 100644 (file)
@@ -59,7 +59,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
 
                if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
                        t2 |= PORT_SUSPEND;
-               if (hcd->remote_wakeup)
+               if (device_may_wakeup(&hcd->self.root_hub->dev))
                        t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
                else
                        t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
@@ -517,7 +517,7 @@ static int ehci_hub_control (
                        if ((temp & PORT_PE) == 0
                                        || (temp & PORT_RESET) != 0)
                                goto error;
-                       if (hcd->remote_wakeup)
+                       if (device_may_wakeup(&hcd->self.root_hub->dev))
                                temp |= PORT_WAKE_BITS;
                        writel (temp | PORT_SUSPEND,
                                &ehci->regs->port_status [wIndex]);
index 13f73a8..08ca0f8 100644 (file)
@@ -210,7 +210,16 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
        /* Serial Bus Release Number is at PCI 0x60 offset */
        pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
 
-       /* REVISIT:  per-port wake capability (PCI 0x62) currently unused */
+       /* Workaround current PCI init glitch:  wakeup bits aren't
+        * being set from PCI PM capability.
+        */
+       if (!device_can_wakeup(&pdev->dev)) {
+               u16     port_wake;
+
+               pci_read_config_word(pdev, 0x62, &port_wake);
+               if (port_wake & 0x0001)
+                       device_init_wakeup(&pdev->dev, 1);
+       }
 
        retval = ehci_pci_reinit(ehci, pdev);
 done:
@@ -269,7 +278,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
        unsigned                port;
-       struct usb_device       *root = hcd->self.root_hub;
        struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
        int                     retval = -EINVAL;
 
@@ -303,13 +311,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
 
 restart:
        ehci_dbg(ehci, "lost power, restarting\n");
-       for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) {
-               port--;
-               if (!root->children [port])
-                       continue;
-               usb_set_device_state(root->children[port],
-                                       USB_STATE_NOTATTACHED);
-       }
+       usb_root_hub_lost_power(hcd->self.root_hub);
 
        /* Else reset, to cope with power loss or flush-to-storage
         * style "resume" having let BIOS kick in during reboot.
index bf03ec0..9b13bf2 100644 (file)
@@ -514,18 +514,18 @@ qh_urb_transaction (
                qtd->urb = urb;
                qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
                list_add_tail (&qtd->qtd_list, head);
+
+               /* for zero length DATA stages, STATUS is always IN */
+               if (len == 0)
+                       token |= (1 /* "in" */ << 8);
        } 
 
        /*
         * data transfer stage:  buffer setup
         */
-       if (likely (len > 0))
-               buf = urb->transfer_dma;
-       else
-               buf = 0;
+       buf = urb->transfer_dma;
 
-       /* for zero length DATA stages, STATUS is always IN */
-       if (!buf || is_input)
+       if (is_input)
                token |= (1 /* "in" */ << 8);
        /* else it's already initted to "out" pid (0 << 8) */
 
@@ -572,7 +572,7 @@ qh_urb_transaction (
         * control requests may need a terminating data "status" ack;
         * bulk ones may need a terminating short packet (zero length).
         */
-       if (likely (buf != 0)) {
+       if (likely (urb->transfer_buffer_length != 0)) {
                int     one_more = 0;
 
                if (usb_pipecontrol (urb->pipe)) {
index 82f6498..584b8dc 100644 (file)
 /* enqueuing/finishing log of urbs */
 //#define URB_TRACE
 
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <linux/usb_isp116x.h>
 #include <linux/platform_device.h>
 #include <asm/system.h>
 #include <asm/byteorder.h>
 
-#ifndef DEBUG
-#      define  STUB_DEBUG_FILE
-#endif
-
 #include "../core/hcd.h"
 #include "isp116x.h"
 
-#define DRIVER_VERSION "05 Aug 2005"
+#define DRIVER_VERSION "03 Nov 2005"
 #define DRIVER_DESC    "ISP116x USB Host Controller Driver"
 
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -164,13 +154,11 @@ static void pack_fifo(struct isp116x *isp116x)
        struct ptd *ptd;
        int buflen = isp116x->atl_last_dir == PTD_DIR_IN
            ? isp116x->atl_bufshrt : isp116x->atl_buflen;
-       int ptd_count = 0;
 
        isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
        isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
        isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
        for (ep = isp116x->atl_active; ep; ep = ep->active) {
-               ++ptd_count;
                ptd = &ep->ptd;
                dump_ptd(ptd);
                dump_ptd_out_data(ptd, ep->data);
@@ -305,9 +293,8 @@ static void postproc_atl_queue(struct isp116x *isp116x)
                udev = urb->dev;
                ptd = &ep->ptd;
                cc = PTD_GET_CC(ptd);
-
-               spin_lock(&urb->lock);
                short_not_ok = 1;
+               spin_lock(&urb->lock);
 
                /* Data underrun is special. For allowed underrun
                   we clear the error and continue as normal. For
@@ -420,7 +407,7 @@ static void postproc_atl_queue(struct isp116x *isp116x)
                        ep->nextpid = 0;
                        break;
                default:
-                       BUG_ON(1);
+                       BUG();
                }
                spin_unlock(&urb->lock);
        }
@@ -628,8 +615,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
                u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
                isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
                if (intstat & HCINT_UE) {
-                       ERR("Unrecoverable error\n");
-                       /* What should we do here? Reset?  */
+                       ERR("Unrecoverable error, HC is dead!\n");
+                       /* IRQ's are off, we do no DMA,
+                          perfectly ready to die ... */
+                       hcd->state = HC_STATE_HALT;
+                       ret = IRQ_HANDLED;
+                       goto done;
                }
                if (intstat & HCINT_RHSC)
                        /* When root hub or any of its ports is going
@@ -640,7 +631,6 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
                if (intstat & HCINT_RD) {
                        DBG("---- remote wakeup\n");
                        usb_hcd_resume_root_hub(hcd);
-                       ret = IRQ_HANDLED;
                }
                irqstat &= ~HCuPINT_OPR;
                ret = IRQ_HANDLED;
@@ -651,6 +641,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
        }
 
        isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
+      done:
        spin_unlock(&isp116x->lock);
        return ret;
 }
@@ -724,6 +715,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
 
        spin_lock_irqsave(&isp116x->lock, flags);
        if (!HC_IS_RUNNING(hcd->state)) {
+               kfree(ep);
                ret = -ENODEV;
                goto fail;
        }
@@ -888,7 +880,7 @@ static void isp116x_endpoint_disable(struct usb_hcd *hcd,
                                     struct usb_host_endpoint *hep)
 {
        int i;
-       struct isp116x_ep *ep = hep->hcpriv;;
+       struct isp116x_ep *ep = hep->hcpriv;
 
        if (!ep)
                return;
@@ -916,8 +908,6 @@ static int isp116x_get_frame(struct usb_hcd *hcd)
        return (int)fmnum;
 }
 
-/*----------------------------------------------------------------*/
-
 /*
   Adapted from ohci-hub.c. Currently we don't support autosuspend.
 */
@@ -968,11 +958,10 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x,
        desc->bHubContrCurrent = 0;
        desc->bNbrPorts = (u8) (reg & 0x3);
        /* Power switching, device type, overcurrent. */
-       desc->wHubCharacteristics =
-           (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f));
+       desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f));
        desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff);
        /* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
-       desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
+       desc->bitmap[0] = 0;
        desc->bitmap[1] = ~0;
 }
 
@@ -1159,135 +1148,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
        return ret;
 }
 
-#ifdef CONFIG_PM
-
-static int isp116x_bus_suspend(struct usb_hcd *hcd)
-{
-       struct isp116x *isp116x = hcd_to_isp116x(hcd);
-       unsigned long flags;
-       u32 val;
-       int ret = 0;
-
-       spin_lock_irqsave(&isp116x->lock, flags);
-
-       val = isp116x_read_reg32(isp116x, HCCONTROL);
-       switch (val & HCCONTROL_HCFS) {
-       case HCCONTROL_USB_OPER:
-               hcd->state = HC_STATE_QUIESCING;
-               val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
-               val |= HCCONTROL_USB_SUSPEND;
-               if (hcd->remote_wakeup)
-                       val |= HCCONTROL_RWE;
-               /* Wait for usb transfers to finish */
-               mdelay(2);
-               isp116x_write_reg32(isp116x, HCCONTROL, val);
-               hcd->state = HC_STATE_SUSPENDED;
-               /* Wait for devices to suspend */
-               mdelay(5);
-       case HCCONTROL_USB_SUSPEND:
-               break;
-       case HCCONTROL_USB_RESUME:
-               isp116x_write_reg32(isp116x, HCCONTROL,
-                                   (val & ~HCCONTROL_HCFS) |
-                                   HCCONTROL_USB_RESET);
-       case HCCONTROL_USB_RESET:
-               ret = -EBUSY;
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       spin_unlock_irqrestore(&isp116x->lock, flags);
-       return ret;
-}
-
-static int isp116x_bus_resume(struct usb_hcd *hcd)
-{
-       struct isp116x *isp116x = hcd_to_isp116x(hcd);
-       u32 val;
-       int ret = -EINPROGRESS;
-
-       msleep(5);
-       spin_lock_irq(&isp116x->lock);
-
-       val = isp116x_read_reg32(isp116x, HCCONTROL);
-       switch (val & HCCONTROL_HCFS) {
-       case HCCONTROL_USB_SUSPEND:
-               val &= ~HCCONTROL_HCFS;
-               val |= HCCONTROL_USB_RESUME;
-               isp116x_write_reg32(isp116x, HCCONTROL, val);
-       case HCCONTROL_USB_RESUME:
-               break;
-       case HCCONTROL_USB_OPER:
-               /* Without setting power_state here the
-                  SUSPENDED state won't be removed from
-                  sysfs/usbN/power.state as a response to remote
-                  wakeup. Maybe in the future. */
-               hcd->self.root_hub->dev.power.power_state = PMSG_ON;
-               ret = 0;
-               break;
-       default:
-               ret = -EBUSY;
-       }
-
-       if (ret != -EINPROGRESS) {
-               spin_unlock_irq(&isp116x->lock);
-               return ret;
-       }
-
-       val = isp116x->rhdesca & RH_A_NDP;
-       while (val--) {
-               u32 stat =
-                   isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
-               /* force global, not selective, resume */
-               if (!(stat & RH_PS_PSS))
-                       continue;
-               DBG("%s: Resuming port %d\n", __func__, val);
-               isp116x_write_reg32(isp116x, RH_PS_POCI, val
-                                   ? HCRHPORT2 : HCRHPORT1);
-       }
-       spin_unlock_irq(&isp116x->lock);
-
-       hcd->state = HC_STATE_RESUMING;
-       mdelay(20);
-
-       /* Go operational */
-       spin_lock_irq(&isp116x->lock);
-       val = isp116x_read_reg32(isp116x, HCCONTROL);
-       isp116x_write_reg32(isp116x, HCCONTROL,
-                           (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
-       spin_unlock_irq(&isp116x->lock);
-       /* see analogous comment above */
-       hcd->self.root_hub->dev.power.power_state = PMSG_ON;
-       hcd->state = HC_STATE_RUNNING;
-
-       return 0;
-}
-
-
-#else
-
-#define        isp116x_bus_suspend     NULL
-#define        isp116x_bus_resume      NULL
-
-#endif
-
 /*-----------------------------------------------------------------*/
 
-#ifdef STUB_DEBUG_FILE
-
-static inline void create_debug_file(struct isp116x *isp116x)
-{
-}
-
-static inline void remove_debug_file(struct isp116x *isp116x)
-{
-}
-
-#else
-
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#ifdef CONFIG_DEBUG_FS
 
 static void dump_irq(struct seq_file *s, char *label, u16 mask)
 {
@@ -1311,13 +1174,9 @@ static void dump_int(struct seq_file *s, char *label, u32 mask)
                   mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : "");
 }
 
-static int proc_isp116x_show(struct seq_file *s, void *unused)
+static int isp116x_show_dbg(struct seq_file *s, void *unused)
 {
        struct isp116x *isp116x = s->private;
-       struct isp116x_ep *ep;
-       struct urb *urb;
-       unsigned i;
-       char *str;
 
        seq_printf(s, "%s\n%s version %s\n",
                   isp116x_to_hcd(isp116x)->product_desc, hcd_name,
@@ -1333,105 +1192,50 @@ static int proc_isp116x_show(struct seq_file *s, void *unused)
        }
 
        spin_lock_irq(&isp116x->lock);
-
        dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB));
        dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT));
        dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB));
        dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT));
-
-       list_for_each_entry(ep, &isp116x->async, schedule) {
-
-               switch (ep->nextpid) {
-               case USB_PID_IN:
-                       str = "in";
-                       break;
-               case USB_PID_OUT:
-                       str = "out";
-                       break;
-               case USB_PID_SETUP:
-                       str = "setup";
-                       break;
-               case USB_PID_ACK:
-                       str = "status";
-                       break;
-               default:
-                       str = "?";
-                       break;
-               };
-               seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep,
-                          ep->epnum, str, ep->maxpacket);
-               list_for_each_entry(urb, &ep->hep->urb_list, urb_list) {
-                       seq_printf(s, "  urb%p, %d/%d\n", urb,
-                                  urb->actual_length,
-                                  urb->transfer_buffer_length);
-               }
-       }
-       if (!list_empty(&isp116x->async))
-               seq_printf(s, "\n");
-
-       seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE);
-
-       for (i = 0; i < PERIODIC_SIZE; i++) {
-               ep = isp116x->periodic[i];
-               if (!ep)
-                       continue;
-               seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]);
-
-               /* DUMB: prints shared entries multiple times */
-               do {
-                       seq_printf(s, "   %d/%p (%sdev%d ep%d%s max %d)\n",
-                                  ep->period, ep,
-                                  (ep->udev->speed ==
-                                   USB_SPEED_FULL) ? "" : "ls ",
-                                  ep->udev->devnum, ep->epnum,
-                                  (ep->epnum ==
-                                   0) ? "" : ((ep->nextpid ==
-                                               USB_PID_IN) ? "in" : "out"),
-                                  ep->maxpacket);
-                       ep = ep->next;
-               } while (ep);
-       }
+       isp116x_show_regs_seq(isp116x, s);
        spin_unlock_irq(&isp116x->lock);
        seq_printf(s, "\n");
 
        return 0;
 }
 
-static int proc_isp116x_open(struct inode *inode, struct file *file)
+static int isp116x_open_seq(struct inode *inode, struct file *file)
 {
-       return single_open(file, proc_isp116x_show, PDE(inode)->data);
+       return single_open(file, isp116x_show_dbg, inode->u.generic_ip);
 }
 
-static struct file_operations proc_ops = {
-       .open = proc_isp116x_open,
+static struct file_operations isp116x_debug_fops = {
+       .open = isp116x_open_seq,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
 };
 
-/* expect just one isp116x per system */
-static const char proc_filename[] = "driver/isp116x";
-
-static void create_debug_file(struct isp116x *isp116x)
+static int create_debug_file(struct isp116x *isp116x)
 {
-       struct proc_dir_entry *pde;
-
-       pde = create_proc_entry(proc_filename, 0, NULL);
-       if (pde == NULL)
-               return;
-
-       pde->proc_fops = &proc_ops;
-       pde->data = isp116x;
-       isp116x->pde = pde;
+       isp116x->dentry = debugfs_create_file(hcd_name,
+                                             S_IRUGO, NULL, isp116x,
+                                             &isp116x_debug_fops);
+       if (!isp116x->dentry)
+               return -ENOMEM;
+       return 0;
 }
 
 static void remove_debug_file(struct isp116x *isp116x)
 {
-       if (isp116x->pde)
-               remove_proc_entry(proc_filename, NULL);
+       debugfs_remove(isp116x->dentry);
 }
 
-#endif
+#else
+
+#define        create_debug_file(d)    0
+#define        remove_debug_file(d)    do{}while(0)
+
+#endif                         /* CONFIG_DEBUG_FS */
 
 /*-----------------------------------------------------------------*/
 
@@ -1466,7 +1270,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
        struct isp116x *isp116x = hcd_to_isp116x(hcd);
        unsigned long t;
        u16 clkrdy = 0;
-       int ret = 0, timeout = 15 /* ms */ ;
+       int ret, timeout = 15 /* ms */ ;
 
        ret = isp116x_sw_reset(isp116x);
        if (ret)
@@ -1482,7 +1286,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
                        break;
        }
        if (!clkrdy) {
-               ERR("Clock not ready after 20ms\n");
+               ERR("Clock not ready after %dms\n", timeout);
                /* After sw_reset the clock won't report to be ready, if
                   H_WAKEUP pin is high. */
                ERR("Please make sure that the H_WAKEUP pin is pulled low!\n");
@@ -1572,7 +1376,8 @@ static int isp116x_start(struct usb_hcd *hcd)
 
        val = 0;
        if (board->remote_wakeup_enable) {
-               hcd->can_wakeup = 1;
+               if (!device_can_wakeup(hcd->self.controller))
+                       device_init_wakeup(hcd->self.controller, 1);
                val |= RH_HS_DRWE;
        }
        isp116x_write_reg32(isp116x, HCRHSTATUS, val);
@@ -1600,12 +1405,126 @@ static int isp116x_start(struct usb_hcd *hcd)
        isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
        isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
 
-       isp116x_show_regs(isp116x);
+       isp116x_show_regs_log(isp116x);
        spin_unlock_irqrestore(&isp116x->lock, flags);
        return 0;
 }
 
-/*-----------------------------------------------------------------*/
+#ifdef CONFIG_PM
+
+static int isp116x_bus_suspend(struct usb_hcd *hcd)
+{
+       struct isp116x *isp116x = hcd_to_isp116x(hcd);
+       unsigned long flags;
+       u32 val;
+       int ret = 0;
+
+       spin_lock_irqsave(&isp116x->lock, flags);
+
+       val = isp116x_read_reg32(isp116x, HCCONTROL);
+       switch (val & HCCONTROL_HCFS) {
+       case HCCONTROL_USB_OPER:
+               val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
+               val |= HCCONTROL_USB_SUSPEND;
+               if (device_may_wakeup(&hcd->self.root_hub->dev))
+                       val |= HCCONTROL_RWE;
+               /* Wait for usb transfers to finish */
+               mdelay(2);
+               isp116x_write_reg32(isp116x, HCCONTROL, val);
+               /* Wait for devices to suspend */
+               mdelay(5);
+       case HCCONTROL_USB_SUSPEND:
+               break;
+       case HCCONTROL_USB_RESUME:
+               isp116x_write_reg32(isp116x, HCCONTROL,
+                                   (val & ~HCCONTROL_HCFS) |
+                                   HCCONTROL_USB_RESET);
+       case HCCONTROL_USB_RESET:
+               ret = -EBUSY;
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       spin_unlock_irqrestore(&isp116x->lock, flags);
+       return ret;
+}
+
+static int isp116x_bus_resume(struct usb_hcd *hcd)
+{
+       struct isp116x *isp116x = hcd_to_isp116x(hcd);
+       u32 val;
+
+       msleep(5);
+       spin_lock_irq(&isp116x->lock);
+
+       val = isp116x_read_reg32(isp116x, HCCONTROL);
+       switch (val & HCCONTROL_HCFS) {
+       case HCCONTROL_USB_SUSPEND:
+               val &= ~HCCONTROL_HCFS;
+               val |= HCCONTROL_USB_RESUME;
+               isp116x_write_reg32(isp116x, HCCONTROL, val);
+       case HCCONTROL_USB_RESUME:
+               break;
+       case HCCONTROL_USB_OPER:
+               spin_unlock_irq(&isp116x->lock);
+               /* Without setting power_state here the
+                  SUSPENDED state won't be removed from
+                  sysfs/usbN/power.state as a response to remote
+                  wakeup. Maybe in the future. */
+               hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+               return 0;
+       default:
+               /* HCCONTROL_USB_RESET: this may happen, when during
+                  suspension the HC lost power. Reinitialize completely */
+               spin_unlock_irq(&isp116x->lock);
+               DBG("Chip has been reset while suspended. Reinit from scratch.\n");
+               isp116x_reset(hcd);
+               isp116x_start(hcd);
+               isp116x_hub_control(hcd, SetPortFeature,
+                                   USB_PORT_FEAT_POWER, 1, NULL, 0);
+               if ((isp116x->rhdesca & RH_A_NDP) == 2)
+                       isp116x_hub_control(hcd, SetPortFeature,
+                                           USB_PORT_FEAT_POWER, 2, NULL, 0);
+               hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+               return 0;
+       }
+
+       val = isp116x->rhdesca & RH_A_NDP;
+       while (val--) {
+               u32 stat =
+                   isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
+               /* force global, not selective, resume */
+               if (!(stat & RH_PS_PSS))
+                       continue;
+               DBG("%s: Resuming port %d\n", __func__, val);
+               isp116x_write_reg32(isp116x, RH_PS_POCI, val
+                                   ? HCRHPORT2 : HCRHPORT1);
+       }
+       spin_unlock_irq(&isp116x->lock);
+
+       hcd->state = HC_STATE_RESUMING;
+       msleep(20);
+
+       /* Go operational */
+       spin_lock_irq(&isp116x->lock);
+       val = isp116x_read_reg32(isp116x, HCCONTROL);
+       isp116x_write_reg32(isp116x, HCCONTROL,
+                           (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
+       spin_unlock_irq(&isp116x->lock);
+       /* see analogous comment above */
+       hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+       hcd->state = HC_STATE_RUNNING;
+
+       return 0;
+}
+
+#else
+
+#define        isp116x_bus_suspend     NULL
+#define        isp116x_bus_resume      NULL
+
+#endif
 
 static struct hc_driver isp116x_hc_driver = {
        .description = hcd_name,
@@ -1735,12 +1654,19 @@ static int __init isp116x_probe(struct platform_device *pdev)
        }
 
        ret = usb_add_hcd(hcd, irq, SA_INTERRUPT);
-       if (ret != 0)
+       if (ret)
                goto err6;
 
-       create_debug_file(isp116x);
+       ret = create_debug_file(isp116x);
+       if (ret) {
+               ERR("Couldn't create debugfs entry\n");
+               goto err7;
+       }
+
        return 0;
 
+      err7:
+       usb_remove_hcd(hcd);
       err6:
        usb_put_hcd(hcd);
       err5:
@@ -1762,13 +1688,9 @@ static int __init isp116x_probe(struct platform_device *pdev)
 */
 static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
 {
-       int ret = 0;
-
-       VDBG("%s: state %x\n", __func__, state);
-
+       VDBG("%s: state %x\n", __func__, state.event);
        dev->dev.power.power_state = state;
-
-       return ret;
+       return 0;
 }
 
 /*
@@ -1776,13 +1698,9 @@ static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
 */
 static int isp116x_resume(struct platform_device *dev)
 {
-       int ret = 0;
-
-       VDBG("%s:  state %x\n", __func__, dev->dev.power.power_state);
-
+       VDBG("%s:  state %x\n", __func__, dev->power.power_state.event);
        dev->dev.power.power_state = PMSG_ON;
-
-       return ret;
+       return 0;
 }
 
 #else
index c6fec96..a1b7c38 100644 (file)
@@ -259,7 +259,7 @@ struct isp116x {
 
        struct isp116x_platform_data *board;
 
-       struct proc_dir_entry *pde;
+       struct dentry *dentry;
        unsigned long stat1, stat2, stat4, stat8, stat16;
 
        /* HC registers */
@@ -450,7 +450,7 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg,
        isp116x_write_data32(isp116x, (u32) val);
 }
 
-#define isp116x_show_reg(d,r) {                                        \
+#define isp116x_show_reg_log(d,r,s) {                          \
        if ((r) < 0x20) {                                       \
                DBG("%-12s[%02x]: %08x\n", #r,                  \
                        r, isp116x_read_reg32(d, r));           \
@@ -459,35 +459,60 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg,
                        r, isp116x_read_reg16(d, r));           \
        }                                                       \
 }
+#define isp116x_show_reg_seq(d,r,s) {                          \
+       if ((r) < 0x20) {                                       \
+               seq_printf(s, "%-12s[%02x]: %08x\n", #r,        \
+                       r, isp116x_read_reg32(d, r));           \
+       } else {                                                \
+               seq_printf(s, "%-12s[%02x]:     %04x\n", #r,    \
+                       r, isp116x_read_reg16(d, r));           \
+       }                                                       \
+}
 
-static inline void isp116x_show_regs(struct isp116x *isp116x)
+#define isp116x_show_regs(d,type,s) {                  \
+       isp116x_show_reg_##type(d, HCREVISION, s);      \
+       isp116x_show_reg_##type(d, HCCONTROL, s);       \
+       isp116x_show_reg_##type(d, HCCMDSTAT, s);       \
+       isp116x_show_reg_##type(d, HCINTSTAT, s);       \
+       isp116x_show_reg_##type(d, HCINTENB, s);        \
+       isp116x_show_reg_##type(d, HCFMINTVL, s);       \
+       isp116x_show_reg_##type(d, HCFMREM, s);         \
+       isp116x_show_reg_##type(d, HCFMNUM, s);         \
+       isp116x_show_reg_##type(d, HCLSTHRESH, s);      \
+       isp116x_show_reg_##type(d, HCRHDESCA, s);       \
+       isp116x_show_reg_##type(d, HCRHDESCB, s);       \
+       isp116x_show_reg_##type(d, HCRHSTATUS, s);      \
+       isp116x_show_reg_##type(d, HCRHPORT1, s);       \
+       isp116x_show_reg_##type(d, HCRHPORT2, s);       \
+       isp116x_show_reg_##type(d, HCHWCFG, s);         \
+       isp116x_show_reg_##type(d, HCDMACFG, s);        \
+       isp116x_show_reg_##type(d, HCXFERCTR, s);       \
+       isp116x_show_reg_##type(d, HCuPINT, s);         \
+       isp116x_show_reg_##type(d, HCuPINTENB, s);      \
+       isp116x_show_reg_##type(d, HCCHIPID, s);        \
+       isp116x_show_reg_##type(d, HCSCRATCH, s);       \
+       isp116x_show_reg_##type(d, HCITLBUFLEN, s);     \
+       isp116x_show_reg_##type(d, HCATLBUFLEN, s);     \
+       isp116x_show_reg_##type(d, HCBUFSTAT, s);       \
+       isp116x_show_reg_##type(d, HCRDITL0LEN, s);     \
+       isp116x_show_reg_##type(d, HCRDITL1LEN, s);     \
+}
+
+/*
+   Dump registers for debugfs.
+*/
+static inline void isp116x_show_regs_seq(struct isp116x *isp116x,
+                                         struct seq_file *s)
+{
+       isp116x_show_regs(isp116x, seq, s);
+}
+
+/*
+   Dump registers to syslog.
+*/
+static inline void isp116x_show_regs_log(struct isp116x *isp116x)
 {
-       isp116x_show_reg(isp116x, HCREVISION);
-       isp116x_show_reg(isp116x, HCCONTROL);
-       isp116x_show_reg(isp116x, HCCMDSTAT);
-       isp116x_show_reg(isp116x, HCINTSTAT);
-       isp116x_show_reg(isp116x, HCINTENB);
-       isp116x_show_reg(isp116x, HCFMINTVL);
-       isp116x_show_reg(isp116x, HCFMREM);
-       isp116x_show_reg(isp116x, HCFMNUM);
-       isp116x_show_reg(isp116x, HCLSTHRESH);
-       isp116x_show_reg(isp116x, HCRHDESCA);
-       isp116x_show_reg(isp116x, HCRHDESCB);
-       isp116x_show_reg(isp116x, HCRHSTATUS);
-       isp116x_show_reg(isp116x, HCRHPORT1);
-       isp116x_show_reg(isp116x, HCRHPORT2);
-       isp116x_show_reg(isp116x, HCHWCFG);
-       isp116x_show_reg(isp116x, HCDMACFG);
-       isp116x_show_reg(isp116x, HCXFERCTR);
-       isp116x_show_reg(isp116x, HCuPINT);
-       isp116x_show_reg(isp116x, HCuPINTENB);
-       isp116x_show_reg(isp116x, HCCHIPID);
-       isp116x_show_reg(isp116x, HCSCRATCH);
-       isp116x_show_reg(isp116x, HCITLBUFLEN);
-       isp116x_show_reg(isp116x, HCATLBUFLEN);
-       isp116x_show_reg(isp116x, HCBUFSTAT);
-       isp116x_show_reg(isp116x, HCRDITL0LEN);
-       isp116x_show_reg(isp116x, HCRDITL1LEN);
+       isp116x_show_regs(isp116x, log, NULL);
 }
 
 #if defined(URB_TRACE)
index bf1d9ab..a4b1240 100644 (file)
  */
  
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#      define DEBUG
-#else
-#      undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
@@ -802,7 +795,6 @@ static int ohci_restart (struct ohci_hcd *ohci)
        int temp;
        int i;
        struct urb_priv *priv;
-       struct usb_device *root = ohci_to_hcd(ohci)->self.root_hub;
 
        /* mark any devices gone, so they do nothing till khubd disconnects.
         * recycle any "live" eds/tds (and urbs) right away.
@@ -811,11 +803,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
         */ 
        spin_lock_irq(&ohci->lock);
        disable (ohci);
-       for (i = 0; i < root->maxchild; i++) {
-               if (root->children [i])
-                       usb_set_device_state (root->children[i],
-                               USB_STATE_NOTATTACHED);
-       }
+       usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub);
        if (!list_empty (&ohci->pending))
                ohci_dbg(ohci, "abort schedule...\n");
        list_for_each_entry (priv, &ohci->pending, pending) {
index 72e3b12..4b2226d 100644 (file)
@@ -372,7 +372,7 @@ done:
                                        & ohci->hc_control)
                                == OHCI_USB_OPER
                        && time_after (jiffies, ohci->next_statechange)
-                       && usb_trylock_device (hcd->self.root_hub)
+                       && usb_trylock_device (hcd->self.root_hub) == 0
                        ) {
                ohci_vdbg (ohci, "autosuspend\n");
                (void) ohci_bus_suspend (hcd);
index 9d65ec3..acde886 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
-
-
-#define PMM_NPS_MODE           1
-#define PMM_GLOBAL_MODE        2
-#define PMM_PERPORT_MODE       3
+#include <asm/arch/ohci.h>
 
 #define PXA_UHC_MAX_PORTNUM    3
 
 #define UHCRHPS(x)              __REG2( 0x4C000050, (x)<<2 )
 
-static int pxa27x_ohci_pmm_state;
-
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
       Ports are powered continuously.
@@ -50,8 +44,6 @@ static int pxa27x_ohci_pmm_state;
  */
 static int pxa27x_ohci_select_pmm( int mode )
 {
-       pxa27x_ohci_pmm_state = mode;
-
        switch ( mode ) {
        case PMM_NPS_MODE:
                UHCRHDA |= RH_A_NPS;
@@ -71,7 +63,6 @@ static int pxa27x_ohci_select_pmm( int mode )
                        "Invalid mode %d, set to non-power switch mode.\n", 
                        mode );
 
-               pxa27x_ohci_pmm_state = PMM_NPS_MODE;
                UHCRHDA |= RH_A_NPS;
        }
 
@@ -82,8 +73,13 @@ extern int usb_disabled(void);
 
 /*-------------------------------------------------------------------------*/
 
-static void pxa27x_start_hc(struct platform_device *dev)
+static int pxa27x_start_hc(struct device *dev)
 {
+       int retval = 0;
+       struct pxaohci_platform_data *inf;
+
+       inf = dev->platform_data;
+
        pxa_set_cken(CKEN10_USBHOST, 1);
 
        UHCHR |= UHCHR_FHR;
@@ -94,21 +90,11 @@ static void pxa27x_start_hc(struct platform_device *dev)
        while (UHCHR & UHCHR_FSBIR)
                cpu_relax();
 
-       /* This could be properly abstracted away through the
-          device data the day more machines are supported and
-          their differences can be figured out correctly. */
-       if (machine_is_mainstone()) {
-               /* setup Port1 GPIO pin. */
-               pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);  /* USBHPWR1 */
-               pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
-
-               /* Set the Power Control Polarity Low and Power Sense
-                  Polarity Low to active low. Supply power to USB ports. */
-               UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
-                       ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+       if (inf->init)
+               retval = inf->init(dev);
 
-               pxa27x_ohci_pmm_state = PMM_PERPORT_MODE;
-       }
+       if (retval < 0)
+               return retval;
 
        UHCHR &= ~UHCHR_SSE;
 
@@ -117,10 +103,19 @@ static void pxa27x_start_hc(struct platform_device *dev)
        /* Clear any OTG Pin Hold */
        if (PSSR & PSSR_OTGPH)
                PSSR |= PSSR_OTGPH;
+
+       return 0;
 }
 
-static void pxa27x_stop_hc(struct platform_device *dev)
+static void pxa27x_stop_hc(struct device *dev)
 {
+       struct pxaohci_platform_data *inf;
+
+       inf = dev->platform_data;
+
+       if (inf->exit)
+               inf->exit(dev);
+
        UHCHR |= UHCHR_FHR;
        udelay(11);
        UHCHR &= ~UHCHR_FHR;
@@ -147,22 +142,27 @@ static void pxa27x_stop_hc(struct platform_device *dev)
  * through the hotplug entry's driver_data.
  *
  */
-int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
-                         struct platform_device *dev)
+int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
 {
        int retval;
        struct usb_hcd *hcd;
+       struct pxaohci_platform_data *inf;
 
-       if (dev->resource[1].flags != IORESOURCE_IRQ) {
+       inf = pdev->dev.platform_data;
+
+       if (!inf)
+               return -ENODEV;
+
+       if (pdev->resource[1].flags != IORESOURCE_IRQ) {
                pr_debug ("resource[1] is not IORESOURCE_IRQ");
                return -ENOMEM;
        }
 
-       hcd = usb_create_hcd (driver, &dev->dev, "pxa27x");
+       hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
        if (!hcd)
                return -ENOMEM;
-       hcd->rsrc_start = dev->resource[0].start;
-       hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+       hcd->rsrc_start = pdev->resource[0].start;
+       hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
 
        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
                pr_debug("request_mem_region failed");
@@ -177,18 +177,22 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
                goto err2;
        }
 
-       pxa27x_start_hc(dev);
+       if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) {
+               pr_debug("pxa27x_start_hc failed");
+               goto err3;
+       }
 
        /* Select Power Management Mode */
-       pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state);
+       pxa27x_ohci_select_pmm(inf->port_mode);
 
        ohci_hcd_init(hcd_to_ohci(hcd));
 
-       retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
+       retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
        if (retval == 0)
                return retval;
 
-       pxa27x_stop_hc(dev);
+       pxa27x_stop_hc(&pdev->dev);
+ err3:
        iounmap(hcd->regs);
  err2:
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -211,10 +215,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
  * context, normally "rmmod", "apmd", or something similar.
  *
  */
-void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev)
+void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
        usb_remove_hcd(hcd);
-       pxa27x_stop_hc(dev);
+       pxa27x_stop_hc(&pdev->dev);
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
@@ -292,15 +296,12 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
 
 static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
 {
-       int ret;
-
        pr_debug ("In ohci_hcd_pxa27x_drv_probe");
 
        if (usb_disabled())
                return -ENODEV;
 
-       ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
-       return ret;
+       return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
 }
 
 static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
@@ -308,31 +309,55 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
        usb_hcd_pxa27x_remove(hcd, pdev);
+       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_PM
+static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state)
 {
-//     struct usb_hcd *hcd = platform_get_drvdata(dev);
-       printk("%s: not implemented yet\n", __FUNCTION__);
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+       if (time_before(jiffies, ohci->next_statechange))
+               msleep(5);
+       ohci->next_statechange = jiffies;
+
+       pxa27x_stop_hc(&pdev->dev);
+       hcd->state = HC_STATE_SUSPENDED;
+       pdev->dev.power.power_state = PMSG_SUSPEND;
 
        return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev)
+static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
 {
-//     struct usb_hcd *hcd = platform_get_drvdata(dev);
-       printk("%s: not implemented yet\n", __FUNCTION__);
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       int status;
+
+       if (time_before(jiffies, ohci->next_statechange))
+               msleep(5);
+       ohci->next_statechange = jiffies;
+
+       if ((status = pxa27x_start_hc(&pdev->dev)) < 0)
+               return status;
+
+       pdev->dev.power.power_state = PMSG_ON;
+       usb_hcd_resume_root_hub(hcd);
 
        return 0;
 }
+#endif
 
 
 static struct platform_driver ohci_hcd_pxa27x_driver = {
        .probe          = ohci_hcd_pxa27x_drv_probe,
        .remove         = ohci_hcd_pxa27x_drv_remove,
+#ifdef CONFIG_PM
        .suspend        = ohci_hcd_pxa27x_drv_suspend, 
        .resume         = ohci_hcd_pxa27x_drv_resume,
+#endif
        .driver         = {
                .name   = "pxa27x-ohci",
        },
index e46528c..3ef2c0c 100644 (file)
@@ -9,12 +9,6 @@
  */
 
 #include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#else
-#undef DEBUG
-#endif
-
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
index a7722a6..517360b 100644 (file)
 #undef PACKET_TRACE
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#      define DEBUG
-#else
-#      undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -1581,7 +1574,9 @@ sl811h_start(struct usb_hcd *hcd)
        hcd->state = HC_STATE_RUNNING;
 
        if (sl811->board) {
-               hcd->can_wakeup = sl811->board->can_wakeup;
+               if (!device_can_wakeup(hcd->self.controller))
+                       device_init_wakeup(hcd->self.controller,
+                               sl811->board->can_wakeup);
                hcd->power_budget = sl811->board->power * 2;
        }
 
@@ -1805,9 +1800,10 @@ sl811h_resume(struct platform_device *dev)
         * let's assume it'd only be powered to enable remote wakeup.
         */
        if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND
-                       || !hcd->can_wakeup) {
+                       || !device_can_wakeup(&hcd->self.root_hub->dev)) {
                sl811->port1 = 0;
                port_power(sl811, 1);
+               usb_root_hub_lost_power(hcd->self.root_hub);
                return 0;
        }
 
index e73faf8..5056b74 100644 (file)
@@ -38,7 +38,7 @@ MODULE_LICENSE("GPL");
 /* MACROS                                                             */
 /*====================================================================*/
 
-#if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG)
+#if defined(DEBUG) || defined(PCMCIA_DEBUG)
 
 static int pc_debug = 0;
 module_param(pc_debug, int, 0644);
@@ -129,7 +129,8 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
        resources[2].end   = base_addr + 1;
 
        /* The driver core will probe for us.  We know sl811-hcd has been
-        * initialized already because of the link order dependency.
+        * initialized already because of the link order dependency created
+        * by referencing "sl811h_driver".
         */
        platform_dev.name = sl811h_driver.name;
        return platform_device_register(&platform_dev);
index 151154d..5832953 100644 (file)
@@ -2,8 +2,8 @@
  * UHCI-specific debugging code. Invaluable when something
  * goes wrong, but don't get in my face.
  *
- * Kernel visible pointers are surrounded in []'s and bus
- * visible pointers are surrounded in ()'s
+ * Kernel visible pointers are surrounded in []s and bus
+ * visible pointers are surrounded in ()s
  *
  * (C) Copyright 1999 Linus Torvalds
  * (C) Copyright 1999-2001 Johannes Erdfelt
@@ -19,7 +19,7 @@
 
 static struct dentry *uhci_debugfs_root = NULL;
 
-/* Handle REALLY large printk's so we don't overflow buffers */
+/* Handle REALLY large printks so we don't overflow buffers */
 static inline void lprintk(char *buf)
 {
        char *p;
@@ -160,7 +160,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
                        }
 
                        if (active && ni > i) {
-                               out += sprintf(out, "%*s[skipped %d active TD's]\n", space, "", ni - i);
+                               out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i);
                                tmp = ntmp;
                                td = ntd;
                                i = ni;
@@ -173,7 +173,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
        if (list_empty(&urbp->queue_list) || urbp->queued)
                goto out;
 
-       out += sprintf(out, "%*sQueued QH's:\n", -space, "--");
+       out += sprintf(out, "%*sQueued QHs:\n", -space, "--");
 
        head = &urbp->queue_list;
        tmp = head->next;
@@ -197,7 +197,7 @@ out:
        }
 
 #ifdef CONFIG_PROC_FS
-static const char *qh_names[] = {
+static const char * const qh_names[] = {
   "skel_int128_qh", "skel_int64_qh",
   "skel_int32_qh", "skel_int16_qh",
   "skel_int8_qh", "skel_int4_qh",
@@ -464,7 +464,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
                } while (tmp != head);
        }
 
-       out += sprintf(out, "Skeleton QH's\n");
+       out += sprintf(out, "Skeleton QHs\n");
 
        for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
                int shown = 0;
index 79efaf7..dfe121d 100644 (file)
  */
 
 #include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#else
-#undef DEBUG
-#endif
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -67,10 +62,10 @@ Alan Stern"
 
 /*
  * debug = 0, no debugging messages
- * debug = 1, dump failed URB's except for stalls
- * debug = 2, dump all failed URB's (including stalls)
+ * debug = 1, dump failed URBs except for stalls
+ * debug = 2, dump all failed URBs (including stalls)
  *            show all queues in /debug/uhci/[pci_addr]
- * debug = 3, show all TD's in URB's when dumping
+ * debug = 3, show all TDs in URBs when dumping
  */
 #ifdef DEBUG
 static int debug = 1;
@@ -93,7 +88,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
 #define FSBR_DELAY     msecs_to_jiffies(50)
 
 /* When we timeout an idle transfer for FSBR, we'll switch it over to */
-/* depth first traversal. We'll do it in groups of this number of TD's */
+/* depth first traversal. We'll do it in groups of this number of TDs */
 /* to make sure it doesn't hog all of the bandwidth */
 #define DEPTH_INTERVAL 5
 
@@ -478,8 +473,6 @@ static int uhci_start(struct usb_hcd *hcd)
        struct dentry *dentry;
 
        hcd->uses_new_polling = 1;
-       if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM))
-               hcd->can_wakeup = 1;            /* Assume it supports PME# */
 
        dentry = debugfs_create_file(hcd->self.bus_name,
                        S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci,
@@ -573,7 +566,7 @@ static int uhci_start(struct usb_hcd *hcd)
        uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH;
 
        /* This dummy TD is to work around a bug in Intel PIIX controllers */
-       uhci_fill_td(uhci->term_td, 0, (UHCI_NULL_DATA_SIZE << 21) |
+       uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
                (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
        uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle);
 
@@ -735,8 +728,9 @@ static int uhci_resume(struct usb_hcd *hcd)
 
        dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
 
-       /* We aren't in D3 state anymore, we do that even if dead as I
-        * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0
+       /* Since we aren't in D3 any more, it's safe to set this flag
+        * even if the controller was dead.  It might not even be dead
+        * any more, if the firmware or quirks code has reset it.
         */
        set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
        mb();
@@ -755,8 +749,12 @@ static int uhci_resume(struct usb_hcd *hcd)
        check_and_reset_hc(uhci);
        configure_hc(uhci);
 
-       if (uhci->rh_state == UHCI_RH_RESET)
+       if (uhci->rh_state == UHCI_RH_RESET) {
+
+               /* The controller had to be reset */
+               usb_root_hub_lost_power(hcd->self.root_hub);
                suspend_rh(uhci, UHCI_RH_SUSPENDED);
+       }
 
        spin_unlock_irq(&uhci->lock);
 
@@ -882,7 +880,7 @@ static int __init uhci_hcd_init(void)
 
 init_failed:
        if (kmem_cache_destroy(uhci_up_cachep))
-               warn("not all urb_priv's were freed!");
+               warn("not all urb_privs were freed!");
 
 up_failed:
        debugfs_remove(uhci_debugfs_root);
@@ -900,7 +898,7 @@ static void __exit uhci_hcd_cleanup(void)
        pci_unregister_driver(&uhci_pci_driver);
        
        if (kmem_cache_destroy(uhci_up_cachep))
-               warn("not all urb_priv's were freed!");
+               warn("not all urb_privs were freed!");
 
        debugfs_remove(uhci_debugfs_root);
        kfree(errbuf);
index e576db5..8b4b887 100644 (file)
@@ -71,8 +71,6 @@
 #define   USBLEGSUP_RWC                0x8f00  /* the R/WC bits */
 #define   USBLEGSUP_RO         0x5040  /* R/O and reserved bits */
 
-#define UHCI_NULL_DATA_SIZE    0x7FF   /* for UHCI controller TD */
-
 #define UHCI_PTR_BITS          cpu_to_le32(0x000F)
 #define UHCI_PTR_TERM          cpu_to_le32(0x0001)
 #define UHCI_PTR_QH            cpu_to_le32(0x0002)
@@ -168,9 +166,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) {
 #define TD_TOKEN_EXPLEN_MASK   0x7FF           /* expected length, encoded as n - 1 */
 #define TD_TOKEN_PID_MASK      0xFF
 
-#define uhci_explen(len)       ((len) << TD_TOKEN_EXPLEN_SHIFT)
+#define uhci_explen(len)       ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \
+                                       TD_TOKEN_EXPLEN_SHIFT)
 
-#define uhci_expected_length(token) ((((token) >> 21) + 1) & TD_TOKEN_EXPLEN_MASK)
+#define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \
+                                       1) & TD_TOKEN_EXPLEN_MASK)
 #define uhci_toggle(token)     (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1)
 #define uhci_endpoint(token)   (((token) >> 15) & 0xf)
 #define uhci_devaddr(token)    (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f)
@@ -223,10 +223,10 @@ static u32 inline td_status(struct uhci_td *td) {
  */
 
 /*
- * The UHCI driver places Interrupt, Control and Bulk into QH's both
- * to group together TD's for one transfer, and also to faciliate queuing
- * of URB's. To make it easy to insert entries into the schedule, we have
- * a skeleton of QH's for each predefined Interrupt latency, low-speed
+ * The UHCI driver places Interrupt, Control and Bulk into QHs both
+ * to group together TDs for one transfer, and also to facilitate queuing
+ * of URBs. To make it easy to insert entries into the schedule, we have
+ * a skeleton of QHs for each predefined Interrupt latency, low-speed
  * control, full-speed control and terminating QH (see explanation for
  * the terminating QH below).
  *
@@ -257,8 +257,8 @@ static u32 inline td_status(struct uhci_td *td) {
  *   reclamation.
  *
  * Isochronous transfers are stored before the start of the skeleton
- * schedule and don't use QH's. While the UHCI spec doesn't forbid the
- * use of QH's for Isochronous, it doesn't use them either. And the spec
+ * schedule and don't use QHs. While the UHCI spec doesn't forbid the
+ * use of QHs for Isochronous, it doesn't use them either. And the spec
  * says that queues never advance on an error completion status, which
  * makes them totally unsuitable for Isochronous transfers.
  */
@@ -359,7 +359,7 @@ struct uhci_hcd {
        struct dma_pool *td_pool;
 
        struct uhci_td *term_td;        /* Terminating TD, see UHCI bug */
-       struct uhci_qh *skelqh[UHCI_NUM_SKELQH];        /* Skeleton QH's */
+       struct uhci_qh *skelqh[UHCI_NUM_SKELQH];        /* Skeleton QHs */
 
        spinlock_t lock;
 
@@ -389,22 +389,22 @@ struct uhci_hcd {
        unsigned long resuming_ports;
        unsigned long ports_timeout;            /* Time to stop signalling */
 
-       /* Main list of URB's currently controlled by this HC */
+       /* Main list of URBs currently controlled by this HC */
        struct list_head urb_list;
 
-       /* List of QH's that are done, but waiting to be unlinked (race) */
+       /* List of QHs that are done, but waiting to be unlinked (race) */
        struct list_head qh_remove_list;
        unsigned int qh_remove_age;             /* Age in frames */
 
-       /* List of TD's that are done, but waiting to be freed (race) */
+       /* List of TDs that are done, but waiting to be freed (race) */
        struct list_head td_remove_list;
        unsigned int td_remove_age;             /* Age in frames */
 
-       /* List of asynchronously unlinked URB's */
+       /* List of asynchronously unlinked URBs */
        struct list_head urb_remove_list;
        unsigned int urb_remove_age;            /* Age in frames */
 
-       /* List of URB's awaiting completion callback */
+       /* List of URBs awaiting completion callback */
        struct list_head complete_list;
 
        int rh_numports;                        /* Number of root-hub ports */
index 7e46887..b607600 100644 (file)
@@ -80,7 +80,7 @@ static inline void uhci_fill_td(struct uhci_td *td, u32 status,
 }
 
 /*
- * We insert Isochronous URB's directly into the frame list at the beginning
+ * We insert Isochronous URBs directly into the frame list at the beginning
  */
 static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum)
 {
@@ -369,7 +369,7 @@ static void uhci_append_queued_urb(struct uhci_hcd *uhci, struct urb *eurb, stru
                                uhci_fixup_toggle(urb,
                                        uhci_toggle(td_token(lltd)) ^ 1));
 
-       /* All qh's in the queue need to link to the next queue */
+       /* All qhs in the queue need to link to the next queue */
        urbp->qh->link = eurbp->qh->link;
 
        wmb();                  /* Make sure we flush everything */
@@ -502,7 +502,7 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
        }
 
        /* Check to see if the remove list is empty. Set the IOC bit */
-       /* to force an interrupt so we can remove the TD's*/
+       /* to force an interrupt so we can remove the TDs*/
        if (list_empty(&uhci->td_remove_list))
                uhci_set_next_interrupt(uhci);
 
@@ -596,7 +596,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
                return -ENOMEM;
 
        uhci_add_td_to_urb(urb, td);
-       uhci_fill_td(td, status, destination | uhci_explen(7),
+       uhci_fill_td(td, status, destination | uhci_explen(8),
                urb->setup_dma);
 
        /*
@@ -612,7 +612,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
        }
 
        /*
-        * Build the DATA TD's
+        * Build the DATA TDs
         */
        while (len > 0) {
                int pktsze = len;
@@ -628,7 +628,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
                destination ^= TD_TOKEN_TOGGLE;
        
                uhci_add_td_to_urb(urb, td);
-               uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1),
+               uhci_fill_td(td, status, destination | uhci_explen(pktsze),
                        data);
 
                data += pktsze;
@@ -658,7 +658,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
 
        uhci_add_td_to_urb(urb, td);
        uhci_fill_td(td, status | TD_CTRL_IOC,
-               destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0);
+               destination | uhci_explen(0), 0);
 
        qh = uhci_alloc_qh(uhci);
        if (!qh)
@@ -744,7 +744,7 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb)
 
        urb->actual_length = 0;
 
-       /* The rest of the TD's (but the last) are data */
+       /* The rest of the TDs (but the last) are data */
        tmp = tmp->next;
        while (tmp != head && tmp->next != head) {
                unsigned int ctrlstat;
@@ -848,7 +848,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb
                status |= TD_CTRL_SPD;
 
        /*
-        * Build the DATA TD's
+        * Build the DATA TDs
         */
        do {    /* Allow zero length packets */
                int pktsze = maxsze;
@@ -864,7 +864,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb
                        return -ENOMEM;
 
                uhci_add_td_to_urb(urb, td);
-               uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1) |
+               uhci_fill_td(td, status, destination | uhci_explen(pktsze) |
                        (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
                         usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
                        data);
@@ -890,7 +890,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb
                        return -ENOMEM;
 
                uhci_add_td_to_urb(urb, td);
-               uhci_fill_td(td, status, destination | uhci_explen(UHCI_NULL_DATA_SIZE) |
+               uhci_fill_td(td, status, destination | uhci_explen(0) |
                        (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
                         usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
                        data);
@@ -1025,7 +1025,7 @@ static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsig
        list_for_each_entry(up, &uhci->urb_list, urb_list) {
                struct urb *u = up->urb;
 
-               /* look for pending URB's with identical pipe handle */
+               /* look for pending URBs with identical pipe handle */
                if ((urb->pipe == u->pipe) && (urb->dev == u->dev) &&
                    (u->status == -EINPROGRESS) && (u != urb)) {
                        if (!last_urb)
@@ -1092,7 +1092,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb)
                        return -ENOMEM;
 
                uhci_add_td_to_urb(urb, td);
-               uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1),
+               uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length),
                        urb->transfer_dma + urb->iso_frame_desc[i].offset);
 
                if (i + 1 >= urb->number_of_packets)
@@ -1355,7 +1355,7 @@ static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb)
 
        uhci_delete_queued_urb(uhci, urb);
 
-       /* The interrupt loop will reclaim the QH's */
+       /* The interrupt loop will reclaim the QHs */
        uhci_remove_qh(uhci, urbp->qh);
        urbp->qh = NULL;
 }
@@ -1413,7 +1413,7 @@ static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb)
        list_for_each_entry(td, head, list) {
                /*
                 * Make sure we don't do the last one (since it'll have the
-                * TERM bit set) as well as we skip every so many TD's to
+                * TERM bit set) as well as we skip every so many TDs to
                 * make sure it doesn't hog the bandwidth
                 */
                if (td->list.next != head && (count % DEPTH_INTERVAL) ==
index 1d973bc..0498711 100644 (file)
@@ -962,7 +962,6 @@ MODULE_DEVICE_TABLE (usb, mdc800_table);
  */
 static struct usb_driver mdc800_usb_driver =
 {
-       .owner =        THIS_MODULE,
        .name =         "mdc800",
        .probe =        mdc800_usb_probe,
        .disconnect =   mdc800_usb_disconnect,
index 950543a..458f2ac 100644 (file)
@@ -160,7 +160,6 @@ static void mts_usb_disconnect(struct usb_interface *intf);
 static struct usb_device_id mts_usb_ids [];
 
 static struct usb_driver mts_usb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "microtekX6",
        .probe =        mts_usb_probe,
        .disconnect =   mts_usb_disconnect,
index 1e53934..509dd0a 100644 (file)
@@ -273,6 +273,20 @@ config USB_ATI_REMOTE
          To compile this driver as a module, choose M here: the module will be
          called ati_remote.
 
+config USB_ATI_REMOTE2
+       tristate "ATI / Philips USB RF remote control"
+       depends on USB && INPUT
+       ---help---
+         Say Y here if you want to use an ATI or Philips USB RF remote control.
+         These are RF remotes with USB receivers.
+         ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
+         and is also available as a separate product.
+         This driver provides mouse pointer, left and right mouse buttons,
+         and maps all the other remote buttons to keypress events.
+
+         To compile this driver as a module, choose M here: the module will be
+         called ati_remote2.
+
 config USB_KEYSPAN_REMOTE
        tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
        depends on USB && INPUT && EXPERIMENTAL
index 07cb17d..d512d9f 100644 (file)
@@ -28,6 +28,7 @@ endif
 
 obj-$(CONFIG_USB_AIPTEK)       += aiptek.o
 obj-$(CONFIG_USB_ATI_REMOTE)   += ati_remote.o
+obj-$(CONFIG_USB_ATI_REMOTE2)  += ati_remote2.o
 obj-$(CONFIG_USB_HID)          += usbhid.o
 obj-$(CONFIG_USB_KBD)          += usbkbd.o
 obj-$(CONFIG_USB_KBTAB)                += kbtab.o
index a32558b..df29b80 100644 (file)
@@ -261,7 +261,6 @@ static struct usb_device_id usb_acecad_id_table [] = {
 MODULE_DEVICE_TABLE(usb, usb_acecad_id_table);
 
 static struct usb_driver usb_acecad_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usb_acecad",
        .probe =        usb_acecad_probe,
        .disconnect =   usb_acecad_disconnect,
index 0e2505c..a6693b0 100644 (file)
@@ -338,7 +338,7 @@ struct aiptek {
  * the bitmap which comes from the tablet. This hides the
  * issue that the F_keys are not sequentially numbered.
  */
-static int macroKeyEvents[] = {
+static const int macroKeyEvents[] = {
        KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
        KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
        KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,
@@ -2093,7 +2093,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        /* Programming the tablet macro keys needs to be done with a for loop
         * as the keycodes are discontiguous.
         */
-       for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
+       for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
                set_bit(macroKeyEvents[i], inputdev->keybit);
 
        /*
@@ -2135,7 +2135,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
         * not an error :-)
         */
 
-       for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
+       for (i = 0; i < ARRAY_SIZE(speeds); ++i) {
                aiptek->curSetting.programmableDelay = speeds[i];
                (void)aiptek_program_tablet(aiptek);
                if (aiptek->inputdev->absmax[ABS_X] > 0) {
@@ -2190,7 +2190,6 @@ fail1:    input_free_device(inputdev);
 static void aiptek_disconnect(struct usb_interface *intf);
 
 static struct usb_driver aiptek_driver = {
-       .owner = THIS_MODULE,
        .name = "aiptek",
        .probe = aiptek_probe,
        .disconnect = aiptek_disconnect,
index 15840db..1949b54 100644 (file)
@@ -452,7 +452,6 @@ static int atp_resume(struct usb_interface *iface)
 }
 
 static struct usb_driver atp_driver = {
-       .owner          = THIS_MODULE,
        .name           = "appletouch",
        .probe          = atp_probe,
        .disconnect     = atp_disconnect,
index 9a2a47d..f7bdc50 100644 (file)
@@ -96,6 +96,7 @@
 #include <linux/usb.h>
 #include <linux/usb_input.h>
 #include <linux/wait.h>
+#include <linux/jiffies.h>
 
 /*
  * Module and Version Information, Module Parameters
@@ -146,7 +147,7 @@ static char init1[] = { 0x01, 0x00, 0x20, 0x14 };
 static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
 
 /* Acceleration curve for directional control pad */
-static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
+static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
 
 /* Duplicate event filtering time.
  * Sequential, identical KIND_FILTERED inputs with less than
@@ -197,7 +198,7 @@ struct ati_remote {
 #define KIND_ACCEL      7   /* Directional keypad - left, right, up, down.*/
 
 /* Translation table from hardware messages to input events. */
-static struct {
+static const struct {
        short kind;
        unsigned char data1, data2;
        int type;
@@ -295,7 +296,6 @@ static void ati_remote_disconnect   (struct usb_interface *interface);
 
 /* usb specific object to register with the usb subsystem */
 static struct usb_driver ati_remote_driver = {
-       .owner        = THIS_MODULE,
        .name         = "ati_remote",
        .probe        = ati_remote_probe,
        .disconnect   = ati_remote_disconnect,
@@ -472,7 +472,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
                /* Filter duplicate events which happen "too close" together. */
                if ((ati_remote->old_data[0] == data[1]) &&
                        (ati_remote->old_data[1] == data[2]) &&
-                       ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
+                       time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) {
                        ati_remote->repeat_count++;
                } else {
                        ati_remote->repeat_count = 0;
@@ -507,16 +507,16 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
         * pad down, so we increase acceleration, ramping up over two seconds to
         * a maximum speed.  The acceleration curve is #defined above.
         */
-       if ((jiffies - ati_remote->old_jiffies) > (HZ >> 2)) {
+       if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) {
                acc = 1;
                ati_remote->acc_jiffies = jiffies;
        }
-       else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 3))  acc = accel[0];
-       else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 2))  acc = accel[1];
-       else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 1))  acc = accel[2];
-       else if ((jiffies - ati_remote->acc_jiffies) < HZ )        acc = accel[3];
-       else if ((jiffies - ati_remote->acc_jiffies) < HZ+(HZ>>1)) acc = accel[4];
-       else if ((jiffies - ati_remote->acc_jiffies) < (HZ << 1))  acc = accel[5];
+       else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3)))  acc = accel[0];
+       else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2)))  acc = accel[1];
+       else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1)))  acc = accel[2];
+       else if (time_before(jiffies, ati_remote->acc_jiffies + HZ))         acc = accel[3];
+       else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4];
+       else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1)))  acc = accel[5];
        else acc = accel[6];
 
        input_regs(dev, regs);
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c
new file mode 100644 (file)
index 0000000..ab1a1ae
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * ati_remote2 - ATI/Philips USB RF remote driver
+ *
+ * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
+ *
+ * This program is free software; you can 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/usb_input.h>
+
+#define DRIVER_DESC    "ATI/Philips USB RF remote driver"
+#define DRIVER_VERSION "0.1"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
+MODULE_LICENSE("GPL");
+
+static unsigned int mode_mask = 0x1F;
+module_param(mode_mask, uint, 0644);
+MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
+
+static struct usb_device_id ati_remote2_id_table[] = {
+       { USB_DEVICE(0x0471, 0x0602) }, /* ATI Remote Wonder II */
+       { }
+};
+MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
+
+static struct {
+       int hw_code;
+       int key_code;
+} ati_remote2_key_table[] = {
+       { 0x00, KEY_0 },
+       { 0x01, KEY_1 },
+       { 0x02, KEY_2 },
+       { 0x03, KEY_3 },
+       { 0x04, KEY_4 },
+       { 0x05, KEY_5 },
+       { 0x06, KEY_6 },
+       { 0x07, KEY_7 },
+       { 0x08, KEY_8 },
+       { 0x09, KEY_9 },
+       { 0x0c, KEY_POWER },
+       { 0x0d, KEY_MUTE },
+       { 0x10, KEY_VOLUMEUP },
+       { 0x11, KEY_VOLUMEDOWN },
+       { 0x20, KEY_CHANNELUP },
+       { 0x21, KEY_CHANNELDOWN },
+       { 0x28, KEY_FORWARD },
+       { 0x29, KEY_REWIND },
+       { 0x2c, KEY_PLAY },
+       { 0x30, KEY_PAUSE },
+       { 0x31, KEY_STOP },
+       { 0x37, KEY_RECORD },
+       { 0x38, KEY_DVD },
+       { 0x39, KEY_TV },
+       { 0x54, KEY_MENU },
+       { 0x58, KEY_UP },
+       { 0x59, KEY_DOWN },
+       { 0x5a, KEY_LEFT },
+       { 0x5b, KEY_RIGHT },
+       { 0x5c, KEY_OK },
+       { 0x78, KEY_A },
+       { 0x79, KEY_B },
+       { 0x7a, KEY_C },
+       { 0x7b, KEY_D },
+       { 0x7c, KEY_E },
+       { 0x7d, KEY_F },
+       { 0x82, KEY_ENTER },
+       { 0x8e, KEY_VENDOR },
+       { 0x96, KEY_COFFEE },
+       { 0xa9, BTN_LEFT },
+       { 0xaa, BTN_RIGHT },
+       { 0xbe, KEY_QUESTION },
+       { 0xd5, KEY_FRONT },
+       { 0xd0, KEY_EDIT },
+       { 0xf9, KEY_INFO },
+       { (0x00 << 8) | 0x3f, KEY_PROG1 },
+       { (0x01 << 8) | 0x3f, KEY_PROG2 },
+       { (0x02 << 8) | 0x3f, KEY_PROG3 },
+       { (0x03 << 8) | 0x3f, KEY_PROG4 },
+       { (0x04 << 8) | 0x3f, KEY_PC },
+       { 0, KEY_RESERVED }
+};
+
+struct ati_remote2 {
+       struct input_dev *idev;
+       struct usb_device *udev;
+
+       struct usb_interface *intf[2];
+       struct usb_endpoint_descriptor *ep[2];
+       struct urb *urb[2];
+       void *buf[2];
+       dma_addr_t buf_dma[2];
+
+       unsigned long jiffies;
+       int mode;
+
+       char name[64];
+       char phys[64];
+};
+
+static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
+static void ati_remote2_disconnect(struct usb_interface *interface);
+
+static struct usb_driver ati_remote2_driver = {
+       .name       = "ati_remote2",
+       .probe      = ati_remote2_probe,
+       .disconnect = ati_remote2_disconnect,
+       .id_table   = ati_remote2_id_table,
+};
+
+static int ati_remote2_open(struct input_dev *idev)
+{
+       struct ati_remote2 *ar2 = idev->private;
+       int r;
+
+       r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
+       if (r) {
+               dev_err(&ar2->intf[0]->dev,
+                       "%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+               return r;
+       }
+       r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
+       if (r) {
+               usb_kill_urb(ar2->urb[0]);
+               dev_err(&ar2->intf[1]->dev,
+                       "%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+               return r;
+       }
+
+       return 0;
+}
+
+static void ati_remote2_close(struct input_dev *idev)
+{
+       struct ati_remote2 *ar2 = idev->private;
+
+       usb_kill_urb(ar2->urb[0]);
+       usb_kill_urb(ar2->urb[1]);
+}
+
+static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs)
+{
+       struct input_dev *idev = ar2->idev;
+       u8 *data = ar2->buf[0];
+
+       if (data[0] > 4) {
+               dev_err(&ar2->intf[0]->dev,
+                       "Unknown mode byte (%02x %02x %02x %02x)\n",
+                       data[3], data[2], data[1], data[0]);
+               return;
+       }
+
+       if (!((1 << data[0]) & mode_mask))
+               return;
+
+       input_regs(idev, regs);
+       input_event(idev, EV_REL, REL_X, (s8) data[1]);
+       input_event(idev, EV_REL, REL_Y, (s8) data[2]);
+       input_sync(idev);
+}
+
+static int ati_remote2_lookup(unsigned int hw_code)
+{
+       int i;
+
+       for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+               if (ati_remote2_key_table[i].hw_code == hw_code)
+                       return i;
+
+       return -1;
+}
+
+static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs)
+{
+       struct input_dev *idev = ar2->idev;
+       u8 *data = ar2->buf[1];
+       int hw_code, index;
+
+       if (data[0] > 4) {
+               dev_err(&ar2->intf[1]->dev,
+                       "Unknown mode byte (%02x %02x %02x %02x)\n",
+                       data[3], data[2], data[1], data[0]);
+               return;
+       }
+
+       hw_code = data[2];
+       /*
+        * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
+        * Use the mode byte to figure out which one was pressed.
+        */
+       if (hw_code == 0x3f) {
+               /*
+                * For some incomprehensible reason the mouse pad generates
+                * events which look identical to the events from the last
+                * pressed mode key. Naturally we don't want to generate key
+                * events for the mouse pad so we filter out any subsequent
+                * events from the same mode key.
+                */
+               if (ar2->mode == data[0])
+                       return;
+
+               if (data[1] == 0)
+                       ar2->mode = data[0];
+
+               hw_code |= data[0] << 8;
+       }
+
+       if (!((1 << data[0]) & mode_mask))
+               return;
+
+       index = ati_remote2_lookup(hw_code);
+       if (index < 0) {
+               dev_err(&ar2->intf[1]->dev,
+                       "Unknown code byte (%02x %02x %02x %02x)\n",
+                       data[3], data[2], data[1], data[0]);
+               return;
+       }
+
+       switch (data[1]) {
+       case 0: /* release */
+               break;
+       case 1: /* press */
+               ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_DELAY]);
+               break;
+       case 2: /* repeat */
+
+               /* No repeat for mouse buttons. */
+               if (ati_remote2_key_table[index].key_code == BTN_LEFT ||
+                   ati_remote2_key_table[index].key_code == BTN_RIGHT)
+                       return;
+
+               if (!time_after_eq(jiffies, ar2->jiffies))
+                       return;
+
+               ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_PERIOD]);
+               break;
+       default:
+               dev_err(&ar2->intf[1]->dev,
+                       "Unknown state byte (%02x %02x %02x %02x)\n",
+                       data[3], data[2], data[1], data[0]);
+               return;
+       }
+
+       input_regs(idev, regs);
+       input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
+       input_sync(idev);
+}
+
+static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs)
+{
+       struct ati_remote2 *ar2 = urb->context;
+       int r;
+
+       switch (urb->status) {
+       case 0:
+               ati_remote2_input_mouse(ar2, regs);
+               break;
+       case -ENOENT:
+       case -EILSEQ:
+       case -ECONNRESET:
+       case -ESHUTDOWN:
+               dev_dbg(&ar2->intf[0]->dev,
+                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+               return;
+       default:
+               dev_err(&ar2->intf[0]->dev,
+                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+       }
+
+       r = usb_submit_urb(urb, GFP_ATOMIC);
+       if (r)
+               dev_err(&ar2->intf[0]->dev,
+                       "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+}
+
+static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs)
+{
+       struct ati_remote2 *ar2 = urb->context;
+       int r;
+
+       switch (urb->status) {
+       case 0:
+               ati_remote2_input_key(ar2, regs);
+               break;
+       case -ENOENT:
+       case -EILSEQ:
+       case -ECONNRESET:
+       case -ESHUTDOWN:
+               dev_dbg(&ar2->intf[1]->dev,
+                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+               return;
+       default:
+               dev_err(&ar2->intf[1]->dev,
+                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+       }
+
+       r = usb_submit_urb(urb, GFP_ATOMIC);
+       if (r)
+               dev_err(&ar2->intf[1]->dev,
+                       "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+}
+
+static int ati_remote2_input_init(struct ati_remote2 *ar2)
+{
+       struct input_dev *idev;
+       int i;
+
+       idev = input_allocate_device();
+       if (!idev)
+               return -ENOMEM;
+
+       ar2->idev = idev;
+       idev->private = ar2;
+
+       idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
+       idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+       idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+               set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
+
+       idev->rep[REP_DELAY]  = 250;
+       idev->rep[REP_PERIOD] = 33;
+
+       idev->open = ati_remote2_open;
+       idev->close = ati_remote2_close;
+
+       idev->name = ar2->name;
+       idev->phys = ar2->phys;
+
+       usb_to_input_id(ar2->udev, &idev->id);
+       idev->cdev.dev = &ar2->udev->dev;
+
+       i = input_register_device(idev);
+       if (i)
+               input_free_device(idev);
+
+       return i;
+}
+
+static int ati_remote2_urb_init(struct ati_remote2 *ar2)
+{
+       struct usb_device *udev = ar2->udev;
+       int i, pipe, maxp;
+
+       for (i = 0; i < 2; i++) {
+               ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
+               if (!ar2->buf[i])
+                       return -ENOMEM;
+
+               ar2->urb[i] = usb_alloc_urb(0, GFP_KERNEL);
+               if (!ar2->urb[i])
+                       return -ENOMEM;
+
+               pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress);
+               maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+               maxp = maxp > 4 ? 4 : maxp;
+
+               usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp,
+                                i ? ati_remote2_complete_key : ati_remote2_complete_mouse,
+                                ar2, ar2->ep[i]->bInterval);
+               ar2->urb[i]->transfer_dma = ar2->buf_dma[i];
+               ar2->urb[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       }
+
+       return 0;
+}
+
+static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
+{
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               if (ar2->urb[i])
+                       usb_free_urb(ar2->urb[i]);
+
+               if (ar2->buf[i])
+                       usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
+       }
+}
+
+static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(interface);
+       struct usb_host_interface *alt = interface->cur_altsetting;
+       struct ati_remote2 *ar2;
+       int r;
+
+       if (alt->desc.bInterfaceNumber)
+               return -ENODEV;
+
+       ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL);
+       if (!ar2)
+               return -ENOMEM;
+
+       ar2->udev = udev;
+
+       ar2->intf[0] = interface;
+       ar2->ep[0] = &alt->endpoint[0].desc;
+
+       ar2->intf[1] = usb_ifnum_to_if(udev, 1);
+       r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
+       if (r)
+               goto fail1;
+       alt = ar2->intf[1]->cur_altsetting;
+       ar2->ep[1] = &alt->endpoint[0].desc;
+
+       r = ati_remote2_urb_init(ar2);
+       if (r)
+               goto fail2;
+
+       usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
+       strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
+
+       strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));
+
+       r = ati_remote2_input_init(ar2);
+       if (r)
+               goto fail2;
+
+       usb_set_intfdata(interface, ar2);
+
+       return 0;
+
+ fail2:
+       ati_remote2_urb_cleanup(ar2);
+
+       usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
+ fail1:
+       kfree(ar2);
+
+       return r;
+}
+
+static void ati_remote2_disconnect(struct usb_interface *interface)
+{
+       struct ati_remote2 *ar2;
+       struct usb_host_interface *alt = interface->cur_altsetting;
+
+       if (alt->desc.bInterfaceNumber)
+               return;
+
+       ar2 = usb_get_intfdata(interface);
+       usb_set_intfdata(interface, NULL);
+
+       input_unregister_device(ar2->idev);
+
+       ati_remote2_urb_cleanup(ar2);
+
+       usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
+
+       kfree(ar2);
+}
+
+static int __init ati_remote2_init(void)
+{
+       int r;
+
+       r = usb_register(&ati_remote2_driver);
+       if (r)
+               printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r);
+       else
+               printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n");
+
+       return r;
+}
+
+static void __exit ati_remote2_exit(void)
+{
+       usb_deregister(&ati_remote2_driver);
+}
+
+module_init(ati_remote2_init);
+module_exit(ati_remote2_exit);
index 26ca5b8..b44d398 100644 (file)
@@ -38,7 +38,7 @@ typedef s16 fixp_t;
 #define FRAC_MASK ((1<<FRAC_N)-1)
 
 // Not to be used directly. Use fixp_{cos,sin}
-static fixp_t cos_table[45] = {
+static const fixp_t cos_table[45] = {
        0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8,
        0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD,
        0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1,
index a3e44ef..5f52979 100644 (file)
@@ -1454,7 +1454,7 @@ void hid_init_reports(struct hid_device *hid)
  * Alphabetically sorted blacklist by quirk type.
  */
 
-static struct hid_blacklist {
+static const struct hid_blacklist {
        __u16 idVendor;
        __u16 idProduct;
        unsigned quirks;
@@ -1930,7 +1930,6 @@ static struct usb_device_id hid_usb_ids [] = {
 MODULE_DEVICE_TABLE (usb, hid_usb_ids);
 
 static struct usb_driver hid_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbhid",
        .probe =        hid_probe,
        .disconnect =   hid_disconnect,
index 1220a50..192a03b 100644 (file)
@@ -39,7 +39,7 @@
 
 #define unk    KEY_UNKNOWN
 
-static unsigned char hid_keyboard[256] = {
+static const unsigned char hid_keyboard[256] = {
          0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
         50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
          4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
@@ -58,7 +58,7 @@ static unsigned char hid_keyboard[256] = {
        150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
 };
 
-static struct {
+static const struct {
        __s32 x;
        __s32 y;
 }  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
index 440377c..4dff847 100644 (file)
@@ -826,7 +826,6 @@ static int hiddev_usbd_probe(struct usb_interface *intf,
 
 
 static /* const */ struct usb_driver hiddev_driver = {
-       .owner =        THIS_MODULE,
        .name =         "hiddev",
        .probe =        hiddev_usbd_probe,
 };
index 4a50acb..7618ae5 100644 (file)
@@ -250,7 +250,6 @@ static void itmtouch_disconnect(struct usb_interface *intf)
 MODULE_DEVICE_TABLE(usb, itmtouch_ids);
 
 static struct usb_driver itmtouch_driver = {
-       .owner =        THIS_MODULE,
        .name =         "itmtouch",
        .probe =        itmtouch_probe,
        .disconnect =   itmtouch_disconnect,
index fd48e74..f6d5cea 100644 (file)
@@ -197,7 +197,6 @@ static void kbtab_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver kbtab_driver = {
-       .owner =        THIS_MODULE,
        .name =         "kbtab",
        .probe =        kbtab_probe,
        .disconnect =   kbtab_disconnect,
index a32cfe5..b4a051b 100644 (file)
@@ -95,7 +95,7 @@ struct usb_keyspan {
  * Currently there are 15 and 17 button models so RESERVED codes
  * are blank areas in the mapping.
  */
-static int keyspan_key_table[] = {
+static const int keyspan_key_table[] = {
        KEY_RESERVED,           /* 0 is just a place holder. */
        KEY_RESERVED,
        KEY_STOP,
@@ -559,7 +559,6 @@ static void keyspan_disconnect(struct usb_interface *interface)
  */
 static struct usb_driver keyspan_driver =
 {
-       .owner =        THIS_MODULE,
        .name =         "keyspan_remote",
        .probe =        keyspan_probe,
        .disconnect =   keyspan_disconnect,
index 52cc18c..f018953 100644 (file)
@@ -310,7 +310,6 @@ static void mtouchusb_disconnect(struct usb_interface *intf)
 MODULE_DEVICE_TABLE(usb, mtouchusb_devices);
 
 static struct usb_driver mtouchusb_driver = {
-       .owner          = THIS_MODULE,
        .name           = "mtouchusb",
        .probe          = mtouchusb_probe,
        .disconnect     = mtouchusb_disconnect,
index b747623..fdf0f78 100644 (file)
@@ -441,7 +441,6 @@ static struct usb_device_id powermate_devices [] = {
 MODULE_DEVICE_TABLE (usb, powermate_devices);
 
 static struct usb_driver powermate_driver = {
-       .owner =        THIS_MODULE,
         .name =         "powermate",
         .probe =        powermate_probe,
         .disconnect =   powermate_disconnect,
index 7420c6b..3b3c7b4 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************
  * touchkitusb.c  --  Driver for eGalax TouchKit USB Touchscreens
  *
- * Copyright (C) 2004 by Daniel Ritz
+ * Copyright (C) 2004-2005 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
  *
  * This program is free software; you can redistribute it and/or
 #define TOUCHKIT_MAX_YC                        0x07ff
 #define TOUCHKIT_YC_FUZZ               0x0
 #define TOUCHKIT_YC_FLAT               0x0
-#define TOUCHKIT_REPORT_DATA_SIZE      8
+#define TOUCHKIT_REPORT_DATA_SIZE      16
 
 #define TOUCHKIT_DOWN                  0x01
-#define TOUCHKIT_POINT_TOUCH           0x81
-#define TOUCHKIT_POINT_NOTOUCH         0x80
 
-#define TOUCHKIT_GET_TOUCHED(dat)      ((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0)
-#define TOUCHKIT_GET_X(dat)            (((dat)[3] << 7) | (dat)[4])
-#define TOUCHKIT_GET_Y(dat)            (((dat)[1] << 7) | (dat)[2])
+#define TOUCHKIT_PKT_TYPE_MASK         0xFE
+#define TOUCHKIT_PKT_TYPE_REPT         0x80
+#define TOUCHKIT_PKT_TYPE_DIAG         0x0A
 
 #define DRIVER_VERSION                 "v0.1"
 #define DRIVER_AUTHOR                  "Daniel Ritz <daniel.ritz@gmx.ch>"
@@ -62,6 +60,8 @@ MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
 struct touchkit_usb {
        unsigned char *data;
        dma_addr_t data_dma;
+       char buffer[TOUCHKIT_REPORT_DATA_SIZE];
+       int buf_len;
        struct urb *irq;
        struct usb_device *udev;
        struct input_dev *input;
@@ -77,11 +77,128 @@ static struct usb_device_id touchkit_devices[] = {
        {}
 };
 
+/* helpers to read the data */
+static inline int touchkit_get_touched(char *data)
+{
+       return (data[0] & TOUCHKIT_DOWN) ? 1 : 0;
+}
+
+static inline int touchkit_get_x(char *data)
+{
+       return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F);
+}
+
+static inline int touchkit_get_y(char *data)
+{
+       return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F);
+}
+
+
+/* processes one input packet. */
+static void touchkit_process_pkt(struct touchkit_usb *touchkit,
+                                 struct pt_regs *regs, char *pkt)
+{
+       int x, y;
+
+       /* only process report packets */
+       if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT)
+               return;
+
+       if (swap_xy) {
+               y = touchkit_get_x(pkt);
+               x = touchkit_get_y(pkt);
+       } else {
+               x = touchkit_get_x(pkt);
+               y = touchkit_get_y(pkt);
+       }
+
+       input_regs(touchkit->input, regs);
+       input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt));
+       input_report_abs(touchkit->input, ABS_X, x);
+       input_report_abs(touchkit->input, ABS_Y, y);
+       input_sync(touchkit->input);
+}
+
+
+static int touchkit_get_pkt_len(char *buf)
+{
+       switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) {
+       case TOUCHKIT_PKT_TYPE_REPT:
+               return 5;
+
+       case TOUCHKIT_PKT_TYPE_DIAG:
+               return buf[1] + 2;
+       }
+
+       return 0;
+}
+
+static void touchkit_process(struct touchkit_usb *touchkit, int len,
+                             struct pt_regs *regs)
+{
+       char *buffer;
+       int pkt_len, buf_len, pos;
+
+       /* if the buffer contains data, append */
+       if (unlikely(touchkit->buf_len)) {
+               int tmp;
+
+               /* if only 1 byte in buffer, add another one to get length */
+               if (touchkit->buf_len == 1)
+                       touchkit->buffer[1] = touchkit->data[0];
+
+               pkt_len = touchkit_get_pkt_len(touchkit->buffer);
+
+               /* unknown packet: drop everything */
+               if (!pkt_len)
+                       return;
+
+               /* append, process */
+               tmp = pkt_len - touchkit->buf_len;
+               memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp);
+               touchkit_process_pkt(touchkit, regs, touchkit->buffer);
+
+               buffer = touchkit->data + tmp;
+               buf_len = len - tmp;
+       } else {
+               buffer = touchkit->data;
+               buf_len = len;
+       }
+
+       /* only one byte left in buffer */
+       if (unlikely(buf_len == 1)) {
+               touchkit->buffer[0] = buffer[0];
+               touchkit->buf_len = 1;
+               return;
+       }
+
+       /* loop over the buffer */
+       pos = 0;
+       while (pos < buf_len) {
+               /* get packet len */
+               pkt_len = touchkit_get_pkt_len(buffer + pos);
+
+               /* unknown packet: drop everything */
+               if (unlikely(!pkt_len))
+                       return;
+
+               /* full packet: process */
+               if (likely(pkt_len <= buf_len)) {
+                       touchkit_process_pkt(touchkit, regs, buffer + pos);
+               } else {
+                       /* incomplete packet: save in buffer */
+                       memcpy(touchkit->buffer, buffer + pos, buf_len - pos);
+                       touchkit->buf_len = buf_len - pos;
+               }
+               pos += pkt_len;
+       }
+}
+
+
 static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
 {
        struct touchkit_usb *touchkit = urb->context;
        int retval;
-       int x, y;
 
        switch (urb->status) {
        case 0:
@@ -105,20 +222,7 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
                goto exit;
        }
 
-       if (swap_xy) {
-               y = TOUCHKIT_GET_X(touchkit->data);
-               x = TOUCHKIT_GET_Y(touchkit->data);
-       } else {
-               x = TOUCHKIT_GET_X(touchkit->data);
-               y = TOUCHKIT_GET_Y(touchkit->data);
-       }
-
-       input_regs(touchkit->input, regs);
-       input_report_key(touchkit->input, BTN_TOUCH,
-                        TOUCHKIT_GET_TOUCHED(touchkit->data));
-       input_report_abs(touchkit->input, ABS_X, x);
-       input_report_abs(touchkit->input, ABS_Y, y);
-       input_sync(touchkit->input);
+       touchkit_process(touchkit, urb->actual_length, regs);
 
 exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -267,7 +371,6 @@ static void touchkit_disconnect(struct usb_interface *intf)
 MODULE_DEVICE_TABLE(usb, touchkit_devices);
 
 static struct usb_driver touchkit_driver = {
-       .owner          = THIS_MODULE,
        .name           = "touchkitusb",
        .probe          = touchkit_probe,
        .disconnect     = touchkit_disconnect,
index 226b6f9..2f3edc2 100644 (file)
@@ -345,7 +345,6 @@ static struct usb_device_id usb_kbd_id_table [] = {
 MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
 
 static struct usb_driver usb_kbd_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbkbd",
        .probe =        usb_kbd_probe,
        .disconnect =   usb_kbd_disconnect,
index 230f6b1..af52613 100644 (file)
@@ -226,7 +226,6 @@ static struct usb_device_id usb_mouse_id_table [] = {
 MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
 
 static struct usb_driver usb_mouse_driver = {
-       .owner          = THIS_MODULE,
        .name           = "usbmouse",
        .probe          = usb_mouse_probe,
        .disconnect     = usb_mouse_disconnect,
index dc099bb..48df4cf 100644 (file)
@@ -945,7 +945,6 @@ static void wacom_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver wacom_driver = {
-       .owner =        THIS_MODULE,
        .name =         "wacom",
        .probe =        wacom_probe,
        .disconnect =   wacom_disconnect,
index 43112f0..e278489 100644 (file)
@@ -70,7 +70,7 @@
 
 #define XPAD_PKT_LEN 32
 
-static struct xpad_device {
+static const struct xpad_device {
        u16 idVendor;
        u16 idProduct;
        char *name;
@@ -81,13 +81,13 @@ static struct xpad_device {
        { 0x0000, 0x0000, "X-Box pad" }
 };
 
-static signed short xpad_btn[] = {
+static const signed short xpad_btn[] = {
        BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,       /* "analog" buttons */
        BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR,    /* start/back/sticks */
        -1                                              /* terminating entry */
 };
 
-static signed short xpad_abs[] = {
+static const signed short xpad_abs[] = {
        ABS_X, ABS_Y,           /* left stick */
        ABS_RX, ABS_RY,         /* right stick */
        ABS_Z, ABS_RZ,          /* triggers left/right */
@@ -316,7 +316,6 @@ static void xpad_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver xpad_driver = {
-       .owner          = THIS_MODULE,
        .name           = "xpad",
        .probe          = xpad_probe,
        .disconnect     = xpad_disconnect,
index f526aeb..1bfc105 100644 (file)
@@ -987,7 +987,6 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 }
 
 static struct usb_driver yealink_driver = {
-       .owner          = THIS_MODULE,
        .name           = "yealink",
        .probe          = usb_probe,
        .disconnect     = usb_disconnect,
index 27b23c5..18d8eaf 100644 (file)
@@ -812,7 +812,6 @@ static struct usb_device_id dabusb_ids [] = {
 MODULE_DEVICE_TABLE (usb, dabusb_ids);
 
 static struct usb_driver dabusb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "dabusb",
        .probe =        dabusb_probe,
        .disconnect =   dabusb_disconnect,
index 7503f5b..6a5700e 100644 (file)
@@ -150,7 +150,6 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
 
 /* USB subsystem interface */
 static struct usb_driver usb_dsbr100_driver = {
-       .owner =        THIS_MODULE,
        .name =         "dsbr100",
        .probe =        usb_dsbr100_probe,
        .disconnect =   usb_dsbr100_disconnect,
index ba41fc7..a42c222 100644 (file)
@@ -3457,7 +3457,7 @@ static void ibmcam_model3_setup_after_video_if(struct uvd *uvd)
        if(init_model3_input) {
                if (debug > 0)
                        info("Setting input to RCA.");
-               for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) {
+               for (i=0; i < ARRAY_SIZE(initData); i++) {
                        ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index);
                }
        }
index 9fe2c27..e2ede58 100644 (file)
@@ -77,14 +77,14 @@ static int saturation =     MAX_SATURATION/2;
 static int sharpness = MAX_SHARPNESS/2;
 static int whitebal =  3*(MAX_WHITEBAL/4);
 
-static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
+static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
 
 /* These FPS speeds are from the windows config box. They are
  * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
  * real fps.
  */
 
-static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
+static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
                               { 24, 40, 48, 60, 72, 80, 100 },
                               { 18, 30, 36, 45, 54, 60, 75  },
                               { 6,  10, 12, 15, 18, 21, 25  } };
@@ -95,7 +95,7 @@ struct cam_size {
        u8      cmd;
 };
 
-static struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
+static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
                                          { 160, 136, 0xa },
                                          { 176, 144, 0x4 },
                                          { 320, 240, 0x5 } };
index 036c485..3a0e8ce 100644 (file)
@@ -211,7 +211,7 @@ static struct ov51x_decomp_ops *ov518_mmx_decomp_ops;
 
 /* Number of times to retry a failed I2C transaction. Increase this if you
  * are getting "Failed to read sensor ID..." */
-static int i2c_detect_tries = 5;
+static const int i2c_detect_tries = 5;
 
 /* MMX support is present in kernel and CPU. Checked upon decomp module load. */
 #if defined(__i386__) || defined(__x86_64__)
@@ -6008,7 +6008,6 @@ ov51x_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver ov511_driver = {
-       .owner =        THIS_MODULE,
        .name =         "ov511",
        .id_table =     device_table,
        .probe =        ov51x_probe,
index 5309919..359c4b2 100644 (file)
 #define PT_RESET_CONTROL_FORMATTER             0x02
 #define PT_STATUS_FORMATTER                    0x03
 
-static char *size2name[PSZ_MAX] =
+static const char *size2name[PSZ_MAX] =
 {
        "subQCIF",
        "QSIF",
index 5524fd7..09ca612 100644 (file)
@@ -111,7 +111,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 static void usb_pwc_disconnect(struct usb_interface *intf);
 
 static struct usb_driver pwc_driver = {
-       .owner =                THIS_MODULE,
        .name =                 "Philips webcam",       /* name */
        .id_table =             pwc_device_table,
        .probe =                usb_pwc_probe,          /* probe() */
index f69e443..b2ae29a 100644 (file)
@@ -1401,7 +1401,6 @@ static void se401_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver se401_driver = {
-       .owner          = THIS_MODULE,
         .name          = "se401",
         .id_table      = device_table,
        .probe          = se401_probe,
index b2e66e3..8d1a1c3 100644 (file)
@@ -1316,7 +1316,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
        struct v4l2_control ctrl;
        struct v4l2_queryctrl *qctrl;
        struct v4l2_rect* rect;
-       u8 i = 0, n = 0;
+       u8 i = 0;
        int err = 0;
 
        if (!(cam->state & DEV_INITIALIZED)) {
@@ -1352,7 +1352,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
                return err;
 
        if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
-               DBG(3, "Compressed video format is active, quality %d", 
+               DBG(3, "Compressed video format is active, quality %d",
                    cam->compression.quality)
        else
                DBG(3, "Uncompressed video format is active")
@@ -1364,9 +1364,8 @@ static int sn9c102_init(struct sn9c102_device* cam)
                }
 
        if (s->set_ctrl) {
-               n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-               for (i = 0; i < n; i++)
-                       if (s->qctrl[i].id != 0 && 
+               for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+                       if (s->qctrl[i].id != 0 &&
                            !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
                                ctrl.id = s->qctrl[i].id;
                                ctrl.value = qctrl[i].default_value;
@@ -1388,7 +1387,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
                init_waitqueue_head(&cam->wait_stream);
                cam->nreadbuffers = 2;
                memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
-               memcpy(&(s->_rect), &(s->cropcap.defrect), 
+               memcpy(&(s->_rect), &(s->cropcap.defrect),
                       sizeof(struct v4l2_rect));
                cam->state |= DEV_INITIALIZED;
        }
@@ -1810,13 +1809,12 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
        {
                struct sn9c102_sensor* s = cam->sensor;
                struct v4l2_queryctrl qc;
-               u8 i, n;
+               u8 i;
 
                if (copy_from_user(&qc, arg, sizeof(qc)))
                        return -EFAULT;
 
-               n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-               for (i = 0; i < n; i++)
+               for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
                        if (qc.id && qc.id == s->qctrl[i].id) {
                                memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
                                if (copy_to_user(arg, &qc, sizeof(qc)))
@@ -1852,7 +1850,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
        {
                struct sn9c102_sensor* s = cam->sensor;
                struct v4l2_control ctrl;
-               u8 i, n;
+               u8 i;
                int err = 0;
 
                if (!s->set_ctrl)
@@ -1861,8 +1859,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
                if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
                        return -EFAULT;
 
-               n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-               for (i = 0; i < n; i++)
+               for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
                        if (ctrl.id == s->qctrl[i].id) {
                                if (ctrl.value < s->qctrl[i].minimum ||
                                    ctrl.value > s->qctrl[i].maximum)
@@ -2544,7 +2541,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        unsigned int i, n;
        int err = 0, r;
 
-       n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
+       n = ARRAY_SIZE(sn9c102_id_table);
        for (i = 0; i < n-1; i++)
                if (le16_to_cpu(udev->descriptor.idVendor) == 
                    sn9c102_id_table[i].idVendor &&
@@ -2711,7 +2708,6 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
 
 
 static struct usb_driver sn9c102_usb_driver = {
-       .owner =      THIS_MODULE,
        .name =       "sn9c102",
        .id_table =   sn9c102_id_table,
        .probe =      sn9c102_usb_probe,
index 0fd0fa9..774038b 100644 (file)
@@ -1477,7 +1477,6 @@ static void stv680_disconnect (struct usb_interface *intf)
 }
 
 static struct usb_driver stv680_driver = {
-       .owner =        THIS_MODULE,
        .name =         "stv680",
        .probe =        stv680_probe,
        .disconnect =   stv680_disconnect,
index 4459406..b0551cd 100644 (file)
@@ -151,7 +151,7 @@ struct usb_stv {
 };
 
 
-static unsigned char red[256] = { 
+static const unsigned char red[256] = {
        0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
        18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, 
        44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, 
@@ -176,7 +176,7 @@ static unsigned char red[256] = {
        220, 220, 221, 221 
 }; 
 
-static unsigned char green[256] = {
+static const unsigned char green[256] = {
        0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
        21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, 
        50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, 
@@ -201,7 +201,7 @@ static unsigned char green[256] = {
        245, 245, 246, 246 
 }; 
 
-static unsigned char blue[256] = {
+static const unsigned char blue[256] = {
        0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
        23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, 
        55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, 
index 24efb21..4bd1133 100644 (file)
@@ -725,7 +725,7 @@ int usbvideo_register(
                /* Allocate user_data separately because of kmalloc's limits */
                if (num_extra > 0) {
                        up->user_size = num_cams * num_extra;
-                       up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL);
+                       up->user_data = kmalloc(up->user_size, GFP_KERNEL);
                        if (up->user_data == NULL) {
                                err("%s: Failed to allocate user_data (%d. bytes)",
                                    __FUNCTION__, up->user_size);
@@ -955,7 +955,7 @@ static struct file_operations usbvideo_fops = {
        .ioctl =  usbvideo_v4l_ioctl,
        .llseek = no_llseek,
 };
-static struct video_device usbvideo_template = {
+static const struct video_device usbvideo_template = {
        .owner =      THIS_MODULE,
        .type =       VID_TYPE_CAPTURE,
        .hardware =   VID_HARDWARE_CPIA,
index 0bc0b12..1c73155 100644 (file)
@@ -1257,7 +1257,6 @@ static struct usb_device_id vicam_table[] = {
 MODULE_DEVICE_TABLE(usb, vicam_table);
 
 static struct usb_driver vicam_driver = {
-       .owner          = THIS_MODULE,
        .name           = "vicam",
        .probe          = vicam_probe,
        .disconnect     = vicam_disconnect,
index 67612c8..04d6933 100644 (file)
@@ -2958,7 +2958,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
        };
 
        #define V4L1_IOCTL(cmd) \
-               ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
+               ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
                v4l1_ioctls[_IOC_NR((cmd))] : "?")
 
        cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
@@ -3554,7 +3554,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 
 
        /* Allocate 2 bytes of memory for camera control USB transfers */
-       if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
+       if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) {
                DBG(1,"Couldn't allocate memory for camera control transfers")
                err = -ENOMEM;
                goto fail;
@@ -3562,7 +3562,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        memset(cam->control_buffer, 0, 2);
 
        /* Allocate 8 bytes of memory for USB data transfers to the FSB */
-       if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
+       if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) {
                DBG(1, "Couldn't allocate memory for data "
                       "transfers to the FSB")
                err = -ENOMEM;
@@ -3668,7 +3668,6 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
 
 
 static struct usb_driver w9968cf_usb_driver = {
-       .owner =      THIS_MODULE,
        .name =       "w9968cf",
        .id_table =   winbond_id_table,
        .probe =      w9968cf_usb_probe,
index b293db3..449b250 100644 (file)
@@ -767,7 +767,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned
                memset (bep, 0, sizeof (auerbuf_t));
                 bep->list = bcp;
                 INIT_LIST_HEAD (&bep->buff_list);
-                bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL);
+                bep->bufp = kmalloc (bufsize, GFP_KERNEL);
                 if (!bep->bufp)
                        goto bl_fail;
                 bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL);
@@ -1123,7 +1123,7 @@ static int auerswald_int_open (pauerswald_t cp)
                 }
         }
         if (!cp->intbufp) {
-                cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL);
+                cp->intbufp = kmalloc (irqsize, GFP_KERNEL);
                 if (!cp->intbufp) {
                         ret = -ENOMEM;
                         goto intoend;
@@ -2103,7 +2103,6 @@ MODULE_DEVICE_TABLE (usb, auerswald_ids);
 
 /* Standard usb driver struct */
 static struct usb_driver auerswald_driver = {
-       .owner =        THIS_MODULE,
        .name =         "auerswald",
        .probe =        auerswald_probe,
        .disconnect =   auerswald_disconnect,
index b33044d..6671317 100644 (file)
@@ -50,7 +50,6 @@ static void cytherm_disconnect(struct usb_interface *interface);
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver cytherm_driver = {
-       .owner =        THIS_MODULE,
        .name =         "cytherm",
        .probe =        cytherm_probe,
        .disconnect =   cytherm_disconnect,
index c815520..3824df3 100644 (file)
@@ -227,7 +227,6 @@ static void emi26_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver emi26_driver = {
-       .owner          = THIS_MODULE,
        .name           = "emi26 - firmware loader",
        .probe          = emi26_probe,
        .disconnect     = emi26_disconnect,
index 189986a..52fea2e 100644 (file)
@@ -266,7 +266,6 @@ static void emi62_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_driver emi62_driver = {
-       .owner          = THIS_MODULE,
        .name           = "emi62 - firmware loader",
        .probe          = emi62_probe,
        .disconnect     = emi62_disconnect,
index 1dc3e0f..d8cde10 100644 (file)
@@ -114,7 +114,6 @@ static struct usb_class_driver idmouse_class = {
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver idmouse_driver = {
-       .owner = THIS_MODULE,
        .name = DRIVER_SHORT,
        .probe = idmouse_probe,
        .disconnect = idmouse_disconnect,
index 7e93ac9..981d8a5 100644 (file)
@@ -763,7 +763,6 @@ static void ld_usb_disconnect(struct usb_interface *intf)
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver ld_usb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "ldusb",
        .probe =        ld_usb_probe,
        .disconnect =   ld_usb_disconnect,
index 2703e20..1336745 100644 (file)
@@ -282,7 +282,6 @@ static struct usb_class_driver tower_class = {
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver tower_driver = {
-       .owner =        THIS_MODULE,
        .name =         "legousbtower",
        .probe =        tower_probe,
        .disconnect =   tower_disconnect,
index 067a814..605a3c8 100644 (file)
@@ -555,7 +555,6 @@ static void interfacekit_disconnect(struct usb_interface *interface)
 }
 
 static struct usb_driver interfacekit_driver = {
-       .owner = THIS_MODULE,
        .name = "phidgetkit",
        .probe = interfacekit_probe,
        .disconnect = interfacekit_disconnect,
index a30d4a6..b3418d2 100644 (file)
@@ -306,7 +306,6 @@ servo_disconnect(struct usb_interface *interface)
 }
 
 static struct usb_driver servo_driver = {
-       .owner = THIS_MODULE,
        .name = "phidgetservo",
        .probe = servo_probe,
        .disconnect = servo_disconnect,
index 9590dba..384fa37 100644 (file)
@@ -465,14 +465,14 @@ static int probe_rio(struct usb_interface *intf,
 
        rio->rio_dev = dev;
 
-       if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
+       if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
                err("probe_rio: Not enough memory for the output buffer");
                usb_deregister_dev(intf, &usb_rio_class);
                return -ENOMEM;
        }
        dbg("probe_rio: obuf address:%p", rio->obuf);
 
-       if (!(rio->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) {
+       if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
                err("probe_rio: Not enough memory for the input buffer");
                usb_deregister_dev(intf, &usb_rio_class);
                kfree(rio->obuf);
@@ -522,7 +522,6 @@ static struct usb_device_id rio_table [] = {
 MODULE_DEVICE_TABLE (usb, rio_table);
 
 static struct usb_driver rio_driver = {
-       .owner =        THIS_MODULE,
        .name =         "rio500",
        .probe =        probe_rio,
        .disconnect =   disconnect_rio,
index 41ef2b6..3260d59 100644 (file)
@@ -863,9 +863,6 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
 
            switch (length) {
 
-               case 0:
-                       return ret;
-
                case 1:
                        if (userbuffer) {
                                if (get_user(swap8, (u8 __user *)userbuffer))
@@ -1221,9 +1218,6 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
 
            switch (length) {
 
-               case 0:
-                       return ret;
-
                case 1:
 
                        ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM,
@@ -2443,8 +2437,8 @@ sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
        u8 *tempbuf;
        u16 *tempbufb;
        size_t written;
-       static char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
-       static char bootlogo[] = "(o_ //\\ V_/_";
+       static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
+       static const char bootlogo[] = "(o_ //\\ V_/_";
 
        /* sisusb->lock is down */
 
@@ -3489,7 +3483,6 @@ static struct usb_device_id sisusb_table [] = {
 MODULE_DEVICE_TABLE (usb, sisusb_table);
 
 static struct usb_driver sisusb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "sisusb",
        .probe =        sisusb_probe,
        .disconnect =   sisusb_disconnect,
index 85f3725..cc3dae3 100644 (file)
@@ -371,7 +371,6 @@ static void lcd_disconnect(struct usb_interface *interface)
 }
 
 static struct usb_driver lcd_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usblcd",
        .probe =        lcd_probe,
        .disconnect =   lcd_disconnect,
index 3c93921..877b081 100644 (file)
@@ -148,7 +148,6 @@ static void led_disconnect(struct usb_interface *interface)
 }
 
 static struct usb_driver led_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbled",
        .probe =        led_probe,
        .disconnect =   led_disconnect,
index 605a2af..84fa172 100644 (file)
@@ -2134,7 +2134,6 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver usbtest_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbtest",
        .id_table =     id_table,
        .probe =        usbtest_probe,
index 1cabe7e..4081990 100644 (file)
@@ -780,7 +780,6 @@ MODULE_DEVICE_TABLE (usb, uss720_table);
 
 
 static struct usb_driver uss720_driver = {
-       .owner =        THIS_MODULE,
        .name =         "uss720",
        .probe =        uss720_probe,
        .disconnect =   uss720_disconnect,
index 17d0190..6116121 100644 (file)
@@ -97,19 +97,12 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
        if (len >= DATA_MAX)
                len = DATA_MAX;
 
-       /*
-        * Bulk is easy to shortcut reliably. 
-        * XXX Other pipe types need consideration. Currently, we overdo it
-        * and collect garbage for them: better more than less.
-        */
-       if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) {
-               if (usb_pipein(pipe)) {
-                       if (ev_type == 'S')
-                               return '<';
-               } else {
-                       if (ev_type == 'C')
-                               return '>';
-               }
+       if (usb_pipein(pipe)) {
+               if (ev_type == 'S')
+                       return '<';
+       } else {
+               if (ev_type == 'C')
+                       return '>';
        }
 
        /*
index 542120e..5411816 100644 (file)
@@ -912,13 +912,16 @@ static const struct usb_device_id products [] = {
        // ASIX AX88772 10/100
         USB_DEVICE (0x0b95, 0x7720),
         .driver_info = (unsigned long) &ax88772_info,
+}, {
+       // Linksys USB200M Rev 2
+       USB_DEVICE (0x13b1, 0x0018),
+       .driver_info = (unsigned long) &ax88772_info,
 },
        { },            // END
 };
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver asix_driver = {
-       .owner =        THIS_MODULE,
        .name =         "asix",
        .id_table =     products,
        .probe =        usbnet_probe,
index 37ef365..be5f5e1 100644 (file)
@@ -934,7 +934,6 @@ static struct usb_device_id catc_id_table [] = {
 MODULE_DEVICE_TABLE(usb, catc_id_table);
 
 static struct usb_driver catc_driver = {
-       .owner =        THIS_MODULE,
        .name =         driver_name,
        .probe =        catc_probe,
        .disconnect =   catc_disconnect,
index c008c98..63f1f3b 100644 (file)
@@ -476,7 +476,6 @@ static const struct usb_device_id   products [] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver cdc_driver = {
-       .owner =        THIS_MODULE,
        .name =         "cdc_ether",
        .id_table =     products,
        .probe =        usbnet_probe,
index f05cfb8..ec801e8 100644 (file)
@@ -306,7 +306,6 @@ MODULE_DEVICE_TABLE(usb, products);
 /*-------------------------------------------------------------------------*/
 
 static struct usb_driver cdc_subset_driver = {
-       .owner =        THIS_MODULE,
        .name =         "cdc_subset",
        .probe =        usbnet_probe,
        .suspend =      usbnet_suspend,
index 2455e9a..faf1e86 100644 (file)
@@ -377,7 +377,6 @@ static const struct usb_device_id   products [] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver gl620a_driver = {
-       .owner =        THIS_MODULE,
        .name =         "gl620a",
        .id_table =     products,
        .probe =        usbnet_probe,
index b577651..def3bb8 100644 (file)
@@ -175,7 +175,6 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table);
  *     kaweth_driver
  ****************************************************************/
 static struct usb_driver kaweth_driver = {
-       .owner =        THIS_MODULE,
        .name =         driver_name,
        .probe =        kaweth_probe,
        .disconnect =   kaweth_disconnect,
index b3799b1..78e6a43 100644 (file)
@@ -593,7 +593,6 @@ static const struct usb_device_id   products [] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver net1080_driver = {
-       .owner =        THIS_MODULE,
        .name =         "net1080",
        .id_table =     products,
        .probe =        usbnet_probe,
index 683e3df..156a2f1 100644 (file)
@@ -45,7 +45,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.6.12 (2005/01/13)"
+#define DRIVER_VERSION "v0.6.13 (2005/11/13)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -57,12 +57,14 @@ static const char driver_name[] = "pegasus";
 
 static int loopback = 0;
 static int mii_mode = 0;
+static char *devid=NULL;
 
 static struct usb_eth_dev usb_dev_id[] = {
 #define        PEGASUS_DEV(pn, vid, pid, flags)        \
        {.name = pn, .vendor = vid, .device = pid, .private = flags},
 #include "pegasus.h"
 #undef PEGASUS_DEV
+       {NULL, 0, 0, 0},
        {NULL, 0, 0, 0}
 };
 
@@ -71,6 +73,7 @@ static struct usb_device_id pegasus_ids[] = {
        {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
 #include "pegasus.h"
 #undef PEGASUS_DEV
+       {},
        {}
 };
 
@@ -79,8 +82,10 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 module_param(loopback, bool, 0);
 module_param(mii_mode, bool, 0);
+module_param(devid, charp, 0);
 MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)");
 MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0");
+MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'");
 
 /* use ethtool to change the level for any given device */
 static int msg_level = -1;
@@ -113,7 +118,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs)
                break;
        default:
                if (netif_msg_drv(pegasus))
-                       dev_err(&pegasus->intf->dev, "%s, status %d\n",
+                       dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
                                __FUNCTION__, urb->status);
        }
        pegasus->flags &= ~ETH_REGS_CHANGED;
@@ -308,9 +313,9 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
        __le16 regdi;
        int ret;
 
-       ret = set_register(pegasus, PhyCtrl, 0);
-       ret = set_registers(pegasus, PhyAddr, sizeof (data), data);
-       ret = set_register(pegasus, PhyCtrl, (indx | PHY_READ));
+       set_register(pegasus, PhyCtrl, 0);
+       set_registers(pegasus, PhyAddr, sizeof (data), data);
+       set_register(pegasus, PhyCtrl, (indx | PHY_READ));
        for (i = 0; i < REG_TIMEOUT; i++) {
                ret = get_registers(pegasus, PhyCtrl, 1, data);
                if (data[0] & PHY_DONE)
@@ -319,12 +324,12 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
        if (i < REG_TIMEOUT) {
                ret = get_registers(pegasus, PhyData, 2, &regdi);
                *regd = le16_to_cpu(regdi);
-               return 1;
+               return ret;
        }
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
 
-       return 0;
+       return ret;
 }
 
 static int mdio_read(struct net_device *dev, int phy_id, int loc)
@@ -344,20 +349,20 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
 
        data[1] = (u8) regd;
        data[2] = (u8) (regd >> 8);
-       ret = set_register(pegasus, PhyCtrl, 0);
-       ret = set_registers(pegasus, PhyAddr, sizeof(data), data);
-       ret = set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
+       set_register(pegasus, PhyCtrl, 0);
+       set_registers(pegasus, PhyAddr, sizeof(data), data);
+       set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
        for (i = 0; i < REG_TIMEOUT; i++) {
                ret = get_registers(pegasus, PhyCtrl, 1, data);
                if (data[0] & PHY_DONE)
                        break;
        }
        if (i < REG_TIMEOUT)
-               return 0;
+               return ret;
 
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-       return 1;
+       return -ETIMEDOUT;
 }
 
 static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
@@ -374,9 +379,9 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
        __le16 retdatai;
        int ret;
 
-       ret = set_register(pegasus, EpromCtrl, 0);
-       ret = set_register(pegasus, EpromOffset, index);
-       ret = set_register(pegasus, EpromCtrl, EPROM_READ);
+       set_register(pegasus, EpromCtrl, 0);
+       set_register(pegasus, EpromOffset, index);
+       set_register(pegasus, EpromCtrl, EPROM_READ);
 
        for (i = 0; i < REG_TIMEOUT; i++) {
                ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
@@ -386,12 +391,12 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
        if (i < REG_TIMEOUT) {
                ret = get_registers(pegasus, EpromData, 2, &retdatai);
                *retdata = le16_to_cpu(retdatai);
-               return 0;
+               return ret;
        }
 
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-       return -1;
+       return -ETIMEDOUT;
 }
 
 #ifdef PEGASUS_WRITE_EEPROM
@@ -400,8 +405,8 @@ static inline void enable_eprom_write(pegasus_t * pegasus)
        __u8 tmp;
        int ret;
 
-       ret = get_registers(pegasus, EthCtrl2, 1, &tmp);
-       ret = set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
+       get_registers(pegasus, EthCtrl2, 1, &tmp);
+       set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
 }
 
 static inline void disable_eprom_write(pegasus_t * pegasus)
@@ -409,9 +414,9 @@ static inline void disable_eprom_write(pegasus_t * pegasus)
        __u8 tmp;
        int ret;
 
-       ret = get_registers(pegasus, EthCtrl2, 1, &tmp);
-       ret = set_register(pegasus, EpromCtrl, 0);
-       ret = set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
+       get_registers(pegasus, EthCtrl2, 1, &tmp);
+       set_register(pegasus, EpromCtrl, 0);
+       set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
 }
 
 static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
@@ -420,11 +425,11 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
        __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
        int ret;
 
-       ret = set_registers(pegasus, EpromOffset, 4, d);
+       set_registers(pegasus, EpromOffset, 4, d);
        enable_eprom_write(pegasus);
-       ret = set_register(pegasus, EpromOffset, index);
-       ret = set_registers(pegasus, EpromData, 2, &data);
-       ret = set_register(pegasus, EpromCtrl, EPROM_WRITE);
+       set_register(pegasus, EpromOffset, index);
+       set_registers(pegasus, EpromData, 2, &data);
+       set_register(pegasus, EpromCtrl, EPROM_WRITE);
 
        for (i = 0; i < REG_TIMEOUT; i++) {
                ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
@@ -433,10 +438,10 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
        }
        disable_eprom_write(pegasus);
        if (i < REG_TIMEOUT)
-               return 0;
+               return ret;
        if (netif_msg_drv(pegasus))
                dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-       return -1;
+       return -ETIMEDOUT;
 }
 #endif                         /* PEGASUS_WRITE_EEPROM */
 
@@ -454,10 +459,9 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id)
 static void set_ethernet_addr(pegasus_t * pegasus)
 {
        __u8 node_id[6];
-       int ret;
 
        get_node_id(pegasus, node_id);
-       ret = set_registers(pegasus, EthID, sizeof (node_id), node_id);
+       set_registers(pegasus, EthID, sizeof (node_id), node_id);
        memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id));
 }
 
@@ -465,30 +469,29 @@ static inline int reset_mac(pegasus_t * pegasus)
 {
        __u8 data = 0x8;
        int i;
-       int ret;
 
-       ret = set_register(pegasus, EthCtrl1, data);
+       set_register(pegasus, EthCtrl1, data);
        for (i = 0; i < REG_TIMEOUT; i++) {
-               ret = get_registers(pegasus, EthCtrl1, 1, &data);
+               get_registers(pegasus, EthCtrl1, 1, &data);
                if (~data & 0x08) {
                        if (loopback & 1)
                                break;
                        if (mii_mode && (pegasus->features & HAS_HOME_PNA))
-                               ret = set_register(pegasus, Gpio1, 0x34);
+                               set_register(pegasus, Gpio1, 0x34);
                        else
-                               ret = set_register(pegasus, Gpio1, 0x26);
-                       ret = set_register(pegasus, Gpio0, pegasus->features);
-                       ret = set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
+                               set_register(pegasus, Gpio1, 0x26);
+                       set_register(pegasus, Gpio0, pegasus->features);
+                       set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
                        break;
                }
        }
        if (i == REG_TIMEOUT)
-               return 1;
+               return -ETIMEDOUT;
 
        if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
            usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
-               ret = set_register(pegasus, Gpio0, 0x24);
-               ret = set_register(pegasus, Gpio0, 0x26);
+               set_register(pegasus, Gpio0, 0x24);
+               set_register(pegasus, Gpio0, 0x26);
        }
        if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
                __u16 auxmode;
@@ -527,7 +530,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
                write_mii_word(pegasus, 0, 0x1b, auxmode | 4);
        }
 
-       return 0;
+       return ret;
 }
 
 static void fill_skb_pool(pegasus_t * pegasus)
@@ -881,9 +884,8 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
 static inline void disable_net_traffic(pegasus_t * pegasus)
 {
        int tmp = 0;
-       int ret;
 
-       ret = set_registers(pegasus, EthCtrl0, 2, &tmp);
+       set_registers(pegasus, EthCtrl0, 2, &tmp);
 }
 
 static inline void get_interrupt_interval(pegasus_t * pegasus)
@@ -1206,18 +1208,17 @@ static __u8 mii_phy_probe(pegasus_t * pegasus)
 static inline void setup_pegasus_II(pegasus_t * pegasus)
 {
        __u8 data = 0xa5;
-       int ret;
        
-       ret = set_register(pegasus, Reg1d, 0);
-       ret = set_register(pegasus, Reg7b, 1);
+       set_register(pegasus, Reg1d, 0);
+       set_register(pegasus, Reg7b, 1);
        mdelay(100);
        if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
-               ret = set_register(pegasus, Reg7b, 0);
+               set_register(pegasus, Reg7b, 0);
        else
-               ret = set_register(pegasus, Reg7b, 2);
+               set_register(pegasus, Reg7b, 2);
 
-       ret = set_register(pegasus, 0x83, data);
-       ret = get_registers(pegasus, 0x83, 1, &data);
+       set_register(pegasus, 0x83, data);
+       get_registers(pegasus, 0x83, 1, &data);
 
        if (data == 0xa5) {
                pegasus->chip = 0x8513;
@@ -1225,14 +1226,14 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
                pegasus->chip = 0;
        }
 
-       ret = set_register(pegasus, 0x80, 0xc0);
-       ret = set_register(pegasus, 0x83, 0xff);
-       ret = set_register(pegasus, 0x84, 0x01);
+       set_register(pegasus, 0x80, 0xc0);
+       set_register(pegasus, 0x83, 0xff);
+       set_register(pegasus, 0x84, 0x01);
        
        if (pegasus->features & HAS_HOME_PNA && mii_mode)
-               ret = set_register(pegasus, Reg81, 6);
+               set_register(pegasus, Reg81, 6);
        else
-               ret = set_register(pegasus, Reg81, 2);
+               set_register(pegasus, Reg81, 2);
 }
 
 
@@ -1414,9 +1415,42 @@ static struct usb_driver pegasus_driver = {
        .resume = pegasus_resume,
 };
 
+static void parse_id(char *id)
+{
+       unsigned int vendor_id=0, device_id=0, flags=0, i=0;
+       char *token, *name=NULL;
+
+       if ((token = strsep(&id, ":")) != NULL)
+               name = token;
+       /* name now points to a null terminated string*/
+       if ((token = strsep(&id, ":")) != NULL)
+               vendor_id = simple_strtoul(token, NULL, 16);
+       if ((token = strsep(&id, ":")) != NULL)
+               device_id = simple_strtoul(token, NULL, 16);
+       flags = simple_strtoul(id, NULL, 16);
+       pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n",
+               driver_name, name, vendor_id, device_id, flags);
+
+       if (vendor_id > 0x10000 || vendor_id == 0)
+               return;
+       if (device_id > 0x10000 || device_id == 0)
+               return;
+
+       for (i=0; usb_dev_id[i].name; i++);
+       usb_dev_id[i].name = name;
+       usb_dev_id[i].vendor = vendor_id;
+       usb_dev_id[i].device = device_id;
+       usb_dev_id[i].private = flags;
+       pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+       pegasus_ids[i].idVendor = vendor_id;
+       pegasus_ids[i].idProduct = device_id;
+}
+
 static int __init pegasus_init(void)
 {
        pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
+       if (devid)
+               parse_id(devid);
        pegasus_workqueue = create_singlethread_workqueue("pegasus");
        if (!pegasus_workqueue)
                return -ENOMEM;
index 89856aa..4fe8633 100644 (file)
@@ -127,7 +127,6 @@ static const struct usb_device_id   products [] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver plusb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "plusb",
        .id_table =     products,
        .probe =        usbnet_probe,
index c0ecbab..49991ac 100644 (file)
@@ -586,7 +586,6 @@ static const struct usb_device_id   products [] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver rndis_driver = {
-       .owner =        THIS_MODULE,
        .name =         "rndis_host",
        .id_table =     products,
        .probe =        usbnet_probe,
index 787dd35..8ca52be 100644 (file)
@@ -177,7 +177,6 @@ static int rtl8150_probe(struct usb_interface *intf,
 static const char driver_name [] = "rtl8150";
 
 static struct usb_driver rtl8150_driver = {
-       .owner =        THIS_MODULE,
        .name =         driver_name,
        .probe =        rtl8150_probe,
        .disconnect =   rtl8150_disconnect,
index 680d139..9c5ab25 100644 (file)
@@ -357,7 +357,6 @@ static const struct usb_device_id   products [] = {
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver zaurus_driver = {
-       .owner =        THIS_MODULE,
        .name =         "zaurus",
        .id_table =     products,
        .probe =        usbnet_probe,
index 2f52261..f3a8e28 100644 (file)
@@ -1722,7 +1722,7 @@ static const struct iw_priv_args zd1201_private_args[] = {
            IW_PRIV_TYPE_NONE, "sethostauth" },
        { ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE,
            IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" },
-       { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 
+       { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1,
            IW_PRIV_TYPE_NONE, "authstation" },
        { ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
            IW_PRIV_TYPE_NONE, "setmaxassoc" },
@@ -1731,9 +1731,9 @@ static const struct iw_priv_args zd1201_private_args[] = {
 };
 
 static const struct iw_handler_def zd1201_iw_handlers = {
-       .num_standard           = sizeof(zd1201_iw_handler)/sizeof(iw_handler),
-       .num_private            = sizeof(zd1201_private_handler)/sizeof(iw_handler),
-       .num_private_args       = sizeof(zd1201_private_args)/sizeof(struct iw_priv_args),
+       .num_standard           = ARRAY_SIZE(zd1201_iw_handler),
+       .num_private            = ARRAY_SIZE(zd1201_private_handler),
+       .num_private_args       = ARRAY_SIZE(zd1201_private_args),
        .standard               = (iw_handler *)zd1201_iw_handler,
        .private                = (iw_handler *)zd1201_private_handler,
        .private_args           = (struct iw_priv_args *) zd1201_private_args,
@@ -1829,6 +1829,8 @@ static int zd1201_probe(struct usb_interface *interface,
        if (err)
                goto err_net;
 
+       SET_NETDEV_DEV(zd->dev, &usb->dev);
+
        err = register_netdev(zd->dev);
        if (err)
                goto err_net;
@@ -1923,7 +1925,6 @@ static int zd1201_resume(struct usb_interface *interface)
 #endif
 
 static struct usb_driver zd1201_usb = {
-       .owner = THIS_MODULE,
        .name = "zd1201",
        .probe = zd1201_probe,
        .disconnect = zd1201_disconnect,
index 1f29d88..dbf1f06 100644 (file)
@@ -23,11 +23,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver airprime_driver = {
-       .owner =        THIS_MODULE,
        .name =         "airprime",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_serial_driver airprime_device = {
index 18022a7..343f6f2 100644 (file)
@@ -27,11 +27,11 @@ static int buffer_size;
 static int debug;
 
 static struct usb_driver anydata_driver = {
-       .owner =        THIS_MODULE,
        .name =         "anydata",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 static int anydata_open(struct usb_serial_port *port, struct file *filp)
index 84bc0ee..4144777 100644 (file)
@@ -113,11 +113,11 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver belkin_driver = {
-       .owner =        THIS_MODULE,
        .name =         "belkin",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 /* All of the device info needed for the serial converters */
index c978700..da46b35 100644 (file)
@@ -67,11 +67,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver cp2101_driver = {
-       .owner          = THIS_MODULE,
        .name           = "cp2101",
        .probe          = usb_serial_probe,
        .disconnect     = usb_serial_disconnect,
        .id_table       = id_table,
+       .no_dynamic_id  =       1,
 };
 
 static struct usb_serial_driver cp2101_device = {
index e581e4a..6d18d4e 100644 (file)
@@ -76,11 +76,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver cyberjack_driver = {
-       .owner =        THIS_MODULE,
        .name =         "cyberjack",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_serial_driver cyberjack_device = {
index af9290e..af18355 100644 (file)
@@ -112,6 +112,7 @@ static struct usb_driver cypress_driver = {
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 struct cypress_private {
index dc74644..8fc414b 100644 (file)
@@ -493,11 +493,11 @@ static struct usb_device_id id_table_4 [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver digi_driver = {
-       .owner =        THIS_MODULE,
        .name =         "digi_acceleport",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 
index 0b0546d..79a766e 100644 (file)
@@ -105,11 +105,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver empeg_driver = {
-       .owner =        THIS_MODULE,
        .name =         "empeg",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_serial_driver empeg_device = {
index 06e04b4..eb863b3 100644 (file)
@@ -471,12 +471,15 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
        { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
        { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
        { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
+       { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
@@ -488,9 +491,10 @@ static struct usb_driver ftdi_driver = {
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
-static char *ftdi_chip_name[] = {
+static const char *ftdi_chip_name[] = {
        [SIO] = "SIO",  /* the serial part of FT8U100AX */
        [FT8U232AM] = "FT8U232AM",
        [FT232BM] = "FT232BM",
index 773ea3e..f380f9e 100644 (file)
 #define XSENS_CONVERTER_6_PID  0xD38E
 #define XSENS_CONVERTER_7_PID  0xD38F
 
+/*
+ * Teratronik product ids.
+ * Submitted by O. Wölfelschneider.
+ */
+#define FTDI_TERATRONIK_VCP_PID         0xEC88 /* Teratronik device (preferring VCP driver on windows) */
+#define FTDI_TERATRONIK_D2XX_PID 0xEC89        /* Teratronik device (preferring D2XX driver on windows) */
+
 /*
  * Evolution Robotics products (http://www.evolution.com/).
  * Submitted by Shawn M. Lavelle.
 /* Pyramid Computer GmbH */
 #define FTDI_PYRAMID_PID       0xE6C8  /* Pyramid Appliance Display */
 
+/*
+ * Posiflex inc retail equipment (http://www.posiflex.com.tw)
+ */
+#define POSIFLEX_VID           0x0d3a  /* Vendor ID */
+#define POSIFLEX_PP7000_PID    0x0300  /* PP-7000II thermal printer */
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
index 35820bd..452efce 100644 (file)
@@ -222,11 +222,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver garmin_driver = {
-       .owner =        THIS_MODULE,
        .name =         "garmin_gps",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 
index 53a47c3..4ddac62 100644 (file)
@@ -68,11 +68,11 @@ static int generic_probe(struct usb_interface *interface,
 }
 
 static struct usb_driver generic_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbserial_generic",
        .probe =        generic_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     generic_serial_ids,
+       .no_dynamic_id =        1,
 };
 #endif
 
index 8eadfb7..e9719da 100644 (file)
@@ -37,11 +37,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver hp49gp_driver = {
-       .owner =        THIS_MODULE,
        .name =         "hp4X",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_serial_driver hp49gp_device = {
index dc4c498..faedbeb 100644 (file)
@@ -184,7 +184,7 @@ struct divisor_table_entry {
 // These assume a 3.6864MHz crystal, the standard /16, and
 // MCR.7 = 0.
 //
-static struct divisor_table_entry divisor_table[] = {
+static const struct divisor_table_entry divisor_table[] = {
        {   50,         4608},  
        {   75,         3072},  
        {   110,        2095},          /* 2094.545455 => 230450   => .0217 % over */
@@ -242,11 +242,11 @@ static void edge_shutdown         (struct usb_serial *serial);
 #include "io_tables.h" /* all of the devices that this driver supports */
 
 static struct usb_driver io_driver = {
-       .owner =        THIS_MODULE,
        .name =         "io_edgeport",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 /* function prototypes for all of our local functions */
@@ -2353,7 +2353,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor)
 
        dbg("%s - %d", __FUNCTION__, baudrate);
 
-       for (i = 0; i < NUM_ENTRIES(divisor_table); i++) {
+       for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
                if ( divisor_table[i].BaudRate == baudrate ) {
                        *divisor = divisor_table[i].Divisor;
                        return 0;
index 5112d7a..123fa8a 100644 (file)
@@ -31,9 +31,6 @@
 #ifndef HIGH8
        #define HIGH8(a)        ((unsigned char)((a & 0xff00) >> 8))
 #endif
-#ifndef NUM_ENTRIES
-       #define NUM_ENTRIES(x)  (sizeof(x)/sizeof((x)[0]))
-#endif
 
 #ifndef __KERNEL__
 #define __KERNEL__
index c7c3a3c..e3463de 100644 (file)
@@ -537,7 +537,7 @@ static unsigned char IMAGE_ARRAY_NAME[] = {
 
 };
 
-static struct edge_firmware_version_info IMAGE_VERSION_NAME = {
+static const struct edge_firmware_version_info IMAGE_VERSION_NAME = {
        2, 0, 3 };              // Major, Minor, Build
 
 #undef IMAGE_VERSION_NAME
index 832b6d6..2edf9ca 100644 (file)
@@ -216,11 +216,11 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver io_driver = {
-       .owner =        THIS_MODULE,
        .name =         "io_ti",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 
@@ -2843,7 +2843,7 @@ static struct edge_buf *edge_buf_alloc(unsigned int size)
  * Free the buffer and all associated memory.
  */
 
-void edge_buf_free(struct edge_buf *eb)
+static void edge_buf_free(struct edge_buf *eb)
 {
        if (eb) {
                kfree(eb->buf_buf);
index d5d0664..06d07ce 100644 (file)
@@ -542,11 +542,11 @@ static struct usb_device_id ipaq_id_table [] = {
 MODULE_DEVICE_TABLE (usb, ipaq_id_table);
 
 static struct usb_driver ipaq_driver = {
-       .owner =        THIS_MODULE,
        .name =         "ipaq",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     ipaq_id_table,
+       .no_dynamic_id =        1,
 };
 
 
index 7744b81..2dd191f 100644 (file)
@@ -152,11 +152,11 @@ static struct usb_device_id usb_ipw_ids[] = {
 MODULE_DEVICE_TABLE(usb, usb_ipw_ids);
 
 static struct usb_driver usb_ipw_driver = {
-       .owner =        THIS_MODULE,
        .name =         "ipwtty",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     usb_ipw_ids,
+       .no_dynamic_id =        1,
 };
 
 static int debug;
index 19f329e..a590104 100644 (file)
@@ -125,11 +125,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver ir_driver = {
-       .owner =        THIS_MODULE,
        .name =         "ir-usb",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 
index 5cfc13b..7472ed6 100644 (file)
@@ -520,11 +520,11 @@ static struct usb_device_id keyspan_ids_combined[] = {
 MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
 
 static struct usb_driver keyspan_driver = {
-       .owner =        THIS_MODULE,
        .name =         "keyspan",                
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     keyspan_ids_combined,
+       .no_dynamic_id =        1,
 };
 
 /* usb_device_id table for the pre-firmware download keyspan devices */
index cd4f48b..b0441c3 100644 (file)
@@ -150,11 +150,11 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver keyspan_pda_driver = {
-       .owner =        THIS_MODULE,
        .name =         "keyspan_pda",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_device_id id_table_std [] = {
index a8951c0..4e2f7df 100644 (file)
@@ -116,11 +116,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver kl5kusb105d_driver = {
-       .owner =        THIS_MODULE,
        .name =         "kl5kusb105d",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_serial_driver kl5kusb105d_device = {
index 9456dd9..d9c21e2 100644 (file)
@@ -97,11 +97,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver kobil_driver = {
-       .owner =        THIS_MODULE,
        .name =         "kobil",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 
index ca5dbad..b6d6cab 100644 (file)
@@ -125,11 +125,11 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver mct_u232_driver = {
-       .owner =        THIS_MODULE,
        .name =         "mct_u232",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_serial_driver mct_u232_device = {
index 3caf970..762d8ff 100644 (file)
@@ -80,11 +80,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver omninet_driver = {
-       .owner =        THIS_MODULE,
        .name =         "omninet",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 
index 7716000..3fd2405 100644 (file)
@@ -95,11 +95,11 @@ static struct usb_device_id option_ids[] = {
 MODULE_DEVICE_TABLE(usb, option_ids);
 
 static struct usb_driver option_driver = {
-       .owner      = THIS_MODULE,
        .name       = "option",
        .probe      = usb_serial_probe,
        .disconnect = usb_serial_disconnect,
        .id_table   = option_ids,
+       .no_dynamic_id =        1,
 };
 
 /* The card has three separate interfaces, wich the serial driver
index 41a45a5..f037210 100644 (file)
@@ -82,11 +82,11 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver pl2303_driver = {
-       .owner =        THIS_MODULE,
        .name =         "pl2303",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 #define SET_LINE_REQUEST_TYPE          0x21
@@ -810,7 +810,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        u8 status_idx = UART_STATE;
-       u8 length = UART_STATE;
+       u8 length = UART_STATE + 1;
 
        if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
            (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 ||
index c22bdc0..f0215f8 100644 (file)
@@ -160,14 +160,14 @@ static struct usb_device_id id_table[] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver safe_driver = {
-       .owner =        THIS_MODULE,
        .name =         "safe_serial",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
-static __u16 crc10_table[256] = {
+static const __u16 crc10_table[256] = {
        0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
        0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
        0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
@@ -425,7 +425,7 @@ static int __init safe_init (void)
        if (vendor || product) {
                info ("vendor: %x product: %x\n", vendor, product);
 
-               for (i = 0; i < (sizeof (id_table) / sizeof (struct usb_device_id)); i++) {
+               for (i = 0; i < ARRAY_SIZE(id_table); i++) {
                        if (!id_table[i].idVendor && !id_table[i].idProduct) {
                                id_table[i].idVendor = vendor;
                                id_table[i].idProduct = product;
index 205dbf7..abb830c 100644 (file)
@@ -248,11 +248,11 @@ static struct usb_device_id ti_id_table_combined[] = {
 };
 
 static struct usb_driver ti_usb_driver = {
-       .owner                  = THIS_MODULE,
        .name                   = "ti_usb_3410_5052",
        .probe                  = usb_serial_probe,
        .disconnect             = usb_serial_disconnect,
        .id_table               = ti_id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_serial_driver ti_1port_device = {
@@ -351,17 +351,14 @@ static int __init ti_init(void)
        int i,j;
        int ret;
 
-
        /* insert extra vendor and product ids */
-       j = sizeof(ti_id_table_3410)/sizeof(struct usb_device_id)
-               - TI_EXTRA_VID_PID_COUNT - 1;
+       j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1;
        for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) {
                ti_id_table_3410[j].idVendor = vendor_3410[i];
                ti_id_table_3410[j].idProduct = product_3410[i];
                ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
        }
-       j = sizeof(ti_id_table_5052)/sizeof(struct usb_device_id)
-               - TI_EXTRA_VID_PID_COUNT - 1;
+       j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1;
        for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) {
                ti_id_table_5052[j].idVendor = vendor_5052[i];
                ti_id_table_5052[j].idProduct = product_5052[i];
index 0c4881d..8bc8337 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/list.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 #include <linux/usb.h>
 #include "usb-serial.h"
 #include "pl2303.h"
 
 /* Driver structure we register with the USB core */
 static struct usb_driver usb_serial_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usbserial",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
+       .no_dynamic_id =        1,
 };
 
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
@@ -188,6 +189,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
 
        portNumber = tty->index - serial->minor;
        port = serial->port[portNumber];
+       if (!port)
+               return -ENODEV;
+
+       if (down_interruptible(&port->sem))
+               return -ERESTARTSYS;
         
        ++port->open_count;
 
@@ -213,6 +219,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
                        goto bailout_module_put;
        }
 
+       up(&port->sem);
        return 0;
 
 bailout_module_put:
@@ -220,6 +227,7 @@ bailout_module_put:
 bailout_kref_put:
        kref_put(&serial->kref, destroy_serial);
        port->open_count = 0;
+       up(&port->sem);
        return retval;
 }
 
@@ -232,8 +240,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
+       down(&port->sem);
+
        if (port->open_count == 0)
-               return;
+               goto out;
 
        --port->open_count;
        if (port->open_count == 0) {
@@ -251,6 +261,9 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
        }
 
        kref_put(&port->serial->kref, destroy_serial);
+
+out:
+       up(&port->sem);
 }
 
 static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
@@ -258,6 +271,9 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int
        struct usb_serial_port *port = tty->driver_data;
        int retval = -EINVAL;
 
+       if (!port)
+               goto exit;
+
        dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
 
        if (!port->open_count) {
@@ -277,6 +293,9 @@ static int serial_write_room (struct tty_struct *tty)
        struct usb_serial_port *port = tty->driver_data;
        int retval = -EINVAL;
 
+       if (!port)
+               goto exit;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -296,6 +315,9 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
        struct usb_serial_port *port = tty->driver_data;
        int retval = -EINVAL;
 
+       if (!port)
+               goto exit;
+
        dbg("%s = port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -314,6 +336,9 @@ static void serial_throttle (struct tty_struct * tty)
 {
        struct usb_serial_port *port = tty->driver_data;
 
+       if (!port)
+               return;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -330,6 +355,9 @@ static void serial_unthrottle (struct tty_struct * tty)
 {
        struct usb_serial_port *port = tty->driver_data;
 
+       if (!port)
+               return;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -347,6 +375,9 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
        struct usb_serial_port *port = tty->driver_data;
        int retval = -ENODEV;
 
+       if (!port)
+               goto exit;
+
        dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
 
        if (!port->open_count) {
@@ -368,6 +399,9 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 {
        struct usb_serial_port *port = tty->driver_data;
 
+       if (!port)
+               return;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -384,6 +418,9 @@ static void serial_break (struct tty_struct *tty, int break_state)
 {
        struct usb_serial_port *port = tty->driver_data;
 
+       if (!port)
+               return;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -445,6 +482,9 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file)
 {
        struct usb_serial_port *port = tty->driver_data;
 
+       if (!port)
+               goto exit;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -464,6 +504,9 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file,
 {
        struct usb_serial_port *port = tty->driver_data;
 
+       if (!port)
+               goto exit;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        if (!port->open_count) {
@@ -742,6 +785,7 @@ int usb_serial_probe(struct usb_interface *interface,
                port->number = i + serial->minor;
                port->serial = serial;
                spin_lock_init(&port->lock);
+               sema_init(&port->sem, 1);
                INIT_WORK(&port->work, usb_serial_port_softint, port);
                serial->port[i] = port;
        }
index 238a5a8..d7d27c3 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/config.h>
 #include <linux/kref.h>
+#include <asm/semaphore.h>
 
 #define SERIAL_TTY_MAJOR       188     /* Nice legal number now */
 #define SERIAL_TTY_MINORS      255     /* loads of devices :) */
@@ -30,6 +31,8 @@
  * @serial: pointer back to the struct usb_serial owner of this port.
  * @tty: pointer to the corresponding tty for this port.
  * @lock: spinlock to grab when updating portions of this structure.
+ * @sem: semaphore used to synchronize serial_open() and serial_close()
+ *     access for this port.
  * @number: the number of the port (the minor number).
  * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
  * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -60,6 +63,7 @@ struct usb_serial_port {
        struct usb_serial *     serial;
        struct tty_struct *     tty;
        spinlock_t              lock;
+       struct semaphore        sem;
        unsigned char           number;
 
        unsigned char *         interrupt_in_buffer;
index a473c1c..49b1fbe 100644 (file)
@@ -173,11 +173,11 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver visor_driver = {
-       .owner =        THIS_MODULE,
        .name =         "visor",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
index 18c3183..a7c3c47 100644 (file)
@@ -127,11 +127,11 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver whiteheat_driver = {
-       .owner =        THIS_MODULE,
        .name =         "whiteheat",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
index c41d64d..92be101 100644 (file)
@@ -112,6 +112,15 @@ config USB_STORAGE_JUMPSHOT
          Say Y here to include additional code to support the Lexar Jumpshot
          USB CompactFlash reader.
 
+config USB_STORAGE_ALAUDA
+       bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)"
+       depends on USB_STORAGE && EXPERIMENTAL
+       help
+         Say Y here to include additional code to support the Olympus MAUSB-10
+         and Fujifilm DPC-R1 USB Card reader/writer devices.
+
+         These devices are based on the Alauda chip and support support both
+         XD and SmartMedia cards.
 
 config USB_STORAGE_ONETOUCH
        bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
@@ -124,3 +133,17 @@ config USB_STORAGE_ONETOUCH
          hard drive's as an input device. An action can be associated with
          this input in any keybinding software. (e.g. gnome's keyboard short-
          cuts)
+
+config USB_LIBUSUAL
+       bool "The shared table of common (or usual) storage devices"
+       depends on USB
+       help
+         This module contains a table of common (or usual) devices
+         for usb-storage and ub drivers, and allows to switch binding
+         of these devices without rebuilding modules.
+
+         Typical syntax of /etc/modprobe.conf is:
+
+               options libusual bias="ub"
+
+         If unsure, say N.
index 44ab8f9..8cbba22 100644 (file)
@@ -18,7 +18,12 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM)   += dpcm.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)   += isd200.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)  += datafab.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
+usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA)   += alauda.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
 
 usb-storage-objs :=    scsiglue.o protocol.o transport.o usb.o \
                        initializers.o $(usb-storage-obj-y)
+
+ifneq ($(CONFIG_USB_LIBUSUAL),)
+       obj-$(CONFIG_USB)       += libusual.o
+endif
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
new file mode 100644 (file)
index 0000000..4d3cbb1
--- /dev/null
@@ -0,0 +1,1119 @@
+/*
+ * Driver for Alauda-based card readers
+ *
+ * Current development and maintenance by:
+ *   (c) 2005 Daniel Drake <dsd@gentoo.org>
+ *
+ * The 'Alauda' is a chip manufacturered by RATOC for OEM use.
+ *
+ * Alauda implements a vendor-specific command set to access two media reader
+ * ports (XD, SmartMedia). This driver converts SCSI commands to the commands
+ * which are accepted by these devices.
+ *
+ * The driver was developed through reverse-engineering, with the help of the
+ * sddr09 driver which has many similarities, and with some help from the
+ * (very old) vendor-supplied GPL sma03 driver.
+ *
+ * For protocol info, see http://alauda.sourceforge.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, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "transport.h"
+#include "protocol.h"
+#include "debug.h"
+#include "alauda.h"
+
+#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
+#define LSB_of(s) ((s)&0xFF)
+#define MSB_of(s) ((s)>>8)
+
+#define MEDIA_PORT(us) us->srb->device->lun
+#define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)]
+
+#define PBA_LO(pba) ((pba & 0xF) << 5)
+#define PBA_HI(pba) (pba >> 3)
+#define PBA_ZONE(pba) (pba >> 11)
+
+/*
+ * Media handling
+ */
+
+struct alauda_card_info {
+       unsigned char id;               /* id byte */
+       unsigned char chipshift;        /* 1<<cs bytes total capacity */
+       unsigned char pageshift;        /* 1<<ps bytes in a page */
+       unsigned char blockshift;       /* 1<<bs pages per block */
+       unsigned char zoneshift;        /* 1<<zs blocks per zone */
+};
+
+static struct alauda_card_info alauda_card_ids[] = {
+       /* NAND flash */
+       { 0x6e, 20, 8, 4, 8},   /* 1 MB */
+       { 0xe8, 20, 8, 4, 8},   /* 1 MB */
+       { 0xec, 20, 8, 4, 8},   /* 1 MB */
+       { 0x64, 21, 8, 4, 9},   /* 2 MB */
+       { 0xea, 21, 8, 4, 9},   /* 2 MB */
+       { 0x6b, 22, 9, 4, 9},   /* 4 MB */
+       { 0xe3, 22, 9, 4, 9},   /* 4 MB */
+       { 0xe5, 22, 9, 4, 9},   /* 4 MB */
+       { 0xe6, 23, 9, 4, 10},  /* 8 MB */
+       { 0x73, 24, 9, 5, 10},  /* 16 MB */
+       { 0x75, 25, 9, 5, 10},  /* 32 MB */
+       { 0x76, 26, 9, 5, 10},  /* 64 MB */
+       { 0x79, 27, 9, 5, 10},  /* 128 MB */
+       { 0x71, 28, 9, 5, 10},  /* 256 MB */
+
+       /* MASK ROM */
+       { 0x5d, 21, 9, 4, 8},   /* 2 MB */
+       { 0xd5, 22, 9, 4, 9},   /* 4 MB */
+       { 0xd6, 23, 9, 4, 10},  /* 8 MB */
+       { 0x57, 24, 9, 4, 11},  /* 16 MB */
+       { 0x58, 25, 9, 4, 12},  /* 32 MB */
+       { 0,}
+};
+
+static struct alauda_card_info *alauda_card_find_id(unsigned char id) {
+       int i;
+
+       for (i = 0; alauda_card_ids[i].id != 0; i++)
+               if (alauda_card_ids[i].id == id)
+                       return &(alauda_card_ids[i]);
+       return NULL;
+}
+
+/*
+ * ECC computation.
+ */
+
+static unsigned char parity[256];
+static unsigned char ecc2[256];
+
+static void nand_init_ecc(void) {
+       int i, j, a;
+
+       parity[0] = 0;
+       for (i = 1; i < 256; i++)
+               parity[i] = (parity[i&(i-1)] ^ 1);
+
+       for (i = 0; i < 256; i++) {
+               a = 0;
+               for (j = 0; j < 8; j++) {
+                       if (i & (1<<j)) {
+                               if ((j & 1) == 0)
+                                       a ^= 0x04;
+                               if ((j & 2) == 0)
+                                       a ^= 0x10;
+                               if ((j & 4) == 0)
+                                       a ^= 0x40;
+                       }
+               }
+               ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0));
+       }
+}
+
+/* compute 3-byte ecc on 256 bytes */
+static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) {
+       int i, j, a;
+       unsigned char par, bit, bits[8];
+
+       par = 0;
+       for (j = 0; j < 8; j++)
+               bits[j] = 0;
+
+       /* collect 16 checksum bits */
+       for (i = 0; i < 256; i++) {
+               par ^= data[i];
+               bit = parity[data[i]];
+               for (j = 0; j < 8; j++)
+                       if ((i & (1<<j)) == 0)
+                               bits[j] ^= bit;
+       }
+
+       /* put 4+4+4 = 12 bits in the ecc */
+       a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0];
+       ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));
+
+       a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4];
+       ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));
+
+       ecc[2] = ecc2[par];
+}
+
+static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) {
+       return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]);
+}
+
+static void nand_store_ecc(unsigned char *data, unsigned char *ecc) {
+       memcpy(data, ecc, 3);
+}
+
+/*
+ * Alauda driver
+ */
+
+/*
+ * Forget our PBA <---> LBA mappings for a particular port
+ */
+static void alauda_free_maps (struct alauda_media_info *media_info)
+{
+       unsigned int shift = media_info->zoneshift
+               + media_info->blockshift + media_info->pageshift;
+       unsigned int num_zones = media_info->capacity >> shift;
+       unsigned int i;
+
+       if (media_info->lba_to_pba != NULL)
+               for (i = 0; i < num_zones; i++) {
+                       kfree(media_info->lba_to_pba[i]);
+                       media_info->lba_to_pba[i] = NULL;
+               }
+
+       if (media_info->pba_to_lba != NULL)
+               for (i = 0; i < num_zones; i++) {
+                       kfree(media_info->pba_to_lba[i]);
+                       media_info->pba_to_lba[i] = NULL;
+               }
+}
+
+/*
+ * Returns 2 bytes of status data
+ * The first byte describes media status, and second byte describes door status
+ */
+static int alauda_get_media_status(struct us_data *us, unsigned char *data)
+{
+       int rc;
+       unsigned char command;
+
+       if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+               command = ALAUDA_GET_XD_MEDIA_STATUS;
+       else
+               command = ALAUDA_GET_SM_MEDIA_STATUS;
+
+       rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
+               command, 0xc0, 0, 1, data, 2);
+
+       US_DEBUGP("alauda_get_media_status: Media status %02X %02X\n",
+               data[0], data[1]);
+
+       return rc;
+}
+
+/*
+ * Clears the "media was changed" bit so that we know when it changes again
+ * in the future.
+ */
+static int alauda_ack_media(struct us_data *us)
+{
+       unsigned char command;
+
+       if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+               command = ALAUDA_ACK_XD_MEDIA_CHANGE;
+       else
+               command = ALAUDA_ACK_SM_MEDIA_CHANGE;
+
+       return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
+               command, 0x40, 0, 1, NULL, 0);
+}
+
+/*
+ * Retrieves a 4-byte media signature, which indicates manufacturer, capacity,
+ * and some other details.
+ */
+static int alauda_get_media_signature(struct us_data *us, unsigned char *data)
+{
+       unsigned char command;
+
+       if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+               command = ALAUDA_GET_XD_MEDIA_SIG;
+       else
+               command = ALAUDA_GET_SM_MEDIA_SIG;
+
+       return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
+               command, 0xc0, 0, 0, data, 4);
+}
+
+/*
+ * Resets the media status (but not the whole device?)
+ */
+static int alauda_reset_media(struct us_data *us)
+{
+       unsigned char *command = us->iobuf;
+
+       memset(command, 0, 9);
+       command[0] = ALAUDA_BULK_CMD;
+       command[1] = ALAUDA_BULK_RESET_MEDIA;
+       command[8] = MEDIA_PORT(us);
+
+       return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+               command, 9, NULL);
+}
+
+/*
+ * Examines the media and deduces capacity, etc.
+ */
+static int alauda_init_media(struct us_data *us)
+{
+       unsigned char *data = us->iobuf;
+       int ready = 0;
+       struct alauda_card_info *media_info;
+       unsigned int num_zones;
+
+       while (ready == 0) {
+               msleep(20);
+
+               if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
+                       return USB_STOR_TRANSPORT_ERROR;
+
+               if (data[0] & 0x10)
+                       ready = 1;
+       }
+
+       US_DEBUGP("alauda_init_media: We are ready for action!\n");
+
+       if (alauda_ack_media(us) != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
+
+       msleep(10);
+
+       if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
+
+       if (data[0] != 0x14) {
+               US_DEBUGP("alauda_init_media: Media not ready after ack\n");
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
+
+       US_DEBUGP("alauda_init_media: Media signature: %02X %02X %02X %02X\n",
+               data[0], data[1], data[2], data[3]);
+       media_info = alauda_card_find_id(data[1]);
+       if (media_info == NULL) {
+               printk("alauda_init_media: Unrecognised media signature: "
+                       "%02X %02X %02X %02X\n",
+                       data[0], data[1], data[2], data[3]);
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       MEDIA_INFO(us).capacity = 1 << media_info->chipshift;
+       US_DEBUGP("Found media with capacity: %ldMB\n",
+               MEDIA_INFO(us).capacity >> 20);
+
+       MEDIA_INFO(us).pageshift = media_info->pageshift;
+       MEDIA_INFO(us).blockshift = media_info->blockshift;
+       MEDIA_INFO(us).zoneshift = media_info->zoneshift;
+
+       MEDIA_INFO(us).pagesize = 1 << media_info->pageshift;
+       MEDIA_INFO(us).blocksize = 1 << media_info->blockshift;
+       MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift;
+
+       MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125;
+       MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1;
+
+       num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
+               + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+       MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+       MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+
+       if (alauda_reset_media(us) != USB_STOR_XFER_GOOD)
+               return USB_STOR_TRANSPORT_ERROR;
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Examines the media status and does the right thing when the media has gone,
+ * appeared, or changed.
+ */
+static int alauda_check_media(struct us_data *us)
+{
+       struct alauda_info *info = (struct alauda_info *) us->extra;
+       unsigned char status[2];
+       int rc;
+
+       rc = alauda_get_media_status(us, status);
+
+       /* Check for no media or door open */
+       if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10)
+               || ((status[1] & 0x01) == 0)) {
+               US_DEBUGP("alauda_check_media: No media, or door open\n");
+               alauda_free_maps(&MEDIA_INFO(us));
+               info->sense_key = 0x02;
+               info->sense_asc = 0x3A;
+               info->sense_ascq = 0x00;
+               return USB_STOR_TRANSPORT_FAILED;
+       }
+
+       /* Check for media change */
+       if (status[0] & 0x08) {
+               US_DEBUGP("alauda_check_media: Media change detected\n");
+               alauda_free_maps(&MEDIA_INFO(us));
+               alauda_init_media(us);
+
+               info->sense_key = UNIT_ATTENTION;
+               info->sense_asc = 0x28;
+               info->sense_ascq = 0x00;
+               return USB_STOR_TRANSPORT_FAILED;
+       }
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Checks the status from the 2nd status register
+ * Returns 3 bytes of status data, only the first is known
+ */
+static int alauda_check_status2(struct us_data *us)
+{
+       int rc;
+       unsigned char command[] = {
+               ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2,
+               0, 0, 0, 0, 3, 0, MEDIA_PORT(us)
+       };
+       unsigned char data[3];
+
+       rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+               command, 9, NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+               data, 3, NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       US_DEBUGP("alauda_check_status2: %02X %02X %02X\n", data[0], data[1], data[2]);
+       if (data[0] & ALAUDA_STATUS_ERROR)
+               return USB_STOR_XFER_ERROR;
+
+       return USB_STOR_XFER_GOOD;
+}
+
+/*
+ * Gets the redundancy data for the first page of a PBA
+ * Returns 16 bytes.
+ */
+static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data)
+{
+       int rc;
+       unsigned char command[] = {
+               ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA,
+               PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us)
+       };
+
+       rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+               command, 9, NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+               data, 16, NULL);
+}
+
+/*
+ * Finds the first unused PBA in a zone
+ * Returns the absolute PBA of an unused PBA, or 0 if none found.
+ */
+static u16 alauda_find_unused_pba(struct alauda_media_info *info,
+       unsigned int zone)
+{
+       u16 *pba_to_lba = info->pba_to_lba[zone];
+       unsigned int i;
+
+       for (i = 0; i < info->zonesize; i++)
+               if (pba_to_lba[i] == UNDEF)
+                       return (zone << info->zoneshift) + i;
+
+       return 0;
+}
+
+/*
+ * Reads the redundancy data for all PBA's in a zone
+ * Produces lba <--> pba mappings
+ */
+static int alauda_read_map(struct us_data *us, unsigned int zone)
+{
+       unsigned char *data = us->iobuf;
+       int result;
+       int i, j;
+       unsigned int zonesize = MEDIA_INFO(us).zonesize;
+       unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+       unsigned int lba_offset, lba_real, blocknum;
+       unsigned int zone_base_lba = zone * uzonesize;
+       unsigned int zone_base_pba = zone * zonesize;
+       u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
+       u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
+       if (lba_to_pba == NULL || pba_to_lba == NULL) {
+               result = USB_STOR_TRANSPORT_ERROR;
+               goto error;
+       }
+
+       US_DEBUGP("alauda_read_map: Mapping blocks for zone %d\n", zone);
+
+       /* 1024 PBA's per zone */
+       for (i = 0; i < zonesize; i++)
+               lba_to_pba[i] = pba_to_lba[i] = UNDEF;
+
+       for (i = 0; i < zonesize; i++) {
+               blocknum = zone_base_pba + i;
+
+               result = alauda_get_redu_data(us, blocknum, data);
+               if (result != USB_STOR_XFER_GOOD) {
+                       result = USB_STOR_TRANSPORT_ERROR;
+                       goto error;
+               }
+
+               /* special PBAs have control field 0^16 */
+               for (j = 0; j < 16; j++)
+                       if (data[j] != 0)
+                               goto nonz;
+               pba_to_lba[i] = UNUSABLE;
+               US_DEBUGP("alauda_read_map: PBA %d has no logical mapping\n", blocknum);
+               continue;
+
+       nonz:
+               /* unwritten PBAs have control field FF^16 */
+               for (j = 0; j < 16; j++)
+                       if (data[j] != 0xff)
+                               goto nonff;
+               continue;
+
+       nonff:
+               /* normal PBAs start with six FFs */
+               if (j < 6) {
+                       US_DEBUGP("alauda_read_map: PBA %d has no logical mapping: "
+                              "reserved area = %02X%02X%02X%02X "
+                              "data status %02X block status %02X\n",
+                              blocknum, data[0], data[1], data[2], data[3],
+                              data[4], data[5]);
+                       pba_to_lba[i] = UNUSABLE;
+                       continue;
+               }
+
+               if ((data[6] >> 4) != 0x01) {
+                       US_DEBUGP("alauda_read_map: PBA %d has invalid address "
+                              "field %02X%02X/%02X%02X\n",
+                              blocknum, data[6], data[7], data[11], data[12]);
+                       pba_to_lba[i] = UNUSABLE;
+                       continue;
+               }
+
+               /* check even parity */
+               if (parity[data[6] ^ data[7]]) {
+                       printk("alauda_read_map: Bad parity in LBA for block %d"
+                              " (%02X %02X)\n", i, data[6], data[7]);
+                       pba_to_lba[i] = UNUSABLE;
+                       continue;
+               }
+
+               lba_offset = short_pack(data[7], data[6]);
+               lba_offset = (lba_offset & 0x07FF) >> 1;
+               lba_real = lba_offset + zone_base_lba;
+
+               /*
+                * Every 1024 physical blocks ("zone"), the LBA numbers
+                * go back to zero, but are within a higher block of LBA's.
+                * Also, there is a maximum of 1000 LBA's per zone.
+                * In other words, in PBA 1024-2047 you will find LBA 0-999
+                * which are really LBA 1000-1999. This allows for 24 bad
+                * or special physical blocks per zone.
+                */
+
+               if (lba_offset >= uzonesize) {
+                       printk("alauda_read_map: Bad low LBA %d for block %d\n",
+                              lba_real, blocknum);
+                       continue;
+               }
+
+               if (lba_to_pba[lba_offset] != UNDEF) {
+                       printk("alauda_read_map: LBA %d seen for PBA %d and %d\n",
+                              lba_real, lba_to_pba[lba_offset], blocknum);
+                       continue;
+               }
+
+               pba_to_lba[i] = lba_real;
+               lba_to_pba[lba_offset] = blocknum;
+               continue;
+       }
+
+       MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba;
+       MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba;
+       result = 0;
+       goto out;
+
+error:
+       kfree(lba_to_pba);
+       kfree(pba_to_lba);
+out:
+       return result;
+}
+
+/*
+ * Checks to see whether we have already mapped a certain zone
+ * If we haven't, the map is generated
+ */
+static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone)
+{
+       if (MEDIA_INFO(us).lba_to_pba[zone] == NULL
+               || MEDIA_INFO(us).pba_to_lba[zone] == NULL)
+               alauda_read_map(us, zone);
+}
+
+/*
+ * Erases an entire block
+ */
+static int alauda_erase_block(struct us_data *us, u16 pba)
+{
+       int rc;
+       unsigned char command[] = {
+               ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba),
+               PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us)
+       };
+       unsigned char buf[2];
+
+       US_DEBUGP("alauda_erase_block: Erasing PBA %d\n", pba);
+
+       rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+               command, 9, NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+               buf, 2, NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       US_DEBUGP("alauda_erase_block: Erase result: %02X %02X\n",
+               buf[0], buf[1]);
+       return rc;
+}
+
+/*
+ * Reads data from a certain offset page inside a PBA, including interleaved
+ * redundancy data. Returns (pagesize+64)*pages bytes in data.
+ */
+static int alauda_read_block_raw(struct us_data *us, u16 pba,
+               unsigned int page, unsigned int pages, unsigned char *data)
+{
+       int rc;
+       unsigned char command[] = {
+               ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba),
+               PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us)
+       };
+
+       US_DEBUGP("alauda_read_block: pba %d page %d count %d\n",
+               pba, page, pages);
+
+       rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+               command, 9, NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+               data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL);
+}
+
+/*
+ * Reads data from a certain offset page inside a PBA, excluding redundancy
+ * data. Returns pagesize*pages bytes in data. Note that data must be big enough
+ * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra'
+ * trailing bytes outside this function.
+ */
+static int alauda_read_block(struct us_data *us, u16 pba,
+               unsigned int page, unsigned int pages, unsigned char *data)
+{
+       int i, rc;
+       unsigned int pagesize = MEDIA_INFO(us).pagesize;
+
+       rc = alauda_read_block_raw(us, pba, page, pages, data);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       /* Cut out the redundancy data */
+       for (i = 0; i < pages; i++) {
+               int dest_offset = i * pagesize;
+               int src_offset = i * (pagesize + 64);
+               memmove(data + dest_offset, data + src_offset, pagesize);
+       }
+
+       return rc;
+}
+
+/*
+ * Writes an entire block of data and checks status after write.
+ * Redundancy data must be already included in data. Data should be
+ * (pagesize+64)*blocksize bytes in length.
+ */
+static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data)
+{
+       int rc;
+       struct alauda_info *info = (struct alauda_info *) us->extra;
+       unsigned char command[] = {
+               ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba),
+               PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us)
+       };
+
+       US_DEBUGP("alauda_write_block: pba %d\n", pba);
+
+       rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+               command, 9, NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data,
+               (MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize,
+               NULL);
+       if (rc != USB_STOR_XFER_GOOD)
+               return rc;
+
+       return alauda_check_status2(us);
+}
+
+/*
+ * Write some data to a specific LBA.
+ */
+static int alauda_write_lba(struct us_data *us, u16 lba,
+                unsigned int page, unsigned int pages,
+                unsigned char *ptr, unsigned char *blockbuffer)
+{
+       u16 pba, lbap, new_pba;
+       unsigned char *bptr, *cptr, *xptr;
+       unsigned char ecc[3];
+       int i, result;
+       unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+       unsigned int zonesize = MEDIA_INFO(us).zonesize;
+       unsigned int pagesize = MEDIA_INFO(us).pagesize;
+       unsigned int blocksize = MEDIA_INFO(us).blocksize;
+       unsigned int lba_offset = lba % uzonesize;
+       unsigned int new_pba_offset;
+       unsigned int zone = lba / uzonesize;
+
+       alauda_ensure_map_for_zone(us, zone);
+
+       pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
+       if (pba == 1) {
+               /* Maybe it is impossible to write to PBA 1.
+                  Fake success, but don't do anything. */
+               printk("alauda_write_lba: avoid writing to pba 1\n");
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
+       if (!new_pba) {
+               printk("alauda_write_lba: Out of unused blocks\n");
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       /* read old contents */
+       if (pba != UNDEF) {
+               result = alauda_read_block_raw(us, pba, 0,
+                       blocksize, blockbuffer);
+               if (result != USB_STOR_XFER_GOOD)
+                       return result;
+       } else {
+               memset(blockbuffer, 0, blocksize * (pagesize + 64));
+       }
+
+       lbap = (lba_offset << 1) | 0x1000;
+       if (parity[MSB_of(lbap) ^ LSB_of(lbap)])
+               lbap ^= 1;
+
+       /* check old contents and fill lba */
+       for (i = 0; i < blocksize; i++) {
+               bptr = blockbuffer + (i * (pagesize + 64));
+               cptr = bptr + pagesize;
+               nand_compute_ecc(bptr, ecc);
+               if (!nand_compare_ecc(cptr+13, ecc)) {
+                       US_DEBUGP("Warning: bad ecc in page %d- of pba %d\n",
+                                 i, pba);
+                       nand_store_ecc(cptr+13, ecc);
+               }
+               nand_compute_ecc(bptr + (pagesize / 2), ecc);
+               if (!nand_compare_ecc(cptr+8, ecc)) {
+                       US_DEBUGP("Warning: bad ecc in page %d+ of pba %d\n",
+                                 i, pba);
+                       nand_store_ecc(cptr+8, ecc);
+               }
+               cptr[6] = cptr[11] = MSB_of(lbap);
+               cptr[7] = cptr[12] = LSB_of(lbap);
+       }
+
+       /* copy in new stuff and compute ECC */
+       xptr = ptr;
+       for (i = page; i < page+pages; i++) {
+               bptr = blockbuffer + (i * (pagesize + 64));
+               cptr = bptr + pagesize;
+               memcpy(bptr, xptr, pagesize);
+               xptr += pagesize;
+               nand_compute_ecc(bptr, ecc);
+               nand_store_ecc(cptr+13, ecc);
+               nand_compute_ecc(bptr + (pagesize / 2), ecc);
+               nand_store_ecc(cptr+8, ecc);
+       }
+
+       result = alauda_write_block(us, new_pba, blockbuffer);
+       if (result != USB_STOR_XFER_GOOD)
+               return result;
+
+       new_pba_offset = new_pba - (zone * zonesize);
+       MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba;
+       MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba;
+       US_DEBUGP("alauda_write_lba: Remapped LBA %d to PBA %d\n",
+               lba, new_pba);
+
+       if (pba != UNDEF) {
+               unsigned int pba_offset = pba - (zone * zonesize);
+               result = alauda_erase_block(us, pba);
+               if (result != USB_STOR_XFER_GOOD)
+                       return result;
+               MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF;
+       }
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Read data from a specific sector address
+ */
+static int alauda_read_data(struct us_data *us, unsigned long address,
+               unsigned int sectors)
+{
+       unsigned char *buffer;
+       u16 lba, max_lba;
+       unsigned int page, len, index, offset;
+       unsigned int blockshift = MEDIA_INFO(us).blockshift;
+       unsigned int pageshift = MEDIA_INFO(us).pageshift;
+       unsigned int blocksize = MEDIA_INFO(us).blocksize;
+       unsigned int pagesize = MEDIA_INFO(us).pagesize;
+       unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+       int result;
+
+       /*
+        * Since we only read in one block at a time, we have to create
+        * a bounce buffer and move the data a piece at a time between the
+        * bounce buffer and the actual transfer buffer.
+        * We make this buffer big enough to hold temporary redundancy data,
+        * which we use when reading the data blocks.
+        */
+
+       len = min(sectors, blocksize) * (pagesize + 64);
+       buffer = kmalloc(len, GFP_NOIO);
+       if (buffer == NULL) {
+               printk("alauda_read_data: Out of memory\n");
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       /* Figure out the initial LBA and page */
+       lba = address >> blockshift;
+       page = (address & MEDIA_INFO(us).blockmask);
+       max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift);
+
+       result = USB_STOR_TRANSPORT_GOOD;
+       index = offset = 0;
+
+       while (sectors > 0) {
+               unsigned int zone = lba / uzonesize; /* integer division */
+               unsigned int lba_offset = lba - (zone * uzonesize);
+               unsigned int pages;
+               u16 pba;
+               alauda_ensure_map_for_zone(us, zone);
+
+               /* Not overflowing capacity? */
+               if (lba >= max_lba) {
+                       US_DEBUGP("Error: Requested lba %u exceeds "
+                                 "maximum %u\n", lba, max_lba);
+                       result = USB_STOR_TRANSPORT_ERROR;
+                       break;
+               }
+
+               /* Find number of pages we can read in this block */
+               pages = min(sectors, blocksize - page);
+               len = pages << pageshift;
+
+               /* Find where this lba lives on disk */
+               pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
+
+               if (pba == UNDEF) {     /* this lba was never written */
+                       US_DEBUGP("Read %d zero pages (LBA %d) page %d\n",
+                                 pages, lba, page);
+
+                       /* This is not really an error. It just means
+                          that the block has never been written.
+                          Instead of returning USB_STOR_TRANSPORT_ERROR
+                          it is better to return all zero data. */
+
+                       memset(buffer, 0, len);
+               } else {
+                       US_DEBUGP("Read %d pages, from PBA %d"
+                                 " (LBA %d) page %d\n",
+                                 pages, pba, lba, page);
+
+                       result = alauda_read_block(us, pba, page, pages, buffer);
+                       if (result != USB_STOR_TRANSPORT_GOOD)
+                               break;
+               }
+
+               /* Store the data in the transfer buffer */
+               usb_stor_access_xfer_buf(buffer, len, us->srb,
+                               &index, &offset, TO_XFER_BUF);
+
+               page = 0;
+               lba++;
+               sectors -= pages;
+       }
+
+       kfree(buffer);
+       return result;
+}
+
+/*
+ * Write data to a specific sector address
+ */
+static int alauda_write_data(struct us_data *us, unsigned long address,
+               unsigned int sectors)
+{
+       unsigned char *buffer, *blockbuffer;
+       unsigned int page, len, index, offset;
+       unsigned int blockshift = MEDIA_INFO(us).blockshift;
+       unsigned int pageshift = MEDIA_INFO(us).pageshift;
+       unsigned int blocksize = MEDIA_INFO(us).blocksize;
+       unsigned int pagesize = MEDIA_INFO(us).pagesize;
+       u16 lba, max_lba;
+       int result;
+
+       /*
+        * Since we don't write the user data directly to the device,
+        * we have to create a bounce buffer and move the data a piece
+        * at a time between the bounce buffer and the actual transfer buffer.
+        */
+
+       len = min(sectors, blocksize) * pagesize;
+       buffer = kmalloc(len, GFP_NOIO);
+       if (buffer == NULL) {
+               printk("alauda_write_data: Out of memory\n");
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       /*
+        * We also need a temporary block buffer, where we read in the old data,
+        * overwrite parts with the new data, and manipulate the redundancy data
+        */
+       blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
+       if (blockbuffer == NULL) {
+               printk("alauda_write_data: Out of memory\n");
+               kfree(buffer);
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       /* Figure out the initial LBA and page */
+       lba = address >> blockshift;
+       page = (address & MEDIA_INFO(us).blockmask);
+       max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift);
+
+       result = USB_STOR_TRANSPORT_GOOD;
+       index = offset = 0;
+
+       while (sectors > 0) {
+               /* Write as many sectors as possible in this block */
+               unsigned int pages = min(sectors, blocksize - page);
+               len = pages << pageshift;
+
+               /* Not overflowing capacity? */
+               if (lba >= max_lba) {
+                       US_DEBUGP("alauda_write_data: Requested lba %u exceeds "
+                                 "maximum %u\n", lba, max_lba);
+                       result = USB_STOR_TRANSPORT_ERROR;
+                       break;
+               }
+
+               /* Get the data from the transfer buffer */
+               usb_stor_access_xfer_buf(buffer, len, us->srb,
+                               &index, &offset, FROM_XFER_BUF);
+
+               result = alauda_write_lba(us, lba, page, pages, buffer,
+                       blockbuffer);
+               if (result != USB_STOR_TRANSPORT_GOOD)
+                       break;
+
+               page = 0;
+               lba++;
+               sectors -= pages;
+       }
+
+       kfree(buffer);
+       kfree(blockbuffer);
+       return result;
+}
+
+/*
+ * Our interface with the rest of the world
+ */
+
+static void alauda_info_destructor(void *extra)
+{
+       struct alauda_info *info = (struct alauda_info *) extra;
+       int port;
+
+       if (!info)
+               return;
+
+       for (port = 0; port < 2; port++) {
+               struct alauda_media_info *media_info = &info->port[port];
+
+               alauda_free_maps(media_info);
+               kfree(media_info->lba_to_pba);
+               kfree(media_info->pba_to_lba);
+       }
+}
+
+/*
+ * Initialize alauda_info struct and find the data-write endpoint
+ */
+int init_alauda(struct us_data *us)
+{
+       struct alauda_info *info;
+       struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
+       nand_init_ecc();
+
+       us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO);
+       if (!us->extra) {
+               US_DEBUGP("init_alauda: Gah! Can't allocate storage for"
+                       "alauda info struct!\n");
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+       info = (struct alauda_info *) us->extra;
+       us->extra_destructor = alauda_info_destructor;
+
+       info->wr_ep = usb_sndbulkpipe(us->pusb_dev,
+               altsetting->endpoint[0].desc.bEndpointAddress
+               & USB_ENDPOINT_NUMBER_MASK);
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
+int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
+{
+       int rc;
+       struct alauda_info *info = (struct alauda_info *) us->extra;
+       unsigned char *ptr = us->iobuf;
+       static unsigned char inquiry_response[36] = {
+               0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
+       };
+
+       if (srb->cmnd[0] == INQUIRY) {
+               US_DEBUGP("alauda_transport: INQUIRY. "
+                       "Returning bogus response.\n");
+               memcpy(ptr, inquiry_response, sizeof(inquiry_response));
+               fill_inquiry_response(us, ptr, 36);
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       if (srb->cmnd[0] == TEST_UNIT_READY) {
+               US_DEBUGP("alauda_transport: TEST_UNIT_READY.\n");
+               return alauda_check_media(us);
+       }
+
+       if (srb->cmnd[0] == READ_CAPACITY) {
+               unsigned int num_zones;
+               unsigned long capacity;
+
+               rc = alauda_check_media(us);
+               if (rc != USB_STOR_TRANSPORT_GOOD)
+                       return rc;
+
+               num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
+                       + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+
+               capacity = num_zones * MEDIA_INFO(us).uzonesize
+                       * MEDIA_INFO(us).blocksize;
+
+               /* Report capacity and page size */
+               ((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1);
+               ((__be32 *) ptr)[1] = cpu_to_be32(512);
+
+               usb_stor_set_xfer_buf(ptr, 8, srb);
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       if (srb->cmnd[0] == READ_10) {
+               unsigned int page, pages;
+
+               rc = alauda_check_media(us);
+               if (rc != USB_STOR_TRANSPORT_GOOD)
+                       return rc;
+
+               page = short_pack(srb->cmnd[3], srb->cmnd[2]);
+               page <<= 16;
+               page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
+               pages = short_pack(srb->cmnd[8], srb->cmnd[7]);
+
+               US_DEBUGP("alauda_transport: READ_10: page %d pagect %d\n",
+                         page, pages);
+
+               return alauda_read_data(us, page, pages);
+       }
+
+       if (srb->cmnd[0] == WRITE_10) {
+               unsigned int page, pages;
+
+               rc = alauda_check_media(us);
+               if (rc != USB_STOR_TRANSPORT_GOOD)
+                       return rc;
+
+               page = short_pack(srb->cmnd[3], srb->cmnd[2]);
+               page <<= 16;
+               page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
+               pages = short_pack(srb->cmnd[8], srb->cmnd[7]);
+
+               US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n",
+                         page, pages);
+
+               return alauda_write_data(us, page, pages);
+       }
+
+       if (srb->cmnd[0] == REQUEST_SENSE) {
+               US_DEBUGP("alauda_transport: REQUEST_SENSE.\n");
+
+               memset(ptr, 0, 18);
+               ptr[0] = 0xF0;
+               ptr[2] = info->sense_key;
+               ptr[7] = 11;
+               ptr[12] = info->sense_asc;
+               ptr[13] = info->sense_ascq;
+               usb_stor_set_xfer_buf(ptr, 18, srb);
+
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
+               /* sure.  whatever.  not like we can stop the user from popping
+                  the media out of the device (no locking doors, etc) */
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       US_DEBUGP("alauda_transport: Gah! Unknown command: %d (0x%x)\n",
+               srb->cmnd[0], srb->cmnd[0]);
+       info->sense_key = 0x05;
+       info->sense_asc = 0x20;
+       info->sense_ascq = 0x00;
+       return USB_STOR_TRANSPORT_FAILED;
+}
+
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h
new file mode 100644 (file)
index 0000000..a700f87
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Driver for Alauda-based card readers
+ *
+ * Current development and maintenance by:
+ *    (c) 2005 Daniel Drake <dsd@gentoo.org>
+ *
+ * See alauda.c for more explanation.
+ *
+ * This program is free software; you can redistribute 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.
+ */
+
+#ifndef _USB_ALAUDA_H
+#define _USB_ALAUDA_H
+
+/*
+ * Status bytes
+ */
+#define ALAUDA_STATUS_ERROR            0x01
+#define ALAUDA_STATUS_READY            0x40
+
+/*
+ * Control opcodes (for request field)
+ */
+#define ALAUDA_GET_XD_MEDIA_STATUS     0x08
+#define ALAUDA_GET_SM_MEDIA_STATUS     0x98
+#define ALAUDA_ACK_XD_MEDIA_CHANGE     0x0a
+#define ALAUDA_ACK_SM_MEDIA_CHANGE     0x9a
+#define ALAUDA_GET_XD_MEDIA_SIG                0x86
+#define ALAUDA_GET_SM_MEDIA_SIG                0x96
+
+/*
+ * Bulk command identity (byte 0)
+ */
+#define ALAUDA_BULK_CMD                        0x40
+
+/*
+ * Bulk opcodes (byte 1)
+ */
+#define ALAUDA_BULK_GET_REDU_DATA      0x85
+#define ALAUDA_BULK_READ_BLOCK         0x94
+#define ALAUDA_BULK_ERASE_BLOCK                0xa3
+#define ALAUDA_BULK_WRITE_BLOCK                0xb4
+#define ALAUDA_BULK_GET_STATUS2                0xb7
+#define ALAUDA_BULK_RESET_MEDIA                0xe0
+
+/*
+ * Port to operate on (byte 8)
+ */
+#define ALAUDA_PORT_XD                 0x00
+#define ALAUDA_PORT_SM                 0x01
+
+/*
+ * LBA and PBA are unsigned ints. Special values.
+ */
+#define UNDEF    0xffff
+#define SPARE    0xfffe
+#define UNUSABLE 0xfffd
+
+int init_alauda(struct us_data *us);
+int alauda_transport(struct scsi_cmnd *srb, struct us_data *us);
+
+struct alauda_media_info {
+       unsigned long capacity;         /* total media size in bytes */
+       unsigned int pagesize;          /* page size in bytes */
+       unsigned int blocksize;         /* number of pages per block */
+       unsigned int uzonesize;         /* number of usable blocks per zone */
+       unsigned int zonesize;          /* number of blocks per zone */
+       unsigned int blockmask;         /* mask to get page from address */
+
+       unsigned char pageshift;
+       unsigned char blockshift;
+       unsigned char zoneshift;
+
+       u16 **lba_to_pba;               /* logical to physical block map */
+       u16 **pba_to_lba;               /* physical to logical block map */
+};
+
+struct alauda_info {
+       struct alauda_media_info port[2];
+       int wr_ep;                      /* endpoint to write data out of */
+
+       unsigned char sense_key;
+       unsigned long sense_asc;        /* additional sense code */
+       unsigned long sense_ascq;       /* additional sense code qualifier */
+};
+
+#endif
+
index 5a93217..01e4306 100644 (file)
@@ -132,6 +132,7 @@ void usb_stor_show_command(struct scsi_cmnd *srb)
        case 0x5C: what = "READ BUFFER CAPACITY"; break;
        case 0x5D: what = "SEND CUE SHEET"; break;
        case GPCMD_BLANK: what = "BLANK"; break;
+       case REPORT_LUNS: what = "REPORT LUNS"; break;
        case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break;
        case READ_12: what = "READ_12"; break;
        case WRITE_12: what = "WRITE_12"; break;
index 7372386..4c1b2bd 100644 (file)
  * mode */
 int usb_stor_euscsi_init(struct us_data *us);
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-int sddr09_init(struct us_data *us);
-#endif
-
 /* This function is required to activate all four slots on the UCR-61S2B
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c
new file mode 100644 (file)
index 0000000..b28151d
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * libusual
+ *
+ * The libusual contains the table of devices common for ub and usb-storage.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+#include <linux/vmalloc.h>
+
+/*
+ */
+#define USU_MOD_FL_THREAD   1  /* Thread is running */
+#define USU_MOD_FL_PRESENT  2  /* The module is loaded */
+
+struct mod_status {
+       unsigned long fls;
+};
+
+static struct mod_status stat[3];
+static DEFINE_SPINLOCK(usu_lock);
+
+/*
+ */
+#define USB_US_DEFAULT_BIAS    USB_US_TYPE_STOR
+static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS);
+
+#define BIAS_NAME_SIZE  (sizeof("usb-storage"))
+static const char *bias_names[3] = { "none", "usb-storage", "ub" };
+
+static DECLARE_MUTEX_LOCKED(usu_init_notify);
+static DECLARE_COMPLETION(usu_end_notify);
+static atomic_t total_threads = ATOMIC_INIT(0);
+
+static int usu_probe_thread(void *arg);
+
+/*
+ * The table.
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName,useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = ((useType)<<24) }
+
+struct usb_device_id storage_usb_ids [] = {
+#      include "unusual_devs.h"
+       { } /* Terminating entry */
+};
+
+#undef USUAL_DEV
+#undef UNUSUAL_DEV
+
+MODULE_DEVICE_TABLE(usb, storage_usb_ids);
+EXPORT_SYMBOL_GPL(storage_usb_ids);
+
+/*
+ * @type: the module type as an integer
+ */
+void usb_usual_set_present(int type)
+{
+       struct mod_status *st;
+       unsigned long flags;
+
+       if (type <= 0 || type >= 3)
+               return;
+       st = &stat[type];
+       spin_lock_irqsave(&usu_lock, flags);
+       st->fls |= USU_MOD_FL_PRESENT;
+       spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_usual_set_present);
+
+void usb_usual_clear_present(int type)
+{
+       struct mod_status *st;
+       unsigned long flags;
+
+       if (type <= 0 || type >= 3)
+               return;
+       st = &stat[type];
+       spin_lock_irqsave(&usu_lock, flags);
+       st->fls &= ~USU_MOD_FL_PRESENT;
+       spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_usual_clear_present);
+
+/*
+ * Match the calling driver type against the table.
+ * Returns: 0 if the device matches.
+ */
+int usb_usual_check_type(const struct usb_device_id *id, int caller_type)
+{
+       int id_type = USB_US_TYPE(id->driver_info);
+
+       if (caller_type <= 0 || caller_type >= 3)
+               return -EINVAL;
+
+       /* Drivers grab fixed assignment devices */
+       if (id_type == caller_type)
+               return 0;
+       /* Drivers grab devices biased to them */
+       if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias))
+               return 0;
+       return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(usb_usual_check_type);
+
+/*
+ */
+static int usu_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       int type;
+       int rc;
+       unsigned long flags;
+
+       type = USB_US_TYPE(id->driver_info);
+       if (type == 0)
+               type = atomic_read(&usu_bias);
+
+       spin_lock_irqsave(&usu_lock, flags);
+       if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) {
+               spin_unlock_irqrestore(&usu_lock, flags);
+               return -ENXIO;
+       }
+       stat[type].fls |= USU_MOD_FL_THREAD;
+       spin_unlock_irqrestore(&usu_lock, flags);
+
+       rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM);
+       if (rc < 0) {
+               printk(KERN_WARNING "libusual: "
+                   "Unable to start the thread for %s: %d\n",
+                   bias_names[type], rc);
+               spin_lock_irqsave(&usu_lock, flags);
+               stat[type].fls &= ~USU_MOD_FL_THREAD;
+               spin_unlock_irqrestore(&usu_lock, flags);
+               return rc;      /* Not being -ENXIO causes a message printed */
+       }
+       atomic_inc(&total_threads);
+
+       return -ENXIO;
+}
+
+static void usu_disconnect(struct usb_interface *intf)
+{
+       ;       /* We should not be here. */
+}
+
+static struct usb_driver usu_driver = {
+       .name =         "libusual",
+       .probe =        usu_probe,
+       .disconnect =   usu_disconnect,
+       .id_table =     storage_usb_ids,
+};
+
+/*
+ * A whole new thread for a purpose of request_module seems quite stupid.
+ * The request_module forks once inside again. However, if we attempt
+ * to load a storage module from our own modprobe thread, that module
+ * references our symbols, which cannot be resolved until our module is
+ * initialized. I wish there was a way to wait for the end of initialization.
+ * The module notifier reports MODULE_STATE_COMING only.
+ * So, we wait until module->init ends as the next best thing.
+ */
+static int usu_probe_thread(void *arg)
+{
+       int type = (unsigned long) arg;
+       struct mod_status *st = &stat[type];
+       int rc;
+       unsigned long flags;
+
+       daemonize("libusual_%d", type); /* "usb-storage" is kinda too long */
+
+       /* A completion does not work here because it's counted. */
+       down(&usu_init_notify);
+       up(&usu_init_notify);
+
+       rc = request_module(bias_names[type]);
+       spin_lock_irqsave(&usu_lock, flags);
+       if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) {
+               /*
+                * This should not happen, but let us keep tabs on it.
+                */
+               printk(KERN_NOTICE "libusual: "
+                   "modprobe for %s succeeded, but module is not present\n",
+                   bias_names[type]);
+       }
+       st->fls &= ~USU_MOD_FL_THREAD;
+       spin_unlock_irqrestore(&usu_lock, flags);
+
+       complete_and_exit(&usu_end_notify, 0);
+}
+
+/*
+ */
+static int __init usb_usual_init(void)
+{
+       int rc;
+
+       rc = usb_register(&usu_driver);
+       up(&usu_init_notify);
+       return rc;
+}
+
+static void __exit usb_usual_exit(void)
+{
+       /*
+        * We do not check for any drivers present, because
+        * they keep us pinned with symbol references.
+        */
+
+       usb_deregister(&usu_driver);
+
+       while (atomic_read(&total_threads) > 0) {
+               wait_for_completion(&usu_end_notify);
+               atomic_dec(&total_threads);
+       }
+}
+
+/*
+ * Validate and accept the bias parameter.
+ */
+static int usu_set_bias(const char *bias_s, struct kernel_param *kp)
+{
+       int i;
+       int len;
+       int bias_n = 0;
+
+       len = strlen(bias_s);
+       if (len == 0)
+               return -EDOM;
+       if (bias_s[len-1] == '\n')
+               --len;
+
+       for (i = 1; i < 3; i++) {
+               if (strncmp(bias_s, bias_names[i], len) == 0) {
+                       bias_n = i;
+                       break;
+               }
+       }
+       if (bias_n == 0)
+               return -EINVAL;
+
+       atomic_set(&usu_bias, bias_n);
+       return 0;
+}
+
+static int usu_get_bias(char *buffer, struct kernel_param *kp)
+{
+       return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)]));
+}
+
+module_init(usb_usual_init);
+module_exit(usb_usual_exit);
+
+module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR);
+__MODULE_PARM_TYPE(bias, "string");
+MODULE_PARM_DESC(bias, "Bias to usb-storage or ub");
+
+MODULE_LICENSE("GPL");
index 89401a5..55ee2d3 100644 (file)
@@ -52,6 +52,7 @@ struct usb_onetouch {
        struct urb *irq;        /* urb for interrupt in report */
        unsigned char *data;    /* input data */
        dma_addr_t data_dma;
+       unsigned int is_open:1;
 };
 
 static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
@@ -89,6 +90,7 @@ static int usb_onetouch_open(struct input_dev *dev)
 {
        struct usb_onetouch *onetouch = dev->private;
 
+       onetouch->is_open = 1;
        onetouch->irq->dev = onetouch->udev;
        if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
                err("usb_submit_urb failed");
@@ -103,8 +105,30 @@ static void usb_onetouch_close(struct input_dev *dev)
        struct usb_onetouch *onetouch = dev->private;
 
        usb_kill_urb(onetouch->irq);
+       onetouch->is_open = 0;
 }
 
+#ifdef CONFIG_PM
+static void usb_onetouch_pm_hook(struct us_data *us, int action)
+{
+       struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra;
+
+       if (onetouch->is_open) {
+               switch (action) {
+               case US_SUSPEND:
+                       usb_kill_urb(onetouch->irq);
+                       break;
+               case US_RESUME:
+                       if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0)
+                               err("usb_submit_urb failed");
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+#endif /* CONFIG_PM */
+
 int onetouch_connect_input(struct us_data *ss)
 {
        struct usb_device *udev = ss->pusb_dev;
@@ -185,6 +209,9 @@ int onetouch_connect_input(struct us_data *ss)
 
        ss->extra_destructor = onetouch_release_input;
        ss->extra = onetouch;
+#ifdef CONFIG_PM
+       ss->suspend_resume_hook = usb_onetouch_pm_hook;
+#endif
 
        input_register_device(onetouch->dev);
 
index 02bff01..845bed4 100644 (file)
 #ifndef _PROTOCOL_H_
 #define _PROTOCOL_H_
 
-/* Sub Classes */
-
-#define US_SC_RBC      0x01            /* Typically, flash devices */
-#define US_SC_8020     0x02            /* CD-ROM */
-#define US_SC_QIC      0x03            /* QIC-157 Tapes */
-#define US_SC_UFI      0x04            /* Floppy */
-#define US_SC_8070     0x05            /* Removable media */
-#define US_SC_SCSI     0x06            /* Transparent */
-#define US_SC_ISD200    0x07           /* ISD200 ATA */
-#define US_SC_MIN      US_SC_RBC
-#define US_SC_MAX      US_SC_ISD200
-
-#define US_SC_DEVICE   0xff            /* Use device's value */
-
 /* Protocol handling routines */
 extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*);
 extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*);
index 0ea2f5a..fb8baca 100644 (file)
@@ -133,13 +133,11 @@ static struct nand_flash_dev nand_flash_ids[] = {
        { 0,}
 };
 
-#define SIZE(a)        (sizeof(a)/sizeof((a)[0]))
-
 static struct nand_flash_dev *
 nand_find_id(unsigned char id) {
        int i;
 
-       for (i = 0; i < SIZE(nand_flash_ids); i++)
+       for (i = 0; i < ARRAY_SIZE(nand_flash_ids); i++)
                if (nand_flash_ids[i].model_id == id)
                        return &(nand_flash_ids[i]);
        return NULL;
@@ -214,6 +212,20 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) {
  * The actual driver starts here.
  */
 
+struct sddr09_card_info {
+       unsigned long   capacity;       /* Size of card in bytes */
+       int             pagesize;       /* Size of page in bytes */
+       int             pageshift;      /* log2 of pagesize */
+       int             blocksize;      /* Size of block in pages */
+       int             blockshift;     /* log2 of blocksize */
+       int             blockmask;      /* 2^blockshift - 1 */
+       int             *lba_to_pba;    /* logical to physical map */
+       int             *pba_to_lba;    /* physical to logical map */
+       int             lbact;          /* number of available pages */
+       int             flags;
+#define        SDDR09_WP       1               /* write protected */
+};
+
 /*
  * On my 16MB card, control blocks have size 64 (16 real control bytes,
  * and 48 junk bytes). In reality of course the card uses 16 control bytes,
@@ -237,7 +249,7 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) {
 #define SPARE    0xfffffffe
 #define UNUSABLE 0xfffffffd
 
-static int erase_bad_lba_entries = 0;
+static const int erase_bad_lba_entries = 0;
 
 /* send vendor interface command (0x41) */
 /* called for requests 0, 1, 8 */
@@ -260,8 +272,11 @@ sddr09_send_command(struct us_data *us,
 
        rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype,
                                   0, 0, xfer_data, xfer_len);
-       return (rc == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD :
-                       USB_STOR_TRANSPORT_ERROR);
+       switch (rc) {
+               case USB_STOR_XFER_GOOD:        return 0;
+               case USB_STOR_XFER_STALLED:     return -EPIPE;
+               default:                        return -EIO;
+       }
 }
 
 static int
@@ -308,20 +323,12 @@ sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) {
        command[4] = buflen;
 
        result = sddr09_send_scsi_command(us, command, 12);
-       if (result != USB_STOR_TRANSPORT_GOOD) {
-               US_DEBUGP("request sense failed\n");
+       if (result)
                return result;
-       }
 
        result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
                        sensebuf, buflen, NULL);
-       if (result != USB_STOR_XFER_GOOD) {
-               US_DEBUGP("request sense bulk in failed\n");
-               return USB_STOR_TRANSPORT_ERROR;
-       } else {
-               US_DEBUGP("request sense worked\n");
-               return USB_STOR_TRANSPORT_GOOD;
-       }
+       return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 /*
@@ -369,7 +376,7 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress,
 
        result = sddr09_send_scsi_command(us, command, 12);
 
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("Result for send_control in sddr09_read2%d %d\n",
                          x, result);
                return result;
@@ -381,9 +388,9 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress,
        if (result != USB_STOR_XFER_GOOD) {
                US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n",
                          x, result);
-               return USB_STOR_TRANSPORT_ERROR;
+               return -EIO;
        }
-       return USB_STOR_TRANSPORT_GOOD;
+       return 0;
 }
 
 /*
@@ -497,7 +504,7 @@ sddr09_erase(struct us_data *us, unsigned long Eaddress) {
 
        result = sddr09_send_scsi_command(us, command, 12);
 
-       if (result != USB_STOR_TRANSPORT_GOOD)
+       if (result)
                US_DEBUGP("Result for send_control in sddr09_erase %d\n",
                          result);
 
@@ -555,7 +562,7 @@ sddr09_writeX(struct us_data *us,
 
        result = sddr09_send_scsi_command(us, command, 12);
 
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("Result for send_control in sddr09_writeX %d\n",
                          result);
                return result;
@@ -567,9 +574,9 @@ sddr09_writeX(struct us_data *us,
        if (result != USB_STOR_XFER_GOOD) {
                US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n",
                          result);
-               return USB_STOR_TRANSPORT_ERROR;
+               return -EIO;
        }
-       return USB_STOR_TRANSPORT_GOOD;
+       return 0;
 }
 
 /* erase address, write same address */
@@ -633,7 +640,7 @@ sddr09_read_sg_test_only(struct us_data *us) {
 
        result = sddr09_send_scsi_command(us, command, 4*nsg+3);
 
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("Result for send_control in sddr09_read_sg %d\n",
                          result);
                return result;
@@ -641,7 +648,7 @@ sddr09_read_sg_test_only(struct us_data *us) {
 
        buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO);
        if (!buf)
-               return USB_STOR_TRANSPORT_ERROR;
+               return -ENOMEM;
 
        result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
                                       buf, bulklen, NULL);
@@ -649,10 +656,10 @@ sddr09_read_sg_test_only(struct us_data *us) {
        if (result != USB_STOR_XFER_GOOD) {
                US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n",
                          result);
-               return USB_STOR_TRANSPORT_ERROR;
+               return -EIO;
        }
 
-       return USB_STOR_TRANSPORT_GOOD;
+       return 0;
 }
 #endif
 
@@ -681,14 +688,13 @@ sddr09_read_status(struct us_data *us, unsigned char *status) {
        command[1] = LUNBITS;
 
        result = sddr09_send_scsi_command(us, command, 12);
-       if (result != USB_STOR_TRANSPORT_GOOD)
+       if (result)
                return result;
 
        result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
                                       data, 64, NULL);
        *status = data[0];
-       return (result == USB_STOR_XFER_GOOD ?
-                       USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
+       return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 static int
@@ -703,6 +709,13 @@ sddr09_read_data(struct us_data *us,
        unsigned int len, index, offset;
        int result;
 
+       // Figure out the initial LBA and page
+       lba = address >> info->blockshift;
+       page = (address & info->blockmask);
+       maxlba = info->capacity >> (info->pageshift + info->blockshift);
+       if (lba >= maxlba)
+               return -EIO;
+
        // Since we only read in one block at a time, we have to create
        // a bounce buffer and move the data a piece at a time between the
        // bounce buffer and the actual transfer buffer.
@@ -711,18 +724,13 @@ sddr09_read_data(struct us_data *us,
        buffer = kmalloc(len, GFP_NOIO);
        if (buffer == NULL) {
                printk("sddr09_read_data: Out of memory\n");
-               return USB_STOR_TRANSPORT_ERROR;
+               return -ENOMEM;
        }
 
-       // Figure out the initial LBA and page
-       lba = address >> info->blockshift;
-       page = (address & info->blockmask);
-       maxlba = info->capacity >> (info->pageshift + info->blockshift);
-
        // This could be made much more efficient by checking for
        // contiguous LBA's. Another exercise left to the student.
 
-       result = USB_STOR_TRANSPORT_GOOD;
+       result = 0;
        index = offset = 0;
 
        while (sectors > 0) {
@@ -735,7 +743,7 @@ sddr09_read_data(struct us_data *us,
                if (lba >= maxlba) {
                        US_DEBUGP("Error: Requested lba %u exceeds "
                                  "maximum %u\n", lba, maxlba);
-                       result = USB_STOR_TRANSPORT_ERROR;
+                       result = -EIO;
                        break;
                }
 
@@ -749,7 +757,7 @@ sddr09_read_data(struct us_data *us,
 
                        /* This is not really an error. It just means
                           that the block has never been written.
-                          Instead of returning USB_STOR_TRANSPORT_ERROR
+                          Instead of returning an error
                           it is better to return all zero data. */
 
                        memset(buffer, 0, len);
@@ -764,7 +772,7 @@ sddr09_read_data(struct us_data *us,
 
                        result = sddr09_read20(us, address>>1,
                                        pages, info->pageshift, buffer, 0);
-                       if (result != USB_STOR_TRANSPORT_GOOD)
+                       if (result)
                                break;
                }
 
@@ -830,7 +838,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
                pba = sddr09_find_unused_pba(info, lba);
                if (!pba) {
                        printk("sddr09_write_lba: Out of unused blocks\n");
-                       return USB_STOR_TRANSPORT_ERROR;
+                       return -ENOSPC;
                }
                info->pba_to_lba[pba] = lba;
                info->lba_to_pba[lba] = pba;
@@ -841,7 +849,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
                /* Maybe it is impossible to write to PBA 1.
                   Fake success, but don't do anything. */
                printk("sddr09: avoid writing to pba 1\n");
-               return USB_STOR_TRANSPORT_GOOD;
+               return 0;
        }
 
        pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT);
@@ -850,7 +858,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
        address = (pba << (info->pageshift + info->blockshift));
        result = sddr09_read22(us, address>>1, info->blocksize,
                               info->pageshift, blockbuffer, 0);
-       if (result != USB_STOR_TRANSPORT_GOOD)
+       if (result)
                return result;
 
        /* check old contents and fill lba */
@@ -897,7 +905,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
        {
                unsigned char status = 0;
                int result2 = sddr09_read_status(us, &status);
-               if (result2 != USB_STOR_TRANSPORT_GOOD)
+               if (result2)
                        US_DEBUGP("sddr09_write_inplace: cannot read status\n");
                else if (status != 0xc0)
                        US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n",
@@ -920,13 +928,20 @@ sddr09_write_data(struct us_data *us,
                  unsigned int sectors) {
 
        struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
-       unsigned int lba, page, pages;
+       unsigned int lba, maxlba, page, pages;
        unsigned int pagelen, blocklen;
        unsigned char *blockbuffer;
        unsigned char *buffer;
        unsigned int len, index, offset;
        int result;
 
+       // Figure out the initial LBA and page
+       lba = address >> info->blockshift;
+       page = (address & info->blockmask);
+       maxlba = info->capacity >> (info->pageshift + info->blockshift);
+       if (lba >= maxlba)
+               return -EIO;
+
        // blockbuffer is used for reading in the old data, overwriting
        // with the new data, and performing ECC calculations
 
@@ -938,7 +953,7 @@ sddr09_write_data(struct us_data *us,
        blockbuffer = kmalloc(blocklen, GFP_NOIO);
        if (!blockbuffer) {
                printk("sddr09_write_data: Out of memory\n");
-               return USB_STOR_TRANSPORT_ERROR;
+               return -ENOMEM;
        }
 
        // Since we don't write the user data directly to the device,
@@ -950,14 +965,10 @@ sddr09_write_data(struct us_data *us,
        if (buffer == NULL) {
                printk("sddr09_write_data: Out of memory\n");
                kfree(blockbuffer);
-               return USB_STOR_TRANSPORT_ERROR;
+               return -ENOMEM;
        }
 
-       // Figure out the initial LBA and page
-       lba = address >> info->blockshift;
-       page = (address & info->blockmask);
-
-       result = USB_STOR_TRANSPORT_GOOD;
+       result = 0;
        index = offset = 0;
 
        while (sectors > 0) {
@@ -967,13 +978,21 @@ sddr09_write_data(struct us_data *us,
                pages = min(sectors, info->blocksize - page);
                len = (pages << info->pageshift);
 
+               /* Not overflowing capacity? */
+               if (lba >= maxlba) {
+                       US_DEBUGP("Error: Requested lba %u exceeds "
+                                 "maximum %u\n", lba, maxlba);
+                       result = -EIO;
+                       break;
+               }
+
                // Get the data from the transfer buffer
                usb_stor_access_xfer_buf(buffer, len, us->srb,
                                &index, &offset, FROM_XFER_BUF);
 
                result = sddr09_write_lba(us, lba, page, pages,
                                buffer, blockbuffer);
-               if (result != USB_STOR_TRANSPORT_GOOD)
+               if (result)
                        break;
 
                page = 0;
@@ -1022,7 +1041,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) {
        command[1] = LUNBITS;
 
        result = sddr09_send_scsi_command(us, command, 12);
-       if (result != USB_STOR_TRANSPORT_GOOD)
+       if (result)
                return result;
 
        result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
@@ -1031,8 +1050,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) {
        for (i = 0; i < 4; i++)
                deviceID[i] = content[i];
 
-       return (result == USB_STOR_XFER_GOOD ?
-                       USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
+       return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 static int
@@ -1041,7 +1059,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) {
        unsigned char status;
 
        result = sddr09_read_status(us, &status);
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("sddr09_get_wp: read_status fails\n");
                return result;
        }
@@ -1057,7 +1075,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) {
        if (status & 0x1)
                US_DEBUGP(" Error");
        US_DEBUGP("\n");
-       return USB_STOR_TRANSPORT_GOOD;
+       return 0;
 }
 
 #if 0
@@ -1089,7 +1107,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
 
        result = sddr09_read_deviceID(us, deviceID);
 
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("Result of read_deviceID is %d\n", result);
                printk("sddr09: could not read card info\n");
                return NULL;
@@ -1200,7 +1218,7 @@ sddr09_read_map(struct us_data *us) {
                                us, address>>1,
                                min(alloc_blocks, numblocks - i),
                                buffer, 0);
-                       if (result != USB_STOR_TRANSPORT_GOOD) {
+                       if (result) {
                                result = -1;
                                goto done;
                        }
@@ -1342,29 +1360,53 @@ sddr09_card_info_destructor(void *extra) {
        kfree(info->pba_to_lba);
 }
 
-static void
-sddr09_init_card_info(struct us_data *us) {
-       if (!us->extra) {
-               us->extra = kmalloc(sizeof(struct sddr09_card_info), GFP_NOIO);
-               if (us->extra) {
-                       memset(us->extra, 0, sizeof(struct sddr09_card_info));
-                       us->extra_destructor = sddr09_card_info_destructor;
-               }
+static int
+sddr09_common_init(struct us_data *us) {
+       int result;
+
+       /* set the configuration -- STALL is an acceptable response here */
+       if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) {
+               US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev
+                               ->actconfig->desc.bConfigurationValue);
+               return -EINVAL;
+       }
+
+       result = usb_reset_configuration(us->pusb_dev);
+       US_DEBUGP("Result of usb_reset_configuration is %d\n", result);
+       if (result == -EPIPE) {
+               US_DEBUGP("-- stall on control interface\n");
+       } else if (result != 0) {
+               /* it's not a stall, but another error -- time to bail */
+               US_DEBUGP("-- Unknown error.  Rejecting device\n");
+               return -EINVAL;
        }
+
+       us->extra = kzalloc(sizeof(struct sddr09_card_info), GFP_NOIO);
+       if (!us->extra)
+               return -ENOMEM;
+       us->extra_destructor = sddr09_card_info_destructor;
+
+       nand_init_ecc();
+       return 0;
 }
 
+
 /*
  * This is needed at a very early stage. If this is not listed in the
  * unusual devices list but called from here then LUN 0 of the combo reader
  * is not recognized. But I do not know what precisely these calls do.
  */
 int
-sddr09_init(struct us_data *us) {
+usb_stor_sddr09_dpcm_init(struct us_data *us) {
        int result;
        unsigned char *data = us->iobuf;
 
+       result = sddr09_common_init(us);
+       if (result)
+               return result;
+
        result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2);
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("sddr09_init: send_command fails\n");
                return result;
        }
@@ -1373,7 +1415,7 @@ sddr09_init(struct us_data *us) {
        // get 07 02
 
        result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2);
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("sddr09_init: 2nd send_command fails\n");
                return result;
        }
@@ -1382,7 +1424,7 @@ sddr09_init(struct us_data *us) {
        // get 07 00
 
        result = sddr09_request_sense(us, data, 18);
-       if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) {
+       if (result == 0 && data[2] != 0) {
                int j;
                for (j=0; j<18; j++)
                        printk(" %02X", data[j]);
@@ -1398,7 +1440,7 @@ sddr09_init(struct us_data *us) {
 
        // test unit ready
 
-       return USB_STOR_TRANSPORT_GOOD;         /* not result */
+       return 0;               /* not result */
 }
 
 /*
@@ -1427,13 +1469,6 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
        };
 
        info = (struct sddr09_card_info *)us->extra;
-       if (!info) {
-               nand_init_ecc();
-               sddr09_init_card_info(us);
-               info = (struct sddr09_card_info *)us->extra;
-               if (!info)
-                       return USB_STOR_TRANSPORT_ERROR;
-       }
 
        if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) {
                /* for a faked command, we have to follow with a faked sense */
@@ -1536,7 +1571,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
                US_DEBUGP("READ_10: read page %d pagect %d\n",
                          page, pages);
 
-               return sddr09_read_data(us, page, pages);
+               result = sddr09_read_data(us, page, pages);
+               return (result == 0 ? USB_STOR_TRANSPORT_GOOD :
+                               USB_STOR_TRANSPORT_ERROR);
        }
 
        if (srb->cmnd[0] == WRITE_10) {
@@ -1549,7 +1586,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
                US_DEBUGP("WRITE_10: write page %d pagect %d\n",
                          page, pages);
 
-               return sddr09_write_data(us, page, pages);
+               result = sddr09_write_data(us, page, pages);
+               return (result == 0 ? USB_STOR_TRANSPORT_GOOD :
+                               USB_STOR_TRANSPORT_ERROR);
        }
 
        /* catch-all for all other commands, except
@@ -1575,10 +1614,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
        US_DEBUGP("SDDR09: Send control for command %s\n", ptr);
 
        result = sddr09_send_scsi_command(us, srb->cmnd, 12);
-       if (result != USB_STOR_TRANSPORT_GOOD) {
+       if (result) {
                US_DEBUGP("sddr09_transport: sddr09_send_scsi_command "
                          "returns %d\n", result);
-               return result;
+               return USB_STOR_TRANSPORT_ERROR;
        }
 
        if (srb->request_bufflen == 0)
@@ -1606,3 +1645,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
+/*
+ * Initialization routine for the sddr09 subdriver
+ */
+int
+usb_stor_sddr09_init(struct us_data *us) {
+       return sddr09_common_init(us);
+}
index c9d78d6..c03089a 100644 (file)
 
 extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
 
-struct sddr09_card_info {
-       unsigned long   capacity;       /* Size of card in bytes */
-       int             pagesize;       /* Size of page in bytes */
-       int             pageshift;      /* log2 of pagesize */
-       int             blocksize;      /* Size of block in pages */
-       int             blockshift;     /* log2 of blocksize */
-       int             blockmask;      /* 2^blockshift - 1 */
-       int             *lba_to_pba;    /* logical to physical map */
-       int             *pba_to_lba;    /* physical to logical map */
-       int             lbact;          /* number of available pages */
-       int             flags;
-#define        SDDR09_WP       1               /* write protected */
-};
+extern int usb_stor_sddr09_dpcm_init(struct us_data *us);
+extern int usb_stor_sddr09_init(struct us_data *us);
 
 #endif
index 0a362cc..633a715 100644 (file)
 #ifndef _TRANSPORT_H_
 #define _TRANSPORT_H_
 
-#include <linux/config.h>
 #include <linux/blkdev.h>
 
-/* Protocols */
-
-#define US_PR_CBI      0x00            /* Control/Bulk/Interrupt */
-#define US_PR_CB       0x01            /* Control/Bulk w/o interrupt */
-#define US_PR_BULK     0x50            /* bulk only */
-#ifdef CONFIG_USB_STORAGE_USBAT
-#define US_PR_USBAT    0x80            /* SCM-ATAPI bridge */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#define US_PR_EUSB_SDDR09      0x81    /* SCM-SCSI bridge for SDDR-09 */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#define US_PR_SDDR55   0x82            /* SDDR-55 (made up) */
-#endif
-#define US_PR_DPCM_USB  0xf0           /* Combination CB/SDDR09 */
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#define US_PR_FREECOM   0xf1           /* Freecom */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#define US_PR_DATAFAB   0xf2           /* Datafab chipsets */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#define US_PR_JUMPSHOT  0xf3           /* Lexar Jumpshot */
-#endif
-
-#define US_PR_DEVICE   0xff            /* Use device's value */
-
 /*
  * Bulk only data structures
  */
index f5f47a3..dc301e5 100644 (file)
@@ -79,13 +79,6 @@ UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001,
                US_SC_8070, US_PR_USBAT, init_usbat, 0),
 #endif
 
-/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
-UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
-               "VIA Technologies Inc.",
-               "USB 2.0 Card Reader",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_IGNORE_RESIDUE ),
-
 /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
  * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
  * for USB floppies that need the SINGLE_LUN enforcement.
@@ -96,6 +89,13 @@ UNUSUAL_DEV(  0x0409, 0x0040, 0x0000, 0x9999,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN ),
 
+/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
+UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
+               "VIA Technologies Inc.",
+               "USB 2.0 Card Reader",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE ),
+
 /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
  * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
  * always fails and confuses drive.
@@ -187,6 +187,14 @@ UNUSUAL_DEV(  0x04b0, 0x0405, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY),
 
+/* Patch for Nikon coolpix 2000
+ * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/
+UNUSUAL_DEV(  0x04b0, 0x0301, 0x0010, 0x0010,
+               "NIKON",
+               "NIKON DSC E2000",
+               US_SC_DEVICE, US_PR_DEVICE,NULL,
+               US_FL_NOT_LOCKABLE ),
+
 /* BENQ DC5330
  * Reported by Manuel Fombuena <mfombuena@ya.com> and
  * Frank Copeland <fjc@thingy.apana.org.au> */
@@ -276,14 +284,14 @@ UNUSUAL_DEV(  0x04e6, 0x0002, 0x0100, 0x0100,
 UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999, 
                "Sandisk",
                "ImageMate SDDR09",
-               US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-               US_FL_SINGLE_LUN ),
+               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+               0),
 
 /* This entry is from Andries.Brouwer@cwi.nl */
 UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
                "SCM Microsystems",
                "eUSB SmartMedia / CompactFlash Adapter",
-               US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, 
+               US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
                0), 
 #endif
 
@@ -527,6 +535,13 @@ UNUSUAL_DEV(  0x057b, 0x0022, 0x0000, 0x9999,
                "Silicon Media R/W",
                US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+UNUSUAL_DEV(  0x0584, 0x0008, 0x0102, 0x0102,
+               "Fujifilm",
+               "DPC-R1 (Alauda)",
+               US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
+#endif
+
 /* Fabrizio Fellini <fello@libero.it> */
 UNUSUAL_DEV(  0x0595, 0x4343, 0x0000, 0x2210,
                "Fujifilm",
@@ -673,8 +688,8 @@ UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100,
 UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100, 
                "Olympus",
                "Camedia MAUSB-2",
-               US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-               US_FL_SINGLE_LUN ),
+               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+               0),
 #endif
 
 /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */
@@ -739,8 +754,8 @@ UNUSUAL_DEV(  0x0781, 0x0100, 0x0100, 0x0100,
 UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999, 
                "Sandisk",
                "ImageMate SDDR-09",
-               US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-               US_FL_SINGLE_LUN ),
+               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+               0),
 #endif
 
 #ifdef CONFIG_USB_STORAGE_FREECOM
@@ -776,6 +791,13 @@ UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
                US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
 #endif
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+UNUSUAL_DEV(  0x07b4, 0x010a, 0x0102, 0x0102,
+               "Olympus",
+               "MAUSB-10 (Alauda)",
+               US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
+#endif
+
 #ifdef CONFIG_USB_STORAGE_DATAFAB
 UNUSUAL_DEV(  0x07c4, 0xa000, 0x0000, 0x0015,
                "Datafab",
@@ -1134,3 +1156,27 @@ UNUSUAL_DEV(  0x55aa, 0xa103, 0x0000, 0x9999,
                US_SC_SCSI, US_PR_SDDR55, NULL,
                US_FL_SINGLE_LUN),
 #endif
+
+/* Control/Bulk transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR),
+
+/* Control/Bulk/Interrupt transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR),
+
+/* Bulk-only transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0),
index 3847ebe..dbcf239 100644 (file)
@@ -94,6 +94,9 @@
 #ifdef CONFIG_USB_STORAGE_ONETOUCH
 #include "onetouch.h"
 #endif
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+#include "alauda.h"
+#endif
 
 /* Some informational data */
 MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
@@ -112,49 +115,33 @@ static atomic_t total_threads = ATOMIC_INIT(0);
 static DECLARE_COMPLETION(threads_gone);
 
 
-/* The entries in this table, except for final ones here
- * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
- * line for line with the entries of us_unsuaul_dev_list[].
+/*
+ * The entries in this table correspond, line for line,
+ * with the entries of us_unusual_dev_list[].
  */
+#ifndef CONFIG_USB_LIBUSUAL
 
 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
                    vendorName, productName,useProtocol, useTransport, \
                    initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) }
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = (USB_US_TYPE_STOR<<24) }
 
 static struct usb_device_id storage_usb_ids [] = {
 
 #      include "unusual_devs.h"
 #undef UNUSUAL_DEV
-       /* Control/Bulk transport for all SubClass values */
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) },
-
-       /* Control/Bulk/Interrupt transport for all SubClass values */
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) },
-
-       /* Bulk-only transport for all SubClass values */
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) },
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
-
+#undef USUAL_DEV
        /* Terminating entry */
        { }
 };
 
 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /* This is the list of devices we recognize, along with their flag data */
 
@@ -167,7 +154,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
  * are free to use as many characters as you like.
  */
 
-#undef UNUSUAL_DEV
 #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
                    vendor_name, product_name, use_protocol, use_transport, \
                    init_function, Flags) \
@@ -177,53 +163,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
        .useProtocol = use_protocol,    \
        .useTransport = use_transport,  \
        .initFunction = init_function,  \
-       .flags = Flags, \
+}
+
+#define USUAL_DEV(use_protocol, use_transport, use_type) \
+{ \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
 }
 
 static struct us_unusual_dev us_unusual_dev_list[] = {
 #      include "unusual_devs.h" 
 #      undef UNUSUAL_DEV
-       /* Control/Bulk transport for all SubClass values */
-       { .useProtocol = US_SC_RBC,
-         .useTransport = US_PR_CB},
-       { .useProtocol = US_SC_8020,
-         .useTransport = US_PR_CB},
-       { .useProtocol = US_SC_QIC,
-         .useTransport = US_PR_CB},
-       { .useProtocol = US_SC_UFI,
-         .useTransport = US_PR_CB},
-       { .useProtocol = US_SC_8070,
-         .useTransport = US_PR_CB},
-       { .useProtocol = US_SC_SCSI,
-         .useTransport = US_PR_CB},
-
-       /* Control/Bulk/Interrupt transport for all SubClass values */
-       { .useProtocol = US_SC_RBC,
-         .useTransport = US_PR_CBI},
-       { .useProtocol = US_SC_8020,
-         .useTransport = US_PR_CBI},
-       { .useProtocol = US_SC_QIC,
-         .useTransport = US_PR_CBI},
-       { .useProtocol = US_SC_UFI,
-         .useTransport = US_PR_CBI},
-       { .useProtocol = US_SC_8070,
-         .useTransport = US_PR_CBI},
-       { .useProtocol = US_SC_SCSI,
-         .useTransport = US_PR_CBI},
-
-       /* Bulk-only transport for all SubClass values */
-       { .useProtocol = US_SC_RBC,
-         .useTransport = US_PR_BULK},
-       { .useProtocol = US_SC_8020,
-         .useTransport = US_PR_BULK},
-       { .useProtocol = US_SC_QIC,
-         .useTransport = US_PR_BULK},
-       { .useProtocol = US_SC_UFI,
-         .useTransport = US_PR_BULK},
-       { .useProtocol = US_SC_8070,
-         .useTransport = US_PR_BULK},
-       { .useProtocol = US_SC_SCSI,
-         .useTransport = US_PR_BULK},
+#      undef USUAL_DEV
 
        /* Terminating entry */
        { NULL }
@@ -240,6 +191,8 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
        down(&us->dev_semaphore);
 
        US_DEBUGP("%s\n", __FUNCTION__);
+       if (us->suspend_resume_hook)
+               (us->suspend_resume_hook)(us, US_SUSPEND);
        iface->dev.power.power_state.event = message.event;
 
        /* When runtime PM is working, we'll set a flag to indicate
@@ -256,6 +209,8 @@ static int storage_resume(struct usb_interface *iface)
        down(&us->dev_semaphore);
 
        US_DEBUGP("%s\n", __FUNCTION__);
+       if (us->suspend_resume_hook)
+               (us->suspend_resume_hook)(us, US_RESUME);
        iface->dev.power.power_state.event = PM_EVENT_ON;
 
        up(&us->dev_semaphore);
@@ -484,14 +439,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
        return 0;
 }
 
+/* Find an unusual_dev descriptor (always succeeds in the current code) */
+static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
+{
+       const int id_index = id - storage_usb_ids;
+       return &us_unusual_dev_list[id_index];
+}
+
 /* Get the unusual_devs entries and the string descriptors */
-static void get_device_info(struct us_data *us, int id_index)
+static void get_device_info(struct us_data *us, const struct usb_device_id *id)
 {
        struct usb_device *dev = us->pusb_dev;
        struct usb_interface_descriptor *idesc =
                &us->pusb_intf->cur_altsetting->desc;
-       struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
-       struct usb_device_id *id = &storage_usb_ids[id_index];
+       struct us_unusual_dev *unusual_dev = find_unusual(id);
 
        /* Store the entries */
        us->unusual_dev = unusual_dev;
@@ -501,7 +462,7 @@ static void get_device_info(struct us_data *us, int id_index)
        us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
                        idesc->bInterfaceProtocol :
                        unusual_dev->useTransport;
-       us->flags = unusual_dev->flags;
+       us->flags = USB_US_ORIG_FLAGS(id->driver_info);
 
        /*
         * This flag is only needed when we're in high-speed, so let's
@@ -516,7 +477,7 @@ static void get_device_info(struct us_data *us, int id_index)
         * from the unusual_devs.h table.
         */
        if (id->idVendor || id->idProduct) {
-               static char *msgs[3] = {
+               static const char *msgs[3] = {
                        "an unneeded SubClass entry",
                        "an unneeded Protocol entry",
                        "unneeded SubClass and Protocol entries"};
@@ -529,7 +490,7 @@ static void get_device_info(struct us_data *us, int id_index)
                if (unusual_dev->useTransport != US_PR_DEVICE &&
                        us->protocol == idesc->bInterfaceProtocol)
                        msg += 2;
-               if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE))
+               if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
                        printk(KERN_NOTICE USB_STORAGE "This device "
                                "(%04x,%04x,%04x S %02x P %02x)"
                                " has %s in unusual_devs.h\n"
@@ -686,6 +647,15 @@ static int get_protocol(struct us_data *us)
                break;
 #endif
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+       case US_PR_ALAUDA:
+               us->transport_name  = "Alauda Control/Bulk";
+               us->transport = alauda_transport;
+               us->transport_reset = usb_stor_Bulk_reset;
+               us->max_lun = 1;
+               break;
+#endif
+
        default:
                return -EIO;
        }
@@ -921,10 +891,12 @@ static int storage_probe(struct usb_interface *intf,
 {
        struct Scsi_Host *host;
        struct us_data *us;
-       const int id_index = id - storage_usb_ids; 
        int result;
        struct task_struct *th;
 
+       if (usb_usual_check_type(id, USB_US_TYPE_STOR))
+               return -ENXIO;
+
        US_DEBUGP("USB Mass Storage device detected\n");
 
        /*
@@ -957,29 +929,7 @@ static int storage_probe(struct usb_interface *intf,
         * of the match from the usb_device_id table, so we can find the
         * corresponding entry in the private table.
         */
-       get_device_info(us, id_index);
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-       if (us->protocol == US_PR_EUSB_SDDR09 ||
-                       us->protocol == US_PR_DPCM_USB) {
-               /* set the configuration -- STALL is an acceptable response here */
-               if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) {
-                       US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev
-                               ->actconfig->desc.bConfigurationValue);
-                       goto BadDevice;
-               }
-               result = usb_reset_configuration(us->pusb_dev);
-
-               US_DEBUGP("Result of usb_reset_configuration is %d\n", result);
-               if (result == -EPIPE) {
-                       US_DEBUGP("-- stall on control interface\n");
-               } else if (result != 0) {
-                       /* it's not a stall, but another error -- time to bail */
-                       US_DEBUGP("-- Unknown error.  Rejecting device\n");
-                       goto BadDevice;
-               }
-       }
-#endif
+       get_device_info(us, id);
 
        /* Get the transport, protocol, and pipe settings */
        result = get_transport(us);
@@ -1044,7 +994,6 @@ static void storage_disconnect(struct usb_interface *intf)
  ***********************************************************************/
 
 static struct usb_driver usb_storage_driver = {
-       .owner =        THIS_MODULE,
        .name =         "usb-storage",
        .probe =        storage_probe,
        .disconnect =   storage_disconnect,
@@ -1062,9 +1011,10 @@ static int __init usb_stor_init(void)
 
        /* register the driver, return usb_register return code if error */
        retval = usb_register(&usb_storage_driver);
-       if (retval == 0)
+       if (retval == 0) {
                printk(KERN_INFO "USB Mass Storage support registered.\n");
-
+               usb_usual_set_present(USB_US_TYPE_STOR);
+       }
        return retval;
 }
 
@@ -1088,6 +1038,8 @@ static void __exit usb_stor_exit(void)
                wait_for_completion(&threads_gone);
                atomic_dec(&total_threads);
        }
+
+       usb_usual_clear_present(USB_US_TYPE_STOR);
 }
 
 module_init(usb_stor_init);
index 98b0971..7259fd1 100644 (file)
@@ -45,6 +45,7 @@
 #define _USB_H_
 
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
@@ -63,38 +64,8 @@ struct us_unusual_dev {
        __u8  useProtocol;
        __u8  useTransport;
        int (*initFunction)(struct us_data *);
-       unsigned int flags;
 };
 
-/*
- * Static flag definitions.  We use this roundabout technique so that the
- * proc_info() routine can automatically display a message for each flag.
- */
-#define US_DO_ALL_FLAGS                                                \
-       US_FLAG(SINGLE_LUN,     0x00000001)                     \
-               /* allow access to only LUN 0 */                \
-       US_FLAG(NEED_OVERRIDE,  0x00000002)                     \
-               /* unusual_devs entry is necessary */           \
-       US_FLAG(SCM_MULT_TARG,  0x00000004)                     \
-               /* supports multiple targets */                 \
-       US_FLAG(FIX_INQUIRY,    0x00000008)                     \
-               /* INQUIRY response needs faking */             \
-       US_FLAG(FIX_CAPACITY,   0x00000010)                     \
-               /* READ CAPACITY response too big */            \
-       US_FLAG(IGNORE_RESIDUE, 0x00000020)                     \
-               /* reported residue is wrong */                 \
-       US_FLAG(BULK32,         0x00000040)                     \
-               /* Uses 32-byte CBW length */                   \
-       US_FLAG(NOT_LOCKABLE,   0x00000080)                     \
-               /* PREVENT/ALLOW not supported */               \
-       US_FLAG(GO_SLOW,        0x00000100)                     \
-               /* Need delay after Command phase */            \
-       US_FLAG(NO_WP_DETECT,   0x00000200)                     \
-               /* Don't check for write-protect */             \
-
-#define US_FLAG(name, value)   US_FL_##name = value ,
-enum { US_DO_ALL_FLAGS };
-#undef US_FLAG
 
 /* Dynamic flag definitions: used in set_bit() etc. */
 #define US_FLIDX_URB_ACTIVE    18  /* 0x00040000  current_urb is in use  */
@@ -122,7 +93,11 @@ enum { US_DO_ALL_FLAGS };
 typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
 typedef int (*trans_reset)(struct us_data*);
 typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
-typedef void (*extra_data_destructor)(void *);  /* extra data destructor   */
+typedef void (*extra_data_destructor)(void *); /* extra data destructor */
+typedef void (*pm_hook)(struct us_data *, int);        /* power management hook */
+
+#define US_SUSPEND     0
+#define US_RESUME      1
 
 /* we allocate one of these for every device that we remember */
 struct us_data {
@@ -178,6 +153,9 @@ struct us_data {
        /* subdriver information */
        void                    *extra;          /* Any extra data          */
        extra_data_destructor   extra_destructor;/* extra data destructor   */
+#ifdef CONFIG_PM
+       pm_hook                 suspend_resume_hook;
+#endif
 };
 
 /* Convert between us_data and the corresponding Scsi_Host */
index 6c3a53f..5d02f16 100644 (file)
@@ -39,10 +39,15 @@ MODULE_DEVICE_TABLE (usb, skel_table);
 /* Get a minor range for your devices from the usb maintainer */
 #define USB_SKEL_MINOR_BASE    192
 
+/* our private defines. if this grows any larger, use your own .h file */
+#define MAX_TRANSFER           ( PAGE_SIZE - 512 )
+#define WRITES_IN_FLIGHT       8
+
 /* Structure to hold all of our device specific stuff */
 struct usb_skel {
        struct usb_device *     udev;                   /* the usb device for this device */
        struct usb_interface *  interface;              /* the interface for this device */
+       struct semaphore        limit_sem;              /* limiting the number of writes in progress */
        unsigned char *         bulk_in_buffer;         /* the buffer to receive data */
        size_t                  bulk_in_size;           /* the size of the receive buffer */
        __u8                    bulk_in_endpointAddr;   /* the address of the bulk in endpoint */
@@ -152,6 +157,7 @@ static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
        /* free up our allocated buffer */
        usb_buffer_free(urb->dev, urb->transfer_buffer_length, 
                        urb->transfer_buffer, urb->transfer_dma);
+       up(&dev->limit_sem);
 }
 
 static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
@@ -160,6 +166,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
        int retval = 0;
        struct urb *urb = NULL;
        char *buf = NULL;
+       size_t writesize = min(count, (size_t)MAX_TRANSFER);
 
        dev = (struct usb_skel *)file->private_data;
 
@@ -167,6 +174,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
        if (count == 0)
                goto exit;
 
+       /* limit the number of URBs in flight to stop a user from using up all RAM */
+       if (down_interruptible(&dev->limit_sem)) {
+               retval = -ERESTARTSYS;
+               goto exit;
+       }
+
        /* create a urb, and a buffer for it, and copy the data to the urb */
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb) {
@@ -174,13 +187,13 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
                goto error;
        }
 
-       buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
+       buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
        if (!buf) {
                retval = -ENOMEM;
                goto error;
        }
 
-       if (copy_from_user(buf, user_buffer, count)) {
+       if (copy_from_user(buf, user_buffer, writesize)) {
                retval = -EFAULT;
                goto error;
        }
@@ -188,7 +201,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
        /* initialize the urb properly */
        usb_fill_bulk_urb(urb, dev->udev,
                          usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
-                         buf, count, skel_write_bulk_callback, dev);
+                         buf, writesize, skel_write_bulk_callback, dev);
        urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        /* send the data out the bulk port */
@@ -202,11 +215,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou
        usb_free_urb(urb);
 
 exit:
-       return count;
+       return writesize;
 
 error:
-       usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
+       usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
        usb_free_urb(urb);
+       up(&dev->limit_sem);
        return retval;
 }
 
@@ -238,13 +252,13 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
        int retval = -ENOMEM;
 
        /* allocate memory for our device state and initialize it */
-       dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev == NULL) {
                err("Out of memory");
                goto error;
        }
-       memset(dev, 0x00, sizeof(*dev));
        kref_init(&dev->kref);
+       sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
 
        dev->udev = usb_get_dev(interface_to_usbdev(interface));
        dev->interface = interface;
@@ -330,7 +344,6 @@ static void skel_disconnect(struct usb_interface *interface)
 }
 
 static struct usb_driver skel_driver = {
-       .owner =        THIS_MODULE,
        .name =         "skeleton",
        .probe =        skel_probe,
        .disconnect =   skel_disconnect,
index 15fb250..b914630 100644 (file)
@@ -52,7 +52,6 @@ static int ds_send_control_cmd(struct ds_device *, u16, u16);
 
 
 static struct usb_driver ds_driver = {
-       .owner =        THIS_MODULE,
        .name =         "DS9490R",
        .probe =        ds_probe,
        .disconnect =   ds_disconnect,
index a93c2bf..6a9a75d 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/module.h>
 #include <linux/net.h>
 #include <linux/ipv6.h>
index 460554b..38d3e80 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -313,7 +313,8 @@ int bio_get_nr_vecs(struct block_device *bdev)
 }
 
 static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
-                         *page, unsigned int len, unsigned int offset)
+                         *page, unsigned int len, unsigned int offset,
+                         unsigned short max_sectors)
 {
        int retried_segments = 0;
        struct bio_vec *bvec;
@@ -327,7 +328,7 @@ static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
        if (bio->bi_vcnt >= bio->bi_max_vecs)
                return 0;
 
-       if (((bio->bi_size + len) >> 9) > q->max_sectors)
+       if (((bio->bi_size + len) >> 9) > max_sectors)
                return 0;
 
        /*
@@ -385,6 +386,25 @@ static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
        return len;
 }
 
+/**
+ *     bio_add_pc_page -       attempt to add page to bio
+ *     @bio: destination bio
+ *     @page: page to add
+ *     @len: vec entry length
+ *     @offset: vec entry offset
+ *
+ *     Attempt to add a page to the bio_vec maplist. This can fail for a
+ *     number of reasons, such as the bio being full or target block
+ *     device limitations. The target block device must allow bio's
+ *      smaller than PAGE_SIZE, so it is always possible to add a single
+ *      page to an empty bio. This should only be used by REQ_PC bios.
+ */
+int bio_add_pc_page(request_queue_t *q, struct bio *bio, struct page *page,
+                   unsigned int len, unsigned int offset)
+{
+       return __bio_add_page(q, bio, page, len, offset, q->max_hw_sectors);
+}
+
 /**
  *     bio_add_page    -       attempt to add page to bio
  *     @bio: destination bio
@@ -401,8 +421,8 @@ static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
 int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
                 unsigned int offset)
 {
-       return __bio_add_page(bdev_get_queue(bio->bi_bdev), bio, page,
-                             len, offset);
+       struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+       return __bio_add_page(q, bio, page, len, offset, q->max_sectors);
 }
 
 struct bio_map_data {
@@ -514,7 +534,7 @@ struct bio *bio_copy_user(request_queue_t *q, unsigned long uaddr,
                        break;
                }
 
-               if (__bio_add_page(q, bio, page, bytes, 0) < bytes) {
+               if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) {
                        ret = -EINVAL;
                        break;
                }
@@ -628,7 +648,8 @@ static struct bio *__bio_map_user_iov(request_queue_t *q,
                        /*
                         * sorry...
                         */
-                       if (__bio_add_page(q, bio, pages[j], bytes, offset) < bytes)
+                       if (bio_add_pc_page(q, bio, pages[j], bytes, offset) <
+                                           bytes)
                                break;
 
                        len -= bytes;
@@ -801,8 +822,8 @@ static struct bio *__bio_map_kern(request_queue_t *q, void *data,
                if (bytes > len)
                        bytes = len;
 
-               if (__bio_add_page(q, bio, virt_to_page(data), bytes,
-                                  offset) < bytes)
+               if (bio_add_pc_page(q, bio, virt_to_page(data), bytes,
+                                   offset) < bytes)
                        break;
 
                data += bytes;
@@ -1228,6 +1249,7 @@ EXPORT_SYMBOL(bio_clone);
 EXPORT_SYMBOL(bio_phys_segments);
 EXPORT_SYMBOL(bio_hw_segments);
 EXPORT_SYMBOL(bio_add_page);
+EXPORT_SYMBOL(bio_add_pc_page);
 EXPORT_SYMBOL(bio_get_nr_vecs);
 EXPORT_SYMBOL(bio_map_user);
 EXPORT_SYMBOL(bio_unmap_user);
index 8186341..55ac032 100644 (file)
@@ -1170,7 +1170,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
        }
 
        ret = rw_verify_area(type, file, pos, tot_len);
-       if (ret)
+       if (ret < 0)
                goto out;
 
        fnv = NULL;
index f2ca782..30cae36 100644 (file)
@@ -14,6 +14,9 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfs_fs.h>
+
+#include <net/inet_sock.h>
+
 #include "nfs4_fs.h"
 #include "callback.h"
 
index a091ee4..df3468a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/security.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
+#include <linux/pagemap.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -182,22 +183,33 @@ bad:
 }
 #endif
 
+/*
+ * rw_verify_area doesn't like huge counts. We limit
+ * them to something that fits in "int" so that others
+ * won't have to do range checks all the time.
+ */
+#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
 
 int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
 {
        struct inode *inode;
        loff_t pos;
 
-       if (unlikely(count > INT_MAX))
+       if (unlikely((ssize_t) count < 0))
                goto Einval;
        pos = *ppos;
        if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
                goto Einval;
 
        inode = file->f_dentry->d_inode;
-       if (inode->i_flock && MANDATORY_LOCK(inode))
-               return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count);
-       return 0;
+       if (inode->i_flock && MANDATORY_LOCK(inode)) {
+               int retval = locks_mandatory_area(
+                       read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
+                       inode, file, pos, count);
+               if (retval < 0)
+                       return retval;
+       }
+       return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
 
 Einval:
        return -EINVAL;
@@ -244,7 +256,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
                return -EFAULT;
 
        ret = rw_verify_area(READ, file, pos, count);
-       if (!ret) {
+       if (ret >= 0) {
+               count = ret;
                ret = security_file_permission (file, MAY_READ);
                if (!ret) {
                        if (file->f_op->read)
@@ -295,7 +308,8 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
                return -EFAULT;
 
        ret = rw_verify_area(WRITE, file, pos, count);
-       if (!ret) {
+       if (ret >= 0) {
+               count = ret;
                ret = security_file_permission (file, MAY_WRITE);
                if (!ret) {
                        if (file->f_op->write)
@@ -497,7 +511,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
        }
 
        ret = rw_verify_area(type, file, pos, tot_len);
-       if (ret)
+       if (ret < 0)
                goto out;
        ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE);
        if (ret)
@@ -653,8 +667,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
                if (!(in_file->f_mode & FMODE_PREAD))
                        goto fput_in;
        retval = rw_verify_area(READ, in_file, ppos, count);
-       if (retval)
+       if (retval < 0)
                goto fput_in;
+       count = retval;
 
        retval = security_file_permission (in_file, MAY_READ);
        if (retval)
@@ -674,8 +689,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
                goto fput_out;
        out_inode = out_file->f_dentry->d_inode;
        retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
-       if (retval)
+       if (retval < 0)
                goto fput_out;
+       count = retval;
 
        retval = security_file_permission (out_file, MAY_WRITE);
        if (retval)
index 578ed3f..302201f 100644 (file)
@@ -321,6 +321,7 @@ static inline int fls(int word)
 #else
 #define fls    generic_fls
 #endif
+#define fls64   generic_fls64
 
 /* Compute powers of two for the given integer.  */
 static inline long floor_log2(unsigned long word)
diff --git a/include/asm-arm/arch-pxa/ohci.h b/include/asm-arm/arch-pxa/ohci.h
new file mode 100644 (file)
index 0000000..7da8956
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef ASMARM_ARCH_OHCI_H
+#define ASMARM_ARCH_OHCI_H
+
+struct device;
+
+struct pxaohci_platform_data {
+       int (*init)(struct device *);
+       void (*exit)(struct device *);
+
+       int port_mode;
+#define PMM_NPS_MODE           1
+#define PMM_GLOBAL_MODE        2
+#define PMM_PERPORT_MODE       3
+};
+
+extern void pxa_set_ohci_info(struct pxaohci_platform_data *info);
+
+#endif
index 7399d43..d02de72 100644 (file)
@@ -332,6 +332,7 @@ static inline unsigned long __ffs(unsigned long word)
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -351,6 +352,7 @@ static inline unsigned long __ffs(unsigned long word)
 #define fls(x) \
        ( __builtin_constant_p(x) ? generic_fls(x) : \
          ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) )
+#define fls64(x)   generic_fls64(x)
 #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
 #define __ffs(x) (ffs(x) - 1)
 #define ffz(x) __ffs( ~(x) )
index 7d062fb..15cc6f2 100644 (file)
@@ -259,6 +259,7 @@ static inline unsigned long __ffs(unsigned long word)
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as
index 1bddb3f..d3eb0f1 100644 (file)
@@ -240,6 +240,7 @@ static inline int test_bit(int nr, const volatile unsigned long *addr)
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN - returns the hamming weight of a N-bit word
index b664bd5..02be7b3 100644 (file)
@@ -228,6 +228,7 @@ found_middle:
                                                        \
        bit ? 33 - bit : bit;                           \
 })
+#define fls64(x)   generic_fls64(x)
 
 /*
  * Every architecture must define this function. It's the fastest
index ce31b73..0e6d985 100644 (file)
@@ -56,6 +56,7 @@ extern __inline__ int test_bit(int nr, const unsigned long * addr)
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
index 5036f59..c0411ec 100644 (file)
@@ -406,5 +406,6 @@ found_middle:
 #endif /* __KERNEL__ */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* _H8300_BITOPS_H */
index ddf1739..4807aa1 100644 (file)
@@ -372,6 +372,7 @@ static inline unsigned long ffz(unsigned long word)
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
index 7232528..36d0fb9 100644 (file)
@@ -345,6 +345,7 @@ fls (int t)
        x |= x >> 16;
        return ia64_popcnt(x);
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as the libc and compiler builtin
index e784439..abea2fd 100644 (file)
@@ -465,6 +465,7 @@ static __inline__ unsigned long __ffs(unsigned long word)
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
index b1bcf7c..13f4c00 100644 (file)
@@ -310,6 +310,7 @@ static inline int fls(int x)
 
        return 32 - cnt;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * Every architecture must define this function. It's the fastest
index c42f88a..4058dd0 100644 (file)
@@ -499,5 +499,6 @@ found_middle:
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* _M68KNOMMU_BITOPS_H */
index 5496f90..3b0c8aa 100644 (file)
@@ -695,7 +695,7 @@ static inline unsigned long fls(unsigned long word)
 
        return flz(~word) + 1;
 }
-
+#define fls64(x)   generic_fls64(x)
 
 /*
  * find_next_zero_bit - find the first zero bit in a memory region
index 55b98c6..15d8c2b 100644 (file)
@@ -263,6 +263,7 @@ static __inline__ int fls(int x)
 
        return ret;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
index 5727229..1996eaa 100644 (file)
@@ -310,6 +310,7 @@ static __inline__ int fls(unsigned int x)
        asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
        return 32 - lz;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
index b07c578..6123276 100644 (file)
@@ -839,6 +839,7 @@ static inline int sched_find_first_bit(unsigned long *b)
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
index 5163d1f..1c52608 100644 (file)
@@ -470,6 +470,7 @@ found_middle:
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* __KERNEL__ */
 
index e1ff63e..ce9c3ad 100644 (file)
@@ -510,6 +510,7 @@ found_middle:
 
 #define ffs(x) generic_ffs(x)
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* __KERNEL__ */
 
index bfbd795..41722b5 100644 (file)
@@ -298,6 +298,7 @@ static inline int ffs(int x)
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
index 6388b83..6efc016 100644 (file)
@@ -119,6 +119,7 @@ static inline unsigned long __ffs(unsigned long word)
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
index b91e799..8955d23 100644 (file)
@@ -276,6 +276,7 @@ found_middle:
 
 #define ffs(x) generic_ffs (x)
 #define fls(x) generic_fls (x)
+#define fls64(x) generic_fls64(x)
 #define __ffs(x) ffs(x)
 
 
index 05a0d37..a4d5d09 100644 (file)
@@ -340,6 +340,20 @@ static __inline__ unsigned long __ffs(unsigned long word)
        return word;
 }
 
+/*
+ * __fls: find last bit set.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static __inline__ unsigned long __fls(unsigned long word)
+{
+       __asm__("bsrq %1,%0"
+               :"=r" (word)
+               :"rm" (word));
+       return word;
+}
+
 #ifdef __KERNEL__
 
 static inline int sched_find_first_bit(const unsigned long *b)
@@ -369,6 +383,19 @@ static __inline__ int ffs(int x)
        return r+1;
 }
 
+/**
+ * fls64 - find last bit set in 64 bit word
+ * @x: the word to search
+ *
+ * This is defined the same way as fls.
+ */
+static __inline__ int fls64(__u64 x)
+{
+       if (x == 0)
+               return 0;
+       return __fls(x) + 1;
+}
+
 /**
  * hweightN - returns the hamming weight of a N-bit word
  * @x: the word to weigh
index e76ee88..0a2065f 100644 (file)
@@ -245,6 +245,7 @@ static __inline__ int fls (unsigned int x)
 {
        return __cntlz(x);
 }
+#define fls64(x)   generic_fls64(x)
 
 static __inline__ int
 find_next_bit(const unsigned long *addr, int size, int offset)
index 685fd37..b60ffe3 100644 (file)
@@ -292,6 +292,8 @@ extern struct bio *bio_clone(struct bio *, gfp_t);
 extern void bio_init(struct bio *);
 
 extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
+extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
+                          unsigned int, unsigned int);
 extern int bio_get_nr_vecs(struct block_device *);
 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
                                unsigned long, unsigned int, int);
index 38c2fb7..6a2a19f 100644 (file)
@@ -76,6 +76,15 @@ static __inline__ int generic_fls(int x)
  */
 #include <asm/bitops.h>
 
+
+static inline int generic_fls64(__u64 x)
+{
+       __u32 h = x >> 32;
+       if (h)
+               return fls(x) + 32;
+       return fls(x);
+}
+
 static __inline__ int get_bitmask_order(unsigned int count)
 {
        int order;
index a33a31e..a18500d 100644 (file)
@@ -184,6 +184,7 @@ struct request {
        void *sense;
 
        unsigned int timeout;
+       int retries;
 
        /*
         * For Power Management requests
@@ -558,6 +559,7 @@ extern void blk_unregister_queue(struct gendisk *disk);
 extern void register_disk(struct gendisk *dev);
 extern void generic_make_request(struct bio *bio);
 extern void blk_put_request(struct request *);
+extern void __blk_put_request(request_queue_t *, struct request *);
 extern void blk_end_sync_rq(struct request *rq);
 extern void blk_attempt_remerge(request_queue_t *, struct request *);
 extern struct request *blk_get_request(request_queue_t *, int, gfp_t);
@@ -579,6 +581,10 @@ extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned
 extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
 extern int blk_execute_rq(request_queue_t *, struct gendisk *,
                          struct request *, int);
+extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *,
+                                 struct request *, int,
+                                 void (*done)(struct request *));
+
 static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
 {
        return bdev->bd_disk->queue;
@@ -696,7 +702,8 @@ extern int blkdev_issue_flush(struct block_device *, sector_t *);
 
 #define MAX_PHYS_SEGMENTS 128
 #define MAX_HW_SEGMENTS 128
-#define MAX_SECTORS 255
+#define SAFE_MAX_SECTORS 255
+#define BLK_DEF_MAX_SECTORS 1024
 
 #define MAX_SEGMENT_SIZE       65536
 
index d068176..c31650d 100644 (file)
@@ -256,6 +256,16 @@ int cpufreq_update_policy(unsigned int cpu);
 /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
 unsigned int cpufreq_get(unsigned int cpu);
 
+/* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */
+#ifdef CONFIG_CPU_FREQ
+unsigned int cpufreq_quick_get(unsigned int cpu);
+#else
+static inline unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+       return 0;
+}
+#endif
+
 
 /*********************************************************************
  *                       CPUFREQ DEFAULT GOVERNOR                    *
index 71fab43..088529f 100644 (file)
@@ -192,10 +192,9 @@ enum {
 #include <linux/workqueue.h>
 
 #include <net/inet_connection_sock.h>
+#include <net/inet_sock.h>
 #include <net/inet_timewait_sock.h>
-#include <net/sock.h>
 #include <net/tcp_states.h>
-#include <net/tcp.h>
 
 enum dccp_state {
        DCCP_OPEN       = TCP_ESTABLISHED,
@@ -408,8 +407,6 @@ struct dccp_ackvec;
  * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss
  * @dccps_timestamp_time - time of latest TIMESTAMP option
  * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
- * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options)
- * @dccps_pmtu_cookie - Last pmtu seen by socket
  * @dccps_packet_size - Set thru setsockopt
  * @dccps_role - Role of this sock, one of %dccp_role
  * @dccps_ndp_count - number of Non Data Packets since last data packet
@@ -434,8 +431,6 @@ struct dccp_sock {
        __u32                           dccps_timestamp_echo;
        __u32                           dccps_packet_size;
        unsigned long                   dccps_ndp_count;
-       __u16                           dccps_ext_header_len;
-       __u32                           dccps_pmtu_cookie;
        __u32                           dccps_mss_cache;
        struct dccp_options             dccps_options;
        struct dccp_ackvec              *dccps_hc_rx_ackvec;
index 5f49a30..745c988 100644 (file)
@@ -63,10 +63,11 @@ static inline int is_zero_ether_addr(const u8 *addr)
  * @addr: Pointer to a six-byte array containing the Ethernet address
  *
  * Return true if the address is a multicast address.
+ * By definition the broadcast address is also a multicast address.
  */
 static inline int is_multicast_ether_addr(const u8 *addr)
 {
-       return ((addr[0] != 0xff) && (0x01 & addr[0]));
+       return (0x01 & addr[0]);
 }
 
 /**
index e677f73..4fab3d0 100644 (file)
@@ -157,8 +157,7 @@ struct pppox_proto {
 extern int register_pppox_proto(int proto_num, struct pppox_proto *pp);
 extern void unregister_pppox_proto(int proto_num);
 extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
-extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd,
-                              unsigned long arg);
+extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 
 /* PPPoX socket states */
 enum {
index 33e8a19..9e2eb9a 100644 (file)
@@ -16,6 +16,7 @@
  */
 #ifndef _LINUX_IP_H
 #define _LINUX_IP_H
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 #define IPTOS_TOS_MASK         0x1E
 #define        IPOPT_TS_TSANDADDR      1               /* timestamps and addresses */
 #define        IPOPT_TS_PRESPEC        3               /* specified modules only */
 
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <net/request_sock.h>
-#include <net/sock.h>
-#include <linux/igmp.h>
-#include <net/flow.h>
-
-struct ip_options {
-  __u32                faddr;                          /* Saved first hop address */
-  unsigned char        optlen;
-  unsigned char srr;
-  unsigned char rr;
-  unsigned char ts;
-  unsigned char is_setbyuser:1,                        /* Set by setsockopt?                   */
-                is_data:1,                     /* Options in __data, rather than skb   */
-                is_strictroute:1,              /* Strict source route                  */
-                srr_is_hit:1,                  /* Packet destination addr was our one  */
-                is_changed:1,                  /* IP checksum more not valid           */      
-                rr_needaddr:1,                 /* Need to record addr of outgoing dev  */
-                ts_needtime:1,                 /* Need to record timestamp             */
-                ts_needaddr:1;                 /* Need to record addr of outgoing dev  */
-  unsigned char router_alert;
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __data[0];
-};
-
-#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
-
-struct inet_request_sock {
-       struct request_sock     req;
-       u32                     loc_addr;
-       u32                     rmt_addr;
-       u16                     rmt_port;
-       u16                     snd_wscale : 4, 
-                               rcv_wscale : 4, 
-                               tstamp_ok  : 1,
-                               sack_ok    : 1,
-                               wscale_ok  : 1,
-                               ecn_ok     : 1,
-                               acked      : 1;
-       struct ip_options       *opt;
-};
-
-static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
-{
-       return (struct inet_request_sock *)sk;
-}
-
-struct ipv6_pinfo;
-
-struct inet_sock {
-       /* sk and pinet6 has to be the first two members of inet_sock */
-       struct sock             sk;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-       struct ipv6_pinfo       *pinet6;
-#endif
-       /* Socket demultiplex comparisons on incoming packets. */
-       __u32                   daddr;          /* Foreign IPv4 addr */
-       __u32                   rcv_saddr;      /* Bound local IPv4 addr */
-       __u16                   dport;          /* Destination port */
-       __u16                   num;            /* Local port */
-       __u32                   saddr;          /* Sending source */
-       __s16                   uc_ttl;         /* Unicast TTL */
-       __u16                   cmsg_flags;
-       struct ip_options       *opt;
-       __u16                   sport;          /* Source port */
-       __u16                   id;             /* ID counter for DF pkts */
-       __u8                    tos;            /* TOS */
-       __u8                    mc_ttl;         /* Multicasting TTL */
-       __u8                    pmtudisc;
-       unsigned                recverr : 1,
-                               freebind : 1,
-                               hdrincl : 1,
-                               mc_loop : 1;
-       int                     mc_index;       /* Multicast device index */
-       __u32                   mc_addr;
-       struct ip_mc_socklist   *mc_list;       /* Group array */
-       /*
-        * Following members are used to retain the infomation to build
-        * an ip header on each ip fragmentation while the socket is corked.
-        */
-       struct {
-               unsigned int            flags;
-               unsigned int            fragsize;
-               struct ip_options       *opt;
-               struct rtable           *rt;
-               int                     length; /* Total length of all frames */
-               u32                     addr;
-               struct flowi            fl;
-       } cork;
-};
-
-#define IPCORK_OPT     1       /* ip-options has been held in ipcork.opt */
-#define IPCORK_ALLFRAG 2       /* always fragment (for ipv6 for now) */
-
-static inline struct inet_sock *inet_sk(const struct sock *sk)
-{
-       return (struct inet_sock *)sk;
-}
-
-static inline void __inet_sk_copy_descendant(struct sock *sk_to,
-                                            const struct sock *sk_from,
-                                            const int ancestor_size)
-{
-       memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
-              sk_from->sk_prot->obj_size - ancestor_size);
-}
-#if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE))
-static inline void inet_sk_copy_descendant(struct sock *sk_to,
-                                          const struct sock *sk_from)
-{
-       __inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock));
-}
-#endif
-#endif
-
-extern int inet_sk_rebuild_header(struct sock *sk);
-
 struct iphdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u8    ihl:4,
index e0b9227..93bbed5 100644 (file)
@@ -171,12 +171,13 @@ enum {
 };
 
 #ifdef __KERNEL__
-#include <linux/in6.h>          /* struct sockaddr_in6 */
 #include <linux/icmpv6.h>
-#include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
 #include <linux/tcp.h>
 #include <linux/udp.h>
 
+#include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
+#include <net/inet_sock.h>
+
 /* 
    This structure contains results of exthdrs parsing
    as offsets from skb->nh.
@@ -199,18 +200,17 @@ static inline int inet6_iif(const struct sk_buff *skb)
        return IP6CB(skb)->iif;
 }
 
-struct tcp6_request_sock {
-       struct tcp_request_sock req;
+struct inet6_request_sock {
        struct in6_addr         loc_addr;
        struct in6_addr         rmt_addr;
        struct sk_buff          *pktopts;
        int                     iif;
 };
 
-static inline struct tcp6_request_sock *tcp6_rsk(const struct request_sock *sk)
-{
-       return (struct tcp6_request_sock *)sk;
-}
+struct tcp6_request_sock {
+       struct tcp_request_sock   tcp6rsk_tcp;
+       struct inet6_request_sock tcp6rsk_inet6;
+};
 
 /**
  * struct ipv6_pinfo - ipv6 private area
@@ -298,12 +298,36 @@ struct tcp6_sock {
        struct ipv6_pinfo inet6;
 };
 
+extern int inet6_sk_rebuild_header(struct sock *sk);
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
 {
        return inet_sk(__sk)->pinet6;
 }
 
+static inline struct inet6_request_sock *
+                       inet6_rsk(const struct request_sock *rsk)
+{
+       return (struct inet6_request_sock *)(((u8 *)rsk) +
+                                            inet_rsk(rsk)->inet6_rsk_offset);
+}
+
+static inline u32 inet6_rsk_offset(struct request_sock *rsk)
+{
+       return rsk->rsk_ops->obj_size - sizeof(struct inet6_request_sock);
+}
+
+static inline struct request_sock *inet6_reqsk_alloc(struct request_sock_ops *ops)
+{
+       struct request_sock *req = reqsk_alloc(ops);
+
+       if (req != NULL)
+               inet_rsk(req)->inet6_rsk_offset = inet6_rsk_offset(req);
+
+       return req;
+}
+
 static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
        return (struct raw6_sock *)sk;
@@ -323,28 +347,37 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
 #define __ipv6_only_sock(sk)   (inet6_sk(sk)->ipv6only)
 #define ipv6_only_sock(sk)     ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
 
-#include <linux/tcp.h>
+struct inet6_timewait_sock {
+       struct in6_addr tw_v6_daddr;
+       struct in6_addr tw_v6_rcv_saddr;
+};
 
 struct tcp6_timewait_sock {
-       struct tcp_timewait_sock tw_v6_sk;
-       struct in6_addr          tw_v6_daddr;
-       struct in6_addr          tw_v6_rcv_saddr;
+       struct tcp_timewait_sock   tcp6tw_tcp;
+       struct inet6_timewait_sock tcp6tw_inet6;
 };
 
-static inline struct tcp6_timewait_sock *tcp6_twsk(const struct sock *sk)
+static inline u16 inet6_tw_offset(const struct proto *prot)
 {
-       return (struct tcp6_timewait_sock *)sk;
+       return prot->twsk_prot->twsk_obj_size -
+                       sizeof(struct inet6_timewait_sock);
 }
 
-static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk)
+{
+       return (struct inet6_timewait_sock *)(((u8 *)sk) +
+                                             inet_twsk(sk)->tw_ipv6_offset);
+}
+
+static inline struct in6_addr *__inet6_rcv_saddr(const struct sock *sk)
 {
        return likely(sk->sk_state != TCP_TIME_WAIT) ?
-               &inet6_sk(sk)->rcv_saddr : &tcp6_twsk(sk)->tw_v6_rcv_saddr;
+               &inet6_sk(sk)->rcv_saddr : &inet6_twsk(sk)->tw_v6_rcv_saddr;
 }
 
-static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct in6_addr *inet6_rcv_saddr(const struct sock *sk)
 {
-       return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
+       return sk->sk_family == AF_INET6 ? __inet6_rcv_saddr(sk) : NULL;
 }
 
 static inline int inet_v6_ipv6only(const struct sock *sk)
@@ -361,13 +394,19 @@ static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
        return NULL;
 }
 
+static inline struct inet6_request_sock *
+                       inet6_rsk(const struct request_sock *rsk)
+{
+       return NULL;
+}
+
 static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
        return NULL;
 }
 
-#define __tcp_v6_rcv_saddr(__sk)       NULL
-#define tcp_v6_rcv_saddr(__sk)         NULL
+#define __inet6_rcv_saddr(__sk)        NULL
+#define inet6_rcv_saddr(__sk)  NULL
 #define tcp_twsk_ipv6only(__sk)                0
 #define inet_v6_ipv6only(__sk)         0
 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
index d6a41e6..28195a2 100644 (file)
@@ -107,7 +107,7 @@ enum sock_type {
 struct socket {
        socket_state            state;
        unsigned long           flags;
-       struct proto_ops        *ops;
+       const struct proto_ops  *ops;
        struct fasync_struct    *fasync_list;
        struct file             *file;
        struct sock             *sk;
@@ -260,7 +260,7 @@ SOCKCALL_WRAP(name, recvmsg, (struct kiocb *iocb, struct socket *sock, struct ms
 SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_area_struct *vma), \
              (file, sock, vma)) \
              \
-static struct proto_ops name##_ops = {                 \
+static const struct proto_ops name##_ops = {                   \
        .family         = fam,                          \
        .owner          = THIS_MODULE,                  \
        .release        = __lock_##name##_release,      \
index 4db67b3..a17e171 100644 (file)
@@ -15,6 +15,7 @@
 #define PCI_CLASS_STORAGE_FLOPPY       0x0102
 #define PCI_CLASS_STORAGE_IPI          0x0103
 #define PCI_CLASS_STORAGE_RAID         0x0104
+#define PCI_CLASS_STORAGE_SAS          0x0107
 #define PCI_CLASS_STORAGE_OTHER                0x0180
 
 #define PCI_BASE_CLASS_NETWORK         0x02
index 7240667..6351c40 100644 (file)
@@ -216,6 +216,16 @@ struct sadb_x_nat_t_port {
 } __attribute__((packed));
 /* sizeof(struct sadb_x_nat_t_port) == 8 */
 
+/* Generic LSM security context */
+struct sadb_x_sec_ctx {
+       uint16_t        sadb_x_sec_len;
+       uint16_t        sadb_x_sec_exttype;
+       uint8_t         sadb_x_ctx_alg;  /* LSMs: e.g., selinux == 1 */
+       uint8_t         sadb_x_ctx_doi;
+       uint16_t        sadb_x_ctx_len;
+} __attribute__((packed));
+/* sizeof(struct sadb_sec_ctx) = 8 */
+
 /* Message types */
 #define SADB_RESERVED          0
 #define SADB_GETSPI            1
@@ -325,7 +335,8 @@ struct sadb_x_nat_t_port {
 #define SADB_X_EXT_NAT_T_SPORT         21
 #define SADB_X_EXT_NAT_T_DPORT         22
 #define SADB_X_EXT_NAT_T_OA            23
-#define SADB_EXT_MAX                   23
+#define SADB_X_EXT_SEC_CTX             24
+#define SADB_EXT_MAX                   24
 
 /* Identity Extension values */
 #define SADB_IDENTTYPE_RESERVED        0
index e87b233..d10f353 100644 (file)
@@ -429,6 +429,7 @@ enum
        TCA_NETEM_CORR,
        TCA_NETEM_DELAY_DIST,
        TCA_NETEM_REORDER,
+       TCA_NETEM_CORRUPT,
        __TCA_NETEM_MAX,
 };
 
@@ -457,6 +458,12 @@ struct tc_netem_reorder
        __u32   correlation;
 };
 
+struct tc_netem_corrupt
+{
+       __u32   probability;
+       __u32   correlation;
+};
+
 #define NETEM_DIST_SCALE       8192
 
 #endif
index 7b2adb3..5d6456b 100644 (file)
@@ -52,9 +52,9 @@ extern void get_random_bytes(void *buf, int nbytes);
 void generate_random_uuid(unsigned char uuid_out[16]);
 
 extern __u32 secure_ip_id(__u32 daddr);
-extern u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport);
-extern u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, 
-                                      __u16 dport);
+extern u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport);
+extern u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, 
+                                     __u16 dport);
 extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
                                        __u16 sport, __u16 dport);
 extern __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
index f7e0ae0..ef75365 100644 (file)
@@ -59,6 +59,12 @@ struct sk_buff;
 struct sock;
 struct sockaddr;
 struct socket;
+struct flowi;
+struct dst_entry;
+struct xfrm_selector;
+struct xfrm_policy;
+struct xfrm_state;
+struct xfrm_user_sec_ctx;
 
 extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
 extern int cap_netlink_recv(struct sk_buff *skb);
@@ -788,6 +794,52 @@ struct swap_info_struct;
  *      which is used to copy security attributes between local stream sockets.
  * @sk_free_security:
  *     Deallocate security structure.
+ * @sk_getsid:
+ *     Retrieve the LSM-specific sid for the sock to enable caching of network
+ *     authorizations.
+ *
+ * Security hooks for XFRM operations.
+ *
+ * @xfrm_policy_alloc_security:
+ *     @xp contains the xfrm_policy being added to Security Policy Database
+ *     used by the XFRM system.
+ *     @sec_ctx contains the security context information being provided by
+ *     the user-level policy update program (e.g., setkey).
+ *     Allocate a security structure to the xp->selector.security field.
+ *     The security field is initialized to NULL when the xfrm_policy is
+ *     allocated.
+ *     Return 0 if operation was successful (memory to allocate, legal context)
+ * @xfrm_policy_clone_security:
+ *     @old contains an existing xfrm_policy in the SPD.
+ *     @new contains a new xfrm_policy being cloned from old.
+ *     Allocate a security structure to the new->selector.security field
+ *     that contains the information from the old->selector.security field.
+ *     Return 0 if operation was successful (memory to allocate).
+ * @xfrm_policy_free_security:
+ *     @xp contains the xfrm_policy
+ *     Deallocate xp->selector.security.
+ * @xfrm_state_alloc_security:
+ *     @x contains the xfrm_state being added to the Security Association
+ *     Database by the XFRM system.
+ *     @sec_ctx contains the security context information being provided by
+ *     the user-level SA generation program (e.g., setkey or racoon).
+ *     Allocate a security structure to the x->sel.security field.  The
+ *     security field is initialized to NULL when the xfrm_state is
+ *     allocated.
+ *     Return 0 if operation was successful (memory to allocate, legal context).
+ * @xfrm_state_free_security:
+ *     @x contains the xfrm_state.
+ *     Deallocate x>sel.security.
+ * @xfrm_policy_lookup:
+ *     @xp contains the xfrm_policy for which the access control is being
+ *     checked.
+ *     @sk_sid contains the sock security label that is used to authorize
+ *     access to the policy xp.
+ *     @dir contains the direction of the flow (input or output).
+ *     Check permission when a sock selects a xfrm_policy for processing
+ *     XFRMs on a packet.  The hook is called when selecting either a
+ *     per-socket policy or a generic xfrm policy.
+ *     Return 0 if permission is granted.
  *
  * Security hooks affecting all Key Management operations
  *
@@ -1237,8 +1289,18 @@ struct security_operations {
        int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
        int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
        void (*sk_free_security) (struct sock *sk);
+       unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);
 #endif /* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+       int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
+       int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new);
+       void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
+       int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
+       void (*xfrm_state_free_security) (struct xfrm_state *x);
+       int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
+#endif /* CONFIG_SECURITY_NETWORK_XFRM */
+
        /* key management security hooks */
 #ifdef CONFIG_KEYS
        int (*key_alloc)(struct key *key);
@@ -2679,6 +2741,11 @@ static inline void security_sk_free(struct sock *sk)
 {
        return security_ops->sk_free_security(sk);
 }
+
+static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+       return security_ops->sk_getsid(sk, fl, dir);
+}
 #else  /* CONFIG_SECURITY_NETWORK */
 static inline int security_unix_stream_connect(struct socket * sock,
                                               struct socket * other, 
@@ -2795,8 +2862,73 @@ static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
 static inline void security_sk_free(struct sock *sk)
 {
 }
+
+static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+       return 0;
+}
 #endif /* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+       return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
+}
+
+static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+       return security_ops->xfrm_policy_clone_security(old, new);
+}
+
+static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
+{
+       security_ops->xfrm_policy_free_security(xp);
+}
+
+static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+       return security_ops->xfrm_state_alloc_security(x, sec_ctx);
+}
+
+static inline void security_xfrm_state_free(struct xfrm_state *x)
+{
+       security_ops->xfrm_state_free_security(x);
+}
+
+static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+       return security_ops->xfrm_policy_lookup(xp, sk_sid, dir);
+}
+#else  /* CONFIG_SECURITY_NETWORK_XFRM */
+static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+       return 0;
+}
+
+static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+       return 0;
+}
+
+static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
+{
+}
+
+static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+       return 0;
+}
+
+static inline void security_xfrm_state_free(struct xfrm_state *x)
+{
+}
+
+static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+       return 0;
+}
+#endif /* CONFIG_SECURITY_NETWORK_XFRM */
+
 #ifdef CONFIG_KEYS
 #ifdef CONFIG_SECURITY
 static inline int security_key_alloc(struct key *key)
index 8c5d600..483cfc4 100644 (file)
@@ -32,7 +32,6 @@
 
 #define HAVE_ALLOC_SKB         /* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB     /* Ditto 8)                */
-#define SLAB_SKB               /* Slabified skbuffs       */
 
 #define CHECKSUM_NONE 0
 #define CHECKSUM_HW 1
@@ -134,7 +133,7 @@ struct skb_frag_struct {
  */
 struct skb_shared_info {
        atomic_t        dataref;
-       unsigned int    nr_frags;
+       unsigned short  nr_frags;
        unsigned short  tso_size;
        unsigned short  tso_segs;
        unsigned short  ufo_size;
@@ -1239,6 +1238,8 @@ extern int               skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
                                                        int hlen,
                                                        struct iovec *iov);
 extern void           skb_free_datagram(struct sock *sk, struct sk_buff *skb);
+extern void           skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
+                                        unsigned int flags);
 extern unsigned int    skb_checksum(const struct sk_buff *skb, int offset,
                                    int len, unsigned int csum);
 extern int            skb_copy_bits(const struct sk_buff *skb, int offset,
index 1739c2d..9f40191 100644 (file)
@@ -27,7 +27,6 @@ struct __kernel_sockaddr_storage {
 #include <linux/compiler.h>            /* __user                       */
 
 extern int sysctl_somaxconn;
-extern void sock_init(void);
 #ifdef CONFIG_PROC_FS
 struct seq_file;
 extern void socket_seq_show(struct seq_file *seq);
index 4be34ef..93fa765 100644 (file)
@@ -390,6 +390,7 @@ enum
        NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
        NET_TCP_CONG_CONTROL=110,
        NET_TCP_ABC=111,
+       NET_IPV4_IPFRAG_MAX_DIST=112,
 };
 
 enum {
index 0e1da66..f2bb239 100644 (file)
@@ -55,22 +55,6 @@ struct tcphdr {
        __u16   urg_ptr;
 };
 
-#define TCP_ACTION_FIN (1 << 7)
-
-enum {
-  TCPF_ESTABLISHED = (1 << 1),
-  TCPF_SYN_SENT  = (1 << 2),
-  TCPF_SYN_RECV  = (1 << 3),
-  TCPF_FIN_WAIT1 = (1 << 4),
-  TCPF_FIN_WAIT2 = (1 << 5),
-  TCPF_TIME_WAIT = (1 << 6),
-  TCPF_CLOSE     = (1 << 7),
-  TCPF_CLOSE_WAIT = (1 << 8),
-  TCPF_LAST_ACK  = (1 << 9),
-  TCPF_LISTEN    = (1 << 10),
-  TCPF_CLOSING   = (1 << 11) 
-};
-
 /*
  *     The union cast uses a gcc extension to avoid aliasing problems
  *  (union is compatible to any of its members)
@@ -254,10 +238,9 @@ struct tcp_sock {
        __u32   snd_wl1;        /* Sequence for window update           */
        __u32   snd_wnd;        /* The window we expect to receive      */
        __u32   max_window;     /* Maximal window ever seen from peer   */
-       __u32   pmtu_cookie;    /* Last pmtu seen by socket             */
        __u32   mss_cache;      /* Cached effective mss, not including SACKS */
        __u16   xmit_size_goal; /* Goal for segmenting output packets   */
-       __u16   ext_header_len; /* Network protocol overhead (IP/IPv6 options) */
+       /* XXX Two bytes hole, try to pack */
 
        __u32   window_clamp;   /* Maximal window to advertise          */
        __u32   rcv_ssthresh;   /* Current window clamp                 */
@@ -295,8 +278,6 @@ struct tcp_sock {
 
        struct sk_buff_head     out_of_order_queue; /* Out of order segments go here */
 
-       struct tcp_func         *af_specific;   /* Operations which are AF_INET{4,6} specific   */
-
        __u32   rcv_wnd;        /* Current receiver window              */
        __u32   rcv_wup;        /* rcv_nxt on last window update sent   */
        __u32   write_seq;      /* Tail(+1) of data held in tcp send buffer */
index b60e0b4..85a5565 100644 (file)
@@ -35,10 +35,10 @@ struct udphdr {
 #define UDP_ENCAP_ESPINUDP     2 /* draft-ietf-ipsec-udp-encaps-06 */
 
 #ifdef __KERNEL__
-
 #include <linux/config.h>
-#include <net/sock.h>
-#include <linux/ip.h>
+#include <linux/types.h>
+
+#include <net/inet_sock.h>
 
 struct udp_sock {
        /* inet_sock has to be the first member */
index d81b050..e59d1bd 100644 (file)
@@ -329,8 +329,6 @@ struct usb_device {
        struct usb_tt   *tt;            /* low/full speed dev, highspeed hub */
        int             ttport;         /* device port on that tt hub */
 
-       struct semaphore serialize;
-
        unsigned int toggle[2];         /* one bit for each endpoint
                                         * ([0] = IN, [1] = OUT) */
 
@@ -349,6 +347,9 @@ struct usb_device {
 
        char **rawdescriptors;          /* Raw descriptors for each config */
 
+       unsigned short bus_mA;          /* Current available from the bus */
+       u8 portnum;                     /* Parent port number (origin 1) */
+
        int have_langid;                /* whether string_langid is valid */
        int string_langid;              /* language ID for strings */
 
@@ -377,11 +378,12 @@ struct usb_device {
 extern struct usb_device *usb_get_dev(struct usb_device *dev);
 extern void usb_put_dev(struct usb_device *dev);
 
-extern void usb_lock_device(struct usb_device *udev);
-extern int usb_trylock_device(struct usb_device *udev);
+/* USB device locking */
+#define usb_lock_device(udev)          down(&(udev)->dev.sem)
+#define usb_unlock_device(udev)                up(&(udev)->dev.sem)
+#define usb_trylock_device(udev)       down_trylock(&(udev)->dev.sem)
 extern int usb_lock_device_for_reset(struct usb_device *udev,
                struct usb_interface *iface);
-extern void usb_unlock_device(struct usb_device *udev);
 
 /* USB port reset for device reinitialization */
 extern int usb_reset_device(struct usb_device *dev);
@@ -529,10 +531,13 @@ static inline int usb_make_path (struct usb_device *dev, char *buf,
 
 /* ----------------------------------------------------------------------- */
 
+struct usb_dynids {
+       spinlock_t lock;
+       struct list_head list;
+};
+
 /**
  * struct usb_driver - identifies USB driver to usbcore
- * @owner: Pointer to the module owner of this driver; initialize
- *     it using THIS_MODULE.
  * @name: The driver name should be unique among USB drivers,
  *     and should normally be the same as the module name.
  * @probe: Called to see if the driver is willing to manage a particular
@@ -553,7 +558,11 @@ static inline int usb_make_path (struct usb_device *dev, char *buf,
  * @id_table: USB drivers use ID table to support hotplugging.
  *     Export this with MODULE_DEVICE_TABLE(usb,...).  This must be set
  *     or your driver's probe function will never get called.
+ * @dynids: used internally to hold the list of dynamically added device
+ *     ids for this driver.
  * @driver: the driver model core driver structure.
+ * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be
+ *     added to this driver by preventing the sysfs file from being created.
  *
  * USB drivers must provide a name, probe() and disconnect() methods,
  * and an id_table.  Other driver fields are optional.
@@ -571,8 +580,6 @@ static inline int usb_make_path (struct usb_device *dev, char *buf,
  * them as necessary, and blocking until the unlinks complete).
  */
 struct usb_driver {
-       struct module *owner;
-
        const char *name;
 
        int (*probe) (struct usb_interface *intf,
@@ -588,7 +595,9 @@ struct usb_driver {
 
        const struct usb_device_id *id_table;
 
+       struct usb_dynids dynids;
        struct device_driver driver;
+       unsigned int no_dynamic_id:1;
 };
 #define        to_usb_driver(d) container_of(d, struct usb_driver, driver)
 
@@ -614,7 +623,11 @@ struct usb_class_driver {
  * use these in module_init()/module_exit()
  * and don't forget MODULE_DEVICE_TABLE(usb, ...)
  */
-extern int usb_register(struct usb_driver *);
+int usb_register_driver(struct usb_driver *, struct module *);
+static inline int usb_register(struct usb_driver *driver)
+{
+       return usb_register_driver(driver, THIS_MODULE);
+}
 extern void usb_deregister(struct usb_driver *);
 
 extern int usb_register_dev(struct usb_interface *intf,
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
new file mode 100644 (file)
index 0000000..b2d0898
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Interface to the libusual.
+ *
+ * Copyright (c) 2005 Pete Zaitcev <zaitcev@redhat.com>
+ * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ * Copyright (c) 1999 Michael Gee (michael@linuxspecific.com)
+ */
+
+#ifndef __LINUX_USB_USUAL_H
+#define __LINUX_USB_USUAL_H
+
+#include <linux/config.h>
+
+/* We should do this for cleanliness... But other usb_foo.h do not do this. */
+/* #include <linux/usb.h> */
+
+/*
+ * The flags field, which we store in usb_device_id.driver_info.
+ * It is compatible with the old usb-storage flags in lower 24 bits.
+ */
+
+/*
+ * Static flag definitions.  We use this roundabout technique so that the
+ * proc_info() routine can automatically display a message for each flag.
+ */
+#define US_DO_ALL_FLAGS                                                \
+       US_FLAG(SINGLE_LUN,     0x00000001)                     \
+               /* allow access to only LUN 0 */                \
+       US_FLAG(NEED_OVERRIDE,  0x00000002)                     \
+               /* unusual_devs entry is necessary */           \
+       US_FLAG(SCM_MULT_TARG,  0x00000004)                     \
+               /* supports multiple targets */                 \
+       US_FLAG(FIX_INQUIRY,    0x00000008)                     \
+               /* INQUIRY response needs faking */             \
+       US_FLAG(FIX_CAPACITY,   0x00000010)                     \
+               /* READ CAPACITY response too big */            \
+       US_FLAG(IGNORE_RESIDUE, 0x00000020)                     \
+               /* reported residue is wrong */                 \
+       US_FLAG(BULK32,         0x00000040)                     \
+               /* Uses 32-byte CBW length */                   \
+       US_FLAG(NOT_LOCKABLE,   0x00000080)                     \
+               /* PREVENT/ALLOW not supported */               \
+       US_FLAG(GO_SLOW,        0x00000100)                     \
+               /* Need delay after Command phase */            \
+       US_FLAG(NO_WP_DETECT,   0x00000200)                     \
+               /* Don't check for write-protect */             \
+
+#define US_FLAG(name, value)   US_FL_##name = value ,
+enum { US_DO_ALL_FLAGS };
+#undef US_FLAG
+
+/*
+ * The bias field for libusual and friends.
+ */
+#define USB_US_TYPE_NONE   0
+#define USB_US_TYPE_STOR   1           /* usb-storage */
+#define USB_US_TYPE_UB     2           /* ub */
+
+#define USB_US_TYPE(flags)             (((flags) >> 24) & 0xFF)
+#define USB_US_ORIG_FLAGS(flags)       ((flags) & 0x00FFFFFF)
+
+/*
+ * This is probably not the best place to keep these constants, conceptually.
+ * But it's the only header included into all places which need them.
+ */
+
+/* Sub Classes */
+
+#define US_SC_RBC      0x01            /* Typically, flash devices */
+#define US_SC_8020     0x02            /* CD-ROM */
+#define US_SC_QIC      0x03            /* QIC-157 Tapes */
+#define US_SC_UFI      0x04            /* Floppy */
+#define US_SC_8070     0x05            /* Removable media */
+#define US_SC_SCSI     0x06            /* Transparent */
+#define US_SC_ISD200    0x07           /* ISD200 ATA */
+#define US_SC_MIN      US_SC_RBC
+#define US_SC_MAX      US_SC_ISD200
+
+#define US_SC_DEVICE   0xff            /* Use device's value */
+
+/* Protocols */
+
+#define US_PR_CBI      0x00            /* Control/Bulk/Interrupt */
+#define US_PR_CB       0x01            /* Control/Bulk w/o interrupt */
+#define US_PR_BULK     0x50            /* bulk only */
+#ifdef CONFIG_USB_STORAGE_USBAT
+#define US_PR_USBAT    0x80            /* SCM-ATAPI bridge */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR09
+#define US_PR_EUSB_SDDR09      0x81    /* SCM-SCSI bridge for SDDR-09 */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR55
+#define US_PR_SDDR55   0x82            /* SDDR-55 (made up) */
+#endif
+#define US_PR_DPCM_USB  0xf0           /* Combination CB/SDDR09 */
+#ifdef CONFIG_USB_STORAGE_FREECOM
+#define US_PR_FREECOM   0xf1           /* Freecom */
+#endif
+#ifdef CONFIG_USB_STORAGE_DATAFAB
+#define US_PR_DATAFAB   0xf2           /* Datafab chipsets */
+#endif
+#ifdef CONFIG_USB_STORAGE_JUMPSHOT
+#define US_PR_JUMPSHOT  0xf3           /* Lexar Jumpshot */
+#endif
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+#define US_PR_ALAUDA    0xf4           /* Alauda chipsets */
+#endif
+
+#define US_PR_DEVICE   0xff            /* Use device's value */
+
+/*
+ */
+#ifdef CONFIG_USB_LIBUSUAL
+
+extern struct usb_device_id storage_usb_ids[];
+extern void usb_usual_set_present(int type);
+extern void usb_usual_clear_present(int type);
+extern int usb_usual_check_type(const struct usb_device_id *, int type);
+#else
+
+#define usb_usual_set_present(t)       do { } while(0)
+#define usb_usual_clear_present(t)     do { } while(0)
+#define usb_usual_check_type(id, t)    (0)
+#endif /* CONFIG_USB_LIBUSUAL */
+
+#endif /* __LINUX_USB_USUAL_H */
index 0fb077d..82fbb75 100644 (file)
@@ -27,6 +27,22 @@ struct xfrm_id
        __u8            proto;
 };
 
+struct xfrm_sec_ctx {
+       __u8    ctx_doi;
+       __u8    ctx_alg;
+       __u16   ctx_len;
+       __u32   ctx_sid;
+       char    ctx_str[0];
+};
+
+/* Security Context Domains of Interpretation */
+#define XFRM_SC_DOI_RESERVED 0
+#define XFRM_SC_DOI_LSM 1
+
+/* Security Context Algorithms */
+#define XFRM_SC_ALG_RESERVED 0
+#define XFRM_SC_ALG_SELINUX 1
+
 /* Selector, used as selector both on policy rules (SPD) and SAs. */
 
 struct xfrm_selector
@@ -146,6 +162,18 @@ enum {
 
 #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
 
+/*
+ * Generic LSM security context for comunicating to user space
+ * NOTE: Same format as sadb_x_sec_ctx
+ */
+struct xfrm_user_sec_ctx {
+       __u16                   len;
+       __u16                   exttype;
+       __u8                    ctx_alg;  /* LSMs: e.g., selinux == 1 */
+       __u8                    ctx_doi;
+       __u16                   ctx_len;
+};
+
 struct xfrm_user_tmpl {
        struct xfrm_id          id;
        __u16                   family;
@@ -176,6 +204,7 @@ enum xfrm_attr_type_t {
        XFRMA_TMPL,             /* 1 or more struct xfrm_user_tmpl */
        XFRMA_SA,
        XFRMA_POLICY,
+       XFRMA_SEC_CTX,          /* struct xfrm_sec_ctx */
        __XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
index b5d785a..bfc1779 100644 (file)
@@ -13,7 +13,7 @@ extern void unix_gc(void);
 #define UNIX_HASH_SIZE 256
 
 extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-extern rwlock_t unix_table_lock;
+extern spinlock_t unix_table_lock;
 
 extern atomic_t unix_tot_inflight;
 
@@ -58,10 +58,10 @@ struct unix_skb_parms {
 #define UNIXCB(skb)    (*(struct unix_skb_parms*)&((skb)->cb))
 #define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
 
-#define unix_state_rlock(s)    read_lock(&unix_sk(s)->lock)
-#define unix_state_runlock(s)  read_unlock(&unix_sk(s)->lock)
-#define unix_state_wlock(s)    write_lock(&unix_sk(s)->lock)
-#define unix_state_wunlock(s)  write_unlock(&unix_sk(s)->lock)
+#define unix_state_rlock(s)    spin_lock(&unix_sk(s)->lock)
+#define unix_state_runlock(s)  spin_unlock(&unix_sk(s)->lock)
+#define unix_state_wlock(s)    spin_lock(&unix_sk(s)->lock)
+#define unix_state_wunlock(s)  spin_unlock(&unix_sk(s)->lock)
 
 #ifdef __KERNEL__
 /* The AF_UNIX socket */
@@ -76,7 +76,7 @@ struct unix_sock {
         struct sock            *other;
         struct sock            *gc_tree;
         atomic_t                inflight;
-        rwlock_t                lock;
+        spinlock_t             lock;
         wait_queue_head_t       peer_wait;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
index 47048b1..90fcc98 100644 (file)
@@ -7,7 +7,6 @@
 #define _ATMCLIP_H
 
 #include <linux/netdevice.h>
-#include <linux/skbuff.h>
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/atmarp.h>
@@ -18,6 +17,7 @@
 #define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back))
 #define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key)
 
+struct sk_buff;
 
 struct clip_vcc {
        struct atm_vcc  *vcc;           /* VCC descriptor */
index 6c196a5..bee8b84 100644 (file)
@@ -9,6 +9,7 @@
 #define _NET_DST_H
 
 #include <linux/config.h>
+#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/rcupdate.h>
 #include <linux/jiffies.h>
index 9a5c94b..ec7eb86 100644 (file)
@@ -84,11 +84,12 @@ struct flowi {
 #define FLOW_DIR_OUT   1
 #define FLOW_DIR_FWD   2
 
-typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
+struct sock;
+typedef void (*flow_resolve_t)(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
                               void **objp, atomic_t **obj_refp);
 
-extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
-                              flow_resolve_t resolver);
+extern void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
+                              flow_resolve_t resolver);
 extern void flow_cache_flush(void);
 extern atomic_t flow_cache_genid;
 
index 52d8b1a..c5b96b2 100644 (file)
@@ -60,7 +60,7 @@ struct genl_info
  */
 struct genl_ops
 {
-       unsigned int            cmd;
+       u8                      cmd;
        unsigned int            flags;
        struct nla_policy       *policy;
        int                    (*doit)(struct sk_buff *skb,
index 6cdebee..e7c3f20 100644 (file)
 
 #include <linux/config.h>
 #include <linux/icmp.h>
-#include <linux/skbuff.h>
 
-#include <net/sock.h>
-#include <net/protocol.h>
+#include <net/inet_sock.h>
 #include <net/snmp.h>
-#include <linux/ip.h>
 
 struct icmp_err {
   int          errno;
@@ -38,6 +35,10 @@ DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics);
 #define ICMP_INC_STATS_BH(field)       SNMP_INC_STATS_BH(icmp_statistics, field)
 #define ICMP_INC_STATS_USER(field)     SNMP_INC_STATS_USER(icmp_statistics, field)
 
+struct dst_entry;
+struct net_proto_family;
+struct sk_buff;
+
 extern void    icmp_send(struct sk_buff *skb_in,  int type, int code, u32 info);
 extern int     icmp_rcv(struct sk_buff *skb);
 extern int     icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
index 225fc75..03b766a 100644 (file)
 #ifndef IEEE80211_CRYPT_H
 #define IEEE80211_CRYPT_H
 
-#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <asm/atomic.h>
 
 enum {
        IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
 };
 
+struct sk_buff;
+struct module;
+
 struct ieee80211_crypto_ops {
        const char *name;
        struct list_head list;
@@ -87,6 +92,8 @@ struct ieee80211_crypt_data {
        atomic_t refcnt;
 };
 
+struct ieee80211_device;
+
 int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
 int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
 struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
new file mode 100644 (file)
index 0000000..b33b438
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * NET         Generic infrastructure for INET6 connection oriented protocols.
+ *
+ * Authors:    Many people, see the TCPv6 sources
+ *
+ *             From code originally in TCPv6
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+#ifndef _INET6_CONNECTION_SOCK_H
+#define _INET6_CONNECTION_SOCK_H
+
+#include <linux/types.h>
+
+struct in6_addr;
+struct inet_bind_bucket;
+struct request_sock;
+struct sk_buff;
+struct sock;
+struct sockaddr;
+
+extern int inet6_csk_bind_conflict(const struct sock *sk,
+                                  const struct inet_bind_bucket *tb);
+
+extern struct request_sock *inet6_csk_search_req(const struct sock *sk,
+                                                struct request_sock ***prevp,
+                                                const __u16 rport,
+                                                const struct in6_addr *raddr,
+                                                const struct in6_addr *laddr,
+                                                const int iif);
+
+extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
+                                          struct request_sock *req,
+                                          const unsigned long timeout);
+
+extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
+
+extern int inet6_csk_xmit(struct sk_buff *skb, int ipfragok);
+#endif /* _INET6_CONNECTION_SOCK_H */
index 5a2beed..25f708f 100644 (file)
@@ -48,6 +48,32 @@ static inline int inet6_sk_ehashfn(const struct sock *sk)
        return inet6_ehashfn(laddr, lport, faddr, fport);
 }
 
+static inline void __inet6_hash(struct inet_hashinfo *hashinfo,
+                               struct sock *sk)
+{
+       struct hlist_head *list;
+       rwlock_t *lock;
+
+       BUG_TRAP(sk_unhashed(sk));
+
+       if (sk->sk_state == TCP_LISTEN) {
+               list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
+               lock = &hashinfo->lhash_lock;
+               inet_listen_wlock(hashinfo);
+       } else {
+               unsigned int hash;
+               sk->sk_hash = hash = inet6_sk_ehashfn(sk);
+               hash &= (hashinfo->ehash_size - 1);
+               list = &hashinfo->ehash[hash].chain;
+               lock = &hashinfo->ehash[hash].lock;
+               write_lock(lock);
+       }
+
+       __sk_add_node(sk, list);
+       sock_prot_inc_use(sk->sk_prot);
+       write_unlock(lock);
+}
+
 /*
  * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
  * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
@@ -84,10 +110,10 @@ static inline struct sock *
 
                if(*((__u32 *)&(tw->tw_dport))  == ports        &&
                   sk->sk_family                == PF_INET6) {
-                       const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk);
+                       const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
 
-                       if (ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr)        &&
-                           ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr)    &&
+                       if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)   &&
+                           ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr)       &&
                            (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
                                goto hit;
                }
index f943306..227adcb 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef _INET_COMMON_H
 #define _INET_COMMON_H
 
-extern struct proto_ops                inet_stream_ops;
-extern struct proto_ops                inet_dgram_ops;
+extern const struct proto_ops          inet_stream_ops;
+extern const struct proto_ops          inet_dgram_ops;
 
 /*
  *     INET4 prototypes used by INET6
index b0c9906..50234fa 100644 (file)
 #ifndef _INET_CONNECTION_SOCK_H
 #define _INET_CONNECTION_SOCK_H
 
-#include <linux/ip.h>
+#include <linux/compiler.h>
 #include <linux/string.h>
 #include <linux/timer.h>
+
+#include <net/inet_sock.h>
 #include <net/request_sock.h>
 
 #define INET_CSK_DEBUG 1
@@ -29,6 +31,29 @@ struct inet_bind_bucket;
 struct inet_hashinfo;
 struct tcp_congestion_ops;
 
+/*
+ * Pointers to address related TCP functions
+ * (i.e. things that depend on the address family)
+ */
+struct inet_connection_sock_af_ops {
+       int         (*queue_xmit)(struct sk_buff *skb, int ipfragok);
+       void        (*send_check)(struct sock *sk, int len,
+                                 struct sk_buff *skb);
+       int         (*rebuild_header)(struct sock *sk);
+       int         (*conn_request)(struct sock *sk, struct sk_buff *skb);
+       struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb,
+                                     struct request_sock *req,
+                                     struct dst_entry *dst);
+       int         (*remember_stamp)(struct sock *sk);
+       __u16       net_header_len;
+       int         (*setsockopt)(struct sock *sk, int level, int optname, 
+                                 char __user *optval, int optlen);
+       int         (*getsockopt)(struct sock *sk, int level, int optname, 
+                                 char __user *optval, int __user *optlen);
+       void        (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
+       int sockaddr_len;
+};
+
 /** inet_connection_sock - INET connection oriented sock
  *
  * @icsk_accept_queue:    FIFO of established children 
@@ -36,13 +61,16 @@ struct tcp_congestion_ops;
  * @icsk_timeout:         Timeout
  * @icsk_retransmit_timer: Resend (no ack)
  * @icsk_rto:             Retransmit timeout
+ * @icsk_pmtu_cookie      Last pmtu seen by socket
  * @icsk_ca_ops                   Pluggable congestion control hook
+ * @icsk_af_ops                   Operations which are AF_INET{4,6} specific
  * @icsk_ca_state:        Congestion control state
  * @icsk_retransmits:     Number of unrecovered [RTO] timeouts
  * @icsk_pending:         Scheduled timer event
  * @icsk_backoff:         Backoff
  * @icsk_syn_retries:      Number of allowed SYN (or equivalent) retries
  * @icsk_probes_out:      unanswered 0 window probes
+ * @icsk_ext_hdr_len:     Network protocol overhead (IP/IPv6 options)
  * @icsk_ack:             Delayed ACK control data
  */
 struct inet_connection_sock {
@@ -54,14 +82,17 @@ struct inet_connection_sock {
        struct timer_list         icsk_retransmit_timer;
        struct timer_list         icsk_delack_timer;
        __u32                     icsk_rto;
+       __u32                     icsk_pmtu_cookie;
        struct tcp_congestion_ops *icsk_ca_ops;
+       struct inet_connection_sock_af_ops *icsk_af_ops;
+       unsigned int              (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
        __u8                      icsk_ca_state;
        __u8                      icsk_retransmits;
        __u8                      icsk_pending;
        __u8                      icsk_backoff;
        __u8                      icsk_syn_retries;
        __u8                      icsk_probes_out;
-       /* 2 BYTES HOLE, TRY TO PACK! */
+       __u16                     icsk_ext_hdr_len;
        struct {
                __u8              pending;       /* ACK is pending                         */
                __u8              quick;         /* Scheduled number of quick acks         */
@@ -192,8 +223,12 @@ extern struct request_sock *inet_csk_search_req(const struct sock *sk,
                                                const __u16 rport,
                                                const __u32 raddr,
                                                const __u32 laddr);
+extern int inet_csk_bind_conflict(const struct sock *sk,
+                                 const struct inet_bind_bucket *tb);
 extern int inet_csk_get_port(struct inet_hashinfo *hashinfo,
-                            struct sock *sk, unsigned short snum);
+                            struct sock *sk, unsigned short snum,
+                            int (*bind_conflict)(const struct sock *sk,
+                                                 const struct inet_bind_bucket *tb));
 
 extern struct dst_entry* inet_csk_route_req(struct sock *sk,
                                            const struct request_sock *req);
@@ -207,7 +242,7 @@ static inline void inet_csk_reqsk_queue_add(struct sock *sk,
 
 extern void inet_csk_reqsk_queue_hash_add(struct sock *sk,
                                          struct request_sock *req,
-                                         const unsigned timeout);
+                                         unsigned long timeout);
 
 static inline void inet_csk_reqsk_queue_removed(struct sock *sk,
                                                struct request_sock *req)
@@ -273,4 +308,6 @@ static inline unsigned int inet_csk_listen_poll(const struct sock *sk)
 extern int  inet_csk_listen_start(struct sock *sk, const int nr_table_entries);
 extern void inet_csk_listen_stop(struct sock *sk);
 
+extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
+
 #endif /* _INET_CONNECTION_SOCK_H */
index b0c47e2..d599c6b 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <linux/ip.h>
 #include <linux/skbuff.h>
+
+#include <net/inet_sock.h>
 #include <net/dsfield.h>
 
 enum {
index 07840ba..135d80f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/wait.h>
 
 #include <net/inet_connection_sock.h>
+#include <net/inet_sock.h>
 #include <net/route.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
@@ -128,26 +129,6 @@ struct inet_hashinfo {
        kmem_cache_t                    *bind_bucket_cachep;
 };
 
-static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
-                              const __u32 faddr, const __u16 fport)
-{
-       unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
-       h ^= h >> 16;
-       h ^= h >> 8;
-       return h;
-}
-
-static inline int inet_sk_ehashfn(const struct sock *sk)
-{
-       const struct inet_sock *inet = inet_sk(sk);
-       const __u32 laddr = inet->rcv_saddr;
-       const __u16 lport = inet->num;
-       const __u32 faddr = inet->daddr;
-       const __u16 fport = inet->dport;
-
-       return inet_ehashfn(laddr, lport, faddr, fport);
-}
-
 static inline struct inet_ehash_bucket *inet_ehash_bucket(
        struct inet_hashinfo *hashinfo,
        unsigned int hash)
@@ -434,4 +415,7 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
 
        return sk;
 }
+
+extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
+                            struct sock *sk);
 #endif /* _INET_HASHTABLES_H */
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
new file mode 100644 (file)
index 0000000..883eb52
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * INET                An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             Definitions for inet_sock
+ *
+ * Authors:    Many, reorganised here by
+ *             Arnaldo Carvalho de Melo <acme@mandriva.com>
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+#ifndef _INET_SOCK_H
+#define _INET_SOCK_H
+
+#include <linux/config.h>
+
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <net/flow.h>
+#include <net/sock.h>
+#include <net/request_sock.h>
+
+/** struct ip_options - IP Options
+ *
+ * @faddr - Saved first hop address
+ * @is_setbyuser - Set by setsockopt?
+ * @is_data - Options in __data, rather than skb
+ * @is_strictroute - Strict source route
+ * @srr_is_hit - Packet destination addr was our one
+ * @is_changed - IP checksum more not valid
+ * @rr_needaddr - Need to record addr of outgoing dev
+ * @ts_needtime - Need to record timestamp
+ * @ts_needaddr - Need to record addr of outgoing dev
+ */
+struct ip_options {
+       __u32           faddr;
+       unsigned char   optlen;
+       unsigned char   srr;
+       unsigned char   rr;
+       unsigned char   ts;
+       unsigned char   is_setbyuser:1,
+                       is_data:1,
+                       is_strictroute:1,
+                       srr_is_hit:1,
+                       is_changed:1,
+                       rr_needaddr:1,
+                       ts_needtime:1,
+                       ts_needaddr:1;
+       unsigned char   router_alert;
+       unsigned char   __pad1;
+       unsigned char   __pad2;
+       unsigned char   __data[0];
+};
+
+#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
+
+struct inet_request_sock {
+       struct request_sock     req;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       u16                     inet6_rsk_offset;
+       /* 2 bytes hole, try to pack */
+#endif
+       u32                     loc_addr;
+       u32                     rmt_addr;
+       u16                     rmt_port;
+       u16                     snd_wscale : 4, 
+                               rcv_wscale : 4, 
+                               tstamp_ok  : 1,
+                               sack_ok    : 1,
+                               wscale_ok  : 1,
+                               ecn_ok     : 1,
+                               acked      : 1;
+       struct ip_options       *opt;
+};
+
+static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
+{
+       return (struct inet_request_sock *)sk;
+}
+
+struct ip_mc_socklist;
+struct ipv6_pinfo;
+struct rtable;
+
+/** struct inet_sock - representation of INET sockets
+ *
+ * @sk - ancestor class
+ * @pinet6 - pointer to IPv6 control block
+ * @daddr - Foreign IPv4 addr
+ * @rcv_saddr - Bound local IPv4 addr
+ * @dport - Destination port
+ * @num - Local port
+ * @saddr - Sending source
+ * @uc_ttl - Unicast TTL
+ * @sport - Source port
+ * @id - ID counter for DF pkts
+ * @tos - TOS
+ * @mc_ttl - Multicasting TTL
+ * @is_icsk - is this an inet_connection_sock?
+ * @mc_index - Multicast device index
+ * @mc_list - Group array
+ * @cork - info to build ip hdr on each ip frag while socket is corked
+ */
+struct inet_sock {
+       /* sk and pinet6 has to be the first two members of inet_sock */
+       struct sock             sk;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       struct ipv6_pinfo       *pinet6;
+#endif
+       /* Socket demultiplex comparisons on incoming packets. */
+       __u32                   daddr;
+       __u32                   rcv_saddr;
+       __u16                   dport;
+       __u16                   num;
+       __u32                   saddr;
+       __s16                   uc_ttl;
+       __u16                   cmsg_flags;
+       struct ip_options       *opt;
+       __u16                   sport;
+       __u16                   id;
+       __u8                    tos;
+       __u8                    mc_ttl;
+       __u8                    pmtudisc;
+       __u8                    recverr:1,
+                               is_icsk:1,
+                               freebind:1,
+                               hdrincl:1,
+                               mc_loop:1;
+       int                     mc_index;
+       __u32                   mc_addr;
+       struct ip_mc_socklist   *mc_list;
+       struct {
+               unsigned int            flags;
+               unsigned int            fragsize;
+               struct ip_options       *opt;
+               struct rtable           *rt;
+               int                     length; /* Total length of all frames */
+               u32                     addr;
+               struct flowi            fl;
+       } cork;
+};
+
+#define IPCORK_OPT     1       /* ip-options has been held in ipcork.opt */
+#define IPCORK_ALLFRAG 2       /* always fragment (for ipv6 for now) */
+
+static inline struct inet_sock *inet_sk(const struct sock *sk)
+{
+       return (struct inet_sock *)sk;
+}
+
+static inline void __inet_sk_copy_descendant(struct sock *sk_to,
+                                            const struct sock *sk_from,
+                                            const int ancestor_size)
+{
+       memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
+              sk_from->sk_prot->obj_size - ancestor_size);
+}
+#if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE))
+static inline void inet_sk_copy_descendant(struct sock *sk_to,
+                                          const struct sock *sk_from)
+{
+       __inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock));
+}
+#endif
+
+extern int inet_sk_rebuild_header(struct sock *sk);
+
+static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
+                                       const __u32 faddr, const __u16 fport)
+{
+       unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
+       h ^= h >> 16;
+       h ^= h >> 8;
+       return h;
+}
+
+static inline int inet_sk_ehashfn(const struct sock *sk)
+{
+       const struct inet_sock *inet = inet_sk(sk);
+       const __u32 laddr = inet->rcv_saddr;
+       const __u16 lport = inet->num;
+       const __u32 faddr = inet->daddr;
+       const __u16 fport = inet->dport;
+
+       return inet_ehashfn(laddr, lport, faddr, fport);
+}
+
+#endif /* _INET_SOCK_H */
index 28f7b21..1da294c 100644 (file)
 
 #include <linux/config.h>
 
-#include <linux/ip.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/timer.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 
+#include <net/inet_sock.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
+#include <net/timewait_sock.h>
 
 #include <asm/atomic.h>
 
@@ -127,7 +128,8 @@ struct inet_timewait_sock {
        __u16                   tw_num;
        /* And these are ours. */
        __u8                    tw_ipv6only:1;
-       /* 31 bits hole, try to pack */
+       /* 15 bits hole, try to pack */
+       __u16                   tw_ipv6_offset;
        int                     tw_timeout;
        unsigned long           tw_ttd;
        struct inet_bind_bucket *tw_tb;
@@ -199,7 +201,7 @@ static inline void inet_twsk_put(struct inet_timewait_sock *tw)
                printk(KERN_DEBUG "%s timewait_sock %p released\n",
                       tw->tw_prot->name, tw);
 #endif
-               kmem_cache_free(tw->tw_prot->twsk_slab, tw);
+               kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
                module_put(owner);
        }
 }
index 7fda471..0965515 100644 (file)
@@ -25,6 +25,7 @@ struct inet_peer
        __u32                   v4daddr;        /* peer's address */
        __u16                   avl_height;
        __u16                   ip_id_count;    /* IP ID for the next packet */
+       atomic_t                rid;            /* Frag reception counter */
        __u32                   tcp_ts;
        unsigned long           tcp_ts_stamp;
 };
index e4563bb..f7e7fd7 100644 (file)
 
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/socket.h>
 #include <linux/ip.h>
 #include <linux/in.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/in_route.h>
-#include <net/route.h>
-#include <net/arp.h>
+
+#include <net/inet_sock.h>
 #include <net/snmp.h>
 
 struct sock;
@@ -45,6 +41,7 @@ struct inet_skb_parm
 #define IPSKB_TRANSLATED       2
 #define IPSKB_FORWARDED                4
 #define IPSKB_XFRM_TUNNEL_SIZE 8
+#define IPSKB_FRAG_COMPLETE    16
 };
 
 struct ipcm_cookie
@@ -74,6 +71,13 @@ extern rwlock_t ip_ra_lock;
 
 #define IP_FRAG_TIME   (30 * HZ)               /* fragment lifetime    */
 
+struct msghdr;
+struct net_device;
+struct packet_type;
+struct rtable;
+struct sk_buff;
+struct sockaddr;
+
 extern void            ip_mc_dropsocket(struct sock *);
 extern void            ip_mc_dropdevice(struct net_device *dev);
 extern int             igmp_mc_proc_init(void);
@@ -168,6 +172,7 @@ extern int sysctl_ipfrag_high_thresh;
 extern int sysctl_ipfrag_low_thresh;
 extern int sysctl_ipfrag_time;
 extern int sysctl_ipfrag_secret_interval;
+extern int sysctl_ipfrag_max_dist;
 
 /* From inetpeer.c */
 extern int inet_peer_threshold;
@@ -182,6 +187,8 @@ extern int sysctl_ip_dynaddr;
 extern void ipfrag_init(void);
 
 #ifdef CONFIG_INET
+#include <net/dst.h>
+
 /* The function in 2.2 was invalid, producing wrong result for
  * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
 static inline
index 14de4eb..e000fa2 100644 (file)
@@ -238,6 +238,8 @@ extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
                               struct net_device *dev, u32 *spec_dst, u32 *itag);
 extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
 
+struct rtentry;
+
 /* Exported by fib_semantics.c */
 extern int ip_fib_check_default(u32 gw, struct net_device *dev);
 extern int fib_sync_down(u32 local, struct net_device *dev, int force);
index 3b5559a..7d2674f 100644 (file)
@@ -251,16 +251,15 @@ struct ip_vs_daemon_user {
 #include <linux/config.h>
 #include <linux/list.h>                 /* for struct list_head */
 #include <linux/spinlock.h>             /* for struct rwlock_t */
-#include <linux/skbuff.h>               /* for struct sk_buff */
-#include <linux/ip.h>                   /* for struct iphdr */
 #include <asm/atomic.h>                 /* for struct atomic_t */
-#include <linux/netdevice.h>           /* for struct neighbour */
-#include <net/dst.h>                   /* for struct dst_entry */
-#include <net/udp.h>
 #include <linux/compiler.h>
+#include <linux/timer.h>
 
+#include <net/checksum.h>
 
 #ifdef CONFIG_IP_VS_DEBUG
+#include <linux/net.h>
+
 extern int ip_vs_get_debug_level(void);
 #define IP_VS_DBG(level, msg...)                       \
     do {                                               \
@@ -429,8 +428,11 @@ struct ip_vs_stats
        spinlock_t              lock;           /* spin lock */
 };
 
+struct dst_entry;
+struct iphdr;
 struct ip_vs_conn;
 struct ip_vs_app;
+struct sk_buff;
 
 struct ip_vs_protocol {
        struct ip_vs_protocol   *next;
index 0a2ad51..860bbac 100644 (file)
@@ -240,6 +240,8 @@ extern struct ipv6_txoptions *      ipv6_renew_options(struct sock *sk, struct ipv6_t
 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
                                          struct ipv6_txoptions *opt);
 
+extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
+
 extern int ip6_frag_nqueues;
 extern atomic_t ip6_frag_mem;
 
@@ -525,6 +527,9 @@ extern int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
 extern int inet6_ioctl(struct socket *sock, unsigned int cmd, 
                       unsigned long arg);
 
+extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+                             struct sock *sk);
+
 /*
  * reassembly.c
  */
@@ -533,8 +538,11 @@ extern int sysctl_ip6frag_low_thresh;
 extern int sysctl_ip6frag_time;
 extern int sysctl_ip6frag_secret_interval;
 
-extern struct proto_ops inet6_stream_ops;
-extern struct proto_ops inet6_dgram_ops;
+extern const struct proto_ops inet6_stream_ops;
+extern const struct proto_ops inet6_dgram_ops;
+
+struct group_source_req;
+struct group_filter;
 
 extern int ip6_mc_source(int add, int omode, struct sock *sk,
                         struct group_source_req *pgsr);
index f85d6e4..bbac87e 100644 (file)
@@ -35,11 +35,20 @@ enum {
 
 #ifdef __KERNEL__
 
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
+#include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/icmpv6.h>
+#include <linux/in6.h>
+#include <linux/types.h>
+
 #include <net/neighbour.h>
-#include <asm/atomic.h>
+
+struct ctl_table;
+struct file;
+struct inet6_dev;
+struct net_device;
+struct net_proto_family;
+struct sk_buff;
 
 extern struct neigh_table nd_tbl;
 
@@ -108,7 +117,7 @@ extern int                  igmp6_event_report(struct sk_buff *skb);
 extern void                    igmp6_cleanup(void);
 
 #ifdef CONFIG_SYSCTL
-extern int                     ndisc_ifinfo_sysctl_change(ctl_table *ctl,
+extern int                     ndisc_ifinfo_sysctl_change(struct ctl_table *ctl,
                                                           int write,
                                                           struct file * filp,
                                                           void __user *buffer,
index 34c0773..6fa9ae1 100644 (file)
@@ -49,8 +49,8 @@
 #ifdef __KERNEL__
 
 #include <asm/atomic.h>
-#include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/skbuff.h>
 #include <linux/rcupdate.h>
 #include <linux/seq_file.h>
 
index bd08964..b225d84 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
index 357691f..63f7db9 100644 (file)
@@ -65,7 +65,7 @@ struct inet_protosw {
        int              protocol; /* This is the L4 protocol number.  */
 
        struct proto     *prot;
-       struct proto_ops *ops;
+       const struct proto_ops *ops;
   
        int              capability; /* Which (if any) capability do
                                      * we need to use this socket
@@ -76,6 +76,7 @@ struct inet_protosw {
 };
 #define INET_PROTOSW_REUSE 0x01             /* Are ports automatically reusable? */
 #define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
+#define INET_PROTOSW_ICSK      0x04  /* Is this an inet_connection_sock? */
 
 extern struct net_protocol *inet_protocol_base;
 extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
index f479174..e67b28a 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <linux/config.h>
 
+#include <net/protocol.h>
+
 extern struct proto raw_prot;
 
 extern void    raw_err(struct sock *, struct sk_buff *, u32 info);
index b52cc52..11641c9 100644 (file)
@@ -244,7 +244,7 @@ static inline int reqsk_queue_is_full(const struct request_sock_queue *queue)
 
 static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
                                        u32 hash, struct request_sock *req,
-                                       unsigned timeout)
+                                       unsigned long timeout)
 {
        struct listen_sock *lopt = queue->listen_opt;
 
index 8e7794e..f5c22d7 100644 (file)
@@ -277,6 +277,24 @@ struct sctp_sock {
        __u32 default_context;
        __u32 default_timetolive;
 
+       /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
+        * the destination address every heartbeat interval. This value
+        * will be inherited by all new associations.
+        */
+       __u32 hbinterval;
+
+       /* This is the max_retrans value for new associations. */
+       __u16 pathmaxrxt;
+
+       /* The initial Path MTU to use for new associations. */
+       __u32 pathmtu;
+
+       /* The default SACK delay timeout for new associations. */
+       __u32 sackdelay;
+
+       /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+       __u32 param_flags;
+
        struct sctp_initmsg initmsg;
        struct sctp_rtoinfo rtoinfo;
        struct sctp_paddrparams paddrparam;
@@ -845,9 +863,6 @@ struct sctp_transport {
        /* Data that has been sent, but not acknowledged. */
        __u32 flight_size;
 
-       /* PMTU       : The current known path MTU.  */
-       __u32 pmtu;
-
        /* Destination */
        struct dst_entry *dst;
        /* Source address. */
@@ -862,7 +877,22 @@ struct sctp_transport {
        /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
         * the destination address every heartbeat interval.
         */
-       int hb_interval;
+       __u32 hbinterval;
+
+       /* This is the max_retrans value for the transport and will
+        * be initialized from the assocs value.  This can be changed
+        * using SCTP_SET_PEER_ADDR_PARAMS socket option.
+        */
+       __u16 pathmaxrxt;
+
+       /* PMTU       : The current known path MTU.  */
+       __u32 pathmtu;
+
+       /* SACK delay timeout */
+       __u32 sackdelay;
+
+       /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+       __u32 param_flags;
 
        /* When was the last time (in jiffies) that we heard from this
         * transport?  We use this to pick new active and retran paths.
@@ -882,22 +912,11 @@ struct sctp_transport {
         */
        int state;
 
-       /* hb_allowed  : The current heartbeat state of this destination,
-        *             :  i.e. ALLOW-HB, NO-HEARTBEAT, etc.
-        */
-       int hb_allowed;
-
        /* These are the error stats for this destination.  */
 
        /* Error count : The current error count for this destination.  */
        unsigned short error_count;
 
-       /* This is the max_retrans value for the transport and will
-        * be initialized to proto.max_retrans.path.  This can be changed
-        * using SCTP_SET_PEER_ADDR_PARAMS socket option.
-        */
-       int max_retrans;
-
        /* Per         : A timer used by each destination.
         * Destination :
         * Timer       :
@@ -1502,6 +1521,28 @@ struct sctp_association {
        /* The largest timeout or RTO value to use in attempting an INIT */
        __u16 max_init_timeo;
 
+       /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
+        * the destination address every heartbeat interval. This value
+        * will be inherited by all new transports.
+        */
+       __u32 hbinterval;
+
+       /* This is the max_retrans value for new transports in the
+        * association.
+        */
+       __u16 pathmaxrxt;
+
+       /* Association : The smallest PMTU discovered for all of the
+        * PMTU        : peer's transport addresses.
+        */
+       __u32 pathmtu;
+
+       /* SACK delay timeout */
+       __u32 sackdelay;
+
+       /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+       __u32 param_flags;
+
        int timeouts[SCTP_NUM_TIMEOUT_TYPES];
        struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES];
 
@@ -1571,11 +1612,6 @@ struct sctp_association {
         */
        wait_queue_head_t       wait;
 
-       /* Association : The smallest PMTU discovered for all of the
-        * PMTU        : peer's transport addresses.
-        */
-       __u32 pmtu;
-
        /* The message size at which SCTP fragmentation will occur. */
        __u32 frag_point;
 
index f1c3bc5..8a6bef6 100644 (file)
@@ -93,6 +93,8 @@ enum sctp_optname {
 #define SCTP_STATUS SCTP_STATUS
        SCTP_GET_PEER_ADDR_INFO,
 #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
+       SCTP_DELAYED_ACK_TIME,
+#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
 
        /* Internal Socket Options. Some of the sctp library functions are 
         * implemented using these socket options.
@@ -503,13 +505,41 @@ struct sctp_setadaption {
  *   unreachable. The following structure is used to access and modify an
  *   address's parameters:
  */
+enum  sctp_spp_flags {
+       SPP_HB_ENABLE = 1,              /*Enable heartbeats*/
+       SPP_HB_DISABLE = 2,             /*Disable heartbeats*/
+       SPP_HB = SPP_HB_ENABLE | SPP_HB_DISABLE,
+       SPP_HB_DEMAND = 4,              /*Send heartbeat immediately*/
+       SPP_PMTUD_ENABLE = 8,           /*Enable PMTU discovery*/
+       SPP_PMTUD_DISABLE = 16,         /*Disable PMTU discovery*/
+       SPP_PMTUD = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE,
+       SPP_SACKDELAY_ENABLE = 32,      /*Enable SACK*/
+       SPP_SACKDELAY_DISABLE = 64,     /*Disable SACK*/
+       SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE,
+};
+
 struct sctp_paddrparams {
        sctp_assoc_t            spp_assoc_id;
        struct sockaddr_storage spp_address;
        __u32                   spp_hbinterval;
        __u16                   spp_pathmaxrxt;
+       __u32                   spp_pathmtu;
+       __u32                   spp_sackdelay;
+       __u32                   spp_flags;
 } __attribute__((packed, aligned(4)));
 
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ */
+struct sctp_assoc_value {
+    sctp_assoc_t            assoc_id;
+    uint32_t                assoc_value;
+};
+
 /*
  * 7.2.2 Peer Address Information
  *
index 982b4ec..6961700 100644 (file)
@@ -493,6 +493,7 @@ extern void sk_stream_kill_queues(struct sock *sk);
 extern int sk_wait_data(struct sock *sk, long *timeo);
 
 struct request_sock_ops;
+struct timewait_sock_ops;
 
 /* Networking protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
@@ -557,11 +558,10 @@ struct proto {
        kmem_cache_t            *slab;
        unsigned int            obj_size;
 
-       kmem_cache_t            *twsk_slab;
-       unsigned int            twsk_obj_size;
        atomic_t                *orphan_count;
 
        struct request_sock_ops *rsk_prot;
+       struct timewait_sock_ops *twsk_prot;
 
        struct module           *owner;
 
@@ -926,6 +926,29 @@ static inline void sock_put(struct sock *sk)
                sk_free(sk);
 }
 
+static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
+{
+       int rc = NET_RX_SUCCESS;
+
+       if (sk_filter(sk, skb, 0))
+               goto discard_and_relse;
+
+       skb->dev = NULL;
+
+       bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk))
+               rc = sk->sk_backlog_rcv(sk, skb);
+       else
+               sk_add_backlog(sk, skb);
+       bh_unlock_sock(sk);
+out:
+       sock_put(sk);
+       return rc;
+discard_and_relse:
+       kfree_skb(skb);
+       goto out;
+}
+
 /* Detach socket from process context.
  * Announce socket dead, detach it from wait queue and inode.
  * Note that parent inode held reference count on this struct sock,
@@ -1166,7 +1189,10 @@ static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
  
 static inline int sock_error(struct sock *sk)
 {
-       int err = xchg(&sk->sk_err, 0);
+       int err;
+       if (likely(!sk->sk_err))
+               return 0;
+       err = xchg(&sk->sk_err, 0);
        return -err;
 }
 
index d78025f..77f21c6 100644 (file)
@@ -224,53 +224,6 @@ extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
 extern int tcp_memory_pressure;
 
-/*
- *     Pointers to address related TCP functions
- *     (i.e. things that depend on the address family)
- */
-
-struct tcp_func {
-       int                     (*queue_xmit)           (struct sk_buff *skb,
-                                                        int ipfragok);
-
-       void                    (*send_check)           (struct sock *sk,
-                                                        struct tcphdr *th,
-                                                        int len,
-                                                        struct sk_buff *skb);
-
-       int                     (*rebuild_header)       (struct sock *sk);
-
-       int                     (*conn_request)         (struct sock *sk,
-                                                        struct sk_buff *skb);
-
-       struct sock *           (*syn_recv_sock)        (struct sock *sk,
-                                                        struct sk_buff *skb,
-                                                        struct request_sock *req,
-                                                        struct dst_entry *dst);
-    
-       int                     (*remember_stamp)       (struct sock *sk);
-
-       __u16                   net_header_len;
-
-       int                     (*setsockopt)           (struct sock *sk, 
-                                                        int level, 
-                                                        int optname, 
-                                                        char __user *optval, 
-                                                        int optlen);
-
-       int                     (*getsockopt)           (struct sock *sk, 
-                                                        int level, 
-                                                        int optname, 
-                                                        char __user *optval, 
-                                                        int __user *optlen);
-
-
-       void                    (*addr2sockaddr)        (struct sock *sk,
-                                                        struct sockaddr *);
-
-       int sockaddr_len;
-};
-
 /*
  * The next routines deal with comparing 32 bit unsigned ints
  * and worry about wraparound (automatic with unsigned arithmetic).
@@ -334,6 +287,9 @@ extern int                  tcp_rcv_established(struct sock *sk,
 
 extern void                    tcp_rcv_space_adjust(struct sock *sk);
 
+extern int                     tcp_twsk_unique(struct sock *sk,
+                                               struct sock *sktw, void *twp);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
                                         const unsigned int pkts)
 {
@@ -405,8 +361,7 @@ extern void                 tcp_parse_options(struct sk_buff *skb,
  *     TCP v4 functions exported for the inet6 API
  */
 
-extern void                    tcp_v4_send_check(struct sock *sk, 
-                                                 struct tcphdr *th, int len, 
+extern void                    tcp_v4_send_check(struct sock *sk, int len,
                                                  struct sk_buff *skb);
 
 extern int                     tcp_v4_conn_request(struct sock *sk,
@@ -490,34 +445,16 @@ typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
 extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
                         sk_read_actor_t recv_actor);
 
-/* Initialize RCV_MSS value.
- * RCV_MSS is an our guess about MSS used by the peer.
- * We haven't any direct information about the MSS.
- * It's better to underestimate the RCV_MSS rather than overestimate.
- * Overestimations make us ACKing less frequently than needed.
- * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
- */
+extern void tcp_initialize_rcv_mss(struct sock *sk);
 
-static inline void tcp_initialize_rcv_mss(struct sock *sk)
-{
-       struct tcp_sock *tp = tcp_sk(sk);
-       unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
-
-       hint = min(hint, tp->rcv_wnd/2);
-       hint = min(hint, TCP_MIN_RCVMSS);
-       hint = max(hint, TCP_MIN_MSS);
-
-       inet_csk(sk)->icsk_ack.rcv_mss = hint;
-}
-
-static __inline__ void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
+static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
 {
        tp->pred_flags = htonl((tp->tcp_header_len << 26) |
                               ntohl(TCP_FLAG_ACK) |
                               snd_wnd);
 }
 
-static __inline__ void tcp_fast_path_on(struct tcp_sock *tp)
+static inline void tcp_fast_path_on(struct tcp_sock *tp)
 {
        __tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale);
 }
@@ -535,7 +472,7 @@ static inline void tcp_fast_path_check(struct sock *sk, struct tcp_sock *tp)
  * Rcv_nxt can be after the window if our peer push more data
  * than the offered window.
  */
-static __inline__ u32 tcp_receive_window(const struct tcp_sock *tp)
+static inline u32 tcp_receive_window(const struct tcp_sock *tp)
 {
        s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt;
 
@@ -707,6 +644,7 @@ extern void tcp_cleanup_congestion_control(struct sock *sk);
 extern int tcp_set_default_congestion_control(const char *name);
 extern void tcp_get_default_congestion_control(char *name);
 extern int tcp_set_congestion_control(struct sock *sk, const char *name);
+extern void tcp_slow_start(struct tcp_sock *tp);
 
 extern struct tcp_congestion_ops tcp_init_congestion_ops;
 extern u32 tcp_reno_ssthresh(struct sock *sk);
@@ -746,7 +684,7 @@ static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event)
  *     "Packets left network, but not honestly ACKed yet" PLUS
  *     "Packets fast retransmitted"
  */
-static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
+static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
 {
        return (tp->packets_out - tp->left_out + tp->retrans_out);
 }
@@ -766,33 +704,6 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk)
                            (tp->snd_cwnd >> 2)));
 }
 
-/*
- * Linear increase during slow start
- */
-static inline void tcp_slow_start(struct tcp_sock *tp)
-{
-       if (sysctl_tcp_abc) {
-               /* RFC3465: Slow Start
-                * TCP sender SHOULD increase cwnd by the number of
-                * previously unacknowledged bytes ACKed by each incoming
-                * acknowledgment, provided the increase is not more than L
-                */
-               if (tp->bytes_acked < tp->mss_cache)
-                       return;
-
-               /* We MAY increase by 2 if discovered delayed ack */
-               if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
-                       if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-                               tp->snd_cwnd++;
-               }
-       }
-       tp->bytes_acked = 0;
-
-       if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-               tp->snd_cwnd++;
-}
-
-
 static inline void tcp_sync_left_out(struct tcp_sock *tp)
 {
        if (tp->rx_opt.sack_ok &&
@@ -801,34 +712,7 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp)
        tp->left_out = tp->sacked_out + tp->lost_out;
 }
 
-/* Set slow start threshold and cwnd not falling to slow start */
-static inline void __tcp_enter_cwr(struct sock *sk)
-{
-       const struct inet_connection_sock *icsk = inet_csk(sk);
-       struct tcp_sock *tp = tcp_sk(sk);
-
-       tp->undo_marker = 0;
-       tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
-       tp->snd_cwnd = min(tp->snd_cwnd,
-                          tcp_packets_in_flight(tp) + 1U);
-       tp->snd_cwnd_cnt = 0;
-       tp->high_seq = tp->snd_nxt;
-       tp->snd_cwnd_stamp = tcp_time_stamp;
-       TCP_ECN_queue_cwr(tp);
-}
-
-static inline void tcp_enter_cwr(struct sock *sk)
-{
-       struct tcp_sock *tp = tcp_sk(sk);
-
-       tp->prior_ssthresh = 0;
-       tp->bytes_acked = 0;
-       if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
-               __tcp_enter_cwr(sk);
-               tcp_set_ca_state(sk, TCP_CA_CWR);
-       }
-}
-
+extern void tcp_enter_cwr(struct sock *sk);
 extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
 
 /* Slow start with delack produces 3 packets of burst, so that
@@ -860,14 +744,14 @@ static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
                return left <= tcp_max_burst(tp);
 }
 
-static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, 
-                                          const struct sk_buff *skb)
+static inline void tcp_minshall_update(struct tcp_sock *tp, int mss,
+                                      const struct sk_buff *skb)
 {
        if (skb->len < mss)
                tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
 }
 
-static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
        if (!tp->packets_out && !icsk->icsk_pending)
@@ -875,18 +759,18 @@ static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *t
                                          icsk->icsk_rto, TCP_RTO_MAX);
 }
 
-static __inline__ void tcp_push_pending_frames(struct sock *sk,
-                                              struct tcp_sock *tp)
+static inline void tcp_push_pending_frames(struct sock *sk,
+                                          struct tcp_sock *tp)
 {
        __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
 }
 
-static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
+static inline void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
        tp->snd_wl1 = seq;
 }
 
-static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
+static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
        tp->snd_wl1 = seq;
 }
@@ -894,19 +778,19 @@ static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 /*
  * Calculate(/check) TCP checksum
  */
-static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
-                                  unsigned long saddr, unsigned long daddr, 
-                                  unsigned long base)
+static inline u16 tcp_v4_check(struct tcphdr *th, int len,
+                              unsigned long saddr, unsigned long daddr, 
+                              unsigned long base)
 {
        return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
 }
 
-static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
+static inline int __tcp_checksum_complete(struct sk_buff *skb)
 {
        return __skb_checksum_complete(skb);
 }
 
-static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
+static inline int tcp_checksum_complete(struct sk_buff *skb)
 {
        return skb->ip_summed != CHECKSUM_UNNECESSARY &&
                __tcp_checksum_complete(skb);
@@ -914,7 +798,7 @@ static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
 
 /* Prequeue for VJ style copy to user, combined with checksumming. */
 
-static __inline__ void tcp_prequeue_init(struct tcp_sock *tp)
+static inline void tcp_prequeue_init(struct tcp_sock *tp)
 {
        tp->ucopy.task = NULL;
        tp->ucopy.len = 0;
@@ -930,7 +814,7 @@ static __inline__ void tcp_prequeue_init(struct tcp_sock *tp)
  *
  * NOTE: is this not too big to inline?
  */
-static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
@@ -971,7 +855,7 @@ static const char *statename[]={
 };
 #endif
 
-static __inline__ void tcp_set_state(struct sock *sk, int state)
+static inline void tcp_set_state(struct sock *sk, int state)
 {
        int oldstate = sk->sk_state;
 
@@ -1005,7 +889,7 @@ static __inline__ void tcp_set_state(struct sock *sk, int state)
 #endif 
 }
 
-static __inline__ void tcp_done(struct sock *sk)
+static inline void tcp_done(struct sock *sk)
 {
        tcp_set_state(sk, TCP_CLOSE);
        tcp_clear_xmit_timers(sk);
@@ -1018,81 +902,13 @@ static __inline__ void tcp_done(struct sock *sk)
                inet_csk_destroy_sock(sk);
 }
 
-static __inline__ void tcp_sack_reset(struct tcp_options_received *rx_opt)
+static inline void tcp_sack_reset(struct tcp_options_received *rx_opt)
 {
        rx_opt->dsack = 0;
        rx_opt->eff_sacks = 0;
        rx_opt->num_sacks = 0;
 }
 
-static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp, __u32 tstamp)
-{
-       if (tp->rx_opt.tstamp_ok) {
-               *ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
-                                         (TCPOPT_NOP << 16) |
-                                         (TCPOPT_TIMESTAMP << 8) |
-                                         TCPOLEN_TIMESTAMP);
-               *ptr++ = htonl(tstamp);
-               *ptr++ = htonl(tp->rx_opt.ts_recent);
-       }
-       if (tp->rx_opt.eff_sacks) {
-               struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks;
-               int this_sack;
-
-               *ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
-                                         (TCPOPT_NOP << 16) |
-                                         (TCPOPT_SACK << 8) |
-                                         (TCPOLEN_SACK_BASE +
-                                          (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)));
-               for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) {
-                       *ptr++ = htonl(sp[this_sack].start_seq);
-                       *ptr++ = htonl(sp[this_sack].end_seq);
-               }
-               if (tp->rx_opt.dsack) {
-                       tp->rx_opt.dsack = 0;
-                       tp->rx_opt.eff_sacks--;
-               }
-       }
-}
-
-/* Construct a tcp options header for a SYN or SYN_ACK packet.
- * If this is every changed make sure to change the definition of
- * MAX_SYN_SIZE to match the new maximum number of options that you
- * can generate.
- */
-static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
-                                            int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent)
-{
-       /* We always get an MSS option.
-        * The option bytes which will be seen in normal data
-        * packets should timestamps be used, must be in the MSS
-        * advertised.  But we subtract them from tp->mss_cache so
-        * that calculations in tcp_sendmsg are simpler etc.
-        * So account for this fact here if necessary.  If we
-        * don't do this correctly, as a receiver we won't
-        * recognize data packets as being full sized when we
-        * should, and thus we won't abide by the delayed ACK
-        * rules correctly.
-        * SACKs don't matter, we never delay an ACK when we
-        * have any of those going out.
-        */
-       *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
-       if (ts) {
-               if(sack)
-                       *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
-                                                 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
-               else
-                       *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-                                                 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
-               *ptr++ = htonl(tstamp);         /* TSVAL */
-               *ptr++ = htonl(ts_recent);      /* TSECR */
-       } else if(sack)
-               *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-                                         (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
-       if (offer_wscale)
-               *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
-}
-
 /* Determine a window scaling and initial window to offer. */
 extern void tcp_select_initial_window(int __space, __u32 mss,
                                      __u32 *rcv_wnd, __u32 *window_clamp,
@@ -1117,9 +933,9 @@ static inline int tcp_full_space(const struct sock *sk)
        return tcp_win_from_space(sk->sk_rcvbuf); 
 }
 
-static __inline__ void tcp_openreq_init(struct request_sock *req,
-                                       struct tcp_options_received *rx_opt,
-                                       struct sk_buff *skb)
+static inline void tcp_openreq_init(struct request_sock *req,
+                                   struct tcp_options_received *rx_opt,
+                                   struct sk_buff *skb)
 {
        struct inet_request_sock *ireq = inet_rsk(req);
 
index b9d4176..b0b6459 100644 (file)
@@ -31,4 +31,20 @@ enum {
 
 #define TCP_STATE_MASK 0xF
 
+#define TCP_ACTION_FIN (1 << 7)
+
+enum {
+       TCPF_ESTABLISHED = (1 << 1),
+       TCPF_SYN_SENT    = (1 << 2),
+       TCPF_SYN_RECV    = (1 << 3),
+       TCPF_FIN_WAIT1   = (1 << 4),
+       TCPF_FIN_WAIT2   = (1 << 5),
+       TCPF_TIME_WAIT   = (1 << 6),
+       TCPF_CLOSE       = (1 << 7),
+       TCPF_CLOSE_WAIT  = (1 << 8),
+       TCPF_LAST_ACK    = (1 << 9),
+       TCPF_LISTEN      = (1 << 10),
+       TCPF_CLOSING     = (1 << 11) 
+};
+
 #endif /* _LINUX_TCP_STATES_H */
diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h
new file mode 100644 (file)
index 0000000..2544281
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * NET         Generic infrastructure for Network protocols.
+ *
+ * Authors:    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+#ifndef _TIMEWAIT_SOCK_H
+#define _TIMEWAIT_SOCK_H
+
+#include <linux/slab.h>
+#include <net/sock.h>
+
+struct timewait_sock_ops {
+       kmem_cache_t    *twsk_slab;
+       unsigned int    twsk_obj_size;
+       int             (*twsk_unique)(struct sock *sk,
+                                      struct sock *sktw, void *twp);
+};
+
+static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
+{
+       if (sk->sk_prot->twsk_prot->twsk_unique != NULL)
+               return sk->sk_prot->twsk_prot->twsk_unique(sk, sktw, twp);
+       return 0;
+}
+
+#endif /* _TIMEWAIT_SOCK_H */
index 4e86f2d..61f724c 100644 (file)
@@ -44,7 +44,7 @@ extern int                    datagram_send_ctl(struct msghdr *msg,
 /*
  *     address family specific functions
  */
-extern struct tcp_func ipv4_specific;
+extern struct inet_connection_sock_af_ops ipv4_specific;
 
 extern int inet6_destroy_sock(struct sock *sk);
 
index 107b9d7..766fba1 100644 (file)
@@ -22,9 +22,8 @@
 #ifndef _UDP_H
 #define _UDP_H
 
-#include <linux/udp.h>
-#include <linux/ip.h>
 #include <linux/list.h>
+#include <net/inet_sock.h>
 #include <net/sock.h>
 #include <net/snmp.h>
 #include <linux/seq_file.h>
@@ -62,6 +61,7 @@ static inline int udp_lport_inuse(u16 num)
 
 extern struct proto udp_prot;
 
+struct sk_buff;
 
 extern void    udp_err(struct sk_buff *, u32);
 
index 1cdb879..07d7b50 100644 (file)
@@ -2,11 +2,12 @@
 #define _NET_XFRM_H
 
 #include <linux/compiler.h>
+#include <linux/in.h>
 #include <linux/xfrm.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
+#include <linux/socket.h>
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <linux/in6.h>
@@ -144,6 +145,9 @@ struct xfrm_state
         * transformer. */
        struct xfrm_type        *type;
 
+       /* Security context */
+       struct xfrm_sec_ctx     *security;
+
        /* Private data of this transformer, format is opaque,
         * interpreted by xfrm_type methods. */
        void                    *data;
@@ -298,6 +302,7 @@ struct xfrm_policy
        __u8                    flags;
        __u8                    dead;
        __u8                    xfrm_nr;
+       struct xfrm_sec_ctx     *security;
        struct xfrm_tmpl        xfrm_vec[XFRM_MAX_DEPTH];
 };
 
@@ -510,6 +515,25 @@ xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
        return 0;
 }
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+/*     If neither has a context --> match
+ *     Otherwise, both must have a context and the sids, doi, alg must match
+ */
+static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
+{
+       return ((!s1 && !s2) ||
+               (s1 && s2 &&
+                (s1->ctx_sid == s2->ctx_sid) &&
+                (s1->ctx_doi == s2->ctx_doi) &&
+                (s1->ctx_alg == s2->ctx_alg)));
+}
+#else
+static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
+{
+       return 1;
+}
+#endif
+
 /* A struct encoding bundle of transformations to apply to some set of flow.
  *
  * dst->child points to the next element of bundle.
@@ -878,8 +902,8 @@ static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsig
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
 extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
-struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
-                                     int delete);
+struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
+                                         struct xfrm_sec_ctx *ctx, int delete);
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
 void xfrm_policy_flush(void);
 u32 xfrm_get_acqseq(void);
index 20da282..41cfc29 100644 (file)
@@ -151,6 +151,6 @@ extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
 extern void scsi_put_command(struct scsi_cmnd *);
 extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
 extern void scsi_finish_command(struct scsi_cmnd *cmd);
-extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries);
+extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd);
 
 #endif /* _SCSI_SCSI_CMND_H */
index b090a11..4d69dee 100644 (file)
@@ -16,7 +16,6 @@ extern void __scsi_print_sense(const char *name,
 extern void scsi_print_driverbyte(int);
 extern void scsi_print_hostbyte(int);
 extern void scsi_print_status(unsigned char);
-extern int scsi_print_msg(const unsigned char *);
 extern const char *scsi_sense_key_string(unsigned char);
 extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
 
index 85cfd88..e94ca4d 100644 (file)
@@ -79,9 +79,9 @@ struct scsi_device {
        char inq_periph_qual;   /* PQ from INQUIRY data */      
        unsigned char inquiry_len;      /* valid bytes in 'inquiry' */
        unsigned char * inquiry;        /* INQUIRY response data */
-       char * vendor;          /* [back_compat] point into 'inquiry' ... */
-       char * model;           /* ... after scan; point to static string */
-       char * rev;             /* ... "nullnullnullnull" before scan */
+       const char * vendor;            /* [back_compat] point into 'inquiry' ... */
+       const char * model;             /* ... after scan; point to static string */
+       const char * rev;               /* ... "nullnullnullnull" before scan */
        unsigned char current_tag;      /* current tag */
        struct scsi_target      *sdev_target;   /* used only for single_lun */
 
@@ -274,6 +274,12 @@ extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
 extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
                            int data_direction, void *buffer, unsigned bufflen,
                            struct scsi_sense_hdr *, int timeout, int retries);
+extern int scsi_execute_async(struct scsi_device *sdev,
+                             const unsigned char *cmd, int data_direction,
+                             void *buffer, unsigned bufflen, int use_sg,
+                             int timeout, int retries, void *privdata,
+                             void (*done)(void *, char *, int, int),
+                             gfp_t gfp);
 
 static inline unsigned int sdev_channel(struct scsi_device *sdev)
 {
index 6bdc4af..54a8961 100644 (file)
@@ -24,6 +24,9 @@
 #include <linux/transport_class.h>
 
 struct scsi_transport_template;
+struct scsi_target;
+struct scsi_device;
+struct Scsi_Host;
 
 struct spi_transport_attrs {
        int period;             /* value in the PPR/SDTR command */
@@ -143,5 +146,6 @@ void spi_release_transport(struct scsi_transport_template *);
 void spi_schedule_dv_device(struct scsi_device *);
 void spi_dv_device(struct scsi_device *);
 void spi_display_xfer_agreement(struct scsi_target *);
+int spi_print_msg(const unsigned char *);
 
 #endif /* SCSI_TRANSPORT_SPI_H */
index 27f97f9..54aaf56 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
 #include <linux/key.h>
-#include <net/sock.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -614,9 +613,6 @@ static void __init do_basic_setup(void)
        sysctl_init();
 #endif
 
-       /* Networking initialization needs a process context */ 
-       sock_init();
-
        do_initcalls();
 }
 
index 7982656..a5144e4 100644 (file)
@@ -63,7 +63,7 @@
 #include <linux/atalk.h>
 
 struct datalink_proto *ddp_dl, *aarp_dl;
-static struct proto_ops atalk_dgram_ops;
+static const struct proto_ops atalk_dgram_ops;
 
 /**************************************************************************\
 *                                                                          *
@@ -1763,7 +1763,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
  */
 static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-       int rc = -EINVAL;
+       int rc = -ENOIOCTLCMD;
        struct sock *sk = sock->sk;
        void __user *argp = (void __user *)arg;
 
@@ -1813,23 +1813,6 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        rc = atif_ioctl(cmd, argp);
                        rtnl_unlock();
                        break;
-               /* Physical layer ioctl calls */
-               case SIOCSIFLINK:
-               case SIOCGIFHWADDR:
-               case SIOCSIFHWADDR:
-               case SIOCGIFFLAGS:
-               case SIOCSIFFLAGS:
-               case SIOCGIFTXQLEN:
-               case SIOCSIFTXQLEN:
-               case SIOCGIFMTU:
-               case SIOCGIFCONF:
-               case SIOCADDMULTI:
-               case SIOCDELMULTI:
-               case SIOCGIFCOUNT:
-               case SIOCGIFINDEX:
-               case SIOCGIFNAME:
-                       rc = dev_ioctl(cmd, argp);
-                       break;
        }
 
        return rc;
@@ -1841,7 +1824,7 @@ static struct net_proto_family atalk_family_ops = {
        .owner          = THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
        .family         = PF_APPLETALK,
        .owner          = THIS_MODULE,
        .release        = atalk_release,
index 2684a92..f2c5417 100644 (file)
@@ -102,7 +102,7 @@ static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
 }
 
 
-static struct proto_ops pvc_proto_ops = {
+static const struct proto_ops pvc_proto_ops = {
        .family =       PF_ATMPVC,
        .owner =        THIS_MODULE,
 
index d7b2661..3a180cf 100644 (file)
@@ -613,7 +613,7 @@ static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        return error;
 }
 
-static struct proto_ops svc_proto_ops = {
+static const struct proto_ops svc_proto_ops = {
        .family =       PF_ATMSVC,
        .owner =        THIS_MODULE,
 
index 1b683f3..e8753c7 100644 (file)
@@ -54,7 +54,7 @@
 HLIST_HEAD(ax25_list);
 DEFINE_SPINLOCK(ax25_list_lock);
 
-static struct proto_ops ax25_proto_ops;
+static const struct proto_ops ax25_proto_ops;
 
 static void ax25_free_sock(struct sock *sk)
 {
@@ -1827,7 +1827,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                break;
 
        default:
-               res = dev_ioctl(cmd, argp);
+               res = -ENOIOCTLCMD;
                break;
        }
        release_sock(sk);
@@ -1944,7 +1944,7 @@ static struct net_proto_family ax25_family_ops = {
        .owner  =       THIS_MODULE,
 };
 
-static struct proto_ops ax25_proto_ops = {
+static const struct proto_ops ax25_proto_ops = {
        .family         = PF_AX25,
        .owner          = THIS_MODULE,
        .release        = ax25_release,
index ea616e3..fb031fe 100644 (file)
@@ -287,10 +287,9 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
 
-               if (sk->sk_err) {
-                       err = sock_error(sk);
+               err = sock_error(sk);
+               if (err)
                        break;
-               }
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(sk->sk_sleep, &wait);
index 9778c6a..ccbaf69 100644 (file)
@@ -146,7 +146,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        return 0;
 }
 
-static struct proto_ops bnep_sock_ops = {
+static const struct proto_ops bnep_sock_ops = {
        .family     = PF_BLUETOOTH,
        .owner      = THIS_MODULE,
        .release    = bnep_sock_release,
index beb045b..5e22343 100644 (file)
@@ -137,7 +137,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        return -EINVAL;
 }
 
-static struct proto_ops cmtp_sock_ops = {
+static const struct proto_ops cmtp_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = cmtp_sock_release,
index 1d6d0a1..84e6c93 100644 (file)
@@ -575,7 +575,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
        return 0;
 }
 
-static struct proto_ops hci_sock_ops = {
+static const struct proto_ops hci_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = hci_sock_release,
index f8986f8..8f8dd93 100644 (file)
@@ -143,7 +143,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        return -EINVAL;
 }
 
-static struct proto_ops hidp_sock_ops = {
+static const struct proto_ops hidp_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = hidp_sock_release,
index e3bb11c..7f0781e 100644 (file)
@@ -57,7 +57,7 @@
 
 #define VERSION "2.8"
 
-static struct proto_ops l2cap_sock_ops;
+static const struct proto_ops l2cap_sock_ops;
 
 static struct bt_sock_list l2cap_sk_list = {
        .lock = RW_LOCK_UNLOCKED
@@ -767,8 +767,9 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
-       if (sk->sk_err)
-               return sock_error(sk);
+       err = sock_error(sk);
+       if (err)
+               return err;
 
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
@@ -2160,7 +2161,7 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
 
 static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
 
-static struct proto_ops l2cap_sock_ops = {
+static const struct proto_ops l2cap_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = l2cap_sock_release,
index 6c34261..757d2dd 100644 (file)
@@ -58,7 +58,7 @@
 #define BT_DBG(D...)
 #endif
 
-static struct proto_ops rfcomm_sock_ops;
+static const struct proto_ops rfcomm_sock_ops;
 
 static struct bt_sock_list rfcomm_sk_list = {
        .lock = RW_LOCK_UNLOCKED
@@ -907,7 +907,7 @@ static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
 
 static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
 
-static struct proto_ops rfcomm_sock_ops = {
+static const struct proto_ops rfcomm_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = rfcomm_sock_release,
index 9cb00dc..6b61323 100644 (file)
@@ -56,7 +56,7 @@
 
 #define VERSION "0.5"
 
-static struct proto_ops sco_sock_ops;
+static const struct proto_ops sco_sock_ops;
 
 static struct bt_sock_list sco_sk_list = {
        .lock = RW_LOCK_UNLOCKED
@@ -637,8 +637,9 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
-       if (sk->sk_err)
-               return sock_error(sk);
+       err = sock_error(sk);
+       if (err)
+               return err;
 
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
@@ -913,7 +914,7 @@ static ssize_t sco_sysfs_show(struct class *dev, char *buf)
 
 static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
 
-static struct proto_ops sco_sock_ops = {
+static const struct proto_ops sco_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = sco_sock_release,
index f8f1849..188cc1a 100644 (file)
@@ -67,3 +67,4 @@ EXPORT_SYMBOL(br_should_route_hook);
 module_init(br_init)
 module_exit(br_deinit)
 MODULE_LICENSE("GPL");
+MODULE_VERSION(BR_VERSION);
index f564ee9..0b33a7b 100644 (file)
@@ -15,7 +15,9 @@
 
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
 #include <asm/uaccess.h>
 #include "br_private.h"
 
@@ -82,6 +84,87 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
+/* Allow setting mac address of pseudo-bridge to be same as
+ * any of the bound interfaces
+ */
+static int br_set_mac_address(struct net_device *dev, void *p)
+{
+       struct net_bridge *br = netdev_priv(dev);
+       struct sockaddr *addr = p;
+       struct net_bridge_port *port;
+       int err = -EADDRNOTAVAIL;
+
+       spin_lock_bh(&br->lock);
+       list_for_each_entry(port, &br->port_list, list) {
+               if (!compare_ether_addr(port->dev->dev_addr, addr->sa_data)) {
+                       br_stp_change_bridge_id(br, addr->sa_data);
+                       err = 0;
+                       break;
+               }
+       }
+       spin_unlock_bh(&br->lock);
+
+       return err;
+}
+
+static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       strcpy(info->driver, "bridge");
+       strcpy(info->version, BR_VERSION);
+       strcpy(info->fw_version, "N/A");
+       strcpy(info->bus_info, "N/A");
+}
+
+static int br_set_sg(struct net_device *dev, u32 data)
+{
+       struct net_bridge *br = netdev_priv(dev);
+
+       if (data)
+               br->feature_mask |= NETIF_F_SG;
+       else
+               br->feature_mask &= ~NETIF_F_SG;
+
+       br_features_recompute(br);
+       return 0;
+}
+
+static int br_set_tso(struct net_device *dev, u32 data)
+{
+       struct net_bridge *br = netdev_priv(dev);
+
+       if (data)
+               br->feature_mask |= NETIF_F_TSO;
+       else
+               br->feature_mask &= ~NETIF_F_TSO;
+
+       br_features_recompute(br);
+       return 0;
+}
+
+static int br_set_tx_csum(struct net_device *dev, u32 data)
+{
+       struct net_bridge *br = netdev_priv(dev);
+
+       if (data)
+               br->feature_mask |= NETIF_F_IP_CSUM;
+       else
+               br->feature_mask &= ~NETIF_F_IP_CSUM;
+
+       br_features_recompute(br);
+       return 0;
+}
+
+static struct ethtool_ops br_ethtool_ops = {
+       .get_drvinfo = br_getinfo,
+       .get_link = ethtool_op_get_link,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = br_set_sg,
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = br_set_tx_csum,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = br_set_tso,
+};
+
 void br_dev_setup(struct net_device *dev)
 {
        memset(dev->dev_addr, 0, ETH_ALEN);
@@ -96,8 +179,12 @@ void br_dev_setup(struct net_device *dev)
        dev->change_mtu = br_change_mtu;
        dev->destructor = free_netdev;
        SET_MODULE_OWNER(dev);
+       SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
        dev->stop = br_dev_stop;
        dev->tx_queue_len = 0;
-       dev->set_mac_address = NULL;
+       dev->set_mac_address = br_set_mac_address;
        dev->priv_flags = IFF_EBRIDGE;
+
+       dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+               | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
 }
index 975abe2..1132119 100644 (file)
@@ -32,9 +32,8 @@
  * ethtool, use ethtool_ops.  Also, since driver might sleep need to
  * not be holding any locks.
  */
-static int br_initial_port_cost(struct net_device *dev)
+static int port_cost(struct net_device *dev)
 {
-
        struct ethtool_cmd ecmd = { ETHTOOL_GSET };
        struct ifreq ifr;
        mm_segment_t old_fs;
@@ -58,10 +57,6 @@ static int br_initial_port_cost(struct net_device *dev)
                        return 2;
                case SPEED_10:
                        return 100;
-               default:
-                       pr_info("bridge: can't decode speed from %s: %d\n",
-                               dev->name, ecmd.speed);
-                       return 100;
                }
        }
 
@@ -75,6 +70,35 @@ static int br_initial_port_cost(struct net_device *dev)
        return 100;     /* assume old 10Mbps */
 }
 
+
+/*
+ * Check for port carrier transistions.
+ * Called from work queue to allow for calling functions that
+ * might sleep (such as speed check), and to debounce.
+ */
+static void port_carrier_check(void *arg)
+{
+       struct net_bridge_port *p = arg;
+
+       rtnl_lock();
+       if (netif_carrier_ok(p->dev)) {
+               u32 cost = port_cost(p->dev);
+
+               spin_lock_bh(&p->br->lock);
+               if (p->state == BR_STATE_DISABLED) {
+                       p->path_cost = cost;
+                       br_stp_enable_port(p);
+               }
+               spin_unlock_bh(&p->br->lock);
+       } else {
+               spin_lock_bh(&p->br->lock);
+               if (p->state != BR_STATE_DISABLED)
+                       br_stp_disable_port(p);
+               spin_unlock_bh(&p->br->lock);
+       }
+       rtnl_unlock();
+}
+
 static void destroy_nbp(struct net_bridge_port *p)
 {
        struct net_device *dev = p->dev;
@@ -102,6 +126,9 @@ static void del_nbp(struct net_bridge_port *p)
        dev->br_port = NULL;
        dev_set_promiscuity(dev, -1);
 
+       cancel_delayed_work(&p->carrier_check);
+       flush_scheduled_work();
+
        spin_lock_bh(&br->lock);
        br_stp_disable_port(p);
        spin_unlock_bh(&br->lock);
@@ -155,6 +182,7 @@ static struct net_device *new_bridge_dev(const char *name)
        br->bridge_id.prio[1] = 0x00;
        memset(br->bridge_id.addr, 0, ETH_ALEN);
 
+       br->feature_mask = dev->features;
        br->stp_enabled = 0;
        br->designated_root = br->bridge_id;
        br->root_path_cost = 0;
@@ -195,10 +223,9 @@ static int find_portno(struct net_bridge *br)
        return (index >= BR_MAX_PORTS) ? -EXFULL : index;
 }
 
-/* called with RTNL */
+/* called with RTNL but without bridge lock */
 static struct net_bridge_port *new_nbp(struct net_bridge *br, 
-                                      struct net_device *dev,
-                                      unsigned long cost)
+                                      struct net_device *dev)
 {
        int index;
        struct net_bridge_port *p;
@@ -215,12 +242,13 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
        p->br = br;
        dev_hold(dev);
        p->dev = dev;
-       p->path_cost = cost;
+       p->path_cost = port_cost(dev);
        p->priority = 0x8000 >> BR_PORT_BITS;
        dev->br_port = p;
        p->port_no = index;
        br_init_port(p);
        p->state = BR_STATE_DISABLED;
+       INIT_WORK(&p->carrier_check, port_carrier_check, p);
        kobject_init(&p->kobj);
 
        return p;
@@ -322,9 +350,8 @@ void br_features_recompute(struct net_bridge *br)
        struct net_bridge_port *p;
        unsigned long features, checksum;
 
-       features = NETIF_F_SG | NETIF_F_FRAGLIST 
-               | NETIF_F_HIGHDMA | NETIF_F_TSO;
-       checksum = NETIF_F_IP_CSUM;     /* least commmon subset */
+       features = br->feature_mask &~ NETIF_F_IP_CSUM;
+       checksum = br->feature_mask & NETIF_F_IP_CSUM;
 
        list_for_each_entry(p, &br->port_list, list) {
                if (!(p->dev->features 
@@ -351,7 +378,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
        if (dev->br_port != NULL)
                return -EBUSY;
 
-       if (IS_ERR(p = new_nbp(br, dev, br_initial_port_cost(dev))))
+       if (IS_ERR(p = new_nbp(br, dev)))
                return PTR_ERR(p);
 
        if ((err = br_fdb_insert(br, p, dev->dev_addr)))
index b88220a..c387852 100644 (file)
@@ -53,6 +53,11 @@ int br_handle_frame_finish(struct sk_buff *skb)
        /* insert into forwarding database after filtering to avoid spoofing */
        br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
 
+       if (p->state == BR_STATE_LEARNING) {
+               kfree_skb(skb);
+               goto out;
+       }
+
        if (br->dev->flags & IFF_PROMISC) {
                struct sk_buff *skb2;
 
@@ -107,9 +112,6 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
        if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
                goto err;
 
-       if (p->state == BR_STATE_LEARNING)
-               br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
-
        if (p->br->stp_enabled &&
            !memcmp(dest, bridge_ula, 5) &&
            !(dest[5] & 0xF0)) {
@@ -118,9 +120,10 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
                                NULL, br_stp_handle_bpdu);
                        return 1;
                }
+               goto err;
        }
 
-       else if (p->state == BR_STATE_FORWARDING) {
+       if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
                if (br_should_route_hook) {
                        if (br_should_route_hook(pskb)) 
                                return 0;
index 23422bd..223f827 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/ip.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/netfilter_bridge.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/netfilter_arp.h>
 #include <linux/in_route.h>
+
 #include <net/ip.h>
 #include <net/ipv6.h>
+#include <net/route.h>
+
 #include <asm/uaccess.h>
 #include <asm/checksum.h>
 #include "br_private.h"
index 917311c..a43a9c1 100644 (file)
@@ -52,17 +52,9 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
                br_stp_recalculate_bridge_id(br);
                break;
 
-       case NETDEV_CHANGE:     /* device is up but carrier changed */
-               if (!(br->dev->flags & IFF_UP))
-                       break;
-
-               if (netif_carrier_ok(dev)) {
-                       if (p->state == BR_STATE_DISABLED)
-                               br_stp_enable_port(p);
-               } else {
-                       if (p->state != BR_STATE_DISABLED)
-                               br_stp_disable_port(p);
-               }
+       case NETDEV_CHANGE:
+               if (br->dev->flags & IFF_UP)
+                       schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
                break;
 
        case NETDEV_FEAT_CHANGE:
index bdf95a7..c5bd631 100644 (file)
 #define BR_PORT_BITS   10
 #define BR_MAX_PORTS   (1<<BR_PORT_BITS)
 
+#define BR_PORT_DEBOUNCE (HZ/10)
+
+#define BR_VERSION     "2.1"
+
 typedef struct bridge_id bridge_id;
 typedef struct mac_addr mac_addr;
 typedef __u16 port_id;
@@ -78,6 +82,7 @@ struct net_bridge_port
        struct timer_list               hold_timer;
        struct timer_list               message_age_timer;
        struct kobject                  kobj;
+       struct work_struct              carrier_check;
        struct rcu_head                 rcu;
 };
 
@@ -90,6 +95,7 @@ struct net_bridge
        spinlock_t                      hash_lock;
        struct hlist_head               hash[BR_HASH_SIZE];
        struct list_head                age_list;
+       unsigned long                   feature_mask;
 
        /* STP */
        bridge_id                       designated_root;
@@ -201,6 +207,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br);
 extern void br_stp_enable_port(struct net_bridge_port *p);
 extern void br_stp_disable_port(struct net_bridge_port *p);
 extern void br_stp_recalculate_bridge_id(struct net_bridge *br);
+extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
 extern void br_stp_set_bridge_priority(struct net_bridge *br,
                                       u16 newprio);
 extern void br_stp_set_port_priority(struct net_bridge_port *p,
index ac09b6a..cc047f7 100644 (file)
@@ -120,8 +120,7 @@ void br_stp_disable_port(struct net_bridge_port *p)
 }
 
 /* called under bridge lock */
-static void br_stp_change_bridge_id(struct net_bridge *br, 
-                                   const unsigned char *addr)
+void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
 {
        unsigned char oldaddr[6];
        struct net_bridge_port *p;
@@ -158,7 +157,7 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
 
        list_for_each_entry(p, &br->port_list, list) {
                if (addr == br_mac_zero ||
-                   compare_ether_addr(p->dev->dev_addr, addr) < 0)
+                   memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
                        addr = p->dev->dev_addr;
 
        }
index c70b3be..b84fc60 100644 (file)
@@ -196,9 +196,13 @@ config BRIDGE_EBT_LOG
          To compile it as a module, choose M here.  If unsure, say N.
 
 config BRIDGE_EBT_ULOG
-       tristate "ebt: ulog support"
+       tristate "ebt: ulog support (OBSOLETE)"
        depends on BRIDGE_NF_EBTABLES
        help
+         This option enables the old bridge-specific "ebt_ulog" implementation
+         which has been obsoleted by the new "nfnetlink_log" code (see
+         CONFIG_NETFILTER_NETLINK_LOG).
+
          This option adds the ulog watcher, that you can use in any rule
          in any ebtables table. The packet is passed to a userspace
          logging daemon using netlink multicast sockets. This differs
index 662975b..9f6e019 100644 (file)
@@ -3,13 +3,16 @@
  *
  *     Authors:
  *     Bart De Schuymer <bdschuym@pandora.be>
+ *     Harald Welte <laforge@netfilter.org>
  *
  *  April, 2002
  *
  */
 
+#include <linux/in.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_log.h>
+#include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/if_arp.h>
@@ -55,27 +58,30 @@ static void print_MAC(unsigned char *p)
 }
 
 #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
-static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static void
+ebt_log_packet(unsigned int pf, unsigned int hooknum,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const struct nf_loginfo *loginfo,
+   const char *prefix)
 {
-       struct ebt_log_info *info = (struct ebt_log_info *)data;
-       char level_string[4] = "< >";
+       unsigned int bitmask;
 
-       level_string[1] = '0' + info->loglevel;
        spin_lock_bh(&ebt_log_lock);
-       printk(level_string);
-       printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "",
-          out ? out->name : "");
+       printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level,
+              prefix, in ? in->name : "", out ? out->name : "");
 
-       printk("MAC source = ");
        print_MAC(eth_hdr(skb)->h_source);
        printk("MAC dest = ");
        print_MAC(eth_hdr(skb)->h_dest);
 
        printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto));
 
-       if ((info->bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
+       if (loginfo->type == NF_LOG_TYPE_LOG)
+               bitmask = loginfo->u.log.logflags;
+       else
+               bitmask = NF_LOG_MASK;
+
+       if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
           htons(ETH_P_IP)){
                struct iphdr _iph, *ih;
 
@@ -84,10 +90,9 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
                        printk(" INCOMPLETE IP header");
                        goto out;
                }
-               printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,",
-                  NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
-               printk(" IP tos=0x%02X, IP proto=%d", ih->tos,
-                      ih->protocol);
+               printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
+                      "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
+                      NIPQUAD(ih->daddr), ih->tos, ih->protocol);
                if (ih->protocol == IPPROTO_TCP ||
                    ih->protocol == IPPROTO_UDP) {
                        struct tcpudphdr _ports, *pptr;
@@ -104,7 +109,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
                goto out;
        }
 
-       if ((info->bitmask & EBT_LOG_ARP) &&
+       if ((bitmask & EBT_LOG_ARP) &&
            ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
             (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
                struct arphdr _arph, *ah;
@@ -144,6 +149,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
 out:
        printk("\n");
        spin_unlock_bh(&ebt_log_lock);
+
+}
+
+static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+       struct ebt_log_info *info = (struct ebt_log_info *)data;
+       struct nf_loginfo li;
+
+       li.type = NF_LOG_TYPE_LOG;
+       li.u.log.level = info->loglevel;
+       li.u.log.logflags = info->bitmask;
+
+       nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix);
 }
 
 static struct ebt_watcher log =
@@ -154,13 +174,32 @@ static struct ebt_watcher log =
        .me             = THIS_MODULE,
 };
 
+static struct nf_logger ebt_log_logger = {
+       .name           = "ebt_log",
+       .logfn          = &ebt_log_packet,
+       .me             = THIS_MODULE,
+};
+
 static int __init init(void)
 {
-       return ebt_register_watcher(&log);
+       int ret;
+
+       ret = ebt_register_watcher(&log);
+       if (ret < 0)
+               return ret;
+       if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) {
+               printk(KERN_WARNING "ebt_log: not logging via system console "
+                      "since somebody else already registered for PF_INET\n");
+               /* we cannot make module load fail here, since otherwise 
+                * ebtables userspace would abort */
+       }
+
+       return 0;
 }
 
 static void __exit fini(void)
 {
+       nf_log_unregister_logger(&ebt_log_logger);
        ebt_unregister_watcher(&log);
 }
 
index aae26ae..ce617b3 100644 (file)
@@ -3,6 +3,7 @@
  *
  *     Authors:
  *     Bart De Schuymer <bdschuym@pandora.be>
+ *     Harald Welte <laforge@netfilter.org>
  *
  *  November, 2004
  *
@@ -115,14 +116,13 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
        return skb;
 }
 
-static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
+static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+   const struct ebt_ulog_info *uloginfo, const char *prefix)
 {
        ebt_ulog_packet_msg_t *pm;
        size_t size, copy_len;
        struct nlmsghdr *nlh;
-       struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
        unsigned int group = uloginfo->nlgroup;
        ebt_ulog_buff_t *ub = &ulog_buffers[group];
        spinlock_t *lock = &ub->lock;
@@ -216,6 +216,39 @@ alloc_failure:
        goto unlock;
 }
 
+/* this function is registered with the netfilter core */
+static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const struct nf_loginfo *li,
+   const char *prefix)
+{
+       struct ebt_ulog_info loginfo;
+
+       if (!li || li->type != NF_LOG_TYPE_ULOG) {
+               loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
+               loginfo.cprange = 0;
+               loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
+               loginfo.prefix[0] = '\0';
+       } else {
+               loginfo.nlgroup = li->u.ulog.group;
+               loginfo.cprange = li->u.ulog.copy_len;
+               loginfo.qthreshold = li->u.ulog.qthreshold;
+               strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
+       }
+
+       ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
+}
+
+static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+       struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+
+       ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
+}
+
+
 static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
@@ -240,6 +273,12 @@ static struct ebt_watcher ulog = {
        .me             = THIS_MODULE,
 };
 
+static struct nf_logger ebt_ulog_logger = {
+       .name           = EBT_ULOG_WATCHER,
+       .logfn          = &ebt_log_packet,
+       .me             = THIS_MODULE,
+};
+
 static int __init init(void)
 {
        int i, ret = 0;
@@ -265,6 +304,13 @@ static int __init init(void)
        else if ((ret = ebt_register_watcher(&ulog)))
                sock_release(ebtulognl->sk_socket);
 
+       if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) {
+               printk(KERN_WARNING "ebt_ulog: not logging via ulog "
+                      "since somebody else already registered for PF_BRIDGE\n");
+               /* we cannot make module load fail here, since otherwise
+                * ebtables userspace would abort */
+       }
+
        return ret;
 }
 
@@ -273,6 +319,7 @@ static void __exit fini(void)
        ebt_ulog_buff_t *ub;
        int i;
 
+       nf_log_unregister_logger(&ebt_ulog_logger);
        ebt_unregister_watcher(&ulog);
        for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
                ub = &ulog_buffers[i];
index 1bcfef5..f8d322e 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/poll.h>
 #include <linux/highmem.h>
+#include <linux/spinlock.h>
 
 #include <net/protocol.h>
 #include <linux/skbuff.h>
@@ -199,6 +200,41 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
        kfree_skb(skb);
 }
 
+/**
+ *     skb_kill_datagram - Free a datagram skbuff forcibly
+ *     @sk: socket
+ *     @skb: datagram skbuff
+ *     @flags: MSG_ flags
+ *
+ *     This function frees a datagram skbuff that was received by
+ *     skb_recv_datagram.  The flags argument must match the one
+ *     used for skb_recv_datagram.
+ *
+ *     If the MSG_PEEK flag is set, and the packet is still on the
+ *     receive queue of the socket, it will be taken off the queue
+ *     before it is freed.
+ *
+ *     This function currently only disables BH when acquiring the
+ *     sk_receive_queue lock.  Therefore it must not be used in a
+ *     context where that lock is acquired in an IRQ context.
+ */
+
+void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
+{
+       if (flags & MSG_PEEK) {
+               spin_lock_bh(&sk->sk_receive_queue.lock);
+               if (skb == skb_peek(&sk->sk_receive_queue)) {
+                       __skb_unlink(skb, &sk->sk_receive_queue);
+                       atomic_dec(&skb->users);
+               }
+               spin_unlock_bh(&sk->sk_receive_queue.lock);
+       }
+
+       kfree_skb(skb);
+}
+
+EXPORT_SYMBOL(skb_kill_datagram);
+
 /**
  *     skb_copy_datagram_iovec - Copy a datagram to an iovec.
  *     @skb: buffer to copy
index 1a59f21..5081287 100644 (file)
@@ -3277,7 +3277,6 @@ EXPORT_SYMBOL(dev_close);
 EXPORT_SYMBOL(dev_get_by_flags);
 EXPORT_SYMBOL(dev_get_by_index);
 EXPORT_SYMBOL(dev_get_by_name);
-EXPORT_SYMBOL(dev_ioctl);
 EXPORT_SYMBOL(dev_open);
 EXPORT_SYMBOL(dev_queue_xmit);
 EXPORT_SYMBOL(dev_remove_pack);
index 3a10e0b..8964d34 100644 (file)
@@ -13,6 +13,7 @@
  * 2 of the License, or (at your option) any later version.
  *
  * Andi Kleen - Fix a few bad bugs and races.
+ * Kris Katterjohn - Added many additional checks in sk_chk_filter()
  */
 
 #include <linux/module.h>
@@ -250,7 +251,7 @@ load_b:
                        mem[fentry->k] = X;
                        continue;
                default:
-                       /* Invalid instruction counts as RET */
+                       WARN_ON(1);
                        return 0;
                }
 
@@ -283,8 +284,8 @@ load_b:
  *
  * Check the user's filter code. If we let some ugly
  * filter code slip through kaboom! The filter must contain
- * no references or jumps that are out of range, no illegal instructions
- * and no backward jumps. It must end with a RET instruction
+ * no references or jumps that are out of range, no illegal
+ * instructions, and must end with a RET instruction.
  *
  * Returns 0 if the rule set is legal or a negative errno code if not.
  */
@@ -300,38 +301,85 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
        for (pc = 0; pc < flen; pc++) {
                /* all jumps are forward as they are not signed */
                ftest = &filter[pc];
-               if (BPF_CLASS(ftest->code) == BPF_JMP) {
-                       /* but they mustn't jump off the end */
-                       if (BPF_OP(ftest->code) == BPF_JA) {
-                               /*
-                                * Note, the large ftest->k might cause loops.
-                                * Compare this with conditional jumps below,
-                                * where offsets are limited. --ANK (981016)
-                                */
-                               if (ftest->k >= (unsigned)(flen-pc-1))
-                                       return -EINVAL;
-                       } else {
-                               /* for conditionals both must be safe */
-                               if (pc + ftest->jt +1 >= flen ||
-                                   pc + ftest->jf +1 >= flen)
-                                       return -EINVAL;
-                       }
-               }
 
-               /* check for division by zero   -Kris Katterjohn 2005-10-30 */
-               if (ftest->code == (BPF_ALU|BPF_DIV|BPF_K) && ftest->k == 0)
-                       return -EINVAL;
+               /* Only allow valid instructions */
+               switch (ftest->code) {
+               case BPF_ALU|BPF_ADD|BPF_K:
+               case BPF_ALU|BPF_ADD|BPF_X:
+               case BPF_ALU|BPF_SUB|BPF_K:
+               case BPF_ALU|BPF_SUB|BPF_X:
+               case BPF_ALU|BPF_MUL|BPF_K:
+               case BPF_ALU|BPF_MUL|BPF_X:
+               case BPF_ALU|BPF_DIV|BPF_X:
+               case BPF_ALU|BPF_AND|BPF_K:
+               case BPF_ALU|BPF_AND|BPF_X:
+               case BPF_ALU|BPF_OR|BPF_K:
+               case BPF_ALU|BPF_OR|BPF_X:
+               case BPF_ALU|BPF_LSH|BPF_K:
+               case BPF_ALU|BPF_LSH|BPF_X:
+               case BPF_ALU|BPF_RSH|BPF_K:
+               case BPF_ALU|BPF_RSH|BPF_X:
+               case BPF_ALU|BPF_NEG:
+               case BPF_LD|BPF_W|BPF_ABS:
+               case BPF_LD|BPF_H|BPF_ABS:
+               case BPF_LD|BPF_B|BPF_ABS:
+               case BPF_LD|BPF_W|BPF_LEN:
+               case BPF_LD|BPF_W|BPF_IND:
+               case BPF_LD|BPF_H|BPF_IND:
+               case BPF_LD|BPF_B|BPF_IND:
+               case BPF_LD|BPF_IMM:
+               case BPF_LDX|BPF_W|BPF_LEN:
+               case BPF_LDX|BPF_B|BPF_MSH:
+               case BPF_LDX|BPF_IMM:
+               case BPF_MISC|BPF_TAX:
+               case BPF_MISC|BPF_TXA:
+               case BPF_RET|BPF_K:
+               case BPF_RET|BPF_A:
+                       break;
+
+               /* Some instructions need special checks */
 
-               /* check that memory operations use valid addresses. */
-               if (ftest->k >= BPF_MEMWORDS) {
-                       /* but it might not be a memory operation... */
-                       switch (ftest->code) {
-                       case BPF_ST:    
-                       case BPF_STX:   
-                       case BPF_LD|BPF_MEM:    
-                       case BPF_LDX|BPF_MEM:   
+               case BPF_ALU|BPF_DIV|BPF_K:
+                       /* check for division by zero */
+                       if (ftest->k == 0)
                                return -EINVAL;
-                       }
+                       break;
+
+               case BPF_LD|BPF_MEM:
+               case BPF_LDX|BPF_MEM:
+               case BPF_ST:
+               case BPF_STX:
+                       /* check for invalid memory addresses */
+                       if (ftest->k >= BPF_MEMWORDS)
+                               return -EINVAL;
+                       break;
+
+               case BPF_JMP|BPF_JA:
+                       /*
+                        * Note, the large ftest->k might cause loops.
+                        * Compare this with conditional jumps below,
+                        * where offsets are limited. --ANK (981016)
+                        */
+                       if (ftest->k >= (unsigned)(flen-pc-1))
+                               return -EINVAL;
+                       break;
+
+               case BPF_JMP|BPF_JEQ|BPF_K:
+               case BPF_JMP|BPF_JEQ|BPF_X:
+               case BPF_JMP|BPF_JGE|BPF_K:
+               case BPF_JMP|BPF_JGE|BPF_X:
+               case BPF_JMP|BPF_JGT|BPF_K:
+               case BPF_JMP|BPF_JGT|BPF_X:
+               case BPF_JMP|BPF_JSET|BPF_K:
+               case BPF_JMP|BPF_JSET|BPF_X:
+                       /* for conditionals both must be safe */
+                       if (pc + ftest->jt + 1 >= flen ||
+                           pc + ftest->jf + 1 >= flen)
+                               return -EINVAL;
+                       break;
+
+               default:
+                       return -EINVAL;
                }
        }
 
index 7e95b39..c4f2538 100644 (file)
@@ -23,6 +23,7 @@
 #include <net/flow.h>
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
+#include <linux/security.h>
 
 struct flow_cache_entry {
        struct flow_cache_entry *next;
@@ -30,6 +31,7 @@ struct flow_cache_entry {
        u8                      dir;
        struct flowi            key;
        u32                     genid;
+       u32                     sk_sid;
        void                    *object;
        atomic_t                *object_ref;
 };
@@ -162,7 +164,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2)
        return 0;
 }
 
-void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
+void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
                        flow_resolve_t resolver)
 {
        struct flow_cache_entry *fle, **head;
@@ -186,6 +188,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
        for (fle = *head; fle; fle = fle->next) {
                if (fle->family == family &&
                    fle->dir == dir &&
+                   fle->sk_sid == sk_sid &&
                    flow_key_compare(key, &fle->key) == 0) {
                        if (fle->genid == atomic_read(&flow_cache_genid)) {
                                void *ret = fle->object;
@@ -210,6 +213,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
                        *head = fle;
                        fle->family = family;
                        fle->dir = dir;
+                       fle->sk_sid = sk_sid;
                        memcpy(&fle->key, key, sizeof(*key));
                        fle->object = NULL;
                        flow_count(cpu)++;
@@ -221,7 +225,7 @@ nocache:
                void *obj;
                atomic_t *obj_ref;
 
-               resolver(key, family, dir, &obj, &obj_ref);
+               resolver(key, sk_sid, family, dir, &obj, &obj_ref);
 
                if (fle) {
                        fle->genid = atomic_read(&flow_cache_genid);
index 49424a4..281a632 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/string.h>
+#include <linux/if_arp.h>
 #include <linux/inetdevice.h>
 #include <linux/inet.h>
 #include <linux/interrupt.h>
index 7fc3e9e..06cad2d 100644 (file)
@@ -487,9 +487,9 @@ static unsigned int fmt_ip6(char *s,const char ip[16]);
 
 /* Module parameters, defaults. */
 static int pg_count_d = 1000; /* 1000 pkts by default */
-static int pg_delay_d = 0;
-static int pg_clone_skb_d = 0;
-static int debug = 0;
+static int pg_delay_d;
+static int pg_clone_skb_d;
+static int debug;
 
 static DECLARE_MUTEX(pktgen_sem);
 static struct pktgen_thread *pktgen_threads = NULL;
index 83fee37..070f91c 100644 (file)
@@ -135,17 +135,13 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
 struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
                            int fclone)
 {
+       struct skb_shared_info *shinfo;
        struct sk_buff *skb;
        u8 *data;
 
        /* Get the HEAD */
-       if (fclone)
-               skb = kmem_cache_alloc(skbuff_fclone_cache,
-                                      gfp_mask & ~__GFP_DMA);
-       else
-               skb = kmem_cache_alloc(skbuff_head_cache,
-                                      gfp_mask & ~__GFP_DMA);
-
+       skb = kmem_cache_alloc(fclone ? skbuff_fclone_cache : skbuff_head_cache,
+                               gfp_mask & ~__GFP_DMA);
        if (!skb)
                goto out;
 
@@ -162,6 +158,16 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
        skb->data = data;
        skb->tail = data;
        skb->end  = data + size;
+       /* make sure we initialize shinfo sequentially */
+       shinfo = skb_shinfo(skb);
+       atomic_set(&shinfo->dataref, 1);
+       shinfo->nr_frags  = 0;
+       shinfo->tso_size = 0;
+       shinfo->tso_segs = 0;
+       shinfo->ufo_size = 0;
+       shinfo->ip6_frag_id = 0;
+       shinfo->frag_list = NULL;
+
        if (fclone) {
                struct sk_buff *child = skb + 1;
                atomic_t *fclone_ref = (atomic_t *) (child + 1);
@@ -171,13 +177,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 
                child->fclone = SKB_FCLONE_UNAVAILABLE;
        }
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags  = 0;
-       skb_shinfo(skb)->tso_size = 0;
-       skb_shinfo(skb)->tso_segs = 0;
-       skb_shinfo(skb)->frag_list = NULL;
-       skb_shinfo(skb)->ufo_size = 0;
-       skb_shinfo(skb)->ip6_frag_id = 0;
 out:
        return skb;
 nodata:
index 13cc3be..6465b0e 100644 (file)
@@ -1488,7 +1488,7 @@ int proto_register(struct proto *prot, int alloc_slab)
                        }
                }
 
-               if (prot->twsk_obj_size) {
+               if (prot->twsk_prot != NULL) {
                        static const char mask[] = "tw_sock_%s";
 
                        timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
@@ -1497,11 +1497,12 @@ int proto_register(struct proto *prot, int alloc_slab)
                                goto out_free_request_sock_slab;
 
                        sprintf(timewait_sock_slab_name, mask, prot->name);
-                       prot->twsk_slab = kmem_cache_create(timewait_sock_slab_name,
-                                                           prot->twsk_obj_size,
-                                                           0, SLAB_HWCACHE_ALIGN,
-                                                           NULL, NULL);
-                       if (prot->twsk_slab == NULL)
+                       prot->twsk_prot->twsk_slab =
+                               kmem_cache_create(timewait_sock_slab_name,
+                                                 prot->twsk_prot->twsk_obj_size,
+                                                 0, SLAB_HWCACHE_ALIGN,
+                                                 NULL, NULL);
+                       if (prot->twsk_prot->twsk_slab == NULL)
                                goto out_free_timewait_sock_slab_name;
                }
        }
@@ -1548,12 +1549,12 @@ void proto_unregister(struct proto *prot)
                prot->rsk_prot->slab = NULL;
        }
 
-       if (prot->twsk_slab != NULL) {
-               const char *name = kmem_cache_name(prot->twsk_slab);
+       if (prot->twsk_prot != NULL && prot->twsk_prot->twsk_slab != NULL) {
+               const char *name = kmem_cache_name(prot->twsk_prot->twsk_slab);
 
-               kmem_cache_destroy(prot->twsk_slab);
+               kmem_cache_destroy(prot->twsk_prot->twsk_slab);
                kfree(name);
-               prot->twsk_slab = NULL;
+               prot->twsk_prot->twsk_slab = NULL;
        }
 }
 
index 15bfd03..35e2525 100644 (file)
@@ -55,8 +55,9 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
        int done;
 
        do {
-               if (sk->sk_err)
-                       return sock_error(sk);
+               int err = sock_error(sk);
+               if (err)
+                       return err;
                if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
                        return -EPIPE;
                if (!*timeo_p)
@@ -67,6 +68,7 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
                prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
                sk->sk_write_pending++;
                done = sk_wait_event(sk, timeo_p,
+                                    !sk->sk_err &&
                                     !((1 << sk->sk_state) & 
                                       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
                finish_wait(sk->sk_sleep, &wait);
@@ -137,7 +139,9 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
 
                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
                sk->sk_write_pending++;
-               sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) &&
+               sk_wait_event(sk, &current_timeo, !sk->sk_err && 
+                                                 !(sk->sk_shutdown & SEND_SHUTDOWN) &&
+                                                 sk_stream_memory_free(sk) &&
                                                  vm_wait);
                sk->sk_write_pending--;
 
index 344a8da..87b27ff 100644 (file)
@@ -1,3 +1,7 @@
+obj-$(CONFIG_IPV6) += dccp_ipv6.o
+
+dccp_ipv6-y := ipv6.o
+
 obj-$(CONFIG_IP_DCCP) += dccp.o
 
 dccp-y := ccid.o input.o ipv4.o minisocks.o options.o output.o proto.o \
index c9a62cc..ce9cb77 100644 (file)
@@ -55,8 +55,8 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
        from = av->dccpav_buf + av->dccpav_buf_head;
 
        /* Check if buf_head wraps */
-       if (av->dccpav_buf_head + len > av->dccpav_vec_len) {
-               const u32 tailsize = (av->dccpav_vec_len - av->dccpav_buf_head);
+       if ((int)av->dccpav_buf_head + len > av->dccpav_vec_len) {
+               const u32 tailsize = av->dccpav_vec_len - av->dccpav_buf_head;
 
                memcpy(to, from, tailsize);
                to   += tailsize;
@@ -93,8 +93,14 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
 struct dccp_ackvec *dccp_ackvec_alloc(const unsigned int len,
                                      const gfp_t priority)
 {
-       struct dccp_ackvec *av = kmalloc(sizeof(*av) + len, priority);
+       struct dccp_ackvec *av;
 
+       BUG_ON(len == 0);
+
+       if (len > DCCP_MAX_ACKVEC_LEN)
+               return NULL;
+
+       av = kmalloc(sizeof(*av) + len, priority);
        if (av != NULL) {
                av->dccpav_buf_len      = len;
                av->dccpav_buf_head     =
@@ -117,13 +123,13 @@ void dccp_ackvec_free(struct dccp_ackvec *av)
 }
 
 static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
-                                  const unsigned int index)
+                                  const u8 index)
 {
        return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK;
 }
 
 static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
-                                const unsigned int index)
+                                const u8 index)
 {
        return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK;
 }
@@ -135,7 +141,7 @@ static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
  */
 static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
                                                 const unsigned int packets,
-                                                 const unsigned char state)
+                                                const unsigned char state)
 {
        unsigned int gap;
        signed long new_head;
@@ -223,7 +229,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
                 *      could reduce the complexity of this scan.)
                 */
                u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
-               unsigned int index = av->dccpav_buf_head;
+               u8 index = av->dccpav_buf_head;
 
                while (1) {
                        const u8 len = dccp_ackvec_len(av, index);
@@ -291,7 +297,7 @@ void dccp_ackvec_print(const struct dccp_ackvec *av)
 }
 #endif
 
-static void dccp_ackvec_trow_away_ack_record(struct dccp_ackvec *av)
+static void dccp_ackvec_throw_away_ack_record(struct dccp_ackvec *av)
 {
        /*
         * As we're keeping track of the ack vector size (dccpav_vec_len) and
@@ -301,9 +307,10 @@ static void dccp_ackvec_trow_away_ack_record(struct dccp_ackvec *av)
         * draft-ietf-dccp-spec-11.txt Appendix A. -acme
         */
 #if 0
-       av->dccpav_buf_tail = av->dccpav_ack_ptr + 1;
-       if (av->dccpav_buf_tail >= av->dccpav_vec_len)
-               av->dccpav_buf_tail -= av->dccpav_vec_len;
+       u32 new_buf_tail = av->dccpav_ack_ptr + 1;
+       if (new_buf_tail >= av->dccpav_vec_len)
+               new_buf_tail -= av->dccpav_vec_len;
+       av->dccpav_buf_tail = new_buf_tail;
 #endif
        av->dccpav_vec_len -= av->dccpav_sent_len;
 }
@@ -326,7 +333,7 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk,
                              debug_prefix, 1,
                              (unsigned long long)av->dccpav_ack_seqno,
                              (unsigned long long)av->dccpav_ack_ackno);
-               dccp_ackvec_trow_away_ack_record(av);
+               dccp_ackvec_throw_away_ack_record(av);
                av->dccpav_ack_seqno = DCCP_MAX_SEQNO + 1;
        }
 }
@@ -389,7 +396,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
                                              av->dccpav_ack_seqno,
                                              (unsigned long long)
                                              av->dccpav_ack_ackno);
-                               dccp_ackvec_trow_away_ack_record(av);
+                               dccp_ackvec_throw_away_ack_record(av);
                        }
                        /*
                         * If dccpav_ack_seqno was not received, no problem
index d0fd6c6..f7dfb5f 100644 (file)
  * @dccpav_buf - circular buffer of acknowledgeable packets
  */
 struct dccp_ackvec {
-       unsigned int    dccpav_buf_head;
-       unsigned int    dccpav_buf_tail;
        u64             dccpav_buf_ackno;
        u64             dccpav_ack_seqno;
        u64             dccpav_ack_ackno;
-       unsigned int    dccpav_ack_ptr;
-       unsigned int    dccpav_sent_len;
-       unsigned int    dccpav_vec_len;
-       unsigned int    dccpav_buf_len;
        struct timeval  dccpav_time;
+       u8              dccpav_buf_head;
+       u8              dccpav_buf_tail;
+       u8              dccpav_ack_ptr;
+       u8              dccpav_sent_len;
+       u8              dccpav_vec_len;
+       u8              dccpav_buf_len;
        u8              dccpav_buf_nonce;
        u8              dccpav_ack_nonce;
        u8              dccpav_buf[0];
index c37eeea..de681c6 100644 (file)
@@ -21,6 +21,8 @@
 
 #define CCID_MAX 255
 
+struct tcp_info;
+
 struct ccid {
        unsigned char   ccid_id;
        const char      *ccid_name;
index f97b85d..93f26dd 100644 (file)
@@ -59,7 +59,7 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo);
 
 #define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */
 
-extern struct proto dccp_v4_prot;
+extern struct proto dccp_prot;
 
 /* is seq1 < seq2 ? */
 static inline int before48(const u64 seq1, const u64 seq2)
@@ -228,6 +228,9 @@ extern int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                const struct dccp_hdr *dh, const unsigned len);
 
+extern int dccp_v4_init_sock(struct sock *sk);
+extern int dccp_v4_destroy_sock(struct sock *sk);
+
 extern void            dccp_close(struct sock *sk, long timeout);
 extern struct sk_buff  *dccp_make_response(struct sock *sk,
                                            struct dst_entry *dst,
@@ -238,6 +241,7 @@ extern struct sk_buff       *dccp_make_reset(struct sock *sk,
 
 extern int        dccp_connect(struct sock *sk);
 extern int        dccp_disconnect(struct sock *sk, int flags);
+extern void       dccp_unhash(struct sock *sk);
 extern int        dccp_getsockopt(struct sock *sk, int level, int optname,
                                   char __user *optval, int __user *optlen);
 extern int        dccp_setsockopt(struct sock *sk, int level, int optname,
@@ -249,6 +253,13 @@ extern int    dccp_recvmsg(struct kiocb *iocb, struct sock *sk,
                                struct msghdr *msg, size_t len, int nonblock,
                                int flags, int *addr_len);
 extern void       dccp_shutdown(struct sock *sk, int how);
+extern int        inet_dccp_listen(struct socket *sock, int backlog);
+extern unsigned int dccp_poll(struct file *file, struct socket *sock,
+                            poll_table *wait);
+extern void       dccp_v4_send_check(struct sock *sk, int len,
+                                     struct sk_buff *skb);
+extern int        dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
+                                  int addr_len);
 
 extern int        dccp_v4_checksum(const struct sk_buff *skb,
                                    const u32 saddr, const u32 daddr);
@@ -256,6 +267,17 @@ extern int    dccp_v4_checksum(const struct sk_buff *skb,
 extern int        dccp_v4_send_reset(struct sock *sk,
                                      enum dccp_reset_codes code);
 extern void       dccp_send_close(struct sock *sk, const int active);
+extern int        dccp_invalid_packet(struct sk_buff *skb);
+
+static inline int dccp_bad_service_code(const struct sock *sk,
+                                       const __u32 service)
+{
+       const struct dccp_sock *dp = dccp_sk(sk);
+
+       if (dp->dccps_service == service)
+               return 0;
+       return !dccp_list_has_service(dp->dccps_service_list, service);
+}
 
 struct dccp_skb_cb {
        __u8  dccpd_type:4;
index f675d8e..3f78c00 100644 (file)
@@ -28,7 +28,7 @@ static void dccp_get_info(struct sock *sk, struct tcp_info *info)
        info->tcpi_retransmits  = icsk->icsk_retransmits;
        info->tcpi_probes       = icsk->icsk_probes_out;
        info->tcpi_backoff      = icsk->icsk_backoff;
-       info->tcpi_pmtu         = dp->dccps_pmtu_cookie;
+       info->tcpi_pmtu         = icsk->icsk_pmtu_cookie;
 
        if (dp->dccps_options.dccpo_send_ack_vector)
                info->tcpi_options |= TCPI_OPT_SACK;
index 3454d59..b6cba72 100644 (file)
@@ -151,29 +151,12 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
-                        const struct dccp_hdr *dh, const unsigned len)
+static inline int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+                                        const struct dccp_hdr *dh,
+                                        const unsigned len)
 {
        struct dccp_sock *dp = dccp_sk(sk);
 
-       if (dccp_check_seqno(sk, skb))
-               goto discard;
-
-       if (dccp_parse_options(sk, skb))
-               goto discard;
-
-       if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
-               dccp_event_ack_recv(sk, skb);
-
-       if (dp->dccps_options.dccpo_send_ack_vector &&
-           dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
-                           DCCP_SKB_CB(skb)->dccpd_seq,
-                           DCCP_ACKVEC_STATE_RECEIVED))
-               goto discard;
-
-       ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-       ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
        switch (dccp_hdr(skb)->dccph_type) {
        case DCCP_PKT_DATAACK:
        case DCCP_PKT_DATA:
@@ -250,6 +233,37 @@ discard:
        return 0;
 }
 
+int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+                        const struct dccp_hdr *dh, const unsigned len)
+{
+       struct dccp_sock *dp = dccp_sk(sk);
+
+       if (dccp_check_seqno(sk, skb))
+               goto discard;
+
+       if (dccp_parse_options(sk, skb))
+               goto discard;
+
+       if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+               dccp_event_ack_recv(sk, skb);
+
+       if (dp->dccps_options.dccpo_send_ack_vector &&
+           dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+                           DCCP_SKB_CB(skb)->dccpd_seq,
+                           DCCP_ACKVEC_STATE_RECEIVED))
+               goto discard;
+
+       ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+       ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
+
+       return __dccp_rcv_established(sk, skb, dh, len);
+discard:
+       __kfree_skb(skb);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(dccp_rcv_established);
+
 static int dccp_rcv_request_sent_state_process(struct sock *sk,
                                               struct sk_buff *skb,
                                               const struct dccp_hdr *dh,
@@ -286,6 +300,12 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                        goto out_invalid_packet;
                }
 
+                if (dp->dccps_options.dccpo_send_ack_vector &&
+                    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+                                    DCCP_SKB_CB(skb)->dccpd_seq,
+                                    DCCP_ACKVEC_STATE_RECEIVED))
+                        goto out_invalid_packet; /* FIXME: change error code */
+
                dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
                dccp_update_gsr(sk, dp->dccps_isr);
                /*
@@ -309,7 +329,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                        goto out_invalid_packet;
                }
 
-               dccp_sync_mss(sk, dp->dccps_pmtu_cookie);
+               dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 
                /*
                 *    Step 10: Process REQUEST state (second part)
@@ -329,7 +349,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                dccp_set_state(sk, DCCP_PARTOPEN);
 
                /* Make sure socket is routed, for correct metrics. */
-               inet_sk_rebuild_header(sk);
+               icsk->icsk_af_ops->rebuild_header(sk);
 
                if (!sock_flag(sk, SOCK_DEAD)) {
                        sk->sk_state_change(sk);
@@ -398,9 +418,9 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
 
                if (dh->dccph_type == DCCP_PKT_DATAACK ||
                    dh->dccph_type == DCCP_PKT_DATA) {
-                       dccp_rcv_established(sk, skb, dh, len);
+                       __dccp_rcv_established(sk, skb, dh, len);
                        queued = 1; /* packet was queued
-                                      (by dccp_rcv_established) */
+                                      (by __dccp_rcv_established) */
                }
                break;
        }
@@ -444,7 +464,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
         */
        if (sk->sk_state == DCCP_LISTEN) {
                if (dh->dccph_type == DCCP_PKT_REQUEST) {
-                       if (dccp_v4_conn_request(sk, skb) < 0)
+                       if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
+                                                                   skb) < 0)
                                return 1;
 
                        /* FIXME: do congestion control initialization */
@@ -471,14 +492,14 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
                        dccp_event_ack_recv(sk, skb);
 
-               ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-               ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
                if (dp->dccps_options.dccpo_send_ack_vector &&
                    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
                                    DCCP_SKB_CB(skb)->dccpd_seq,
                                    DCCP_ACKVEC_STATE_RECEIVED))
                        goto discard;
+
+               ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+               ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
        }
 
        /*
@@ -566,3 +587,5 @@ discard:
        }
        return 0;
 }
+
+EXPORT_SYMBOL_GPL(dccp_rcv_state_process);
index 656e13e..3f24467 100644 (file)
@@ -19,7 +19,9 @@
 
 #include <net/icmp.h>
 #include <net/inet_hashtables.h>
+#include <net/inet_sock.h>
 #include <net/sock.h>
+#include <net/timewait_sock.h>
 #include <net/tcp_states.h>
 #include <net/xfrm.h>
 
@@ -37,7 +39,8 @@ EXPORT_SYMBOL_GPL(dccp_hashinfo);
 
 static int dccp_v4_get_port(struct sock *sk, const unsigned short snum)
 {
-       return inet_csk_get_port(&dccp_hashinfo, sk, snum);
+       return inet_csk_get_port(&dccp_hashinfo, sk, snum,
+                                inet_csk_bind_conflict);
 }
 
 static void dccp_v4_hash(struct sock *sk)
@@ -45,171 +48,14 @@ static void dccp_v4_hash(struct sock *sk)
        inet_hash(&dccp_hashinfo, sk);
 }
 
-static void dccp_v4_unhash(struct sock *sk)
+void dccp_unhash(struct sock *sk)
 {
        inet_unhash(&dccp_hashinfo, sk);
 }
 
-/* called with local bh disabled */
-static int __dccp_v4_check_established(struct sock *sk, const __u16 lport,
-                                     struct inet_timewait_sock **twp)
-{
-       struct inet_sock *inet = inet_sk(sk);
-       const u32 daddr = inet->rcv_saddr;
-       const u32 saddr = inet->daddr;
-       const int dif = sk->sk_bound_dev_if;
-       INET_ADDR_COOKIE(acookie, saddr, daddr)
-       const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-       unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
-       struct inet_ehash_bucket *head = inet_ehash_bucket(&dccp_hashinfo, hash);
-       const struct sock *sk2;
-       const struct hlist_node *node;
-       struct inet_timewait_sock *tw;
-
-       prefetch(head->chain.first);
-       write_lock(&head->lock);
-
-       /* Check TIME-WAIT sockets first. */
-       sk_for_each(sk2, node, &(head + dccp_hashinfo.ehash_size)->chain) {
-               tw = inet_twsk(sk2);
-
-               if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-                       goto not_unique;
-       }
-       tw = NULL;
-
-       /* And established part... */
-       sk_for_each(sk2, node, &head->chain) {
-               if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-                       goto not_unique;
-       }
+EXPORT_SYMBOL_GPL(dccp_unhash);
 
-       /* Must record num and sport now. Otherwise we will see
-        * in hash table socket with a funny identity. */
-       inet->num = lport;
-       inet->sport = htons(lport);
-       sk->sk_hash = hash;
-       BUG_TRAP(sk_unhashed(sk));
-       __sk_add_node(sk, &head->chain);
-       sock_prot_inc_use(sk->sk_prot);
-       write_unlock(&head->lock);
-
-       if (twp != NULL) {
-               *twp = tw;
-               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-       } else if (tw != NULL) {
-               /* Silly. Should hash-dance instead... */
-               inet_twsk_deschedule(tw, &dccp_death_row);
-               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-               inet_twsk_put(tw);
-       }
-
-       return 0;
-
-not_unique:
-       write_unlock(&head->lock);
-       return -EADDRNOTAVAIL;
-}
-
-/*
- * Bind a port for a connect operation and hash it.
- */
-static int dccp_v4_hash_connect(struct sock *sk)
-{
-       const unsigned short snum = inet_sk(sk)->num;
-       struct inet_bind_hashbucket *head;
-       struct inet_bind_bucket *tb;
-       int ret;
-
-       if (snum == 0) {
-               int low = sysctl_local_port_range[0];
-               int high = sysctl_local_port_range[1];
-               int remaining = (high - low) + 1;
-               int rover = net_random() % (high - low) + low;
-               struct hlist_node *node;
-               struct inet_timewait_sock *tw = NULL;
-
-               local_bh_disable();
-               do {
-                       head = &dccp_hashinfo.bhash[inet_bhashfn(rover,
-                                                   dccp_hashinfo.bhash_size)];
-                       spin_lock(&head->lock);
-
-                       /* Does not bother with rcv_saddr checks,
-                        * because the established check is already
-                        * unique enough.
-                        */
-                       inet_bind_bucket_for_each(tb, node, &head->chain) {
-                               if (tb->port == rover) {
-                                       BUG_TRAP(!hlist_empty(&tb->owners));
-                                       if (tb->fastreuse >= 0)
-                                               goto next_port;
-                                       if (!__dccp_v4_check_established(sk,
-                                                                        rover,
-                                                                        &tw))
-                                               goto ok;
-                                       goto next_port;
-                               }
-                       }
-
-                       tb = inet_bind_bucket_create(dccp_hashinfo.bind_bucket_cachep,
-                                                    head, rover);
-                       if (tb == NULL) {
-                               spin_unlock(&head->lock);
-                               break;
-                       }
-                       tb->fastreuse = -1;
-                       goto ok;
-
-               next_port:
-                       spin_unlock(&head->lock);
-                       if (++rover > high)
-                               rover = low;
-               } while (--remaining > 0);
-
-               local_bh_enable();
-
-               return -EADDRNOTAVAIL;
-
-ok:
-               /* All locks still held and bhs disabled */
-               inet_bind_hash(sk, tb, rover);
-               if (sk_unhashed(sk)) {
-                       inet_sk(sk)->sport = htons(rover);
-                       __inet_hash(&dccp_hashinfo, sk, 0);
-               }
-               spin_unlock(&head->lock);
-
-               if (tw != NULL) {
-                       inet_twsk_deschedule(tw, &dccp_death_row);
-                       inet_twsk_put(tw);
-               }
-
-               ret = 0;
-               goto out;
-       }
-
-       head = &dccp_hashinfo.bhash[inet_bhashfn(snum,
-                                                dccp_hashinfo.bhash_size)];
-       tb   = inet_csk(sk)->icsk_bind_hash;
-       spin_lock_bh(&head->lock);
-       if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
-               __inet_hash(&dccp_hashinfo, sk, 0);
-               spin_unlock_bh(&head->lock);
-               return 0;
-       } else {
-               spin_unlock(&head->lock);
-               /* No definite answer... Walk to established hash table */
-               ret = __dccp_v4_check_established(sk, snum, NULL);
-out:
-               local_bh_enable();
-               return ret;
-       }
-}
-
-static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
-                          int addr_len)
+int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct dccp_sock *dp = dccp_sk(sk);
@@ -259,9 +105,9 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
        inet->dport = usin->sin_port;
        inet->daddr = daddr;
 
-       dp->dccps_ext_header_len = 0;
+       inet_csk(sk)->icsk_ext_hdr_len = 0;
        if (inet->opt != NULL)
-               dp->dccps_ext_header_len = inet->opt->optlen;
+               inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
        /*
         * Socket identity is still unknown (sport may be zero).
         * However we set state to DCCP_REQUESTING and not releasing socket
@@ -269,7 +115,7 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
         * complete initialization after this.
         */
        dccp_set_state(sk, DCCP_REQUESTING);
-       err = dccp_v4_hash_connect(sk);
+       err = inet_hash_connect(&dccp_death_row, sk);
        if (err != 0)
                goto failure;
 
@@ -287,16 +133,6 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
                                                            usin->sin_port);
        dccp_update_gss(sk, dp->dccps_iss);
 
-       /*
-        * SWL and AWL are initially adjusted so that they are not less than
-        * the initial Sequence Numbers received and sent, respectively:
-        *      SWL := max(GSR + 1 - floor(W/4), ISR),
-        *      AWL := max(GSS - W' + 1, ISS).
-        * These adjustments MUST be applied only at the beginning of the
-        * connection.
-        */
-       dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
-
        inet->id = dp->dccps_iss ^ jiffies;
 
        err = dccp_connect(sk);
@@ -316,6 +152,8 @@ failure:
        goto out;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_connect);
+
 /*
  * This routine does path mtu discovery as defined in RFC1191.
  */
@@ -354,7 +192,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
        mtu = dst_mtu(dst);
 
        if (inet->pmtudisc != IP_PMTUDISC_DONT &&
-           dp->dccps_pmtu_cookie > mtu) {
+           inet_csk(sk)->icsk_pmtu_cookie > mtu) {
                dccp_sync_mss(sk, mtu);
 
                /*
@@ -606,6 +444,17 @@ out:
        sock_put(sk);
 }
 
+/* This routine computes an IPv4 DCCP checksum. */
+void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
+{
+       const struct inet_sock *inet = inet_sk(sk);
+       struct dccp_hdr *dh = dccp_hdr(skb);
+
+       dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr);
+}
+
+EXPORT_SYMBOL_GPL(dccp_v4_send_check);
+
 int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
 {
        struct sk_buff *skb;
@@ -641,16 +490,6 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk,
                                           dccp_hdr(skb)->dccph_sport);
 }
 
-static inline int dccp_bad_service_code(const struct sock *sk,
-                                       const __u32 service)
-{
-       const struct dccp_sock *dp = dccp_sk(sk);
-
-       if (dp->dccps_service == service)
-               return 0;
-       return !dccp_list_has_service(dp->dccps_service_list, service);
-}
-
 int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
        struct inet_request_sock *ireq;
@@ -662,7 +501,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
        struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
        __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
-       struct dst_entry *dst = NULL;
 
        /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
        if (((struct rtable *)skb->dst)->rt_flags &
@@ -703,7 +541,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        ireq = inet_rsk(req);
        ireq->loc_addr = daddr;
        ireq->rmt_addr = saddr;
-       /* FIXME: Merge Aristeu's option parsing code when ready */
        req->rcv_wnd    = 100; /* Fake, option parsing will get the
                                  right value */
        ireq->opt       = NULL;
@@ -721,23 +558,22 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        dreq->dreq_iss     = dccp_v4_init_sequence(sk, skb);
        dreq->dreq_service = service;
 
-       if (dccp_v4_send_response(sk, req, dst))
+       if (dccp_v4_send_response(sk, req, NULL))
                goto drop_and_free;
 
        inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
        return 0;
 
 drop_and_free:
-       /*
-        * FIXME: should be reqsk_free after implementing req->rsk_ops
-        */
-       __reqsk_free(req);
+       reqsk_free(req);
 drop:
        DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
        dcb->dccpd_reset_code = reset_code;
        return -1;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_conn_request);
+
 /*
  * The three way handshake has completed - we got a valid ACK or DATAACK -
  * now create the new socket.
@@ -792,6 +628,8 @@ exit:
        return NULL;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock);
+
 static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
 {
        const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -1011,7 +849,9 @@ discard:
        return 0;
 }
 
-static inline int dccp_invalid_packet(struct sk_buff *skb)
+EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
+
+int dccp_invalid_packet(struct sk_buff *skb)
 {
        const struct dccp_hdr *dh;
 
@@ -1065,29 +905,30 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
                return 1;
        }
 
-       /* If the header checksum is incorrect, drop packet and return */
-       if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
-                                   skb->nh.iph->daddr) < 0) {
-               LIMIT_NETDEBUG(KERN_WARNING "DCCP: header checksum is "
-                                           "incorrect\n");
-               return 1;
-       }
-
        return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_invalid_packet);
+
 /* this is called when real data arrives */
 int dccp_v4_rcv(struct sk_buff *skb)
 {
        const struct dccp_hdr *dh;
        struct sock *sk;
-       int rc;
 
        /* Step 1: Check header basics: */
 
        if (dccp_invalid_packet(skb))
                goto discard_it;
 
+       /* If the header checksum is incorrect, drop packet and return */
+       if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
+                                   skb->nh.iph->daddr) < 0) {
+               LIMIT_NETDEBUG(KERN_WARNING "%s: incorrect header checksum\n",
+                              __FUNCTION__);
+               goto discard_it;
+       }
+
        dh = dccp_hdr(skb);
 
        DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
@@ -1143,28 +984,10 @@ int dccp_v4_rcv(struct sk_buff *skb)
                 goto do_time_wait;
        }
 
-       if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
-               dccp_pr_debug("xfrm4_policy_check failed\n");
+       if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_and_relse;
-       }
-
-        if (sk_filter(sk, skb, 0)) {
-               dccp_pr_debug("sk_filter failed\n");
-                goto discard_and_relse;
-       }
-
-       skb->dev = NULL;
-
-       bh_lock_sock(sk);
-       rc = 0;
-       if (!sock_owned_by_user(sk))
-               rc = dccp_v4_do_rcv(sk, skb);
-       else
-               sk_add_backlog(sk, skb);
-       bh_unlock_sock(sk);
 
-       sock_put(sk);
-       return rc;
+       return sk_receive_skb(sk, skb);
 
 no_dccp_socket:
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
@@ -1194,9 +1017,23 @@ do_time_wait:
        goto no_dccp_socket;
 }
 
-static int dccp_v4_init_sock(struct sock *sk)
+struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
+       .queue_xmit     = ip_queue_xmit,
+       .send_check     = dccp_v4_send_check,
+       .rebuild_header = inet_sk_rebuild_header,
+       .conn_request   = dccp_v4_conn_request,
+       .syn_recv_sock  = dccp_v4_request_recv_sock,
+       .net_header_len = sizeof(struct iphdr),
+       .setsockopt     = ip_setsockopt,
+       .getsockopt     = ip_getsockopt,
+       .addr2sockaddr  = inet_csk_addr2sockaddr,
+       .sockaddr_len   = sizeof(struct sockaddr_in),
+};
+
+int dccp_v4_init_sock(struct sock *sk)
 {
        struct dccp_sock *dp = dccp_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        static int dccp_ctl_socket_init = 1;
 
        dccp_options_init(&dp->dccps_options);
@@ -1236,9 +1073,11 @@ static int dccp_v4_init_sock(struct sock *sk)
                dccp_ctl_socket_init = 0;
 
        dccp_init_xmit_timers(sk);
-       inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT;
+       icsk->icsk_rto = DCCP_TIMEOUT_INIT;
        sk->sk_state = DCCP_CLOSED;
        sk->sk_write_space = dccp_write_space;
+       icsk->icsk_af_ops = &dccp_ipv4_af_ops;
+       icsk->icsk_sync_mss = dccp_sync_mss;
        dp->dccps_mss_cache = 536;
        dp->dccps_role = DCCP_ROLE_UNDEFINED;
        dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
@@ -1246,7 +1085,9 @@ static int dccp_v4_init_sock(struct sock *sk)
        return 0;
 }
 
-static int dccp_v4_destroy_sock(struct sock *sk)
+EXPORT_SYMBOL_GPL(dccp_v4_init_sock);
+
+int dccp_v4_destroy_sock(struct sock *sk)
 {
        struct dccp_sock *dp = dccp_sk(sk);
 
@@ -1279,6 +1120,8 @@ static int dccp_v4_destroy_sock(struct sock *sk)
        return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_destroy_sock);
+
 static void dccp_v4_reqsk_destructor(struct request_sock *req)
 {
        kfree(inet_rsk(req)->opt);
@@ -1293,7 +1136,11 @@ static struct request_sock_ops dccp_request_sock_ops = {
        .send_reset     = dccp_v4_ctl_send_reset,
 };
 
-struct proto dccp_v4_prot = {
+static struct timewait_sock_ops dccp_timewait_sock_ops = {
+       .twsk_obj_size  = sizeof(struct inet_timewait_sock),
+};
+
+struct proto dccp_prot = {
        .name                   = "DCCP",
        .owner                  = THIS_MODULE,
        .close                  = dccp_close,
@@ -1307,7 +1154,7 @@ struct proto dccp_v4_prot = {
        .recvmsg                = dccp_recvmsg,
        .backlog_rcv            = dccp_v4_do_rcv,
        .hash                   = dccp_v4_hash,
-       .unhash                 = dccp_v4_unhash,
+       .unhash                 = dccp_unhash,
        .accept                 = inet_csk_accept,
        .get_port               = dccp_v4_get_port,
        .shutdown               = dccp_shutdown,
@@ -1316,5 +1163,7 @@ struct proto dccp_v4_prot = {
        .max_header             = MAX_DCCP_HEADER,
        .obj_size               = sizeof(struct dccp_sock),
        .rsk_prot               = &dccp_request_sock_ops,
-       .twsk_obj_size          = sizeof(struct inet_timewait_sock),
+       .twsk_prot              = &dccp_timewait_sock_ops,
 };
+
+EXPORT_SYMBOL_GPL(dccp_prot);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
new file mode 100644 (file)
index 0000000..c609dc7
--- /dev/null
@@ -0,0 +1,1261 @@
+/*
+ *     DCCP over IPv6
+ *     Linux INET6 implementation 
+ *
+ *     Based on net/dccp6/ipv6.c
+ *
+ *     Arnaldo Carvalho de Melo <acme@ghostprotocols.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.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/xfrm.h>
+
+#include <net/addrconf.h>
+#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
+#include <net/inet_sock.h>
+#include <net/inet6_connection_sock.h>
+#include <net/inet6_hashtables.h>
+#include <net/ip6_route.h>
+#include <net/ipv6.h>
+#include <net/protocol.h>
+#include <net/transp_v6.h>
+#include <net/xfrm.h>
+
+#include "dccp.h"
+#include "ipv6.h"
+
+static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
+static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
+                                  struct request_sock *req);
+static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb);
+
+static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
+
+static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
+static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
+
+static int dccp_v6_get_port(struct sock *sk, unsigned short snum)
+{
+       return inet_csk_get_port(&dccp_hashinfo, sk, snum,
+                                inet6_csk_bind_conflict);
+}
+
+static void dccp_v6_hash(struct sock *sk)
+{
+       if (sk->sk_state != DCCP_CLOSED) {
+               if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) {
+                       dccp_prot.hash(sk);
+                       return;
+               }
+               local_bh_disable();
+               __inet6_hash(&dccp_hashinfo, sk);
+               local_bh_enable();
+       }
+}
+
+static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len,
+                               struct in6_addr *saddr, 
+                               struct in6_addr *daddr, 
+                               unsigned long base)
+{
+       return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base);
+}
+
+static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
+{
+       const struct dccp_hdr *dh = dccp_hdr(skb);
+
+       if (skb->protocol == htons(ETH_P_IPV6))
+               return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
+                                                   skb->nh.ipv6h->saddr.s6_addr32,
+                                                   dh->dccph_dport,
+                                                   dh->dccph_sport);
+       else
+               return secure_dccp_sequence_number(skb->nh.iph->daddr,
+                                                  skb->nh.iph->saddr,
+                                                  dh->dccph_dport,
+                                                  dh->dccph_sport);
+}
+
+static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
+                          int addr_len)
+{
+       struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
+       struct inet_connection_sock *icsk = inet_csk(sk);
+       struct inet_sock *inet = inet_sk(sk);
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct dccp_sock *dp = dccp_sk(sk);
+       struct in6_addr *saddr = NULL, *final_p = NULL, final;
+       struct flowi fl;
+       struct dst_entry *dst;
+       int addr_type;
+       int err;
+
+       dp->dccps_role = DCCP_ROLE_CLIENT;
+
+       if (addr_len < SIN6_LEN_RFC2133) 
+               return -EINVAL;
+
+       if (usin->sin6_family != AF_INET6) 
+               return -EAFNOSUPPORT;
+
+       memset(&fl, 0, sizeof(fl));
+
+       if (np->sndflow) {
+               fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
+               IP6_ECN_flow_init(fl.fl6_flowlabel);
+               if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
+                       struct ip6_flowlabel *flowlabel;
+                       flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+                       if (flowlabel == NULL)
+                               return -EINVAL;
+                       ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
+                       fl6_sock_release(flowlabel);
+               }
+       }
+
+       /*
+        *      connect() to INADDR_ANY means loopback (BSD'ism).
+        */
+       
+       if (ipv6_addr_any(&usin->sin6_addr))
+               usin->sin6_addr.s6_addr[15] = 0x1; 
+
+       addr_type = ipv6_addr_type(&usin->sin6_addr);
+
+       if(addr_type & IPV6_ADDR_MULTICAST)
+               return -ENETUNREACH;
+
+       if (addr_type & IPV6_ADDR_LINKLOCAL) {
+               if (addr_len >= sizeof(struct sockaddr_in6) &&
+                   usin->sin6_scope_id) {
+                       /* If interface is set while binding, indices
+                        * must coincide.
+                        */
+                       if (sk->sk_bound_dev_if &&
+                           sk->sk_bound_dev_if != usin->sin6_scope_id)
+                               return -EINVAL;
+
+                       sk->sk_bound_dev_if = usin->sin6_scope_id;
+               }
+
+               /* Connect to link-local address requires an interface */
+               if (!sk->sk_bound_dev_if)
+                       return -EINVAL;
+       }
+
+       ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
+       np->flow_label = fl.fl6_flowlabel;
+
+       /*
+        *      DCCP over IPv4
+        */
+
+       if (addr_type == IPV6_ADDR_MAPPED) {
+               u32 exthdrlen = icsk->icsk_ext_hdr_len;
+               struct sockaddr_in sin;
+
+               SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
+
+               if (__ipv6_only_sock(sk))
+                       return -ENETUNREACH;
+
+               sin.sin_family = AF_INET;
+               sin.sin_port = usin->sin6_port;
+               sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
+
+               icsk->icsk_af_ops = &dccp_ipv6_mapped;
+               sk->sk_backlog_rcv = dccp_v4_do_rcv;
+
+               err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
+
+               if (err) {
+                       icsk->icsk_ext_hdr_len = exthdrlen;
+                       icsk->icsk_af_ops = &dccp_ipv6_af_ops;
+                       sk->sk_backlog_rcv = dccp_v6_do_rcv;
+                       goto failure;
+               } else {
+                       ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
+                                     inet->saddr);
+                       ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
+                                     inet->rcv_saddr);
+               }
+
+               return err;
+       }
+
+       if (!ipv6_addr_any(&np->rcv_saddr))
+               saddr = &np->rcv_saddr;
+
+       fl.proto = IPPROTO_DCCP;
+       ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+       ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
+       fl.oif = sk->sk_bound_dev_if;
+       fl.fl_ip_dport = usin->sin6_port;
+       fl.fl_ip_sport = inet->sport;
+
+       if (np->opt && np->opt->srcrt) {
+               struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+               ipv6_addr_copy(&final, &fl.fl6_dst);
+               ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+               final_p = &final;
+       }
+
+       err = ip6_dst_lookup(sk, &dst, &fl);
+       if (err)
+               goto failure;
+       if (final_p)
+               ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+               goto failure;
+
+       if (saddr == NULL) {
+               saddr = &fl.fl6_src;
+               ipv6_addr_copy(&np->rcv_saddr, saddr);
+       }
+
+       /* set the source address */
+       ipv6_addr_copy(&np->saddr, saddr);
+       inet->rcv_saddr = LOOPBACK4_IPV6;
+
+       ip6_dst_store(sk, dst, NULL);
+
+       icsk->icsk_ext_hdr_len = 0;
+       if (np->opt)
+               icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
+                                         np->opt->opt_nflen);
+
+       inet->dport = usin->sin6_port;
+
+       dccp_set_state(sk, DCCP_REQUESTING);
+       err = inet6_hash_connect(&dccp_death_row, sk);
+       if (err)
+               goto late_failure;
+       /* FIXME */
+#if 0
+       dp->dccps_gar = secure_dccp_v6_sequence_number(np->saddr.s6_addr32,
+                                                      np->daddr.s6_addr32,
+                                                      inet->sport,
+                                                      inet->dport);
+#endif
+       err = dccp_connect(sk);
+       if (err)
+               goto late_failure;
+
+       return 0;
+
+late_failure:
+       dccp_set_state(sk, DCCP_CLOSED);
+       __sk_dst_reset(sk);
+failure:
+       inet->dport = 0;
+       sk->sk_route_caps = 0;
+       return err;
+}
+
+static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+                       int type, int code, int offset, __u32 info)
+{
+       struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
+       const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
+       struct ipv6_pinfo *np;
+       struct sock *sk;
+       int err;
+       __u64 seq;
+
+       sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+                         &hdr->saddr, dh->dccph_sport, skb->dev->ifindex);
+
+       if (sk == NULL) {
+               ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+               return;
+       }
+
+       if (sk->sk_state == DCCP_TIME_WAIT) {
+               inet_twsk_put((struct inet_timewait_sock *)sk);
+               return;
+       }
+
+       bh_lock_sock(sk);
+       if (sock_owned_by_user(sk))
+               NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS);
+
+       if (sk->sk_state == DCCP_CLOSED)
+               goto out;
+
+       np = inet6_sk(sk);
+
+       if (type == ICMPV6_PKT_TOOBIG) {
+               struct dst_entry *dst = NULL;
+
+               if (sock_owned_by_user(sk))
+                       goto out;
+               if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
+                       goto out;
+
+               /* icmp should have updated the destination cache entry */
+               dst = __sk_dst_check(sk, np->dst_cookie);
+
+               if (dst == NULL) {
+                       struct inet_sock *inet = inet_sk(sk);
+                       struct flowi fl;
+
+                       /* BUGGG_FUTURE: Again, it is not clear how
+                          to handle rthdr case. Ignore this complexity
+                          for now.
+                        */
+                       memset(&fl, 0, sizeof(fl));
+                       fl.proto = IPPROTO_DCCP;
+                       ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+                       ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+                       fl.oif = sk->sk_bound_dev_if;
+                       fl.fl_ip_dport = inet->dport;
+                       fl.fl_ip_sport = inet->sport;
+
+                       if ((err = ip6_dst_lookup(sk, &dst, &fl))) {
+                               sk->sk_err_soft = -err;
+                               goto out;
+                       }
+
+                       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+                               sk->sk_err_soft = -err;
+                               goto out;
+                       }
+
+               } else
+                       dst_hold(dst);
+
+               if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
+                       dccp_sync_mss(sk, dst_mtu(dst));
+               } /* else let the usual retransmit timer handle it */
+               dst_release(dst);
+               goto out;
+       }
+
+       icmpv6_err_convert(type, code, &err);
+
+       seq = DCCP_SKB_CB(skb)->dccpd_seq;
+       /* Might be for an request_sock */
+       switch (sk->sk_state) {
+               struct request_sock *req, **prev;
+       case DCCP_LISTEN:
+               if (sock_owned_by_user(sk))
+                       goto out;
+
+               req = inet6_csk_search_req(sk, &prev, dh->dccph_dport,
+                                          &hdr->daddr, &hdr->saddr,
+                                          inet6_iif(skb));
+               if (!req)
+                       goto out;
+
+               /* ICMPs are not backlogged, hence we cannot get
+                * an established socket here.
+                */
+               BUG_TRAP(req->sk == NULL);
+
+               if (seq != dccp_rsk(req)->dreq_iss) {
+                       NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
+                       goto out;
+               }
+
+               inet_csk_reqsk_queue_drop(sk, req, prev);
+               goto out;
+
+       case DCCP_REQUESTING:
+       case DCCP_RESPOND:  /* Cannot happen.
+                              It can, it SYNs are crossed. --ANK */ 
+               if (!sock_owned_by_user(sk)) {
+                       DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+                       sk->sk_err = err;
+                       /*
+                        * Wake people up to see the error
+                        * (see connect in sock.c)
+                        */
+                       sk->sk_error_report(sk);
+
+                       dccp_done(sk);
+               } else
+                       sk->sk_err_soft = err;
+               goto out;
+       }
+
+       if (!sock_owned_by_user(sk) && np->recverr) {
+               sk->sk_err = err;
+               sk->sk_error_report(sk);
+       } else
+               sk->sk_err_soft = err;
+
+out:
+       bh_unlock_sock(sk);
+       sock_put(sk);
+}
+
+
+static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
+                                struct dst_entry *dst)
+{
+       struct inet6_request_sock *ireq6 = inet6_rsk(req);
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct sk_buff *skb;
+       struct ipv6_txoptions *opt = NULL;
+       struct in6_addr *final_p = NULL, final;
+       struct flowi fl;
+       int err = -1;
+
+       memset(&fl, 0, sizeof(fl));
+       fl.proto = IPPROTO_DCCP;
+       ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+       ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
+       fl.fl6_flowlabel = 0;
+       fl.oif = ireq6->iif;
+       fl.fl_ip_dport = inet_rsk(req)->rmt_port;
+       fl.fl_ip_sport = inet_sk(sk)->sport;
+
+       if (dst == NULL) {
+               opt = np->opt;
+               if (opt == NULL &&
+                   np->rxopt.bits.osrcrt == 2 &&
+                   ireq6->pktopts) {
+                       struct sk_buff *pktopts = ireq6->pktopts;
+                       struct inet6_skb_parm *rxopt = IP6CB(pktopts);
+                       if (rxopt->srcrt)
+                               opt = ipv6_invert_rthdr(sk,
+                                       (struct ipv6_rt_hdr *)(pktopts->nh.raw +
+                                                              rxopt->srcrt));
+               }
+
+               if (opt && opt->srcrt) {
+                       struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
+                       ipv6_addr_copy(&final, &fl.fl6_dst);
+                       ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+                       final_p = &final;
+               }
+
+               err = ip6_dst_lookup(sk, &dst, &fl);
+               if (err)
+                       goto done;
+               if (final_p)
+                       ipv6_addr_copy(&fl.fl6_dst, final_p);
+               if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+                       goto done;
+       }
+
+       skb = dccp_make_response(sk, dst, req);
+       if (skb != NULL) {
+               struct dccp_hdr *dh = dccp_hdr(skb);
+               dh->dccph_checksum = dccp_v6_check(dh, skb->len,
+                                                  &ireq6->loc_addr,
+                                                  &ireq6->rmt_addr,
+                                                  csum_partial((char *)dh,
+                                                               skb->len,
+                                                               skb->csum));
+               ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+               err = ip6_xmit(sk, skb, &fl, opt, 0);
+               if (err == NET_XMIT_CN)
+                       err = 0;
+       }
+
+done:
+        if (opt && opt != np->opt)
+               sock_kfree_s(sk, opt, opt->tot_len);
+       return err;
+}
+
+static void dccp_v6_reqsk_destructor(struct request_sock *req)
+{
+       if (inet6_rsk(req)->pktopts != NULL)
+               kfree_skb(inet6_rsk(req)->pktopts);
+}
+
+static struct request_sock_ops dccp6_request_sock_ops = {
+       .family         = AF_INET6,
+       .obj_size       = sizeof(struct dccp6_request_sock),
+       .rtx_syn_ack    = dccp_v6_send_response,
+       .send_ack       = dccp_v6_reqsk_send_ack,
+       .destructor     = dccp_v6_reqsk_destructor,
+       .send_reset     = dccp_v6_ctl_send_reset,
+};
+
+static struct timewait_sock_ops dccp6_timewait_sock_ops = {
+       .twsk_obj_size  = sizeof(struct dccp6_timewait_sock),
+};
+
+static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
+{
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct dccp_hdr *dh = dccp_hdr(skb);
+
+       dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr,
+                                            len, IPPROTO_DCCP, 
+                                            csum_partial((char *)dh,
+                                                         dh->dccph_doff << 2,
+                                                         skb->csum));
+}
+
+static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
+{
+       struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 
+       const int dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
+                                      sizeof(struct dccp_hdr_ext) +
+                                      sizeof(struct dccp_hdr_reset);
+       struct sk_buff *skb;
+       struct flowi fl;
+       u64 seqno;
+
+       if (rxdh->dccph_type == DCCP_PKT_RESET)
+               return;
+
+       if (!ipv6_unicast_destination(rxskb))
+               return; 
+
+       /*
+        * We need to grab some memory, and put together an RST,
+        * and then put it into the queue to be sent.
+        */
+
+       skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) +
+                       dccp_hdr_reset_len, GFP_ATOMIC);
+       if (skb == NULL) 
+               return;
+
+       skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) +
+                   dccp_hdr_reset_len);
+
+       skb->h.raw = skb_push(skb, dccp_hdr_reset_len);
+       dh = dccp_hdr(skb);
+       memset(dh, 0, dccp_hdr_reset_len);
+
+       /* Swap the send and the receive. */
+       dh->dccph_type  = DCCP_PKT_RESET;
+       dh->dccph_sport = rxdh->dccph_dport;
+       dh->dccph_dport = rxdh->dccph_sport;
+       dh->dccph_doff  = dccp_hdr_reset_len / 4;
+       dh->dccph_x     = 1;
+       dccp_hdr_reset(skb)->dccph_reset_code =
+                               DCCP_SKB_CB(rxskb)->dccpd_reset_code;
+
+       /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+       seqno = 0;
+       if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+               dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
+
+       dccp_hdr_set_seq(dh, seqno);
+       dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
+                        DCCP_SKB_CB(rxskb)->dccpd_seq);
+
+       memset(&fl, 0, sizeof(fl));
+       ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
+       ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
+       dh->dccph_checksum = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
+                                            sizeof(*dh), IPPROTO_DCCP,
+                                            skb->csum);
+       fl.proto = IPPROTO_DCCP;
+       fl.oif = inet6_iif(rxskb);
+       fl.fl_ip_dport = dh->dccph_dport;
+       fl.fl_ip_sport = dh->dccph_sport;
+
+       /* sk = NULL, but it is safe for now. RST socket required. */
+       if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
+               if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
+                       ip6_xmit(NULL, skb, &fl, NULL, 0);
+                       DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
+                       DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
+                       return;
+               }
+       }
+
+       kfree_skb(skb);
+}
+
+static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb)
+{
+       struct flowi fl;
+       struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
+       const int dccp_hdr_ack_len = sizeof(struct dccp_hdr) +
+                                    sizeof(struct dccp_hdr_ext) +
+                                    sizeof(struct dccp_hdr_ack_bits);
+       struct sk_buff *skb;
+
+       skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) +
+                       dccp_hdr_ack_len, GFP_ATOMIC);
+       if (skb == NULL)
+               return;
+
+       skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) +
+                        dccp_hdr_ack_len);
+
+       skb->h.raw = skb_push(skb, dccp_hdr_ack_len);
+       dh = dccp_hdr(skb);
+       memset(dh, 0, dccp_hdr_ack_len);
+
+       /* Build DCCP header and checksum it. */
+       dh->dccph_type  = DCCP_PKT_ACK;
+       dh->dccph_sport = rxdh->dccph_dport;
+       dh->dccph_dport = rxdh->dccph_sport;
+       dh->dccph_doff  = dccp_hdr_ack_len / 4;
+       dh->dccph_x     = 1;
+       
+       dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
+       dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
+                        DCCP_SKB_CB(rxskb)->dccpd_seq);
+
+       memset(&fl, 0, sizeof(fl));
+       ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
+       ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
+
+       /* FIXME: calculate checksum, IPv4 also should... */
+
+       fl.proto = IPPROTO_DCCP;
+       fl.oif = inet6_iif(rxskb);
+       fl.fl_ip_dport = dh->dccph_dport;
+       fl.fl_ip_sport = dh->dccph_sport;
+
+       if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
+               if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
+                       ip6_xmit(NULL, skb, &fl, NULL, 0);
+                       DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
+                       return;
+               }
+       }
+
+       kfree_skb(skb);
+}
+
+static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
+                                  struct request_sock *req)
+{
+       dccp_v6_ctl_send_ack(skb);
+}
+
+static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
+{
+       const struct dccp_hdr *dh = dccp_hdr(skb);
+       const struct ipv6hdr *iph = skb->nh.ipv6h;
+       struct sock *nsk;
+       struct request_sock **prev;
+       /* Find possible connection requests. */
+       struct request_sock *req = inet6_csk_search_req(sk, &prev,
+                                                       dh->dccph_sport,
+                                                       &iph->saddr,
+                                                       &iph->daddr,
+                                                       inet6_iif(skb));
+       if (req != NULL)
+               return dccp_check_req(sk, skb, req, prev);
+
+       nsk = __inet6_lookup_established(&dccp_hashinfo,
+                                        &iph->saddr, dh->dccph_sport,
+                                        &iph->daddr, ntohs(dh->dccph_dport),
+                                        inet6_iif(skb));
+
+       if (nsk != NULL) {
+               if (nsk->sk_state != DCCP_TIME_WAIT) {
+                       bh_lock_sock(nsk);
+                       return nsk;
+               }
+               inet_twsk_put((struct inet_timewait_sock *)nsk);
+               return NULL;
+       }
+
+       return sk;
+}
+
+static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
+{
+       struct inet_request_sock *ireq;
+       struct dccp_sock dp;
+       struct request_sock *req;
+       struct dccp_request_sock *dreq;
+       struct inet6_request_sock *ireq6;
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
+       struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+       __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
+
+       if (skb->protocol == htons(ETH_P_IP))
+               return dccp_v4_conn_request(sk, skb);
+
+       if (!ipv6_unicast_destination(skb))
+               goto drop; 
+
+       if (dccp_bad_service_code(sk, service)) {
+               reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
+               goto drop;
+       }
+       /*
+        *      There are no SYN attacks on IPv6, yet...        
+        */
+       if (inet_csk_reqsk_queue_is_full(sk))
+               goto drop;              
+
+       if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
+               goto drop;
+
+       req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot);
+       if (req == NULL)
+               goto drop;
+
+       /* FIXME: process options */
+
+       dccp_openreq_init(req, &dp, skb);
+
+       ireq6 = inet6_rsk(req);
+       ireq = inet_rsk(req);
+       ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
+       ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
+       req->rcv_wnd    = 100; /* Fake, option parsing will get the
+                                 right value */
+       ireq6->pktopts  = NULL;
+
+       if (ipv6_opt_accepted(sk, skb) ||
+           np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+           np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
+               atomic_inc(&skb->users);
+               ireq6->pktopts = skb;
+       }
+       ireq6->iif = sk->sk_bound_dev_if;
+
+       /* So that link locals have meaning */
+       if (!sk->sk_bound_dev_if &&
+           ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL)
+               ireq6->iif = inet6_iif(skb);
+
+       /* 
+        * Step 3: Process LISTEN state
+        *
+        * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
+        *
+        * In fact we defer setting S.GSR, S.SWL, S.SWH to
+        * dccp_create_openreq_child.
+        */
+       dreq = dccp_rsk(req);
+       dreq->dreq_isr     = dcb->dccpd_seq;
+       dreq->dreq_iss     = dccp_v6_init_sequence(sk, skb);
+       dreq->dreq_service = service;
+
+       if (dccp_v6_send_response(sk, req, NULL))
+               goto drop_and_free;
+
+       inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
+       return 0;
+
+drop_and_free:
+       reqsk_free(req);
+drop:
+       DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+       dcb->dccpd_reset_code = reset_code;
+       return -1;
+}
+
+static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
+                                             struct sk_buff *skb,
+                                             struct request_sock *req,
+                                             struct dst_entry *dst)
+{
+       struct inet6_request_sock *ireq6 = inet6_rsk(req);
+       struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+       struct inet_sock *newinet;
+       struct dccp_sock *newdp;
+       struct dccp6_sock *newdp6;
+       struct sock *newsk;
+       struct ipv6_txoptions *opt;
+
+       if (skb->protocol == htons(ETH_P_IP)) {
+               /*
+                *      v6 mapped
+                */
+
+               newsk = dccp_v4_request_recv_sock(sk, skb, req, dst);
+               if (newsk == NULL) 
+                       return NULL;
+
+               newdp6 = (struct dccp6_sock *)newsk;
+               newdp = dccp_sk(newsk);
+               newinet = inet_sk(newsk);
+               newinet->pinet6 = &newdp6->inet6;
+               newnp = inet6_sk(newsk);
+
+               memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+
+               ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF),
+                             newinet->daddr);
+
+               ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF),
+                             newinet->saddr);
+
+               ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
+
+               inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
+               newsk->sk_backlog_rcv = dccp_v4_do_rcv;
+               newnp->pktoptions  = NULL;
+               newnp->opt         = NULL;
+               newnp->mcast_oif   = inet6_iif(skb);
+               newnp->mcast_hops  = skb->nh.ipv6h->hop_limit;
+
+               /*
+                * No need to charge this sock to the relevant IPv6 refcnt debug socks count
+                * here, dccp_create_openreq_child now does this for us, see the comment in
+                * that function for the gory details. -acme
+                */
+
+               /* It is tricky place. Until this moment IPv4 tcp
+                  worked with IPv6 icsk.icsk_af_ops.
+                  Sync it now.
+                */
+               dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
+
+               return newsk;
+       }
+
+       opt = np->opt;
+
+       if (sk_acceptq_is_full(sk))
+               goto out_overflow;
+
+       if (np->rxopt.bits.osrcrt == 2 &&
+           opt == NULL && ireq6->pktopts) {
+               struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
+               if (rxopt->srcrt)
+                       opt = ipv6_invert_rthdr(sk,
+                               (struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw +
+                                                      rxopt->srcrt));
+       }
+
+       if (dst == NULL) {
+               struct in6_addr *final_p = NULL, final;
+               struct flowi fl;
+
+               memset(&fl, 0, sizeof(fl));
+               fl.proto = IPPROTO_DCCP;
+               ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+               if (opt && opt->srcrt) {
+                       struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
+                       ipv6_addr_copy(&final, &fl.fl6_dst);
+                       ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+                       final_p = &final;
+               }
+               ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
+               fl.oif = sk->sk_bound_dev_if;
+               fl.fl_ip_dport = inet_rsk(req)->rmt_port;
+               fl.fl_ip_sport = inet_sk(sk)->sport;
+
+               if (ip6_dst_lookup(sk, &dst, &fl))
+                       goto out;
+
+               if (final_p)
+                       ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+               if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+                       goto out;
+       } 
+
+       newsk = dccp_create_openreq_child(sk, req, skb);
+       if (newsk == NULL)
+               goto out;
+
+       /*
+        * No need to charge this sock to the relevant IPv6 refcnt debug socks
+        * count here, dccp_create_openreq_child now does this for us, see the
+        * comment in that function for the gory details. -acme
+        */
+
+       ip6_dst_store(newsk, dst, NULL);
+       newsk->sk_route_caps = dst->dev->features &
+               ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+       newdp6 = (struct dccp6_sock *)newsk;
+       newinet = inet_sk(newsk);
+       newinet->pinet6 = &newdp6->inet6;
+       newdp = dccp_sk(newsk);
+       newnp = inet6_sk(newsk);
+
+       memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+
+       ipv6_addr_copy(&newnp->daddr, &ireq6->rmt_addr);
+       ipv6_addr_copy(&newnp->saddr, &ireq6->loc_addr);
+       ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr);
+       newsk->sk_bound_dev_if = ireq6->iif;
+
+       /* Now IPv6 options... 
+
+          First: no IPv4 options.
+        */
+       newinet->opt = NULL;
+
+       /* Clone RX bits */
+       newnp->rxopt.all = np->rxopt.all;
+
+       /* Clone pktoptions received with SYN */
+       newnp->pktoptions = NULL;
+       if (ireq6->pktopts != NULL) {
+               newnp->pktoptions = skb_clone(ireq6->pktopts, GFP_ATOMIC);
+               kfree_skb(ireq6->pktopts);
+               ireq6->pktopts = NULL;
+               if (newnp->pktoptions)
+                       skb_set_owner_r(newnp->pktoptions, newsk);
+       }
+       newnp->opt        = NULL;
+       newnp->mcast_oif  = inet6_iif(skb);
+       newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
+
+       /* Clone native IPv6 options from listening socket (if any)
+
+          Yes, keeping reference count would be much more clever,
+          but we make one more one thing there: reattach optmem
+          to newsk.
+        */
+       if (opt) {
+               newnp->opt = ipv6_dup_options(newsk, opt);
+               if (opt != np->opt)
+                       sock_kfree_s(sk, opt, opt->tot_len);
+       }
+
+       inet_csk(newsk)->icsk_ext_hdr_len = 0;
+       if (newnp->opt)
+               inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
+                                                    newnp->opt->opt_flen);
+
+       dccp_sync_mss(newsk, dst_mtu(dst));
+
+       newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
+
+       __inet6_hash(&dccp_hashinfo, newsk);
+       inet_inherit_port(&dccp_hashinfo, sk, newsk);
+
+       return newsk;
+
+out_overflow:
+       NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS);
+out:
+       NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS);
+       if (opt && opt != np->opt)
+               sock_kfree_s(sk, opt, opt->tot_len);
+       dst_release(dst);
+       return NULL;
+}
+
+/* The socket must have it's spinlock held when we get
+ * here.
+ *
+ * We have a potential double-lock case here, so even when
+ * doing backlog processing we use the BH locking scheme.
+ * This is because we cannot sleep with the original spinlock
+ * held.
+ */
+static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct sk_buff *opt_skb = NULL;
+
+       /* Imagine: socket is IPv6. IPv4 packet arrives,
+          goes to IPv4 receive handler and backlogged.
+          From backlog it always goes here. Kerboom...
+          Fortunately, dccp_rcv_established and rcv_established
+          handle them correctly, but it is not case with
+          dccp_v6_hnd_req and dccp_v6_ctl_send_reset().   --ANK
+        */
+
+       if (skb->protocol == htons(ETH_P_IP))
+               return dccp_v4_do_rcv(sk, skb);
+
+       if (sk_filter(sk, skb, 0))
+               goto discard;
+
+       /*
+        *      socket locking is here for SMP purposes as backlog rcv
+        *      is currently called with bh processing disabled.
+        */
+
+       /* Do Stevens' IPV6_PKTOPTIONS.
+
+          Yes, guys, it is the only place in our code, where we
+          may make it not affecting IPv4.
+          The rest of code is protocol independent,
+          and I do not like idea to uglify IPv4.
+
+          Actually, all the idea behind IPV6_PKTOPTIONS
+          looks not very well thought. For now we latch
+          options, received in the last packet, enqueued
+          by tcp. Feel free to propose better solution.
+                                              --ANK (980728)
+        */
+       if (np->rxopt.all)
+               opt_skb = skb_clone(skb, GFP_ATOMIC);
+
+       if (sk->sk_state == DCCP_OPEN) { /* Fast path */
+               if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
+                       goto reset;
+               return 0;
+       }
+
+       if (sk->sk_state == DCCP_LISTEN) { 
+               struct sock *nsk = dccp_v6_hnd_req(sk, skb);
+               if (!nsk)
+                       goto discard;
+
+               /*
+                * Queue it on the new socket if the new socket is active,
+                * otherwise we just shortcircuit this and continue with
+                * the new socket..
+                */
+               if(nsk != sk) {
+                       if (dccp_child_process(sk, nsk, skb))
+                               goto reset;
+                       if (opt_skb)
+                               __kfree_skb(opt_skb);
+                       return 0;
+               }
+       }
+
+       if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
+               goto reset;
+       return 0;
+
+reset:
+       dccp_v6_ctl_send_reset(skb);
+discard:
+       if (opt_skb)
+               __kfree_skb(opt_skb);
+       kfree_skb(skb);
+       return 0;
+}
+
+static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+{
+       const struct dccp_hdr *dh;
+       struct sk_buff *skb = *pskb;
+       struct sock *sk;
+
+       /* Step 1: Check header basics: */
+
+       if (dccp_invalid_packet(skb))
+               goto discard_it;
+
+       dh = dccp_hdr(skb);
+
+       DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
+       DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
+
+       if (dccp_packet_without_ack(skb))
+               DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
+       else
+               DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
+
+       /* Step 2:
+        *      Look up flow ID in table and get corresponding socket */
+       sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr,
+                           dh->dccph_sport,
+                           &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport),
+                           inet6_iif(skb));
+       /* 
+        * Step 2:
+        *      If no socket ...
+        *              Generate Reset(No Connection) unless P.type == Reset
+        *              Drop packet and return
+        */
+       if (sk == NULL)
+               goto no_dccp_socket;
+
+       /* 
+        * Step 2:
+        *      ... or S.state == TIMEWAIT,
+        *              Generate Reset(No Connection) unless P.type == Reset
+        *              Drop packet and return
+        */
+              
+       if (sk->sk_state == DCCP_TIME_WAIT)
+                goto do_time_wait;
+
+       if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
+               goto discard_and_relse;
+
+       return sk_receive_skb(sk, skb) ? -1 : 0;
+
+no_dccp_socket:
+       if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+               goto discard_it;
+       /*
+        * Step 2:
+        *              Generate Reset(No Connection) unless P.type == Reset
+        *              Drop packet and return
+        */
+       if (dh->dccph_type != DCCP_PKT_RESET) {
+               DCCP_SKB_CB(skb)->dccpd_reset_code =
+                                       DCCP_RESET_CODE_NO_CONNECTION;
+               dccp_v6_ctl_send_reset(skb);
+       }
+discard_it:
+
+       /*
+        *      Discard frame
+        */
+
+       kfree_skb(skb);
+       return 0;
+
+discard_and_relse:
+       sock_put(sk);
+       goto discard_it;
+
+do_time_wait:
+       inet_twsk_put((struct inet_timewait_sock *)sk);
+       goto no_dccp_socket;
+}
+
+static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
+       .queue_xmit     =       inet6_csk_xmit,
+       .send_check     =       dccp_v6_send_check,
+       .rebuild_header =       inet6_sk_rebuild_header,
+       .conn_request   =       dccp_v6_conn_request,
+       .syn_recv_sock  =       dccp_v6_request_recv_sock,
+       .net_header_len =       sizeof(struct ipv6hdr),
+       .setsockopt     =       ipv6_setsockopt,
+       .getsockopt     =       ipv6_getsockopt,
+       .addr2sockaddr  =       inet6_csk_addr2sockaddr,
+       .sockaddr_len   =       sizeof(struct sockaddr_in6)
+};
+
+/*
+ *     DCCP over IPv4 via INET6 API
+ */
+static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
+       .queue_xmit     =       ip_queue_xmit,
+       .send_check     =       dccp_v4_send_check,
+       .rebuild_header =       inet_sk_rebuild_header,
+       .conn_request   =       dccp_v6_conn_request,
+       .syn_recv_sock  =       dccp_v6_request_recv_sock,
+       .net_header_len =       sizeof(struct iphdr),
+       .setsockopt     =       ipv6_setsockopt,
+       .getsockopt     =       ipv6_getsockopt,
+       .addr2sockaddr  =       inet6_csk_addr2sockaddr,
+       .sockaddr_len   =       sizeof(struct sockaddr_in6)
+};
+
+/* NOTE: A lot of things set to zero explicitly by call to
+ *       sk_alloc() so need not be done here.
+ */
+static int dccp_v6_init_sock(struct sock *sk)
+{
+       int err = dccp_v4_init_sock(sk);
+
+       if (err == 0)
+               inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
+
+       return err;
+}
+
+static int dccp_v6_destroy_sock(struct sock *sk)
+{
+       dccp_v4_destroy_sock(sk);
+       return inet6_destroy_sock(sk);
+}
+
+static struct proto dccp_v6_prot = {
+       .name                   = "DCCPv6",
+       .owner                  = THIS_MODULE,
+       .close                  = dccp_close,
+       .connect                = dccp_v6_connect,
+       .disconnect             = dccp_disconnect,
+       .ioctl                  = dccp_ioctl,
+       .init                   = dccp_v6_init_sock,
+       .setsockopt             = dccp_setsockopt,
+       .getsockopt             = dccp_getsockopt,
+       .sendmsg                = dccp_sendmsg,
+       .recvmsg                = dccp_recvmsg,
+       .backlog_rcv            = dccp_v6_do_rcv,
+       .hash                   = dccp_v6_hash,
+       .unhash                 = dccp_unhash,
+       .accept                 = inet_csk_accept,
+       .get_port               = dccp_v6_get_port,
+       .shutdown               = dccp_shutdown,
+       .destroy                = dccp_v6_destroy_sock,
+       .orphan_count           = &dccp_orphan_count,
+       .max_header             = MAX_DCCP_HEADER,
+       .obj_size               = sizeof(struct dccp6_sock),
+       .rsk_prot               = &dccp6_request_sock_ops,
+       .twsk_prot              = &dccp6_timewait_sock_ops,
+};
+
+static struct inet6_protocol dccp_v6_protocol = {
+       .handler        =       dccp_v6_rcv,
+       .err_handler    =       dccp_v6_err,
+       .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
+};
+
+static struct proto_ops inet6_dccp_ops = {
+       .family         = PF_INET6,
+       .owner          = THIS_MODULE,
+       .release        = inet6_release,
+       .bind           = inet6_bind,
+       .connect        = inet_stream_connect,
+       .socketpair     = sock_no_socketpair,
+       .accept         = inet_accept,
+       .getname        = inet6_getname,
+       .poll           = dccp_poll,
+       .ioctl          = inet6_ioctl,
+       .listen         = inet_dccp_listen,
+       .shutdown       = inet_shutdown,
+       .setsockopt     = sock_common_setsockopt,
+       .getsockopt     = sock_common_getsockopt,
+       .sendmsg        = inet_sendmsg,
+       .recvmsg        = sock_common_recvmsg,
+       .mmap           = sock_no_mmap,
+       .sendpage       = sock_no_sendpage,
+};
+
+static struct inet_protosw dccp_v6_protosw = {
+       .type           = SOCK_DCCP,
+       .protocol       = IPPROTO_DCCP,
+       .prot           = &dccp_v6_prot,
+       .ops            = &inet6_dccp_ops,
+       .capability     = -1,
+       .flags          = INET_PROTOSW_ICSK,
+};
+
+static int __init dccp_v6_init(void)
+{
+       int err = proto_register(&dccp_v6_prot, 1);
+
+       if (err != 0)
+               goto out;
+
+       err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
+       if (err != 0)
+               goto out_unregister_proto;
+
+       inet6_register_protosw(&dccp_v6_protosw);
+out:
+       return err;
+out_unregister_proto:
+       proto_unregister(&dccp_v6_prot);
+       goto out;
+}
+
+static void __exit dccp_v6_exit(void)
+{
+       inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
+       inet6_unregister_protosw(&dccp_v6_protosw);
+       proto_unregister(&dccp_v6_prot);
+}
+
+module_init(dccp_v6_init);
+module_exit(dccp_v6_exit);
+
+/*
+ * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
+ * values directly, Also cover the case where the protocol is not specified,
+ * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
+ */
+MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6");
+MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
+MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
diff --git a/net/dccp/ipv6.h b/net/dccp/ipv6.h
new file mode 100644 (file)
index 0000000..e4d4e93
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _DCCP_IPV6_H
+#define _DCCP_IPV6_H
+/*
+ *  net/dccp/ipv6.h
+ *
+ *  An implementation of the DCCP protocol
+ *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.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/config.h>
+#include <linux/dccp.h>
+#include <linux/ipv6.h>
+
+struct dccp6_sock {
+       struct dccp_sock  dccp;
+       /*
+        * ipv6_pinfo has to be the last member of dccp6_sock,
+        * see inet6_sk_generic.
+        */
+       struct ipv6_pinfo inet6;
+};
+
+struct dccp6_request_sock {
+       struct dccp_request_sock  dccp;
+       struct inet6_request_sock inet6;
+};
+
+struct dccp6_timewait_sock {
+       struct inet_timewait_sock   inet;
+       struct inet6_timewait_sock  tw6;
+};
+
+#endif /* _DCCP_IPV6_H */
index 1393461..29261fc 100644 (file)
@@ -40,6 +40,8 @@ struct inet_timewait_death_row dccp_death_row = {
                                            (unsigned long)&dccp_death_row),
 };
 
+EXPORT_SYMBOL_GPL(dccp_death_row);
+
 void dccp_time_wait(struct sock *sk, int state, int timeo)
 {
        struct inet_timewait_sock *tw = NULL;
@@ -50,7 +52,18 @@ void dccp_time_wait(struct sock *sk, int state, int timeo)
        if (tw != NULL) {
                const struct inet_connection_sock *icsk = inet_csk(sk);
                const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
-
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+               if (tw->tw_family == PF_INET6) {
+                       const struct ipv6_pinfo *np = inet6_sk(sk);
+                       struct inet6_timewait_sock *tw6;
+
+                       tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot);
+                       tw6 = inet6_twsk((struct sock *)tw);
+                       ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr);
+                       ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr);
+                       tw->tw_ipv6only = np->ipv6only;
+               }
+#endif
                /* Linkage updates. */
                __inet_twsk_hashdance(tw, sk, &dccp_hashinfo);
 
@@ -170,6 +183,8 @@ out_free:
        return newsk;
 }
 
+EXPORT_SYMBOL_GPL(dccp_create_openreq_child);
+
 /* 
  * Process an incoming packet for RESPOND sockets represented
  * as an request_sock.
@@ -214,7 +229,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
                goto drop;
        }
 
-       child = dccp_v4_request_recv_sock(sk, skb, req, NULL);
+       child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
        if (child == NULL)
                goto listen_overflow;
 
@@ -236,6 +251,8 @@ drop:
        goto out;
 }
 
+EXPORT_SYMBOL_GPL(dccp_check_req);
+
 /*
  *  Queue segment on the new socket if the new socket is active,
  *  otherwise we just shortcircuit this and continue with
@@ -266,3 +283,5 @@ int dccp_child_process(struct sock *parent, struct sock *child,
        sock_put(child);
        return ret;
 }
+
+EXPORT_SYMBOL_GPL(dccp_child_process);
index 74ff870..efd7ffb 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 
+#include <net/inet_sock.h>
 #include <net/sock.h>
 
 #include "ackvec.h"
@@ -43,6 +44,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 {
        if (likely(skb != NULL)) {
                const struct inet_sock *inet = inet_sk(sk);
+               const struct inet_connection_sock *icsk = inet_csk(sk);
                struct dccp_sock *dp = dccp_sk(sk);
                struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
                struct dccp_hdr *dh;
@@ -108,8 +110,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                        break;
                }
 
-               dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr,
-                                                     inet->daddr);
+               icsk->icsk_af_ops->send_check(sk, skb->len, skb);
 
                if (set_ack)
                        dccp_event_ack_sent(sk);
@@ -117,7 +118,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
 
                memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-               err = ip_queue_xmit(skb, 0);
+               err = icsk->icsk_af_ops->queue_xmit(skb, 0);
                if (err <= 0)
                        return err;
 
@@ -134,20 +135,13 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 
 unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
 {
+       struct inet_connection_sock *icsk = inet_csk(sk);
        struct dccp_sock *dp = dccp_sk(sk);
-       int mss_now;
-
-       /*
-        * FIXME: we really should be using the af_specific thing to support
-        *        IPv6.
-        * mss_now = pmtu - tp->af_specific->net_header_len -
-        *           sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
-        */
-       mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) -
-                 sizeof(struct dccp_hdr_ext);
+       int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
+                      sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));
 
        /* Now subtract optional transport overhead */
-       mss_now -= dp->dccps_ext_header_len;
+       mss_now -= icsk->icsk_ext_hdr_len;
 
        /*
         * FIXME: this should come from the CCID infrastructure, where, say,
@@ -160,12 +154,14 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
        mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
 
        /* And store cached results */
-       dp->dccps_pmtu_cookie = pmtu;
+       icsk->icsk_pmtu_cookie = pmtu;
        dp->dccps_mss_cache = mss_now;
 
        return mss_now;
 }
 
+EXPORT_SYMBOL_GPL(dccp_sync_mss);
+
 void dccp_write_space(struct sock *sk)
 {
        read_lock(&sk->sk_callback_lock);
@@ -266,7 +262,7 @@ int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)
 
 int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
-       if (inet_sk_rebuild_header(sk) != 0)
+       if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
                return -EHOSTUNREACH; /* Routing failure or similar. */
 
        return dccp_transmit_skb(sk, (skb_cloned(skb) ?
@@ -321,6 +317,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        return skb;
 }
 
+EXPORT_SYMBOL_GPL(dccp_make_response);
+
 struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
                                const enum dccp_reset_codes code)
                                   
@@ -377,6 +375,7 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
  */
 static inline void dccp_connect_init(struct sock *sk)
 {
+       struct dccp_sock *dp = dccp_sk(sk);
        struct dst_entry *dst = __sk_dst_get(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -385,10 +384,16 @@ static inline void dccp_connect_init(struct sock *sk)
        
        dccp_sync_mss(sk, dst_mtu(dst));
 
-       /*
-        * FIXME: set dp->{dccps_swh,dccps_swl}, with
-        * something like dccp_inc_seq
-        */
+       dccp_update_gss(sk, dp->dccps_iss);
+       /*
+        * SWL and AWL are initially adjusted so that they are not less than
+        * the initial Sequence Numbers received and sent, respectively:
+        *      SWL := max(GSR + 1 - floor(W/4), ISR),
+        *      AWL := max(GSS - W' + 1, ISS).
+        * These adjustments MUST be applied only at the beginning of the
+        * connection.
+        */
+       dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
 
        icsk->icsk_retransmits = 0;
 }
@@ -420,6 +425,8 @@ int dccp_connect(struct sock *sk)
        return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_connect);
+
 void dccp_send_ack(struct sock *sk)
 {
        /* If we have been reset, we may not send again. */
index 8a6b2a9..65b11ea 100644 (file)
@@ -24,7 +24,7 @@
 #include <net/checksum.h>
 
 #include <net/inet_common.h>
-#include <net/ip.h>
+#include <net/inet_sock.h>
 #include <net/protocol.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/poll.h>
-#include <linux/dccp.h>
 
 #include "ccid.h"
 #include "dccp.h"
 
 DEFINE_SNMP_STAT(struct dccp_mib, dccp_statistics) __read_mostly;
 
+EXPORT_SYMBOL_GPL(dccp_statistics);
+
 atomic_t dccp_orphan_count = ATOMIC_INIT(0);
 
+EXPORT_SYMBOL_GPL(dccp_orphan_count);
+
 static struct net_protocol dccp_protocol = {
        .handler        = dccp_v4_rcv,
        .err_handler    = dccp_v4_err,
@@ -149,6 +152,8 @@ int dccp_disconnect(struct sock *sk, int flags)
        return err;
 }
 
+EXPORT_SYMBOL_GPL(dccp_disconnect);
+
 /*
  *     Wait for a DCCP event.
  *
@@ -156,8 +161,8 @@ int dccp_disconnect(struct sock *sk, int flags)
  *     take care of normal races (between the test and the event) and we don't
  *     go look at any of the socket buffers directly.
  */
-static unsigned int dccp_poll(struct file *file, struct socket *sock,
-                             poll_table *wait)
+unsigned int dccp_poll(struct file *file, struct socket *sock,
+                      poll_table *wait)
 {
        unsigned int mask;
        struct sock *sk = sock->sk;
@@ -205,12 +210,16 @@ static unsigned int dccp_poll(struct file *file, struct socket *sock,
        return mask;
 }
 
+EXPORT_SYMBOL_GPL(dccp_poll);
+
 int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
        dccp_pr_debug("entry\n");
        return -ENOIOCTLCMD;
 }
 
+EXPORT_SYMBOL_GPL(dccp_ioctl);
+
 static int dccp_setsockopt_service(struct sock *sk, const u32 service,
                                   char __user *optval, int optlen)
 {
@@ -254,7 +263,9 @@ int dccp_setsockopt(struct sock *sk, int level, int optname,
        int val;
 
        if (level != SOL_DCCP)
-               return ip_setsockopt(sk, level, optname, optval, optlen);
+               return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
+                                                            optname, optval,
+                                                            optlen);
 
        if (optlen < sizeof(int))
                return -EINVAL;
@@ -282,6 +293,8 @@ int dccp_setsockopt(struct sock *sk, int level, int optname,
        return err;
 }
 
+EXPORT_SYMBOL_GPL(dccp_setsockopt);
+
 static int dccp_getsockopt_service(struct sock *sk, int len,
                                   u32 __user *optval,
                                   int __user *optlen)
@@ -320,8 +333,9 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
        int val, len;
 
        if (level != SOL_DCCP)
-               return ip_getsockopt(sk, level, optname, optval, optlen);
-
+               return inet_csk(sk)->icsk_af_ops->getsockopt(sk, level,
+                                                            optname, optval,
+                                                            optlen);
        if (get_user(len, optlen))
                return -EFAULT;
 
@@ -354,6 +368,8 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
        return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_getsockopt);
+
 int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                 size_t len)
 {
@@ -410,6 +426,8 @@ out_discard:
        goto out_release;
 }
 
+EXPORT_SYMBOL_GPL(dccp_sendmsg);
+
 int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                 size_t len, int nonblock, int flags, int *addr_len)
 {
@@ -507,7 +525,9 @@ out:
        return len;
 }
 
-static int inet_dccp_listen(struct socket *sock, int backlog)
+EXPORT_SYMBOL_GPL(dccp_recvmsg);
+
+int inet_dccp_listen(struct socket *sock, int backlog)
 {
        struct sock *sk = sock->sk;
        unsigned char old_state;
@@ -543,6 +563,8 @@ out:
        return err;
 }
 
+EXPORT_SYMBOL_GPL(inet_dccp_listen);
+
 static const unsigned char dccp_new_state[] = {
        /* current state:   new state:      action:     */
        [0]               = DCCP_CLOSED,
@@ -648,12 +670,16 @@ adjudge_to_death:
        sock_put(sk);
 }
 
+EXPORT_SYMBOL_GPL(dccp_close);
+
 void dccp_shutdown(struct sock *sk, int how)
 {
        dccp_pr_debug("entry\n");
 }
 
-static struct proto_ops inet_dccp_ops = {
+EXPORT_SYMBOL_GPL(dccp_shutdown);
+
+static const struct proto_ops inet_dccp_ops = {
        .family         = PF_INET,
        .owner          = THIS_MODULE,
        .release        = inet_release,
@@ -681,11 +707,11 @@ extern struct net_proto_family inet_family_ops;
 static struct inet_protosw dccp_v4_protosw = {
        .type           = SOCK_DCCP,
        .protocol       = IPPROTO_DCCP,
-       .prot           = &dccp_v4_prot,
+       .prot           = &dccp_prot,
        .ops            = &inet_dccp_ops,
        .capability     = -1,
        .no_check       = 0,
-       .flags          = 0,
+       .flags          = INET_PROTOSW_ICSK,
 };
 
 /*
@@ -760,13 +786,15 @@ MODULE_PARM_DESC(thash_entries, "Number of ehash buckets");
 int dccp_debug;
 module_param(dccp_debug, int, 0444);
 MODULE_PARM_DESC(dccp_debug, "Enable debug messages");
+
+EXPORT_SYMBOL_GPL(dccp_debug);
 #endif
 
 static int __init dccp_init(void)
 {
        unsigned long goal;
        int ehash_order, bhash_order, i;
-       int rc = proto_register(&dccp_v4_prot, 1);
+       int rc = proto_register(&dccp_prot, 1);
 
        if (rc)
                goto out;
@@ -869,7 +897,7 @@ out_free_bind_bucket_cachep:
        kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
        dccp_hashinfo.bind_bucket_cachep = NULL;
 out_proto_unregister:
-       proto_unregister(&dccp_v4_prot);
+       proto_unregister(&dccp_prot);
        goto out;
 }
 
@@ -892,7 +920,7 @@ static void __exit dccp_fini(void)
                   get_order(dccp_hashinfo.ehash_size *
                             sizeof(struct inet_ehash_bucket)));
        kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
-       proto_unregister(&dccp_v4_prot);
+       proto_unregister(&dccp_prot);
 }
 
 module_init(dccp_init);
index d402e90..78ec534 100644 (file)
@@ -149,7 +149,7 @@ static void dn_keepalive(struct sock *sk);
 #define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1)
 
 
-static struct proto_ops dn_proto_ops;
+static const struct proto_ops dn_proto_ops;
 static DEFINE_RWLOCK(dn_hash_lock);
 static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
@@ -1252,7 +1252,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                break;
 
        default:
-               err = dev_ioctl(cmd, (void __user *)arg);
+               err = -ENOIOCTLCMD;
                break;
        }
 
@@ -2342,7 +2342,7 @@ static struct net_proto_family    dn_family_ops = {
        .owner  =       THIS_MODULE,
 };
 
-static struct proto_ops dn_proto_ops = {
+static const struct proto_ops dn_proto_ops = {
        .family =       AF_DECnet,
        .owner =        THIS_MODULE,
        .release =      dn_release,
index 8d0cc3c..33ab256 100644 (file)
@@ -408,11 +408,14 @@ int dn_neigh_router_hello(struct sk_buff *skb)
                        }
                }
 
-               if (!dn_db->router) {
-                       dn_db->router = neigh_clone(neigh);
-               } else {
-                       if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
-                               neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
+               /* Only use routers in our area */
+               if ((dn_ntohs(src)>>10) == dn_ntohs((decnet_address)>>10)) {
+                       if (!dn_db->router) {
+                               dn_db->router = neigh_clone(neigh);
+                       } else {
+                               if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
+                                       neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
+                       }
                }
                write_unlock(&neigh->lock);
                neigh_release(neigh);
index 369f25b..44bda85 100644 (file)
@@ -793,7 +793,6 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
 got_it:
        if (sk != NULL) {
                struct dn_scp *scp = DN_SK(sk);
-               int ret;
 
                /* Reset backoff */
                scp->nsp_rxtshift = 0;
@@ -807,21 +806,7 @@ got_it:
                                goto free_out;
                }
 
-               bh_lock_sock(sk);
-               ret = NET_RX_SUCCESS;
-               if (decnet_debug_level & 8)
-                       printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n",
-                               (int)cb->rt_flags, (int)cb->nsp_flags, 
-                               (int)cb->src_port, (int)cb->dst_port, 
-                               !!sock_owned_by_user(sk));
-               if (!sock_owned_by_user(sk))
-                       ret = dn_nsp_backlog_rcv(sk, skb);
-               else
-                       sk_add_backlog(sk, skb);
-               bh_unlock_sock(sk);
-               sock_put(sk);
-
-               return ret;
+               return sk_receive_skb(sk, skb);
        }
 
        return dn_nsp_no_socket(skb, reason);
index 34fdac5..c792994 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
 #include <linux/skbuff.h>
+#include <linux/udp.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <linux/stat.h>
@@ -45,7 +46,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct proto_ops econet_ops;
+static const struct proto_ops econet_ops;
 static struct hlist_head econet_sklist;
 static DEFINE_RWLOCK(econet_lock);
 
@@ -56,7 +57,7 @@ static struct net_device *net2dev_map[256];
 #define EC_PORT_IP     0xd2
 
 #ifdef CONFIG_ECONET_AUNUDP
-static spinlock_t aun_queue_lock;
+static DEFINE_SPINLOCK(aun_queue_lock);
 static struct socket *udpsock;
 #define AUN_PORT       0x8000
 
@@ -686,7 +687,7 @@ static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg
                        break;
 
                default:
-                       return dev_ioctl(cmd, argp);
+                       return -ENOIOCTLCMD;
        }
        /*NOTREACHED*/
        return 0;
@@ -698,7 +699,7 @@ static struct net_proto_family econet_family_ops = {
        .owner  =       THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
        .family =       PF_ECONET,
        .owner =        THIS_MODULE,
        .release =      econet_release,
index 03efaac..4cc6f41 100644 (file)
@@ -410,9 +410,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                return 1;
        }
 
-       if ((is_multicast_ether_addr(hdr->addr1) ||
-            is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
-           ieee->host_decrypt) {
+       if (is_multicast_ether_addr(hdr->addr1)
+           ? ieee->host_mc_decrypt : ieee->host_decrypt) {
                int idx = 0;
                if (skb->len >= hdrlen + 3)
                        idx = skb->data[hdrlen + 3] >> 6;
index e55136a..011cca7 100644 (file)
@@ -456,6 +456,14 @@ config TCP_CONG_BIC
        increase provides TCP friendliness.
        See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/
 
+config TCP_CONG_CUBIC
+       tristate "CUBIC TCP"
+       default m
+       ---help---
+       This is version 2.0 of BIC-TCP which uses a cubic growth function
+       among other techniques.
+       See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf
+
 config TCP_CONG_WESTWOOD
        tristate "TCP Westwood+"
        default m
index f0435d0..c54edd7 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_INET_DIAG) += inet_diag.o
 obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
 obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
+obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o
 obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o
 obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o
 obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o
index d368cf2..966a071 100644 (file)
@@ -93,6 +93,7 @@
 #include <linux/smp_lock.h>
 #include <linux/inet.h>
 #include <linux/igmp.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <net/ip.h>
 #include <net/protocol.h>
@@ -302,6 +303,7 @@ lookup_protocol:
                sk->sk_reuse = 1;
 
        inet = inet_sk(sk);
+       inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
 
        if (SOCK_RAW == sock->type) {
                inet->num = protocol;
@@ -775,16 +777,16 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        err = devinet_ioctl(cmd, (void __user *)arg);
                        break;
                default:
-                       if (!sk->sk_prot->ioctl ||
-                           (err = sk->sk_prot->ioctl(sk, cmd, arg)) ==
-                                                               -ENOIOCTLCMD)
-                               err = dev_ioctl(cmd, (void __user *)arg);
+                       if (sk->sk_prot->ioctl)
+                               err = sk->sk_prot->ioctl(sk, cmd, arg);
+                       else
+                               err = -ENOIOCTLCMD;
                        break;
        }
        return err;
 }
 
-struct proto_ops inet_stream_ops = {
+const struct proto_ops inet_stream_ops = {
        .family =       PF_INET,
        .owner =        THIS_MODULE,
        .release =      inet_release,
@@ -805,7 +807,7 @@ struct proto_ops inet_stream_ops = {
        .sendpage =     tcp_sendpage
 };
 
-struct proto_ops inet_dgram_ops = {
+const struct proto_ops inet_dgram_ops = {
        .family =       PF_INET,
        .owner =        THIS_MODULE,
        .release =      inet_release,
@@ -830,7 +832,7 @@ struct proto_ops inet_dgram_ops = {
  * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without
  * udp_poll
  */
-static struct proto_ops inet_sockraw_ops = {
+static const struct proto_ops inet_sockraw_ops = {
        .family =       PF_INET,
        .owner =        THIS_MODULE,
        .release =      inet_release,
@@ -869,7 +871,8 @@ static struct inet_protosw inetsw_array[] =
                 .ops =        &inet_stream_ops,
                 .capability = -1,
                 .no_check =   0,
-                .flags =      INET_PROTOSW_PERMANENT,
+                .flags =      INET_PROTOSW_PERMANENT |
+                             INET_PROTOSW_ICSK,
         },
 
         {
index 035ad2c..aed537f 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <net/icmp.h>
+#include <net/protocol.h>
 #include <asm/scatterlist.h>
 
 
index b425748..3743208 100644 (file)
@@ -86,6 +86,7 @@
 #include <linux/in.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/fddidevice.h>
index 04a6fe3..7b9bb28 100644 (file)
@@ -58,6 +58,7 @@
 #endif
 #include <linux/kmod.h>
 
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/route.h>
 #include <net/ip_fib.h>
index 1b18ce6..73bfcae 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/pfkeyv2.h>
 #include <linux/random.h>
 #include <net/icmp.h>
+#include <net/protocol.h>
 #include <net/udp.h>
 
 /* decapsulation data for use when post-processing */
index 19b1b98..18f5e50 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
index 7ea0209..e2890ec 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
index 0b298bb..0dd4d06 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
index 6d2a6ac..ef4724d 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
@@ -36,6 +37,7 @@
 #include <linux/netlink.h>
 #include <linux/init.h>
 
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
index 705e3ce..e320b32 100644 (file)
  *             modify it under the terms of the GNU General Public License
  *             as published by the Free Software Foundation; either version
  *             2 of the License, or (at your option) any later version.
+ *
+ * Substantial contributions to this work comes from:
+ *
+ *             David S. Miller, <davem@davemloft.net>
+ *             Stephen Hemminger <shemminger@osdl.org>
+ *             Paul E. McKenney <paulmck@us.ibm.com>
+ *             Patrick McHardy <kaber@trash.net>
  */
 
 #define VERSION "0.404"
@@ -59,6 +66,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
index 92e23b2..be5a519 100644 (file)
@@ -73,6 +73,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/string.h>
 #include <linux/netfilter_ipv4.h>
index 4a195c7..3475811 100644 (file)
@@ -91,6 +91,8 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/times.h>
+
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
index 3fe021f..ae20281 100644 (file)
@@ -37,7 +37,8 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);
  */
 int sysctl_local_port_range[2] = { 1024, 4999 };
 
-static inline int inet_csk_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb)
+int inet_csk_bind_conflict(const struct sock *sk,
+                          const struct inet_bind_bucket *tb)
 {
        const u32 sk_rcv_saddr = inet_rcv_saddr(sk);
        struct sock *sk2;
@@ -62,11 +63,15 @@ static inline int inet_csk_bind_conflict(struct sock *sk, struct inet_bind_bucke
        return node != NULL;
 }
 
+EXPORT_SYMBOL_GPL(inet_csk_bind_conflict);
+
 /* Obtain a reference to a local port for the given sock,
  * if snum is zero it means select any available local port.
  */
 int inet_csk_get_port(struct inet_hashinfo *hashinfo,
-                     struct sock *sk, unsigned short snum)
+                     struct sock *sk, unsigned short snum,
+                     int (*bind_conflict)(const struct sock *sk,
+                                          const struct inet_bind_bucket *tb))
 {
        struct inet_bind_hashbucket *head;
        struct hlist_node *node;
@@ -125,7 +130,7 @@ tb_found:
                        goto success;
                } else {
                        ret = 1;
-                       if (inet_csk_bind_conflict(sk, tb))
+                       if (bind_conflict(sk, tb))
                                goto fail_unlock;
                }
        }
@@ -380,7 +385,7 @@ struct request_sock *inet_csk_search_req(const struct sock *sk,
 EXPORT_SYMBOL_GPL(inet_csk_search_req);
 
 void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
-                                  const unsigned timeout)
+                                  unsigned long timeout)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
@@ -631,3 +636,15 @@ void inet_csk_listen_stop(struct sock *sk)
 }
 
 EXPORT_SYMBOL_GPL(inet_csk_listen_stop);
+
+void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
+{
+       struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
+       const struct inet_sock *inet = inet_sk(sk);
+
+       sin->sin_family         = AF_INET;
+       sin->sin_addr.s_addr    = inet->daddr;
+       sin->sin_port           = inet->dport;
+}
+
+EXPORT_SYMBOL_GPL(inet_csk_addr2sockaddr);
index 39061ed..c499081 100644 (file)
@@ -112,12 +112,12 @@ static int inet_diag_fill(struct sk_buff *skb, struct sock *sk,
                r->idiag_inode = 0;
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
                if (r->idiag_family == AF_INET6) {
-                       const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk);
+                       const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
 
                        ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
-                                      &tcp6tw->tw_v6_rcv_saddr);
+                                      &tw6->tw_v6_rcv_saddr);
                        ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
-                                      &tcp6tw->tw_v6_daddr);
+                                      &tw6->tw_v6_daddr);
                }
 #endif
                nlh->nlmsg_len = skb->tail - b;
@@ -489,9 +489,9 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
        if (r->idiag_family == AF_INET6) {
                ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
-                              &tcp6_rsk(req)->loc_addr);
+                              &inet6_rsk(req)->loc_addr);
                ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
-                              &tcp6_rsk(req)->rmt_addr);
+                              &inet6_rsk(req)->rmt_addr);
        }
 #endif
        nlh->nlmsg_len = skb->tail - b;
@@ -553,13 +553,13 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
                                entry.saddr =
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
                                        (entry.family == AF_INET6) ?
-                                       tcp6_rsk(req)->loc_addr.s6_addr32 :
+                                       inet6_rsk(req)->loc_addr.s6_addr32 :
 #endif
                                        &ireq->loc_addr;
                                entry.daddr = 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
                                        (entry.family == AF_INET6) ?
-                                       tcp6_rsk(req)->rmt_addr.s6_addr32 :
+                                       inet6_rsk(req)->rmt_addr.s6_addr32 :
 #endif
                                        &ireq->rmt_addr;
                                entry.dport = ntohs(ireq->rmt_port);
index e8d29fe..3322811 100644 (file)
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_hashtables.h>
+#include <net/ip.h>
 
 /*
  * Allocate and initialize a new local port bind bucket.
@@ -163,3 +165,179 @@ struct sock *__inet_lookup_listener(const struct hlist_head *head, const u32 dad
 }
 
 EXPORT_SYMBOL_GPL(__inet_lookup_listener);
+
+/* called with local bh disabled */
+static int __inet_check_established(struct inet_timewait_death_row *death_row,
+                                   struct sock *sk, __u16 lport,
+                                   struct inet_timewait_sock **twp)
+{
+       struct inet_hashinfo *hinfo = death_row->hashinfo;
+       struct inet_sock *inet = inet_sk(sk);
+       u32 daddr = inet->rcv_saddr;
+       u32 saddr = inet->daddr;
+       int dif = sk->sk_bound_dev_if;
+       INET_ADDR_COOKIE(acookie, saddr, daddr)
+       const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+       unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
+       struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+       struct sock *sk2;
+       const struct hlist_node *node;
+       struct inet_timewait_sock *tw;
+
+       prefetch(head->chain.first);
+       write_lock(&head->lock);
+
+       /* Check TIME-WAIT sockets first. */
+       sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) {
+               tw = inet_twsk(sk2);
+
+               if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
+                       if (twsk_unique(sk, sk2, twp))
+                               goto unique;
+                       else
+                               goto not_unique;
+               }
+       }
+       tw = NULL;
+
+       /* And established part... */
+       sk_for_each(sk2, node, &head->chain) {
+               if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
+                       goto not_unique;
+       }
+
+unique:
+       /* Must record num and sport now. Otherwise we will see
+        * in hash table socket with a funny identity. */
+       inet->num = lport;
+       inet->sport = htons(lport);
+       sk->sk_hash = hash;
+       BUG_TRAP(sk_unhashed(sk));
+       __sk_add_node(sk, &head->chain);
+       sock_prot_inc_use(sk->sk_prot);
+       write_unlock(&head->lock);
+
+       if (twp) {
+               *twp = tw;
+               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+       } else if (tw) {
+               /* Silly. Should hash-dance instead... */
+               inet_twsk_deschedule(tw, death_row);
+               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+
+               inet_twsk_put(tw);
+       }
+
+       return 0;
+
+not_unique:
+       write_unlock(&head->lock);
+       return -EADDRNOTAVAIL;
+}
+
+static inline u32 inet_sk_port_offset(const struct sock *sk)
+{
+       const struct inet_sock *inet = inet_sk(sk);
+       return secure_ipv4_port_ephemeral(inet->rcv_saddr, inet->daddr, 
+                                         inet->dport);
+}
+
+/*
+ * Bind a port for a connect operation and hash it.
+ */
+int inet_hash_connect(struct inet_timewait_death_row *death_row,
+                     struct sock *sk)
+{
+       struct inet_hashinfo *hinfo = death_row->hashinfo;
+       const unsigned short snum = inet_sk(sk)->num;
+       struct inet_bind_hashbucket *head;
+       struct inet_bind_bucket *tb;
+       int ret;
+
+       if (!snum) {
+               int low = sysctl_local_port_range[0];
+               int high = sysctl_local_port_range[1];
+               int range = high - low;
+               int i;
+               int port;
+               static u32 hint;
+               u32 offset = hint + inet_sk_port_offset(sk);
+               struct hlist_node *node;
+               struct inet_timewait_sock *tw = NULL;
+
+               local_bh_disable();
+               for (i = 1; i <= range; i++) {
+                       port = low + (i + offset) % range;
+                       head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
+                       spin_lock(&head->lock);
+
+                       /* Does not bother with rcv_saddr checks,
+                        * because the established check is already
+                        * unique enough.
+                        */
+                       inet_bind_bucket_for_each(tb, node, &head->chain) {
+                               if (tb->port == port) {
+                                       BUG_TRAP(!hlist_empty(&tb->owners));
+                                       if (tb->fastreuse >= 0)
+                                               goto next_port;
+                                       if (!__inet_check_established(death_row,
+                                                                     sk, port,
+                                                                     &tw))
+                                               goto ok;
+                                       goto next_port;
+                               }
+                       }
+
+                       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
+                       if (!tb) {
+                               spin_unlock(&head->lock);
+                               break;
+                       }
+                       tb->fastreuse = -1;
+                       goto ok;
+
+               next_port:
+                       spin_unlock(&head->lock);
+               }
+               local_bh_enable();
+
+               return -EADDRNOTAVAIL;
+
+ok:
+               hint += i;
+
+               /* Head lock still held and bh's disabled */
+               inet_bind_hash(sk, tb, port);
+               if (sk_unhashed(sk)) {
+                       inet_sk(sk)->sport = htons(port);
+                       __inet_hash(hinfo, sk, 0);
+               }
+               spin_unlock(&head->lock);
+
+               if (tw) {
+                       inet_twsk_deschedule(tw, death_row);;
+                       inet_twsk_put(tw);
+               }
+
+               ret = 0;
+               goto out;
+       }
+
+       head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
+       tb  = inet_csk(sk)->icsk_bind_hash;
+       spin_lock_bh(&head->lock);
+       if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+               __inet_hash(hinfo, sk, 0);
+               spin_unlock_bh(&head->lock);
+               return 0;
+       } else {
+               spin_unlock(&head->lock);
+               /* No definite answer... Walk to established hash table */
+               ret = __inet_check_established(death_row, sk, snum, NULL);
+out:
+               local_bh_enable();
+               return ret;
+       }
+}
+
+EXPORT_SYMBOL_GPL(inet_hash_connect);
index a010e9a..417f126 100644 (file)
@@ -90,8 +90,9 @@ EXPORT_SYMBOL_GPL(__inet_twsk_hashdance);
 
 struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state)
 {
-       struct inet_timewait_sock *tw = kmem_cache_alloc(sk->sk_prot_creator->twsk_slab,
-                                                        SLAB_ATOMIC);
+       struct inet_timewait_sock *tw =
+               kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab,
+                                SLAB_ATOMIC);
        if (tw != NULL) {
                const struct inet_sock *inet = inet_sk(sk);
 
index 2fc3fd3..ce5fe3f 100644 (file)
@@ -401,6 +401,7 @@ struct inet_peer *inet_getpeer(__u32 daddr, int create)
                return NULL;
        n->v4daddr = daddr;
        atomic_set(&n->refcnt, 1);
+       atomic_set(&n->rid, 0);
        n->ip_id_count = secure_ip_id(daddr);
        n->tcp_ts_stamp = 0;
 
index 8ce0ce2..ce2b70c 100644 (file)
@@ -22,6 +22,7 @@
  *             Patrick McHardy :       LRU queue of frag heads for evictor.
  */
 
+#include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -38,6 +39,7 @@
 #include <net/ip.h>
 #include <net/icmp.h>
 #include <net/checksum.h>
+#include <net/inetpeer.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/inet.h>
@@ -56,6 +58,8 @@
 int sysctl_ipfrag_high_thresh = 256*1024;
 int sysctl_ipfrag_low_thresh = 192*1024;
 
+int sysctl_ipfrag_max_dist = 64;
+
 /* Important NOTE! Fragment queue must be destroyed before MSL expires.
  * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
  */
@@ -89,8 +93,10 @@ struct ipq {
        spinlock_t      lock;
        atomic_t        refcnt;
        struct timer_list timer;        /* when will this queue expire?         */
-       int             iif;
        struct timeval  stamp;
+       int             iif;
+       unsigned int    rid;
+       struct inet_peer *peer;
 };
 
 /* Hash table. */
@@ -195,6 +201,9 @@ static void ip_frag_destroy(struct ipq *qp, int *work)
        BUG_TRAP(qp->last_in&COMPLETE);
        BUG_TRAP(del_timer(&qp->timer) == 0);
 
+       if (qp->peer)
+               inet_putpeer(qp->peer);
+
        /* Release all fragment data. */
        fp = qp->fragments;
        while (fp) {
@@ -353,6 +362,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user)
        qp->meat = 0;
        qp->fragments = NULL;
        qp->iif = 0;
+       qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
 
        /* Initialize a timer for this entry. */
        init_timer(&qp->timer);
@@ -398,6 +408,56 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
        return ip_frag_create(hash, iph, user);
 }
 
+/* Is the fragment too far ahead to be part of ipq? */
+static inline int ip_frag_too_far(struct ipq *qp)
+{
+       struct inet_peer *peer = qp->peer;
+       unsigned int max = sysctl_ipfrag_max_dist;
+       unsigned int start, end;
+
+       int rc;
+
+       if (!peer || !max)
+               return 0;
+
+       start = qp->rid;
+       end = atomic_inc_return(&peer->rid);
+       qp->rid = end;
+
+       rc = qp->fragments && (end - start) > max;
+
+       if (rc) {
+               IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
+       }
+
+       return rc;
+}
+
+static int ip_frag_reinit(struct ipq *qp)
+{
+       struct sk_buff *fp;
+
+       if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) {
+               atomic_inc(&qp->refcnt);
+               return -ETIMEDOUT;
+       }
+
+       fp = qp->fragments;
+       do {
+               struct sk_buff *xp = fp->next;
+               frag_kfree_skb(fp, NULL);
+               fp = xp;
+       } while (fp);
+
+       qp->last_in = 0;
+       qp->len = 0;
+       qp->meat = 0;
+       qp->fragments = NULL;
+       qp->iif = 0;
+
+       return 0;
+}
+
 /* Add new segment to existing queue. */
 static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 {
@@ -408,6 +468,12 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
        if (qp->last_in & COMPLETE)
                goto err;
 
+       if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) &&
+           unlikely(ip_frag_too_far(qp)) && unlikely(ip_frag_reinit(qp))) {
+               ipq_kill(qp);
+               goto err;
+       }
+
        offset = ntohs(skb->nh.iph->frag_off);
        flags = offset & ~IP_OFFSET;
        offset &= IP_OFFSET;
index 473d0f2..e45846a 100644 (file)
 #include <linux/sockios.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 
index dbe12da..d3f6c46 100644 (file)
@@ -22,6 +22,7 @@
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
+#include <net/route.h>
 
 /* 
  * Write options to IP header, record destination address to
index eba64e2..2a830de 100644 (file)
@@ -445,6 +445,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
 
        hlen = iph->ihl * 4;
        mtu = dst_mtu(&rt->u.dst) - hlen;       /* Size of data space */
+       IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
 
        /* When frag_list is given, use it. First, check its validity:
         * some transformers could create wrong frag_list or break existing
index 4f2d872..6986e11 100644 (file)
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <linux/icmp.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
-#include <net/tcp.h>
-#include <linux/tcp.h>
+#include <net/tcp_states.h>
 #include <linux/udp.h>
 #include <linux/igmp.h>
 #include <linux/netfilter.h>
@@ -427,8 +427,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
                        err = ip_options_get_from_user(&opt, optval, optlen);
                        if (err)
                                break;
-                       if (sk->sk_type == SOCK_STREAM) {
-                               struct tcp_sock *tp = tcp_sk(sk);
+                       if (inet->is_icsk) {
+                               struct inet_connection_sock *icsk = inet_csk(sk);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                                if (sk->sk_family == PF_INET ||
                                    (!((1 << sk->sk_state) &
@@ -436,10 +436,10 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
                                     inet->daddr != LOOPBACK4_IPV6)) {
 #endif
                                        if (inet->opt)
-                                               tp->ext_header_len -= inet->opt->optlen;
+                                               icsk->icsk_ext_hdr_len -= inet->opt->optlen;
                                        if (opt)
-                                               tp->ext_header_len += opt->optlen;
-                                       tcp_sync_mss(sk, tp->pmtu_cookie);
+                                               icsk->icsk_ext_hdr_len += opt->optlen;
+                                       icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                                }
 #endif
index fc718df..d64e2ec 100644 (file)
@@ -28,6 +28,7 @@
 #include <net/xfrm.h>
 #include <net/icmp.h>
 #include <net/ipcomp.h>
+#include <net/protocol.h>
 
 struct ipcomp_tfms {
        struct list_head list;
index e8674ba..bb3613e 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/in.h>
 #include <linux/if.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
@@ -58,6 +59,7 @@
 #include <net/arp.h>
 #include <net/ip.h>
 #include <net/ipconfig.h>
+#include <net/route.h>
 
 #include <asm/uaccess.h>
 #include <net/checksum.h>
index 302b7eb..caa3b7d 100644 (file)
@@ -52,6 +52,7 @@
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <linux/skbuff.h>
+#include <net/route.h>
 #include <net/sock.h>
 #include <net/icmp.h>
 #include <net/udp.h>
index d7eb680..9b176a9 100644 (file)
@@ -224,34 +224,6 @@ void unregister_ip_vs_app(struct ip_vs_app *app)
 }
 
 
-#if 0000
-/*
- *     Get reference to app by name (called from user context)
- */
-struct ip_vs_app *ip_vs_app_get_by_name(char *appname)
-{
-       struct ip_vs_app *app, *a = NULL;
-
-       down(&__ip_vs_app_mutex);
-
-       list_for_each_entry(ent, &ip_vs_app_list, a_list) {
-               if (strcmp(app->name, appname))
-                       continue;
-
-               /* softirq may call ip_vs_app_get too, so the caller
-                  must disable softirq on the current CPU */
-               if (ip_vs_app_get(app))
-                       a = app;
-               break;
-       }
-
-       up(&__ip_vs_app_mutex);
-
-       return a;
-}
-#endif
-
-
 /*
  *     Bind ip_vs_conn to its ip_vs_app (called by cp constructor)
  */
index 2a3a8c5..81d9035 100644 (file)
  *
  */
 
+#include <linux/in.h>
+#include <linux/net.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/proc_fs.h>             /* for proc_net_* */
 #include <linux/seq_file.h>
@@ -219,7 +222,7 @@ struct ip_vs_conn *ip_vs_conn_in_get
        if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt))
                cp = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port);
 
-       IP_VS_DBG(7, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+       IP_VS_DBG(9, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
                  ip_vs_proto_name(protocol),
                  NIPQUAD(s_addr), ntohs(s_port),
                  NIPQUAD(d_addr), ntohs(d_port),
@@ -254,7 +257,7 @@ struct ip_vs_conn *ip_vs_ct_in_get
   out:
        ct_read_unlock(hash);
 
-       IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+       IP_VS_DBG(9, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
                  ip_vs_proto_name(protocol),
                  NIPQUAD(s_addr), ntohs(s_port),
                  NIPQUAD(d_addr), ntohs(d_port),
@@ -295,7 +298,7 @@ struct ip_vs_conn *ip_vs_conn_out_get
 
        ct_read_unlock(hash);
 
-       IP_VS_DBG(7, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+       IP_VS_DBG(9, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
                  ip_vs_proto_name(protocol),
                  NIPQUAD(s_addr), ntohs(s_port),
                  NIPQUAD(d_addr), ntohs(d_port),
@@ -391,8 +394,9 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
        cp->flags |= atomic_read(&dest->conn_flags);
        cp->dest = dest;
 
-       IP_VS_DBG(9, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
-                 "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n",
+       IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
+                 "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
+                 "dest->refcnt:%d\n",
                  ip_vs_proto_name(cp->protocol),
                  NIPQUAD(cp->caddr), ntohs(cp->cport),
                  NIPQUAD(cp->vaddr), ntohs(cp->vport),
@@ -430,8 +434,9 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
        if (!dest)
                return;
 
-       IP_VS_DBG(9, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
-                 "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n",
+       IP_VS_DBG(7, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
+                 "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
+                 "dest->refcnt:%d\n",
                  ip_vs_proto_name(cp->protocol),
                  NIPQUAD(cp->caddr), ntohs(cp->cport),
                  NIPQUAD(cp->vaddr), ntohs(cp->vport),
@@ -571,7 +576,7 @@ static void ip_vs_conn_expire(unsigned long data)
        ip_vs_conn_hash(cp);
 
   expire_later:
-       IP_VS_DBG(7, "delayed: refcnt-1=%d conn.n_control=%d\n",
+       IP_VS_DBG(7, "delayed: conn->refcnt-1=%d conn->n_control=%d\n",
                  atomic_read(&cp->refcnt)-1,
                  atomic_read(&cp->n_control));
 
index 1a0843c..1aca94a 100644 (file)
@@ -426,7 +426,7 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
                return NULL;
 
        IP_VS_DBG(6, "Schedule fwd:%c c:%u.%u.%u.%u:%u v:%u.%u.%u.%u:%u "
-                 "d:%u.%u.%u.%u:%u flg:%X cnt:%d\n",
+                 "d:%u.%u.%u.%u:%u conn->flags:%X conn->refcnt:%d\n",
                  ip_vs_fwd_tag(cp),
                  NIPQUAD(cp->caddr), ntohs(cp->cport),
                  NIPQUAD(cp->vaddr), ntohs(cp->vport),
index 9bdcf31..c935c50 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/netfilter_ipv4.h>
 
 #include <net/ip.h>
+#include <net/route.h>
 #include <net/sock.h>
 
 #include <asm/uaccess.h>
@@ -447,7 +448,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport)
   out:
        read_unlock(&__ip_vs_svc_lock);
 
-       IP_VS_DBG(6, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n",
+       IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n",
                  fwmark, ip_vs_proto_name(protocol),
                  NIPQUAD(vaddr), ntohs(vport),
                  svc?"hit":"not hit");
@@ -597,7 +598,7 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport)
         */
        list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
                IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, "
-                         "refcnt=%d\n",
+                         "dest->refcnt=%d\n",
                          dest->vfwmark,
                          NIPQUAD(dest->addr), ntohs(dest->port),
                          atomic_read(&dest->refcnt));
@@ -804,7 +805,7 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
        dest = ip_vs_trash_get_dest(svc, daddr, dport);
        if (dest != NULL) {
                IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, "
-                         "refcnt=%d, service %u/%u.%u.%u.%u:%u\n",
+                         "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n",
                          NIPQUAD(daddr), ntohs(dport),
                          atomic_read(&dest->refcnt),
                          dest->vfwmark,
@@ -949,7 +950,8 @@ static void __ip_vs_del_dest(struct ip_vs_dest *dest)
                atomic_dec(&dest->svc->refcnt);
                kfree(dest);
        } else {
-               IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, refcnt=%d\n",
+               IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, "
+                         "dest->refcnt=%d\n",
                          NIPQUAD(dest->addr), ntohs(dest->port),
                          atomic_read(&dest->refcnt));
                list_add(&dest->n_list, &ip_vs_dest_trash);
index f3bc320..9fee19c 100644 (file)
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
index 67b3e2f..e700474 100644 (file)
  * Changes:
  *
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <net/ip_vs.h>
index 561cda3..6e5cb92 100644 (file)
  * me to write this module.
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 /* for sysctl */
 #include <linux/fs.h>
@@ -228,33 +230,6 @@ ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en)
 }
 
 
-#if 0000
-/*
- *     Unhash ip_vs_lblc_entry from ip_vs_lblc_table.
- *     returns bool success.
- */
-static int ip_vs_lblc_unhash(struct ip_vs_lblc_table *tbl,
-                            struct ip_vs_lblc_entry *en)
-{
-       if (list_empty(&en->list)) {
-               IP_VS_ERR("ip_vs_lblc_unhash(): request for not hashed entry, "
-                         "called from %p\n", __builtin_return_address(0));
-               return 0;
-       }
-
-       /*
-        * Remove it from the table
-        */
-       write_lock(&tbl->lock);
-       list_del(&en->list);
-       INIT_LIST_HEAD(&en->list);
-       write_unlock(&tbl->lock);
-
-       return 1;
-}
-#endif
-
-
 /*
  *  Get ip_vs_lblc_entry associated with supplied parameters.
  */
index ce456db..32ba37b 100644 (file)
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 /* for sysctl */
 #include <linux/fs.h>
@@ -414,33 +416,6 @@ ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en)
 }
 
 
-#if 0000
-/*
- *     Unhash ip_vs_lblcr_entry from ip_vs_lblcr_table.
- *     returns bool success.
- */
-static int ip_vs_lblcr_unhash(struct ip_vs_lblcr_table *tbl,
-                            struct ip_vs_lblcr_entry *en)
-{
-       if (list_empty(&en->list)) {
-               IP_VS_ERR("ip_vs_lblcr_unhash(): request for not hashed entry, "
-                         "called from %p\n", __builtin_return_address(0));
-               return 0;
-       }
-
-       /*
-        * Remove it from the table
-        */
-       write_lock(&tbl->lock);
-       list_del(&en->list);
-       INIT_LIST_HEAD(&en->list);
-       write_unlock(&tbl->lock);
-
-       return 1;
-}
-#endif
-
-
 /*
  *  Get ip_vs_lblcr_entry associated with supplied parameters.
  */
index 453e94a..8b0505b 100644 (file)
@@ -12,6 +12,8 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netfilter.h>
index 478e5c7..c36ccf0 100644 (file)
@@ -12,6 +12,8 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netfilter.h>
index 0e878fd..bc28b11 100644 (file)
@@ -275,28 +275,6 @@ static int tcp_timeouts[IP_VS_TCP_S_LAST+1] = {
        [IP_VS_TCP_S_LAST]              =       2*HZ,
 };
 
-
-#if 0
-
-/* FIXME: This is going to die */
-
-static int tcp_timeouts_dos[IP_VS_TCP_S_LAST+1] = {
-       [IP_VS_TCP_S_NONE]              =       2*HZ,
-       [IP_VS_TCP_S_ESTABLISHED]       =       8*60*HZ,
-       [IP_VS_TCP_S_SYN_SENT]          =       60*HZ,
-       [IP_VS_TCP_S_SYN_RECV]          =       10*HZ,
-       [IP_VS_TCP_S_FIN_WAIT]          =       60*HZ,
-       [IP_VS_TCP_S_TIME_WAIT]         =       60*HZ,
-       [IP_VS_TCP_S_CLOSE]             =       10*HZ,
-       [IP_VS_TCP_S_CLOSE_WAIT]        =       60*HZ,
-       [IP_VS_TCP_S_LAST_ACK]          =       30*HZ,
-       [IP_VS_TCP_S_LISTEN]            =       2*60*HZ,
-       [IP_VS_TCP_S_SYNACK]            =       100*HZ,
-       [IP_VS_TCP_S_LAST]              =       2*HZ,
-};
-
-#endif
-
 static char * tcp_state_name_table[IP_VS_TCP_S_LAST+1] = {
        [IP_VS_TCP_S_NONE]              =       "NONE",
        [IP_VS_TCP_S_ESTABLISHED]       =       "ESTABLISHED",
@@ -448,7 +426,7 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
                struct ip_vs_dest *dest = cp->dest;
 
                IP_VS_DBG(8, "%s %s [%c%c%c%c] %u.%u.%u.%u:%d->"
-                         "%u.%u.%u.%u:%d state: %s->%s cnt:%d\n",
+                         "%u.%u.%u.%u:%d state: %s->%s conn->refcnt:%d\n",
                          pp->name,
                          (state_off==TCP_DIR_OUTPUT)?"output ":"input ",
                          th->syn? 'S' : '.',
index 8ae5f2e..89d9175 100644 (file)
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/kernel.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/udp.h>
 
 #include <net/ip_vs.h>
 
index 6f7c50e..7775e6c 100644 (file)
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
index 2e5ced3..1bca714 100644 (file)
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/inetdevice.h>
 #include <linux/net.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
 #include <linux/igmp.h>                 /* for ip_mc_join_group */
+#include <linux/udp.h>
 
 #include <net/ip.h>
 #include <net/sock.h>
index 3c2e963..bba1563 100644 (file)
@@ -68,19 +68,14 @@ struct arpt_table_info {
        unsigned int initial_entries;
        unsigned int hook_entry[NF_ARP_NUMHOOKS];
        unsigned int underflow[NF_ARP_NUMHOOKS];
-       char entries[0] __attribute__((aligned(SMP_CACHE_BYTES)));
+       void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(arpt_target);
 static LIST_HEAD(arpt_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
                                      char *hdr_addr, int len)
 {
@@ -269,9 +264,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
        outdev = out ? out->name : nulldevname;
 
        read_lock_bh(&table->lock);
-       table_base = (void *)table->private->entries
-               + TABLE_OFFSET(table->private,
-                              smp_processor_id());
+       table_base = (void *)table->private->entries[smp_processor_id()];
        e = get_entry(table_base, table->private->hook_entry[hook]);
        back = get_entry(table_base, table->private->underflow[hook]);
 
@@ -462,7 +455,8 @@ static inline int unconditional(const struct arpt_arp *arp)
 /* Figures out from what hook each rule can be called: returns 0 if
  * there are loops.  Puts hook bitmask in comefrom.
  */
-static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int valid_hooks)
+static int mark_source_chains(struct arpt_table_info *newinfo,
+                             unsigned int valid_hooks, void *entry0)
 {
        unsigned int hook;
 
@@ -472,7 +466,7 @@ static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int vali
        for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) {
                unsigned int pos = newinfo->hook_entry[hook];
                struct arpt_entry *e
-                       = (struct arpt_entry *)(newinfo->entries + pos);
+                       = (struct arpt_entry *)(entry0 + pos);
 
                if (!(valid_hooks & (1 << hook)))
                        continue;
@@ -514,13 +508,13 @@ static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int vali
                                                goto next;
 
                                        e = (struct arpt_entry *)
-                                               (newinfo->entries + pos);
+                                               (entry0 + pos);
                                } while (oldpos == pos + e->next_offset);
 
                                /* Move along one */
                                size = e->next_offset;
                                e = (struct arpt_entry *)
-                                       (newinfo->entries + pos + size);
+                                       (entry0 + pos + size);
                                e->counters.pcnt = pos;
                                pos += size;
                        } else {
@@ -537,7 +531,7 @@ static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int vali
                                        newpos = pos + e->next_offset;
                                }
                                e = (struct arpt_entry *)
-                                       (newinfo->entries + newpos);
+                                       (entry0 + newpos);
                                e->counters.pcnt = pos;
                                pos = newpos;
                        }
@@ -689,6 +683,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
 static int translate_table(const char *name,
                           unsigned int valid_hooks,
                           struct arpt_table_info *newinfo,
+                          void *entry0,
                           unsigned int size,
                           unsigned int number,
                           const unsigned int *hook_entries,
@@ -710,11 +705,11 @@ static int translate_table(const char *name,
        i = 0;
 
        /* Walk through entries, checking offsets. */
-       ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+       ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
                                 check_entry_size_and_hooks,
                                 newinfo,
-                                newinfo->entries,
-                                newinfo->entries + size,
+                                entry0,
+                                entry0 + size,
                                 hook_entries, underflows, &i);
        duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
        if (ret != 0)
@@ -743,29 +738,26 @@ static int translate_table(const char *name,
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks)) {
+       if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
                duprintf("Looping hook\n");
                return -ELOOP;
        }
 
        /* Finally, each sanity check must pass */
        i = 0;
-       ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+       ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
                                 check_entry, name, size, &i);
 
        if (ret != 0) {
-               ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+               ARPT_ENTRY_ITERATE(entry0, newinfo->size,
                                   cleanup_entry, &i);
                return ret;
        }
 
        /* And one copy for every other CPU */
        for_each_cpu(i) {
-               if (i == 0)
-                       continue;
-               memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-                      newinfo->entries,
-                      SMP_ALIGN(newinfo->size));
+               if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+                       memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
        return ret;
@@ -807,15 +799,42 @@ static inline int add_entry_to_counter(const struct arpt_entry *e,
        return 0;
 }
 
+static inline int set_entry_to_counter(const struct arpt_entry *e,
+                                      struct arpt_counters total[],
+                                      unsigned int *i)
+{
+       SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+       (*i)++;
+       return 0;
+}
+
 static void get_counters(const struct arpt_table_info *t,
                         struct arpt_counters counters[])
 {
        unsigned int cpu;
        unsigned int i;
+       unsigned int curcpu;
+
+       /* Instead of clearing (by a previous call to memset())
+        * the counters and using adds, we set the counters
+        * with data used by 'current' CPU
+        * We dont care about preemption here.
+        */
+       curcpu = raw_smp_processor_id();
+
+       i = 0;
+       ARPT_ENTRY_ITERATE(t->entries[curcpu],
+                          t->size,
+                          set_entry_to_counter,
+                          counters,
+                          &i);
 
        for_each_cpu(cpu) {
+               if (cpu == curcpu)
+                       continue;
                i = 0;
-               ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+               ARPT_ENTRY_ITERATE(t->entries[cpu],
                                   t->size,
                                   add_entry_to_counter,
                                   counters,
@@ -831,6 +850,7 @@ static int copy_entries_to_user(unsigned int total_size,
        struct arpt_entry *e;
        struct arpt_counters *counters;
        int ret = 0;
+       void *loc_cpu_entry;
 
        /* We need atomic snapshot of counters: rest doesn't change
         * (other than comefrom, which userspace doesn't care
@@ -843,13 +863,13 @@ static int copy_entries_to_user(unsigned int total_size,
                return -ENOMEM;
 
        /* First, sum counters... */
-       memset(counters, 0, countersize);
        write_lock_bh(&table->lock);
        get_counters(table->private, counters);
        write_unlock_bh(&table->lock);
 
-       /* ... then copy entire thing from CPU 0... */
-       if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+       loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+       /* ... then copy entire thing ... */
+       if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
                ret = -EFAULT;
                goto free_counters;
        }
@@ -859,7 +879,7 @@ static int copy_entries_to_user(unsigned int total_size,
        for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
                struct arpt_entry_target *t;
 
-               e = (struct arpt_entry *)(table->private->entries + off);
+               e = (struct arpt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
                                 + offsetof(struct arpt_entry, counters),
                                 &counters[num],
@@ -911,6 +931,47 @@ static int get_entries(const struct arpt_get_entries *entries,
        return ret;
 }
 
+static void free_table_info(struct arpt_table_info *info)
+{
+       int cpu;
+       for_each_cpu(cpu) {
+               if (info->size <= PAGE_SIZE)
+                       kfree(info->entries[cpu]);
+               else
+                       vfree(info->entries[cpu]);
+       }
+       kfree(info);
+}
+
+static struct arpt_table_info *alloc_table_info(unsigned int size)
+{
+       struct arpt_table_info *newinfo;
+       int cpu;
+       
+       newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL);
+       if (!newinfo)
+               return NULL;
+
+       newinfo->size = size;
+
+       for_each_cpu(cpu) {
+               if (size <= PAGE_SIZE)
+                       newinfo->entries[cpu] = kmalloc_node(size,
+                                                       GFP_KERNEL,
+                                                       cpu_to_node(cpu));
+               else
+                       newinfo->entries[cpu] = vmalloc_node(size,
+                                                            cpu_to_node(cpu));
+
+               if (newinfo->entries[cpu] == NULL) {
+                       free_table_info(newinfo);
+                       return NULL;
+               }
+       }
+
+       return newinfo;
+}
+
 static int do_replace(void __user *user, unsigned int len)
 {
        int ret;
@@ -918,6 +979,7 @@ static int do_replace(void __user *user, unsigned int len)
        struct arpt_table *t;
        struct arpt_table_info *newinfo, *oldinfo;
        struct arpt_counters *counters;
+       void *loc_cpu_entry, *loc_cpu_old_entry;
 
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
@@ -930,13 +992,13 @@ static int do_replace(void __user *user, unsigned int len)
        if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
                return -ENOMEM;
 
-       newinfo = vmalloc(sizeof(struct arpt_table_info)
-                         + SMP_ALIGN(tmp.size) *
-                                       (highest_possible_processor_id()+1));
+       newinfo = alloc_table_info(tmp.size);
        if (!newinfo)
                return -ENOMEM;
 
-       if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+       /* choose the copy that is on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
                           tmp.size) != 0) {
                ret = -EFAULT;
                goto free_newinfo;
@@ -947,10 +1009,9 @@ static int do_replace(void __user *user, unsigned int len)
                ret = -ENOMEM;
                goto free_newinfo;
        }
-       memset(counters, 0, tmp.num_counters * sizeof(struct arpt_counters));
 
        ret = translate_table(tmp.name, tmp.valid_hooks,
-                             newinfo, tmp.size, tmp.num_entries,
+                             newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
                              tmp.hook_entry, tmp.underflow);
        if (ret != 0)
                goto free_newinfo_counters;
@@ -989,8 +1050,10 @@ static int do_replace(void __user *user, unsigned int len)
        /* Get the old counters. */
        get_counters(oldinfo, counters);
        /* Decrease module usage counts and free resource */
-       ARPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-       vfree(oldinfo);
+       loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+       ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+
+       free_table_info(oldinfo);
        if (copy_to_user(tmp.counters, counters,
                         sizeof(struct arpt_counters) * tmp.num_counters) != 0)
                ret = -EFAULT;
@@ -1002,11 +1065,11 @@ static int do_replace(void __user *user, unsigned int len)
        module_put(t->me);
        up(&arpt_mutex);
  free_newinfo_counters_untrans:
-       ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL);
+       ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
  free_newinfo_counters:
        vfree(counters);
  free_newinfo:
-       vfree(newinfo);
+       free_table_info(newinfo);
        return ret;
 }
 
@@ -1030,6 +1093,7 @@ static int do_add_counters(void __user *user, unsigned int len)
        struct arpt_counters_info tmp, *paddc;
        struct arpt_table *t;
        int ret = 0;
+       void *loc_cpu_entry;
 
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
@@ -1059,7 +1123,9 @@ static int do_add_counters(void __user *user, unsigned int len)
        }
 
        i = 0;
-       ARPT_ENTRY_ITERATE(t->private->entries,
+       /* Choose the copy that is on our node */
+       loc_cpu_entry = t->private->entries[smp_processor_id()];
+       ARPT_ENTRY_ITERATE(loc_cpu_entry,
                           t->private->size,
                           add_counter_to_entry,
                           paddc->counters,
@@ -1220,30 +1286,32 @@ int arpt_register_table(struct arpt_table *table,
        struct arpt_table_info *newinfo;
        static struct arpt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
+       void *loc_cpu_entry;
 
-       newinfo = vmalloc(sizeof(struct arpt_table_info)
-                         + SMP_ALIGN(repl->size) *
-                                       (highest_possible_processor_id()+1));
+       newinfo = alloc_table_info(repl->size);
        if (!newinfo) {
                ret = -ENOMEM;
                return ret;
        }
-       memcpy(newinfo->entries, repl->entries, repl->size);
+
+       /* choose the copy on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       memcpy(loc_cpu_entry, repl->entries, repl->size);
 
        ret = translate_table(table->name, table->valid_hooks,
-                             newinfo, repl->size,
+                             newinfo, loc_cpu_entry, repl->size,
                              repl->num_entries,
                              repl->hook_entry,
                              repl->underflow);
        duprintf("arpt_register_table: translate table gives %d\n", ret);
        if (ret != 0) {
-               vfree(newinfo);
+               free_table_info(newinfo);
                return ret;
        }
 
        ret = down_interruptible(&arpt_mutex);
        if (ret != 0) {
-               vfree(newinfo);
+               free_table_info(newinfo);
                return ret;
        }
 
@@ -1272,20 +1340,23 @@ int arpt_register_table(struct arpt_table *table,
        return ret;
 
  free_unlock:
-       vfree(newinfo);
+       free_table_info(newinfo);
        goto unlock;
 }
 
 void arpt_unregister_table(struct arpt_table *table)
 {
+       void *loc_cpu_entry;
+
        down(&arpt_mutex);
        LIST_DELETE(&arpt_tables, table);
        up(&arpt_mutex);
 
        /* Decrease module usage counts and free resources */
-       ARPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+       loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+       ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
                           cleanup_entry, NULL);
-       vfree(table->private);
+       free_table_info(table->private);
 }
 
 /* The built-in targets: standard (NULL) and error. */
index e52847f..0366eed 100644 (file)
  *
  */
 
+#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
 #include <linux/moduleparam.h>
+#include <linux/udp.h>
 #include <net/checksum.h>
 #include <net/udp.h>
 
index 744abb9..57956de 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/list.h>
+#include <linux/seq_file.h>
 
 static DEFINE_RWLOCK(ip_ct_gre_lock);
 #define ASSERT_READ_LOCK(x)
index f2dcac7..46becbe 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/timer.h>
 #include <linux/netfilter.h>
 #include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/udp.h>
 #include <linux/seq_file.h>
 #include <net/checksum.h>
index dd476b1..a88bcc5 100644 (file)
@@ -27,6 +27,7 @@
 #endif
 #include <net/checksum.h>
 #include <net/ip.h>
+#include <net/route.h>
 
 #define ASSERT_READ_LOCK(x)
 #define ASSERT_WRITE_LOCK(x)
index 8acb7ed..4f95d47 100644 (file)
@@ -44,6 +44,7 @@
  *
  */
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -53,6 +54,7 @@
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_nat_helper.h>
 #include <linux/ip.h>
+#include <linux/udp.h>
 #include <net/checksum.h>
 #include <net/udp.h>
 #include <asm/uaccess.h>
index 45886c8..2a26d16 100644 (file)
@@ -83,11 +83,6 @@ static DECLARE_MUTEX(ipt_mutex);
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -105,20 +100,15 @@ struct ipt_table_info
        unsigned int underflow[NF_IP_NUMHOOKS];
 
        /* ipt_entry tables: one per CPU */
-       char entries[0] ____cacheline_aligned;
+       void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ipt_target);
 static LIST_HEAD(ipt_match);
 static LIST_HEAD(ipt_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
 #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
@@ -290,8 +280,7 @@ ipt_do_table(struct sk_buff **pskb,
 
        read_lock_bh(&table->lock);
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-       table_base = (void *)table->private->entries
-               + TABLE_OFFSET(table->private, smp_processor_id());
+       table_base = (void *)table->private->entries[smp_processor_id()];
        e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -563,7 +552,8 @@ unconditional(const struct ipt_ip *ip)
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
-mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks)
+mark_source_chains(struct ipt_table_info *newinfo,
+                  unsigned int valid_hooks, void *entry0)
 {
        unsigned int hook;
 
@@ -572,7 +562,7 @@ mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks)
        for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
                unsigned int pos = newinfo->hook_entry[hook];
                struct ipt_entry *e
-                       = (struct ipt_entry *)(newinfo->entries + pos);
+                       = (struct ipt_entry *)(entry0 + pos);
 
                if (!(valid_hooks & (1 << hook)))
                        continue;
@@ -622,13 +612,13 @@ mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks)
                                                goto next;
 
                                        e = (struct ipt_entry *)
-                                               (newinfo->entries + pos);
+                                               (entry0 + pos);
                                } while (oldpos == pos + e->next_offset);
 
                                /* Move along one */
                                size = e->next_offset;
                                e = (struct ipt_entry *)
-                                       (newinfo->entries + pos + size);
+                                       (entry0 + pos + size);
                                e->counters.pcnt = pos;
                                pos += size;
                        } else {
@@ -645,7 +635,7 @@ mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks)
                                        newpos = pos + e->next_offset;
                                }
                                e = (struct ipt_entry *)
-                                       (newinfo->entries + newpos);
+                                       (entry0 + newpos);
                                e->counters.pcnt = pos;
                                pos = newpos;
                        }
@@ -855,6 +845,7 @@ static int
 translate_table(const char *name,
                unsigned int valid_hooks,
                struct ipt_table_info *newinfo,
+               void *entry0,
                unsigned int size,
                unsigned int number,
                const unsigned int *hook_entries,
@@ -875,11 +866,11 @@ translate_table(const char *name,
        duprintf("translate_table: size %u\n", newinfo->size);
        i = 0;
        /* Walk through entries, checking offsets. */
-       ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+       ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry_size_and_hooks,
                                newinfo,
-                               newinfo->entries,
-                               newinfo->entries + size,
+                               entry0,
+                               entry0 + size,
                                hook_entries, underflows, &i);
        if (ret != 0)
                return ret;
@@ -907,27 +898,24 @@ translate_table(const char *name,
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks))
+       if (!mark_source_chains(newinfo, valid_hooks, entry0))
                return -ELOOP;
 
        /* Finally, each sanity check must pass */
        i = 0;
-       ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+       ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry, name, size, &i);
 
        if (ret != 0) {
-               IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+               IPT_ENTRY_ITERATE(entry0, newinfo->size,
                                  cleanup_entry, &i);
                return ret;
        }
 
        /* And one copy for every other CPU */
        for_each_cpu(i) {
-               if (i == 0)
-                       continue;
-               memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-                      newinfo->entries,
-                      SMP_ALIGN(newinfo->size));
+               if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+                       memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
        return ret;
@@ -943,15 +931,12 @@ replace_table(struct ipt_table *table,
 
 #ifdef CONFIG_NETFILTER_DEBUG
        {
-               struct ipt_entry *table_base;
-               unsigned int i;
+               int cpu;
 
-               for_each_cpu(i) {
-                       table_base =
-                               (void *)newinfo->entries
-                               + TABLE_OFFSET(newinfo, i);
-
-                       table_base->comefrom = 0xdead57ac;
+               for_each_cpu(cpu) {
+                       struct ipt_entry *table_base = newinfo->entries[cpu];
+                       if (table_base)
+                               table_base->comefrom = 0xdead57ac;
                }
        }
 #endif
@@ -986,16 +971,44 @@ add_entry_to_counter(const struct ipt_entry *e,
        return 0;
 }
 
+static inline int
+set_entry_to_counter(const struct ipt_entry *e,
+                    struct ipt_counters total[],
+                    unsigned int *i)
+{
+       SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+       (*i)++;
+       return 0;
+}
+
 static void
 get_counters(const struct ipt_table_info *t,
             struct ipt_counters counters[])
 {
        unsigned int cpu;
        unsigned int i;
+       unsigned int curcpu;
+
+       /* Instead of clearing (by a previous call to memset())
+        * the counters and using adds, we set the counters
+        * with data used by 'current' CPU
+        * We dont care about preemption here.
+        */
+       curcpu = raw_smp_processor_id();
+
+       i = 0;
+       IPT_ENTRY_ITERATE(t->entries[curcpu],
+                         t->size,
+                         set_entry_to_counter,
+                         counters,
+                         &i);
 
        for_each_cpu(cpu) {
+               if (cpu == curcpu)
+                       continue;
                i = 0;
-               IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+               IPT_ENTRY_ITERATE(t->entries[cpu],
                                  t->size,
                                  add_entry_to_counter,
                                  counters,
@@ -1012,24 +1025,29 @@ copy_entries_to_user(unsigned int total_size,
        struct ipt_entry *e;
        struct ipt_counters *counters;
        int ret = 0;
+       void *loc_cpu_entry;
 
        /* We need atomic snapshot of counters: rest doesn't change
           (other than comefrom, which userspace doesn't care
           about). */
        countersize = sizeof(struct ipt_counters) * table->private->number;
-       counters = vmalloc(countersize);
+       counters = vmalloc_node(countersize, numa_node_id());
 
        if (counters == NULL)
                return -ENOMEM;
 
        /* First, sum counters... */
-       memset(counters, 0, countersize);
        write_lock_bh(&table->lock);
        get_counters(table->private, counters);
        write_unlock_bh(&table->lock);
 
-       /* ... then copy entire thing from CPU 0... */
-       if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+       /* choose the copy that is on our node/cpu, ...
+        * This choice is lazy (because current thread is
+        * allowed to migrate to another cpu)
+        */
+       loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+       /* ... then copy entire thing ... */
+       if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
                ret = -EFAULT;
                goto free_counters;
        }
@@ -1041,7 +1059,7 @@ copy_entries_to_user(unsigned int total_size,
                struct ipt_entry_match *m;
                struct ipt_entry_target *t;
 
-               e = (struct ipt_entry *)(table->private->entries + off);
+               e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
                                 + offsetof(struct ipt_entry, counters),
                                 &counters[num],
@@ -1110,6 +1128,45 @@ get_entries(const struct ipt_get_entries *entries,
        return ret;
 }
 
+static void free_table_info(struct ipt_table_info *info)
+{
+       int cpu;
+       for_each_cpu(cpu) {
+               if (info->size <= PAGE_SIZE)
+                       kfree(info->entries[cpu]);
+               else
+                       vfree(info->entries[cpu]);
+       }
+       kfree(info);
+}
+
+static struct ipt_table_info *alloc_table_info(unsigned int size)
+{
+       struct ipt_table_info *newinfo;
+       int cpu;
+
+       newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL);
+       if (!newinfo)
+               return NULL;
+
+       newinfo->size = size;
+
+       for_each_cpu(cpu) {
+               if (size <= PAGE_SIZE)
+                       newinfo->entries[cpu] = kmalloc_node(size,
+                               GFP_KERNEL,
+                               cpu_to_node(cpu));
+               else
+                       newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu));
+               if (newinfo->entries[cpu] == 0) {
+                       free_table_info(newinfo);
+                       return NULL;
+               }
+       }
+
+       return newinfo;
+}
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1118,6 +1175,7 @@ do_replace(void __user *user, unsigned int len)
        struct ipt_table *t;
        struct ipt_table_info *newinfo, *oldinfo;
        struct ipt_counters *counters;
+       void *loc_cpu_entry, *loc_cpu_old_entry;
 
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
@@ -1130,13 +1188,13 @@ do_replace(void __user *user, unsigned int len)
        if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
                return -ENOMEM;
 
-       newinfo = vmalloc(sizeof(struct ipt_table_info)
-                         + SMP_ALIGN(tmp.size) * 
-                               (highest_possible_processor_id()+1));
+       newinfo = alloc_table_info(tmp.size);
        if (!newinfo)
                return -ENOMEM;
 
-       if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+       /* choose the copy that is our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
                           tmp.size) != 0) {
                ret = -EFAULT;
                goto free_newinfo;
@@ -1147,10 +1205,9 @@ do_replace(void __user *user, unsigned int len)
                ret = -ENOMEM;
                goto free_newinfo;
        }
-       memset(counters, 0, tmp.num_counters * sizeof(struct ipt_counters));
 
        ret = translate_table(tmp.name, tmp.valid_hooks,
-                             newinfo, tmp.size, tmp.num_entries,
+                             newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
                              tmp.hook_entry, tmp.underflow);
        if (ret != 0)
                goto free_newinfo_counters;
@@ -1189,8 +1246,9 @@ do_replace(void __user *user, unsigned int len)
        /* Get the old counters. */
        get_counters(oldinfo, counters);
        /* Decrease module usage counts and free resource */
-       IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-       vfree(oldinfo);
+       loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+       IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+       free_table_info(oldinfo);
        if (copy_to_user(tmp.counters, counters,
                         sizeof(struct ipt_counters) * tmp.num_counters) != 0)
                ret = -EFAULT;
@@ -1202,11 +1260,11 @@ do_replace(void __user *user, unsigned int len)
        module_put(t->me);
        up(&ipt_mutex);
  free_newinfo_counters_untrans:
-       IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+       IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
        vfree(counters);
  free_newinfo:
-       vfree(newinfo);
+       free_table_info(newinfo);
        return ret;
 }
 
@@ -1239,6 +1297,7 @@ do_add_counters(void __user *user, unsigned int len)
        struct ipt_counters_info tmp, *paddc;
        struct ipt_table *t;
        int ret = 0;
+       void *loc_cpu_entry;
 
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
@@ -1246,7 +1305,7 @@ do_add_counters(void __user *user, unsigned int len)
        if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters))
                return -EINVAL;
 
-       paddc = vmalloc(len);
+       paddc = vmalloc_node(len, numa_node_id());
        if (!paddc)
                return -ENOMEM;
 
@@ -1268,7 +1327,9 @@ do_add_counters(void __user *user, unsigned int len)
        }
 
        i = 0;
-       IPT_ENTRY_ITERATE(t->private->entries,
+       /* Choose the copy that is on our node */
+       loc_cpu_entry = t->private->entries[raw_smp_processor_id()];
+       IPT_ENTRY_ITERATE(loc_cpu_entry,
                          t->private->size,
                          add_counter_to_entry,
                          paddc->counters,
@@ -1460,28 +1521,31 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl)
        struct ipt_table_info *newinfo;
        static struct ipt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
+       void *loc_cpu_entry;
 
-       newinfo = vmalloc(sizeof(struct ipt_table_info)
-                         + SMP_ALIGN(repl->size) * 
-                                       (highest_possible_processor_id()+1));
+       newinfo = alloc_table_info(repl->size);
        if (!newinfo)
                return -ENOMEM;
 
-       memcpy(newinfo->entries, repl->entries, repl->size);
+       /* choose the copy on our node/cpu
+        * but dont care of preemption
+        */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       memcpy(loc_cpu_entry, repl->entries, repl->size);
 
        ret = translate_table(table->name, table->valid_hooks,
-                             newinfo, repl->size,
+                             newinfo, loc_cpu_entry, repl->size,
                              repl->num_entries,
                              repl->hook_entry,
                              repl->underflow);
        if (ret != 0) {
-               vfree(newinfo);
+               free_table_info(newinfo);
                return ret;
        }
 
        ret = down_interruptible(&ipt_mutex);
        if (ret != 0) {
-               vfree(newinfo);
+               free_table_info(newinfo);
                return ret;
        }
 
@@ -1510,20 +1574,23 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl)
        return ret;
 
  free_unlock:
-       vfree(newinfo);
+       free_table_info(newinfo);
        goto unlock;
 }
 
 void ipt_unregister_table(struct ipt_table *table)
 {
+       void *loc_cpu_entry;
+
        down(&ipt_mutex);
        LIST_DELETE(&ipt_tables, table);
        up(&ipt_mutex);
 
        /* Decrease module usage counts and free resources */
-       IPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+       loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+       IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
                          cleanup_entry, NULL);
-       vfree(table->private);
+       free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
index 275a174..2786051 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/inetdevice.h>
 #include <linux/ip.h>
 #include <linux/timer.h>
 #include <linux/module.h>
@@ -18,6 +19,7 @@
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/checksum.h>
+#include <net/route.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
index 1a53924..03f5548 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4/ipt_physdev.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
index 0d7dc66..39d49dc 100644 (file)
@@ -38,6 +38,7 @@
 #include <net/protocol.h>
 #include <net/tcp.h>
 #include <net/udp.h>
+#include <linux/inetdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <net/sock.h>
index a34e60e..e20be33 100644 (file)
@@ -173,10 +173,10 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
                                           struct request_sock *req,
                                           struct dst_entry *dst)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        struct sock *child;
 
-       child = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
+       child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst);
        if (child)
                inet_csk_reqsk_queue_add(sk, req, child);
        else
index 01444a0..16984d4 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/sysctl.h>
 #include <linux/config.h>
 #include <linux/igmp.h>
+#include <linux/inetdevice.h>
 #include <net/snmp.h>
 #include <net/icmp.h>
 #include <net/ip.h>
@@ -22,6 +23,7 @@
 extern int sysctl_ip_nonlocal_bind;
 
 #ifdef CONFIG_SYSCTL
+static int zero;
 static int tcp_retr1_max = 255; 
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
@@ -613,6 +615,15 @@ ctl_table ipv4_table[] = {
                .proc_handler   = &proc_dointvec_jiffies,
                .strategy       = &sysctl_jiffies
        },
+       {
+               .ctl_name       = NET_IPV4_IPFRAG_MAX_DIST,
+               .procname       = "ipfrag_max_dist",
+               .data           = &sysctl_ipfrag_max_dist,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .extra1         = &zero
+       },
        {
                .ctl_name       = NET_TCP_NO_METRICS_SAVE,
                .procname       = "tcp_no_metrics_save",
index ef98b14..00aa80e 100644 (file)
@@ -1696,8 +1696,8 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
        int err = 0;
 
        if (level != SOL_TCP)
-               return tp->af_specific->setsockopt(sk, level, optname,
-                                                  optval, optlen);
+               return icsk->icsk_af_ops->setsockopt(sk, level, optname,
+                                                    optval, optlen);
 
        /* This is a string value all the others are int's */
        if (optname == TCP_CONGESTION) {
@@ -1914,7 +1914,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
        info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime);
        info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp);
 
-       info->tcpi_pmtu = tp->pmtu_cookie;
+       info->tcpi_pmtu = icsk->icsk_pmtu_cookie;
        info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
        info->tcpi_rtt = jiffies_to_usecs(tp->srtt)>>3;
        info->tcpi_rttvar = jiffies_to_usecs(tp->mdev)>>2;
@@ -1939,8 +1939,8 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
        int val, len;
 
        if (level != SOL_TCP)
-               return tp->af_specific->getsockopt(sk, level, optname,
-                                                  optval, optlen);
+               return icsk->icsk_af_ops->getsockopt(sk, level, optname,
+                                                    optval, optlen);
 
        if (get_user(len, optlen))
                return -EFAULT;
index 1d0cd86..035f209 100644 (file)
@@ -30,8 +30,6 @@ static int fast_convergence = 1;
 static int max_increment = 16;
 static int low_window = 14;
 static int beta = 819;         /* = 819/1024 (BICTCP_BETA_SCALE) */
-static int low_utilization_threshold = 153;
-static int low_utilization_period = 2;
 static int initial_ssthresh = 100;
 static int smooth_part = 20;
 
@@ -43,10 +41,6 @@ module_param(low_window, int, 0644);
 MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)");
 module_param(beta, int, 0644);
 MODULE_PARM_DESC(beta, "beta for multiplicative increase");
-module_param(low_utilization_threshold, int, 0644);
-MODULE_PARM_DESC(low_utilization_threshold, "percent (scaled by 1024) for low utilization mode");
-module_param(low_utilization_period, int, 0644);
-MODULE_PARM_DESC(low_utilization_period, "if average delay exceeds then goto to low utilization mode (seconds)");
 module_param(initial_ssthresh, int, 0644);
 MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
 module_param(smooth_part, int, 0644);
@@ -60,11 +54,6 @@ struct bictcp {
        u32     loss_cwnd;      /* congestion window at last loss */
        u32     last_cwnd;      /* the last snd_cwnd */
        u32     last_time;      /* time when updated last_cwnd */
-       u32     delay_min;      /* min delay */
-       u32     delay_max;      /* max delay */
-       u32     last_delay;
-       u8      low_utilization;/* 0: high; 1: low */
-       u32     low_utilization_start;  /* starting time of low utilization detection*/
        u32     epoch_start;    /* beginning of an epoch */
 #define ACK_RATIO_SHIFT        4
        u32     delayed_ack;    /* estimate the ratio of Packets/ACKs << 4 */
@@ -77,11 +66,6 @@ static inline void bictcp_reset(struct bictcp *ca)
        ca->loss_cwnd = 0;
        ca->last_cwnd = 0;
        ca->last_time = 0;
-       ca->delay_min = 0;
-       ca->delay_max = 0;
-       ca->last_delay = 0;
-       ca->low_utilization = 0;
-       ca->low_utilization_start = 0;
        ca->epoch_start = 0;
        ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
 }
@@ -143,8 +127,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
        }
 
        /* if in slow start or link utilization is very low */
-       if ( ca->loss_cwnd == 0 ||
-            (cwnd > ca->loss_cwnd && ca->low_utilization)) {
+       if (ca->loss_cwnd == 0) {
                if (ca->cnt > 20) /* increase cwnd 5% per RTT */
                        ca->cnt = 20;
        }
@@ -154,69 +137,12 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
                ca->cnt = 1;
 }
 
-
-/* Detect low utilization in congestion avoidance */
-static inline void bictcp_low_utilization(struct sock *sk, int flag)
-{
-       const struct tcp_sock *tp = tcp_sk(sk);
-       struct bictcp *ca = inet_csk_ca(sk);
-       u32 dist, delay;
-
-       /* No time stamp */
-       if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
-            /* Discard delay samples right after fast recovery */
-            tcp_time_stamp < ca->epoch_start + HZ ||
-            /* this delay samples may not be accurate */
-            flag == 0) {
-               ca->last_delay = 0;
-               goto notlow;
-       }
-
-       delay = ca->last_delay<<3;      /* use the same scale as tp->srtt*/
-       ca->last_delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
-       if (delay == 0)                 /* no previous delay sample */
-               goto notlow;
-
-       /* first time call or link delay decreases */
-       if (ca->delay_min == 0 || ca->delay_min > delay) {
-               ca->delay_min = ca->delay_max = delay;
-               goto notlow;
-       }
-
-       if (ca->delay_max < delay)
-               ca->delay_max = delay;
-
-       /* utilization is low, if avg delay < dist*threshold
-          for checking_period time */
-       dist = ca->delay_max - ca->delay_min;
-       if (dist <= ca->delay_min>>6 ||
-           tp->srtt - ca->delay_min >=  (dist*low_utilization_threshold)>>10)
-               goto notlow;
-
-       if (ca->low_utilization_start == 0) {
-               ca->low_utilization = 0;
-               ca->low_utilization_start = tcp_time_stamp;
-       } else if ((s32)(tcp_time_stamp - ca->low_utilization_start)
-                       > low_utilization_period*HZ) {
-               ca->low_utilization = 1;
-       }
-
-       return;
-
- notlow:
-       ca->low_utilization = 0;
-       ca->low_utilization_start = 0;
-
-}
-
 static void bictcp_cong_avoid(struct sock *sk, u32 ack,
                              u32 seq_rtt, u32 in_flight, int data_acked)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct bictcp *ca = inet_csk_ca(sk);
 
-       bictcp_low_utilization(sk, data_acked);
-
        if (!tcp_is_cwnd_limited(sk, in_flight))
                return;
 
@@ -249,11 +175,6 @@ static u32 bictcp_recalc_ssthresh(struct sock *sk)
 
        ca->epoch_start = 0;    /* end of epoch */
 
-       /* in case of wrong delay_max*/
-       if (ca->delay_min > 0 && ca->delay_max > ca->delay_min)
-               ca->delay_max = ca->delay_min
-                       + ((ca->delay_max - ca->delay_min)* 90) / 100;
-
        /* Wmax and fast convergence */
        if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
                ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
@@ -289,14 +210,14 @@ static void bictcp_state(struct sock *sk, u8 new_state)
                bictcp_reset(inet_csk_ca(sk));
 }
 
-/* Track delayed acknowledgement ratio using sliding window
+/* Track delayed acknowledgment ratio using sliding window
  * ratio = (15*ratio + sample) / 16
  */
 static void bictcp_acked(struct sock *sk, u32 cnt)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
 
-       if (cnt > 0 &&  icsk->icsk_ca_state == TCP_CA_Open) {
+       if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
                struct bictcp *ca = inet_csk_ca(sk);
                cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
                ca->delayed_ack += cnt;
index c7cc62c..e688c68 100644 (file)
@@ -174,6 +174,34 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
        return err;
 }
 
+
+/*
+ * Linear increase during slow start
+ */
+void tcp_slow_start(struct tcp_sock *tp)
+{
+       if (sysctl_tcp_abc) {
+               /* RFC3465: Slow Start
+                * TCP sender SHOULD increase cwnd by the number of
+                * previously unacknowledged bytes ACKed by each incoming
+                * acknowledgment, provided the increase is not more than L
+                */
+               if (tp->bytes_acked < tp->mss_cache)
+                       return;
+
+               /* We MAY increase by 2 if discovered delayed ack */
+               if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
+                       if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+                               tp->snd_cwnd++;
+               }
+       }
+       tp->bytes_acked = 0;
+
+       if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+               tp->snd_cwnd++;
+}
+EXPORT_SYMBOL_GPL(tcp_slow_start);
+
 /*
  * TCP Reno congestion control
  * This is special case used for fallback as well.
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
new file mode 100644 (file)
index 0000000..31a4986
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * TCP CUBIC: Binary Increase Congestion control for TCP v2.0
+ *
+ * This is from the implementation of CUBIC TCP in
+ * Injong Rhee, Lisong Xu.
+ *  "CUBIC: A New TCP-Friendly High-Speed TCP Variant
+ *  in PFLDnet 2005
+ * Available from:
+ *  http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf
+ *
+ * Unless CUBIC is enabled and congestion window is large
+ * this behaves the same as the original Reno.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+#include <asm/div64.h>
+
+#define BICTCP_BETA_SCALE    1024      /* Scale factor beta calculation
+                                        * max_cwnd = snd_cwnd * beta
+                                        */
+#define BICTCP_B               4        /*
+                                         * In binary search,
+                                         * go to point (max+min)/N
+                                         */
+#define        BICTCP_HZ               10      /* BIC HZ 2^10 = 1024 */
+
+static int fast_convergence = 1;
+static int max_increment = 16;
+static int beta = 819;         /* = 819/1024 (BICTCP_BETA_SCALE) */
+static int initial_ssthresh = 100;
+static int bic_scale = 41;
+static int tcp_friendliness = 1;
+
+static u32 cube_rtt_scale;
+static u32 beta_scale;
+static u64 cube_factor;
+
+/* Note parameters that are used for precomputing scale factors are read-only */
+module_param(fast_convergence, int, 0644);
+MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
+module_param(max_increment, int, 0644);
+MODULE_PARM_DESC(max_increment, "Limit on increment allowed during binary search");
+module_param(beta, int, 0444);
+MODULE_PARM_DESC(beta, "beta for multiplicative increase");
+module_param(initial_ssthresh, int, 0644);
+MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
+module_param(bic_scale, int, 0444);
+MODULE_PARM_DESC(bic_scale, "scale (scaled by 1024) value for bic function (bic_scale/1024)");
+module_param(tcp_friendliness, int, 0644);
+MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness");
+
+#include <asm/div64.h>
+
+/* BIC TCP Parameters */
+struct bictcp {
+       u32     cnt;            /* increase cwnd by 1 after ACKs */
+       u32     last_max_cwnd;  /* last maximum snd_cwnd */
+       u32     loss_cwnd;      /* congestion window at last loss */
+       u32     last_cwnd;      /* the last snd_cwnd */
+       u32     last_time;      /* time when updated last_cwnd */
+       u32     bic_origin_point;/* origin point of bic function */
+       u32     bic_K;          /* time to origin point from the beginning of the current epoch */
+       u32     delay_min;      /* min delay */
+       u32     epoch_start;    /* beginning of an epoch */
+       u32     ack_cnt;        /* number of acks */
+       u32     tcp_cwnd;       /* estimated tcp cwnd */
+#define ACK_RATIO_SHIFT        4
+       u32     delayed_ack;    /* estimate the ratio of Packets/ACKs << 4 */
+};
+
+static inline void bictcp_reset(struct bictcp *ca)
+{
+       ca->cnt = 0;
+       ca->last_max_cwnd = 0;
+       ca->loss_cwnd = 0;
+       ca->last_cwnd = 0;
+       ca->last_time = 0;
+       ca->bic_origin_point = 0;
+       ca->bic_K = 0;
+       ca->delay_min = 0;
+       ca->epoch_start = 0;
+       ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
+       ca->ack_cnt = 0;
+       ca->tcp_cwnd = 0;
+}
+
+static void bictcp_init(struct sock *sk)
+{
+       bictcp_reset(inet_csk_ca(sk));
+       if (initial_ssthresh)
+               tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
+}
+
+/* 64bit divisor, dividend and result. dynamic precision */
+static inline u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor)
+{
+       u_int32_t d = divisor;
+
+       if (divisor > 0xffffffffULL) {
+               unsigned int shift = fls(divisor >> 32);
+
+               d = divisor >> shift;
+               dividend >>= shift;
+       }
+
+       /* avoid 64 bit division if possible */
+       if (dividend >> 32)
+               do_div(dividend, d);
+       else
+               dividend = (uint32_t) dividend / d;
+
+       return dividend;
+}
+
+/*
+ * calculate the cubic root of x using Newton-Raphson
+ */
+static u32 cubic_root(u64 a)
+{
+       u32 x, x1;
+
+       /* Initial estimate is based on:
+        * cbrt(x) = exp(log(x) / 3)
+        */
+       x = 1u << (fls64(a)/3);
+
+       /*
+        * Iteration based on:
+        *                         2
+        * x    = ( 2 * x  +  a / x  ) / 3
+        *  k+1          k         k
+        */
+       do {
+               x1 = x;
+               x = (2 * x + (uint32_t) div64_64(a, x*x)) / 3;
+       } while (abs(x1 - x) > 1);
+
+       return x;
+}
+
+/*
+ * Compute congestion window to use.
+ */
+static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
+{
+       u64 offs;
+       u32 delta, t, bic_target, min_cnt, max_cnt;
+
+       ca->ack_cnt++;  /* count the number of ACKs */
+
+       if (ca->last_cwnd == cwnd &&
+           (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
+               return;
+
+       ca->last_cwnd = cwnd;
+       ca->last_time = tcp_time_stamp;
+
+       if (ca->epoch_start == 0) {
+               ca->epoch_start = tcp_time_stamp;       /* record the beginning of an epoch */
+               ca->ack_cnt = 1;                        /* start counting */
+               ca->tcp_cwnd = cwnd;                    /* syn with cubic */
+
+               if (ca->last_max_cwnd <= cwnd) {
+                       ca->bic_K = 0;
+                       ca->bic_origin_point = cwnd;
+               } else {
+                       /* Compute new K based on
+                        * (wmax-cwnd) * (srtt>>3 / HZ) / c * 2^(3*bictcp_HZ)
+                        */
+                       ca->bic_K = cubic_root(cube_factor
+                                              * (ca->last_max_cwnd - cwnd));
+                       ca->bic_origin_point = ca->last_max_cwnd;
+               }
+       }
+
+        /* cubic function - calc*/
+        /* calculate c * time^3 / rtt,
+         *  while considering overflow in calculation of time^3
+        * (so time^3 is done by using 64 bit)
+        * and without the support of division of 64bit numbers
+        * (so all divisions are done by using 32 bit)
+         *  also NOTE the unit of those veriables
+         *       time  = (t - K) / 2^bictcp_HZ
+         *       c = bic_scale >> 10
+        * rtt  = (srtt >> 3) / HZ
+        * !!! The following code does not have overflow problems,
+        * if the cwnd < 1 million packets !!!
+         */
+
+       /* change the unit from HZ to bictcp_HZ */
+        t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start)
+            << BICTCP_HZ) / HZ;
+
+        if (t < ca->bic_K)             /* t - K */
+               offs = ca->bic_K - t;
+        else
+                offs = t - ca->bic_K;
+
+       /* c/rtt * (t-K)^3 */
+       delta = (cube_rtt_scale * offs * offs * offs) >> (10+3*BICTCP_HZ);
+        if (t < ca->bic_K)                                     /* below origin*/
+                bic_target = ca->bic_origin_point - delta;
+        else                                                   /* above origin*/
+                bic_target = ca->bic_origin_point + delta;
+
+        /* cubic function - calc bictcp_cnt*/
+        if (bic_target > cwnd) {
+               ca->cnt = cwnd / (bic_target - cwnd);
+        } else {
+                ca->cnt = 100 * cwnd;              /* very small increment*/
+        }
+
+       if (ca->delay_min > 0) {
+               /* max increment = Smax * rtt / 0.1  */
+               min_cnt = (cwnd * HZ * 8)/(10 * max_increment * ca->delay_min);
+               if (ca->cnt < min_cnt)
+                       ca->cnt = min_cnt;
+       }
+
+        /* slow start and low utilization  */
+       if (ca->loss_cwnd == 0)         /* could be aggressive in slow start */
+               ca->cnt = 50;
+
+       /* TCP Friendly */
+       if (tcp_friendliness) {
+               u32 scale = beta_scale;
+               delta = (cwnd * scale) >> 3;
+               while (ca->ack_cnt > delta) {           /* update tcp cwnd */
+                       ca->ack_cnt -= delta;
+                       ca->tcp_cwnd++;
+               }
+
+               if (ca->tcp_cwnd > cwnd){       /* if bic is slower than tcp */
+                       delta = ca->tcp_cwnd - cwnd;
+                       max_cnt = cwnd / delta;
+                       if (ca->cnt > max_cnt)
+                               ca->cnt = max_cnt;
+               }
+        }
+
+       ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
+       if (ca->cnt == 0)                       /* cannot be zero */
+               ca->cnt = 1;
+}
+
+
+/* Keep track of minimum rtt */
+static inline void measure_delay(struct sock *sk)
+{
+       const struct tcp_sock *tp = tcp_sk(sk);
+       struct bictcp *ca = inet_csk_ca(sk);
+       u32 delay;
+
+       /* No time stamp */
+       if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
+            /* Discard delay samples right after fast recovery */
+           (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
+               return;
+
+       delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+       if (delay == 0)
+               delay = 1;
+
+       /* first time call or link delay decreases */
+       if (ca->delay_min == 0 || ca->delay_min > delay)
+               ca->delay_min = delay;
+}
+
+static void bictcp_cong_avoid(struct sock *sk, u32 ack,
+                             u32 seq_rtt, u32 in_flight, int data_acked)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct bictcp *ca = inet_csk_ca(sk);
+
+       if (data_acked)
+               measure_delay(sk);
+
+       if (!tcp_is_cwnd_limited(sk, in_flight))
+               return;
+
+       if (tp->snd_cwnd <= tp->snd_ssthresh)
+               tcp_slow_start(tp);
+       else {
+               bictcp_update(ca, tp->snd_cwnd);
+
+               /* In dangerous area, increase slowly.
+                * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
+                */
+               if (tp->snd_cwnd_cnt >= ca->cnt) {
+                       if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+                               tp->snd_cwnd++;
+                       tp->snd_cwnd_cnt = 0;
+               } else
+                       tp->snd_cwnd_cnt++;
+       }
+
+}
+
+static u32 bictcp_recalc_ssthresh(struct sock *sk)
+{
+       const struct tcp_sock *tp = tcp_sk(sk);
+       struct bictcp *ca = inet_csk_ca(sk);
+
+       ca->epoch_start = 0;    /* end of epoch */
+
+       /* Wmax and fast convergence */
+       if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
+               ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
+                       / (2 * BICTCP_BETA_SCALE);
+       else
+               ca->last_max_cwnd = tp->snd_cwnd;
+
+       ca->loss_cwnd = tp->snd_cwnd;
+
+       return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
+}
+
+static u32 bictcp_undo_cwnd(struct sock *sk)
+{
+       struct bictcp *ca = inet_csk_ca(sk);
+
+       return max(tcp_sk(sk)->snd_cwnd, ca->last_max_cwnd);
+}
+
+static u32 bictcp_min_cwnd(struct sock *sk)
+{
+       return tcp_sk(sk)->snd_ssthresh;
+}
+
+static void bictcp_state(struct sock *sk, u8 new_state)
+{
+       if (new_state == TCP_CA_Loss)
+               bictcp_reset(inet_csk_ca(sk));
+}
+
+/* Track delayed acknowledgment ratio using sliding window
+ * ratio = (15*ratio + sample) / 16
+ */
+static void bictcp_acked(struct sock *sk, u32 cnt)
+{
+       const struct inet_connection_sock *icsk = inet_csk(sk);
+
+       if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
+               struct bictcp *ca = inet_csk_ca(sk);
+               cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
+               ca->delayed_ack += cnt;
+       }
+}
+
+
+static struct tcp_congestion_ops cubictcp = {
+       .init           = bictcp_init,
+       .ssthresh       = bictcp_recalc_ssthresh,
+       .cong_avoid     = bictcp_cong_avoid,
+       .set_state      = bictcp_state,
+       .undo_cwnd      = bictcp_undo_cwnd,
+       .min_cwnd       = bictcp_min_cwnd,
+       .pkts_acked     = bictcp_acked,
+       .owner          = THIS_MODULE,
+       .name           = "cubic",
+};
+
+static int __init cubictcp_register(void)
+{
+       BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE);
+
+       /* Precompute a bunch of the scaling factors that are used per-packet
+        * based on SRTT of 100ms
+        */
+
+       beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta);
+
+       cube_rtt_scale = (bic_scale << 3) / 10; /* 1024*c/rtt */
+
+       /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
+        *  so K = cubic_root( (wmax-cwnd)*rtt/c )
+        * the unit of K is bictcp_HZ=2^10, not HZ
+        *
+        *  c = bic_scale >> 10
+        *  rtt = 100ms
+        *
+        * the following code has been designed and tested for
+        * cwnd < 1 million packets
+        * RTT < 100 seconds
+        * HZ < 1,000,00  (corresponding to 10 nano-second)
+        */
+
+       /* 1/c * 2^2*bictcp_HZ * srtt */
+       cube_factor = 1ull << (10+3*BICTCP_HZ); /* 2^40 */
+
+       /* divide by bic_scale and by constant Srtt (100ms) */
+       do_div(cube_factor, bic_scale * 10);
+
+       return tcp_register_congestion_control(&cubictcp);
+}
+
+static void __exit cubictcp_unregister(void)
+{
+       tcp_unregister_congestion_control(&cubictcp);
+}
+
+module_init(cubictcp_register);
+module_exit(cubictcp_unregister);
+
+MODULE_AUTHOR("Sangtae Ha, Stephen Hemminger");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CUBIC TCP");
+MODULE_VERSION("2.0");
index bf2e230..0a46123 100644 (file)
@@ -115,8 +115,8 @@ int sysctl_tcp_abc = 1;
 /* Adapt the MSS value used to make delayed ack decision to the 
  * real world.
  */ 
-static inline void tcp_measure_rcv_mss(struct sock *sk,
-                                      const struct sk_buff *skb)
+static void tcp_measure_rcv_mss(struct sock *sk,
+                               const struct sk_buff *skb)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        const unsigned int lss = icsk->icsk_ack.last_seg_size; 
@@ -246,8 +246,8 @@ static int __tcp_grow_window(const struct sock *sk, struct tcp_sock *tp,
        return 0;
 }
 
-static inline void tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
-                                  struct sk_buff *skb)
+static void tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
+                           struct sk_buff *skb)
 {
        /* Check #1 */
        if (tp->rcv_ssthresh < tp->window_clamp &&
@@ -341,6 +341,26 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
                tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
 }
 
+
+/* Initialize RCV_MSS value.
+ * RCV_MSS is an our guess about MSS used by the peer.
+ * We haven't any direct information about the MSS.
+ * It's better to underestimate the RCV_MSS rather than overestimate.
+ * Overestimations make us ACKing less frequently than needed.
+ * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
+ */
+void tcp_initialize_rcv_mss(struct sock *sk)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
+
+       hint = min(hint, tp->rcv_wnd/2);
+       hint = min(hint, TCP_MIN_RCVMSS);
+       hint = max(hint, TCP_MIN_MSS);
+
+       inet_csk(sk)->icsk_ack.rcv_mss = hint;
+}
+
 /* Receiver "autotuning" code.
  *
  * The algorithm for RTT estimation w/o timestamps is based on
@@ -735,6 +755,27 @@ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst)
        return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
 }
 
+/* Set slow start threshold and cwnd not falling to slow start */
+void tcp_enter_cwr(struct sock *sk)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+
+       tp->prior_ssthresh = 0;
+       tp->bytes_acked = 0;
+       if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
+               tp->undo_marker = 0;
+               tp->snd_ssthresh = inet_csk(sk)->icsk_ca_ops->ssthresh(sk);
+               tp->snd_cwnd = min(tp->snd_cwnd,
+                                  tcp_packets_in_flight(tp) + 1U);
+               tp->snd_cwnd_cnt = 0;
+               tp->high_seq = tp->snd_nxt;
+               tp->snd_cwnd_stamp = tcp_time_stamp;
+               TCP_ECN_queue_cwr(tp);
+
+               tcp_set_ca_state(sk, TCP_CA_CWR);
+       }
+}
+
 /* Initialize metrics on socket. */
 
 static void tcp_init_metrics(struct sock *sk)
@@ -2070,8 +2111,8 @@ static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
                tcp_ack_no_tstamp(sk, seq_rtt, flag);
 }
 
-static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
-                                 u32 in_flight, int good)
+static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
+                          u32 in_flight, int good)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
        icsk->icsk_ca_ops->cong_avoid(sk, ack, rtt, in_flight, good);
@@ -2082,7 +2123,7 @@ static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
  * RFC2988 recommends to restart timer to now+rto.
  */
 
-static inline void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp)
+static void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp)
 {
        if (!tp->packets_out) {
                inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
@@ -2147,7 +2188,7 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
        return acked;
 }
 
-static inline u32 tcp_usrtt(const struct sk_buff *skb)
+static u32 tcp_usrtt(const struct sk_buff *skb)
 {
        struct timeval tv, now;
 
@@ -2342,7 +2383,7 @@ static int tcp_ack_update_window(struct sock *sk, struct tcp_sock *tp,
 
                        if (nwin > tp->max_window) {
                                tp->max_window = nwin;
-                               tcp_sync_mss(sk, tp->pmtu_cookie);
+                               tcp_sync_mss(sk, inet_csk(sk)->icsk_pmtu_cookie);
                        }
                }
        }
@@ -2583,8 +2624,8 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
 /* Fast parse options. This hopes to only see timestamps.
  * If it is wrong it falls back on tcp_parse_options().
  */
-static inline int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
-                                        struct tcp_sock *tp)
+static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
+                                 struct tcp_sock *tp)
 {
        if (th->doff == sizeof(struct tcphdr)>>2) {
                tp->rx_opt.saw_tstamp = 0;
@@ -2804,8 +2845,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
        }
 }
 
-static __inline__ int
-tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
+static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
 {
        if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) {
                if (before(seq, sp->start_seq))
@@ -2817,7 +2857,7 @@ tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
        return 0;
 }
 
-static inline void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
+static void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
        if (tp->rx_opt.sack_ok && sysctl_tcp_dsack) {
                if (before(seq, tp->rcv_nxt))
@@ -2832,7 +2872,7 @@ static inline void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
        }
 }
 
-static inline void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq)
+static void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
        if (!tp->rx_opt.dsack)
                tcp_dsack_set(tp, seq, end_seq);
@@ -2890,7 +2930,7 @@ static void tcp_sack_maybe_coalesce(struct tcp_sock *tp)
        }
 }
 
-static __inline__ void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2)
+static inline void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2)
 {
        __u32 tmp;
 
@@ -3455,7 +3495,7 @@ void tcp_cwnd_application_limited(struct sock *sk)
        tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
+static int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
 {
        /* If the user specified a specific send buffer setting, do
         * not modify it.
@@ -3502,7 +3542,7 @@ static void tcp_new_space(struct sock *sk)
        sk->sk_write_space(sk);
 }
 
-static inline void tcp_check_space(struct sock *sk)
+static void tcp_check_space(struct sock *sk)
 {
        if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) {
                sock_reset_flag(sk, SOCK_QUEUE_SHRUNK);
@@ -3512,7 +3552,7 @@ static inline void tcp_check_space(struct sock *sk)
        }
 }
 
-static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
 {
        tcp_push_pending_frames(sk, tp);
        tcp_check_space(sk);
@@ -3544,7 +3584,7 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
        }
 }
 
-static __inline__ void tcp_ack_snd_check(struct sock *sk)
+static inline void tcp_ack_snd_check(struct sock *sk)
 {
        if (!inet_csk_ack_scheduled(sk)) {
                /* We sent a data segment already. */
@@ -3692,8 +3732,7 @@ static int __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
        return result;
 }
 
-static __inline__ int
-tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
 {
        return skb->ip_summed != CHECKSUM_UNNECESSARY &&
                __tcp_checksum_complete_user(sk, skb);
@@ -3967,12 +4006,12 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                                         struct tcphdr *th, unsigned len)
 {
        struct tcp_sock *tp = tcp_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        int saved_clamp = tp->rx_opt.mss_clamp;
 
        tcp_parse_options(skb, &tp->rx_opt, 0);
 
        if (th->ack) {
-               struct inet_connection_sock *icsk;
                /* rfc793:
                 * "If the state is SYN-SENT then
                 *    first check the ACK bit
@@ -4061,7 +4100,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                if (tp->rx_opt.sack_ok && sysctl_tcp_fack)
                        tp->rx_opt.sack_ok |= 2;
 
-               tcp_sync_mss(sk, tp->pmtu_cookie);
+               tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
                tcp_initialize_rcv_mss(sk);
 
                /* Remember, tcp_poll() does not lock socket!
@@ -4072,7 +4111,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                tcp_set_state(sk, TCP_ESTABLISHED);
 
                /* Make sure socket is routed, for correct metrics.  */
-               tp->af_specific->rebuild_header(sk);
+               icsk->icsk_af_ops->rebuild_header(sk);
 
                tcp_init_metrics(sk);
 
@@ -4098,8 +4137,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                        sk_wake_async(sk, 0, POLL_OUT);
                }
 
-               icsk = inet_csk(sk);
-
                if (sk->sk_write_pending ||
                    icsk->icsk_accept_queue.rskq_defer_accept ||
                    icsk->icsk_ack.pingpong) {
@@ -4173,7 +4210,7 @@ discard:
                if (tp->ecn_flags&TCP_ECN_OK)
                        sock_set_flag(sk, SOCK_NO_LARGESEND);
 
-               tcp_sync_mss(sk, tp->pmtu_cookie);
+               tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
                tcp_initialize_rcv_mss(sk);
 
 
@@ -4220,6 +4257,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                          struct tcphdr *th, unsigned len)
 {
        struct tcp_sock *tp = tcp_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        int queued = 0;
 
        tp->rx_opt.saw_tstamp = 0;
@@ -4236,7 +4274,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                        goto discard;
 
                if(th->syn) {
-                       if(tp->af_specific->conn_request(sk, skb) < 0)
+                       if (icsk->icsk_af_ops->conn_request(sk, skb) < 0)
                                return 1;
 
                        /* Now we have several options: In theory there is 
@@ -4349,7 +4387,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                                /* Make sure socket is routed, for
                                 * correct metrics.
                                 */
-                               tp->af_specific->rebuild_header(sk);
+                               icsk->icsk_af_ops->rebuild_header(sk);
 
                                tcp_init_metrics(sk);
 
@@ -4475,3 +4513,4 @@ EXPORT_SYMBOL(sysctl_tcp_abc);
 EXPORT_SYMBOL(tcp_parse_options);
 EXPORT_SYMBOL(tcp_rcv_established);
 EXPORT_SYMBOL(tcp_rcv_state_process);
+EXPORT_SYMBOL(tcp_initialize_rcv_mss);
index 4d5021e..e9f83e5 100644 (file)
@@ -69,6 +69,7 @@
 #include <net/transp_v6.h>
 #include <net/ipv6.h>
 #include <net/inet_common.h>
+#include <net/timewait_sock.h>
 #include <net/xfrm.h>
 
 #include <linux/inet.h>
@@ -86,8 +87,7 @@ int sysctl_tcp_low_latency;
 /* Socket used for sending RSTs */
 static struct socket *tcp_socket;
 
-void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
-                      struct sk_buff *skb);
+void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
 
 struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
        .lhash_lock     = RW_LOCK_UNLOCKED,
@@ -97,7 +97,8 @@ struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
 
 static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 {
-       return inet_csk_get_port(&tcp_hashinfo, sk, snum);
+       return inet_csk_get_port(&tcp_hashinfo, sk, snum,
+                                inet_csk_bind_conflict);
 }
 
 static void tcp_v4_hash(struct sock *sk)
@@ -118,202 +119,38 @@ static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
                                          skb->h.th->source);
 }
 
-/* called with local bh disabled */
-static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
-                                     struct inet_timewait_sock **twp)
+int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
 {
-       struct inet_sock *inet = inet_sk(sk);
-       u32 daddr = inet->rcv_saddr;
-       u32 saddr = inet->daddr;
-       int dif = sk->sk_bound_dev_if;
-       INET_ADDR_COOKIE(acookie, saddr, daddr)
-       const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-       unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
-       struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
-       struct sock *sk2;
-       const struct hlist_node *node;
-       struct inet_timewait_sock *tw;
-
-       prefetch(head->chain.first);
-       write_lock(&head->lock);
-
-       /* Check TIME-WAIT sockets first. */
-       sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
-               tw = inet_twsk(sk2);
-
-               if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
-                       const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
-                       struct tcp_sock *tp = tcp_sk(sk);
-
-                       /* With PAWS, it is safe from the viewpoint
-                          of data integrity. Even without PAWS it
-                          is safe provided sequence spaces do not
-                          overlap i.e. at data rates <= 80Mbit/sec.
-
-                          Actually, the idea is close to VJ's one,
-                          only timestamp cache is held not per host,
-                          but per port pair and TW bucket is used
-                          as state holder.
+       const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
+       struct tcp_sock *tp = tcp_sk(sk);
 
-                          If TW bucket has been already destroyed we
-                          fall back to VJ's scheme and use initial
-                          timestamp retrieved from peer table.
-                        */
-                       if (tcptw->tw_ts_recent_stamp &&
-                           (!twp || (sysctl_tcp_tw_reuse &&
-                                     xtime.tv_sec -
-                                     tcptw->tw_ts_recent_stamp > 1))) {
-                               tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
-                               if (tp->write_seq == 0)
-                                       tp->write_seq = 1;
-                               tp->rx_opt.ts_recent       = tcptw->tw_ts_recent;
-                               tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
-                               sock_hold(sk2);
-                               goto unique;
-                       } else
-                               goto not_unique;
-               }
-       }
-       tw = NULL;
+       /* With PAWS, it is safe from the viewpoint
+          of data integrity. Even without PAWS it is safe provided sequence
+          spaces do not overlap i.e. at data rates <= 80Mbit/sec.
 
-       /* And established part... */
-       sk_for_each(sk2, node, &head->chain) {
-               if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-                       goto not_unique;
-       }
+          Actually, the idea is close to VJ's one, only timestamp cache is
+          held not per host, but per port pair and TW bucket is used as state
+          holder.
 
-unique:
-       /* Must record num and sport now. Otherwise we will see
-        * in hash table socket with a funny identity. */
-       inet->num = lport;
-       inet->sport = htons(lport);
-       sk->sk_hash = hash;
-       BUG_TRAP(sk_unhashed(sk));
-       __sk_add_node(sk, &head->chain);
-       sock_prot_inc_use(sk->sk_prot);
-       write_unlock(&head->lock);
-
-       if (twp) {
-               *twp = tw;
-               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-       } else if (tw) {
-               /* Silly. Should hash-dance instead... */
-               inet_twsk_deschedule(tw, &tcp_death_row);
-               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-               inet_twsk_put(tw);
+          If TW bucket has been already destroyed we fall back to VJ's scheme
+          and use initial timestamp retrieved from peer table.
+        */
+       if (tcptw->tw_ts_recent_stamp &&
+           (twp == NULL || (sysctl_tcp_tw_reuse &&
+                            xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) {
+               tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
+               if (tp->write_seq == 0)
+                       tp->write_seq = 1;
+               tp->rx_opt.ts_recent       = tcptw->tw_ts_recent;
+               tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
+               sock_hold(sktw);
+               return 1;
        }
 
        return 0;
-
-not_unique:
-       write_unlock(&head->lock);
-       return -EADDRNOTAVAIL;
 }
 
-static inline u32 connect_port_offset(const struct sock *sk)
-{
-       const struct inet_sock *inet = inet_sk(sk);
-
-       return secure_tcp_port_ephemeral(inet->rcv_saddr, inet->daddr, 
-                                        inet->dport);
-}
-
-/*
- * Bind a port for a connect operation and hash it.
- */
-static inline int tcp_v4_hash_connect(struct sock *sk)
-{
-       const unsigned short snum = inet_sk(sk)->num;
-       struct inet_bind_hashbucket *head;
-       struct inet_bind_bucket *tb;
-       int ret;
-
-       if (!snum) {
-               int low = sysctl_local_port_range[0];
-               int high = sysctl_local_port_range[1];
-               int range = high - low;
-               int i;
-               int port;
-               static u32 hint;
-               u32 offset = hint + connect_port_offset(sk);
-               struct hlist_node *node;
-               struct inet_timewait_sock *tw = NULL;
-
-               local_bh_disable();
-               for (i = 1; i <= range; i++) {
-                       port = low + (i + offset) % range;
-                       head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)];
-                       spin_lock(&head->lock);
-
-                       /* Does not bother with rcv_saddr checks,
-                        * because the established check is already
-                        * unique enough.
-                        */
-                       inet_bind_bucket_for_each(tb, node, &head->chain) {
-                               if (tb->port == port) {
-                                       BUG_TRAP(!hlist_empty(&tb->owners));
-                                       if (tb->fastreuse >= 0)
-                                               goto next_port;
-                                       if (!__tcp_v4_check_established(sk,
-                                                                       port,
-                                                                       &tw))
-                                               goto ok;
-                                       goto next_port;
-                               }
-                       }
-
-                       tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port);
-                       if (!tb) {
-                               spin_unlock(&head->lock);
-                               break;
-                       }
-                       tb->fastreuse = -1;
-                       goto ok;
-
-               next_port:
-                       spin_unlock(&head->lock);
-               }
-               local_bh_enable();
-
-               return -EADDRNOTAVAIL;
-
-ok:
-               hint += i;
-
-               /* Head lock still held and bh's disabled */
-               inet_bind_hash(sk, tb, port);
-               if (sk_unhashed(sk)) {
-                       inet_sk(sk)->sport = htons(port);
-                       __inet_hash(&tcp_hashinfo, sk, 0);
-               }
-               spin_unlock(&head->lock);
-
-               if (tw) {
-                       inet_twsk_deschedule(tw, &tcp_death_row);;
-                       inet_twsk_put(tw);
-               }
-
-               ret = 0;
-               goto out;
-       }
-
-       head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
-       tb  = inet_csk(sk)->icsk_bind_hash;
-       spin_lock_bh(&head->lock);
-       if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-               __inet_hash(&tcp_hashinfo, sk, 0);
-               spin_unlock_bh(&head->lock);
-               return 0;
-       } else {
-               spin_unlock(&head->lock);
-               /* No definite answer... Walk to established hash table */
-               ret = __tcp_v4_check_established(sk, snum, NULL);
-out:
-               local_bh_enable();
-               return ret;
-       }
-}
+EXPORT_SYMBOL_GPL(tcp_twsk_unique);
 
 /* This will initiate an outgoing connection. */
 int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -383,9 +220,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        inet->dport = usin->sin_port;
        inet->daddr = daddr;
 
-       tp->ext_header_len = 0;
+       inet_csk(sk)->icsk_ext_hdr_len = 0;
        if (inet->opt)
-               tp->ext_header_len = inet->opt->optlen;
+               inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
 
        tp->rx_opt.mss_clamp = 536;
 
@@ -395,7 +232,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
         * complete initialization after this.
         */
        tcp_set_state(sk, TCP_SYN_SENT);
-       err = tcp_v4_hash_connect(sk);
+       err = inet_hash_connect(&tcp_death_row, sk);
        if (err)
                goto failure;
 
@@ -433,12 +270,10 @@ failure:
 /*
  * This routine does path mtu discovery as defined in RFC1191.
  */
-static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph,
-                                    u32 mtu)
+static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu)
 {
        struct dst_entry *dst;
        struct inet_sock *inet = inet_sk(sk);
-       struct tcp_sock *tp = tcp_sk(sk);
 
        /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
         * send out by Linux are always <576bytes so they should go through
@@ -467,7 +302,7 @@ static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph,
        mtu = dst_mtu(dst);
 
        if (inet->pmtudisc != IP_PMTUDISC_DONT &&
-           tp->pmtu_cookie > mtu) {
+           inet_csk(sk)->icsk_pmtu_cookie > mtu) {
                tcp_sync_mss(sk, mtu);
 
                /* Resend the TCP packet because it's
@@ -644,10 +479,10 @@ out:
 }
 
 /* This routine computes an IPv4 TCP checksum. */
-void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
-                      struct sk_buff *skb)
+void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
 {
        struct inet_sock *inet = inet_sk(sk);
+       struct tcphdr *th = skb->h.th;
 
        if (skb->ip_summed == CHECKSUM_HW) {
                th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0);
@@ -826,7 +661,8 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req)
        kfree(inet_rsk(req)->opt);
 }
 
-static inline void syn_flood_warning(struct sk_buff *skb)
+#ifdef CONFIG_SYN_COOKIES
+static void syn_flood_warning(struct sk_buff *skb)
 {
        static unsigned long warntime;
 
@@ -837,12 +673,13 @@ static inline void syn_flood_warning(struct sk_buff *skb)
                       ntohs(skb->h.th->dest));
        }
 }
+#endif
 
 /*
  * Save and compile IPv4 options into the request_sock if needed.
  */
-static inline struct ip_options *tcp_v4_save_options(struct sock *sk,
-                                                    struct sk_buff *skb)
+static struct ip_options *tcp_v4_save_options(struct sock *sk,
+                                             struct sk_buff *skb)
 {
        struct ip_options *opt = &(IPCB(skb)->opt);
        struct ip_options *dopt = NULL;
@@ -869,6 +706,11 @@ struct request_sock_ops tcp_request_sock_ops = {
        .send_reset     =       tcp_v4_send_reset,
 };
 
+static struct timewait_sock_ops tcp_timewait_sock_ops = {
+       .twsk_obj_size  = sizeof(struct tcp_timewait_sock),
+       .twsk_unique    = tcp_twsk_unique,
+};
+
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
        struct inet_request_sock *ireq;
@@ -1053,9 +895,9 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        ireq->opt             = NULL;
        newinet->mc_index     = inet_iif(skb);
        newinet->mc_ttl       = skb->nh.iph->ttl;
-       newtp->ext_header_len = 0;
+       inet_csk(newsk)->icsk_ext_hdr_len = 0;
        if (newinet->opt)
-               newtp->ext_header_len = newinet->opt->optlen;
+               inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen;
        newinet->id = newtp->write_seq ^ jiffies;
 
        tcp_sync_mss(newsk, dst_mtu(dst));
@@ -1314,16 +1156,6 @@ do_time_wait:
        goto discard_it;
 }
 
-static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
-{
-       struct sockaddr_in *sin = (struct sockaddr_in *) uaddr;
-       struct inet_sock *inet = inet_sk(sk);
-
-       sin->sin_family         = AF_INET;
-       sin->sin_addr.s_addr    = inet->daddr;
-       sin->sin_port           = inet->dport;
-}
-
 /* VJ's idea. Save last timestamp seen from this destination
  * and hold it at least for normal timewait interval to use for duplicate
  * segment detection in subsequent connections, before they enter synchronized
@@ -1382,7 +1214,7 @@ int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw)
        return 0;
 }
 
-struct tcp_func ipv4_specific = {
+struct inet_connection_sock_af_ops ipv4_specific = {
        .queue_xmit     =       ip_queue_xmit,
        .send_check     =       tcp_v4_send_check,
        .rebuild_header =       inet_sk_rebuild_header,
@@ -1392,7 +1224,7 @@ struct tcp_func ipv4_specific = {
        .net_header_len =       sizeof(struct iphdr),
        .setsockopt     =       ip_setsockopt,
        .getsockopt     =       ip_getsockopt,
-       .addr2sockaddr  =       v4_addr2sockaddr,
+       .addr2sockaddr  =       inet_csk_addr2sockaddr,
        .sockaddr_len   =       sizeof(struct sockaddr_in),
 };
 
@@ -1433,7 +1265,8 @@ static int tcp_v4_init_sock(struct sock *sk)
        sk->sk_write_space = sk_stream_write_space;
        sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
-       tp->af_specific = &ipv4_specific;
+       icsk->icsk_af_ops = &ipv4_specific;
+       icsk->icsk_sync_mss = tcp_sync_mss;
 
        sk->sk_sndbuf = sysctl_tcp_wmem[1];
        sk->sk_rcvbuf = sysctl_tcp_rmem[1];
@@ -1989,7 +1822,7 @@ struct proto tcp_prot = {
        .sysctl_rmem            = sysctl_tcp_rmem,
        .max_header             = MAX_TCP_HEADER,
        .obj_size               = sizeof(struct tcp_sock),
-       .twsk_obj_size          = sizeof(struct tcp_timewait_sock),
+       .twsk_prot              = &tcp_timewait_sock_ops,
        .rsk_prot               = &tcp_request_sock_ops,
 };
 
index 1b66a2a..2b9b7f6 100644 (file)
@@ -274,18 +274,18 @@ kill:
 void tcp_time_wait(struct sock *sk, int state, int timeo)
 {
        struct inet_timewait_sock *tw = NULL;
+       const struct inet_connection_sock *icsk = inet_csk(sk);
        const struct tcp_sock *tp = tcp_sk(sk);
        int recycle_ok = 0;
 
        if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)
-               recycle_ok = tp->af_specific->remember_stamp(sk);
+               recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);
 
        if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets)
                tw = inet_twsk_alloc(sk, state);
 
        if (tw != NULL) {
                struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
-               const struct inet_connection_sock *icsk = inet_csk(sk);
                const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
 
                tw->tw_rcv_wscale       = tp->rx_opt.rcv_wscale;
@@ -298,10 +298,12 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                if (tw->tw_family == PF_INET6) {
                        struct ipv6_pinfo *np = inet6_sk(sk);
-                       struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw);
+                       struct inet6_timewait_sock *tw6;
 
-                       ipv6_addr_copy(&tcp6tw->tw_v6_daddr, &np->daddr);
-                       ipv6_addr_copy(&tcp6tw->tw_v6_rcv_saddr, &np->rcv_saddr);
+                       tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot);
+                       tw6 = inet6_twsk((struct sock *)tw);
+                       ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr);
+                       ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr);
                        tw->tw_ipv6only = np->ipv6only;
                }
 #endif
@@ -456,7 +458,6 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
                           struct request_sock **prev)
 {
        struct tcphdr *th = skb->h.th;
-       struct tcp_sock *tp = tcp_sk(sk);
        u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
        int paws_reject = 0;
        struct tcp_options_received tmp_opt;
@@ -613,7 +614,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
                 * ESTABLISHED STATE. If it will be dropped after
                 * socket is created, wait for troubles.
                 */
-               child = tp->af_specific->syn_recv_sock(sk, skb, req, NULL);
+               child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb,
+                                                                req, NULL);
                if (child == NULL)
                        goto listen_overflow;
 
index b7325e0..a7623ea 100644 (file)
@@ -51,8 +51,8 @@ int sysctl_tcp_retrans_collapse = 1;
  */
 int sysctl_tcp_tso_win_divisor = 3;
 
-static inline void update_send_head(struct sock *sk, struct tcp_sock *tp,
-                                   struct sk_buff *skb)
+static void update_send_head(struct sock *sk, struct tcp_sock *tp,
+                            struct sk_buff *skb)
 {
        sk->sk_send_head = skb->next;
        if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
@@ -124,8 +124,8 @@ static void tcp_cwnd_restart(struct sock *sk, struct dst_entry *dst)
        tp->snd_cwnd_used = 0;
 }
 
-static inline void tcp_event_data_sent(struct tcp_sock *tp,
-                                      struct sk_buff *skb, struct sock *sk)
+static void tcp_event_data_sent(struct tcp_sock *tp,
+                               struct sk_buff *skb, struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        const u32 now = tcp_time_stamp;
@@ -142,7 +142,7 @@ static inline void tcp_event_data_sent(struct tcp_sock *tp,
                icsk->icsk_ack.pingpong = 1;
 }
 
-static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
+static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
 {
        tcp_dec_quickack_mode(sk, pkts);
        inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
@@ -212,7 +212,7 @@ void tcp_select_initial_window(int __space, __u32 mss,
  * value can be stuffed directly into th->window for an outgoing
  * frame.
  */
-static __inline__ u16 tcp_select_window(struct sock *sk)
+static u16 tcp_select_window(struct sock *sk)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        u32 cur_win = tcp_receive_window(tp);
@@ -250,6 +250,75 @@ static __inline__ u16 tcp_select_window(struct sock *sk)
        return new_win;
 }
 
+static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp,
+                                        __u32 tstamp)
+{
+       if (tp->rx_opt.tstamp_ok) {
+               *ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
+                                         (TCPOPT_NOP << 16) |
+                                         (TCPOPT_TIMESTAMP << 8) |
+                                         TCPOLEN_TIMESTAMP);
+               *ptr++ = htonl(tstamp);
+               *ptr++ = htonl(tp->rx_opt.ts_recent);
+       }
+       if (tp->rx_opt.eff_sacks) {
+               struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks;
+               int this_sack;
+
+               *ptr++ = htonl((TCPOPT_NOP  << 24) |
+                              (TCPOPT_NOP  << 16) |
+                              (TCPOPT_SACK <<  8) |
+                              (TCPOLEN_SACK_BASE + (tp->rx_opt.eff_sacks *
+                                                    TCPOLEN_SACK_PERBLOCK)));
+               for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) {
+                       *ptr++ = htonl(sp[this_sack].start_seq);
+                       *ptr++ = htonl(sp[this_sack].end_seq);
+               }
+               if (tp->rx_opt.dsack) {
+                       tp->rx_opt.dsack = 0;
+                       tp->rx_opt.eff_sacks--;
+               }
+       }
+}
+
+/* Construct a tcp options header for a SYN or SYN_ACK packet.
+ * If this is every changed make sure to change the definition of
+ * MAX_SYN_SIZE to match the new maximum number of options that you
+ * can generate.
+ */
+static void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
+                                 int offer_wscale, int wscale, __u32 tstamp,
+                                 __u32 ts_recent)
+{
+       /* We always get an MSS option.
+        * The option bytes which will be seen in normal data
+        * packets should timestamps be used, must be in the MSS
+        * advertised.  But we subtract them from tp->mss_cache so
+        * that calculations in tcp_sendmsg are simpler etc.
+        * So account for this fact here if necessary.  If we
+        * don't do this correctly, as a receiver we won't
+        * recognize data packets as being full sized when we
+        * should, and thus we won't abide by the delayed ACK
+        * rules correctly.
+        * SACKs don't matter, we never delay an ACK when we
+        * have any of those going out.
+        */
+       *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
+       if (ts) {
+               if(sack)
+                       *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
+                                                 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+               else
+                       *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+                                                 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+               *ptr++ = htonl(tstamp);         /* TSVAL */
+               *ptr++ = htonl(ts_recent);      /* TSECR */
+       } else if(sack)
+               *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+                                         (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
+       if (offer_wscale)
+               *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
+}
 
 /* This routine actually transmits TCP packets queued in by
  * tcp_do_sendmsg().  This is used by both the initial
@@ -371,7 +440,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
                TCP_ECN_send(sk, tp, skb, tcp_header_size);
        }
 
-       tp->af_specific->send_check(sk, th, skb->len, skb);
+       icsk->icsk_af_ops->send_check(sk, skb->len, skb);
 
        if (likely(tcb->flags & TCPCB_FLAG_ACK))
                tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
@@ -381,7 +450,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 
        TCP_INC_STATS(TCP_MIB_OUTSEGS);
 
-       err = tp->af_specific->queue_xmit(skb, 0);
+       err = icsk->icsk_af_ops->queue_xmit(skb, 0);
        if (unlikely(err <= 0))
                return err;
 
@@ -621,7 +690,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
    It is minimum of user_mss and mss received with SYN.
    It also does not include TCP options.
 
-   tp->pmtu_cookie is last pmtu, seen by this function.
+   inet_csk(sk)->icsk_pmtu_cookie is last pmtu, seen by this function.
 
    tp->mss_cache is current effective sending mss, including
    all tcp options except for SACKs. It is evaluated,
@@ -631,26 +700,26 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
    NOTE1. rfc1122 clearly states that advertised MSS
    DOES NOT include either tcp or ip options.
 
-   NOTE2. tp->pmtu_cookie and tp->mss_cache are READ ONLY outside
-   this function.                      --ANK (980731)
+   NOTE2. inet_csk(sk)->icsk_pmtu_cookie and tp->mss_cache
+   are READ ONLY outside this function.                --ANK (980731)
  */
 
 unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
 {
        struct tcp_sock *tp = tcp_sk(sk);
-       int mss_now;
-
+       struct inet_connection_sock *icsk = inet_csk(sk);
        /* Calculate base mss without TCP options:
           It is MMS_S - sizeof(tcphdr) of rfc1122
         */
-       mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct tcphdr);
+       int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
+                      sizeof(struct tcphdr));
 
        /* Clamp it (mss_clamp does not include tcp options) */
        if (mss_now > tp->rx_opt.mss_clamp)
                mss_now = tp->rx_opt.mss_clamp;
 
        /* Now subtract optional transport overhead */
-       mss_now -= tp->ext_header_len;
+       mss_now -= icsk->icsk_ext_hdr_len;
 
        /* Then reserve room for full set of TCP options and 8 bytes of data */
        if (mss_now < 48)
@@ -664,7 +733,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
                mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len);
 
        /* And store cached results */
-       tp->pmtu_cookie = pmtu;
+       icsk->icsk_pmtu_cookie = pmtu;
        tp->mss_cache = mss_now;
 
        return mss_now;
@@ -694,7 +763,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
 
        if (dst) {
                u32 mtu = dst_mtu(dst);
-               if (mtu != tp->pmtu_cookie)
+               if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
                        mss_now = tcp_sync_mss(sk, mtu);
        }
 
@@ -705,9 +774,10 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
        xmit_size_goal = mss_now;
 
        if (doing_tso) {
-               xmit_size_goal = 65535 -
-                       tp->af_specific->net_header_len -
-                       tp->ext_header_len - tp->tcp_header_len;
+               xmit_size_goal = (65535 -
+                                 inet_csk(sk)->icsk_af_ops->net_header_len -
+                                 inet_csk(sk)->icsk_ext_hdr_len -
+                                 tp->tcp_header_len);
 
                if (tp->max_window &&
                    (xmit_size_goal > (tp->max_window >> 1)))
@@ -723,7 +793,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
 
 /* Congestion window validation. (RFC2861) */
 
-static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
+static void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
 {
        __u32 packets_out = tp->packets_out;
 
@@ -772,7 +842,7 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *sk
 /* This must be invoked the first time we consider transmitting
  * SKB onto the wire.
  */
-static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
+static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
 {
        int tso_segs = tcp_skb_pcount(skb);
 
@@ -1422,7 +1492,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
           (sysctl_tcp_retrans_collapse != 0))
                tcp_retrans_try_collapse(sk, skb, cur_mss);
 
-       if(tp->af_specific->rebuild_header(sk))
+       if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
                return -EHOSTUNREACH; /* Routing failure or similar. */
 
        /* Some Solaris stacks overoptimize and ignore the FIN on a
@@ -1793,7 +1863,7 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
 /* 
  * Do all connect socket setups that can be done AF independent.
  */ 
-static inline void tcp_connect_init(struct sock *sk)
+static void tcp_connect_init(struct sock *sk)
 {
        struct dst_entry *dst = __sk_dst_get(sk);
        struct tcp_sock *tp = tcp_sk(sk);
index 13e7e6e..3b74034 100644 (file)
@@ -330,6 +330,10 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
                vegas->cntRTT = 0;
                vegas->minRTT = 0x7fffffff;
        }
+       /* Use normal slow start */
+       else if (tp->snd_cwnd <= tp->snd_ssthresh) 
+               tcp_slow_start(tp);
+       
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
index 2422a5f..223abaa 100644 (file)
@@ -86,6 +86,7 @@
 #include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
+#include <linux/igmp.h>
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
@@ -846,20 +847,7 @@ out:
 csum_copy_err:
        UDP_INC_STATS_BH(UDP_MIB_INERRORS);
 
-       /* Clear queue. */
-       if (flags&MSG_PEEK) {
-               int clear = 0;
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               if (skb == skb_peek(&sk->sk_receive_queue)) {
-                       __skb_unlink(skb, &sk->sk_receive_queue);
-                       clear = 1;
-               }
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
-               if (clear)
-                       kfree_skb(skb);
-       }
-
-       skb_free_datagram(sk, skb);
+       skb_kill_datagram(sk, skb, flags);
 
        if (noblock)
                return -EAGAIN; 
@@ -1094,7 +1082,7 @@ static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
  * Otherwise, csum completion requires chacksumming packet body,
  * including udp header and folding it to skb->csum.
  */
-static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
+static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
                             unsigned short ulen, u32 saddr, u32 daddr)
 {
        if (uh->check == 0) {
@@ -1108,7 +1096,6 @@ static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
        /* Probably, we should checksum udp header (it should be in cache
         * in any case) and data in tiny packets (< rx copybreak).
         */
-       return 0;
 }
 
 /*
@@ -1141,8 +1128,7 @@ int udp_rcv(struct sk_buff *skb)
        if (pskb_trim_rcsum(skb, ulen))
                goto short_packet;
 
-       if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
-               goto csum_error;
+       udp_checksum_init(skb, uh, ulen, saddr, daddr);
 
        if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
                return udp_v4_mcast_deliver(skb, uh, saddr, daddr);
index 6460eec..9601fd7 100644 (file)
@@ -8,7 +8,8 @@ ipv6-objs :=    af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
                route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
                protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
                exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
-               ip6_flowlabel.o ipv6_syms.o netfilter.o
+               ip6_flowlabel.o ipv6_syms.o netfilter.o \
+               inet6_connection_sock.o
 
 ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
        xfrm6_output.o
index a60585f..704fb73 100644 (file)
@@ -1195,7 +1195,7 @@ struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *
 int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
 {
        const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
-       const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2);
+       const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
        u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
        u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
        int sk_ipv6only = ipv6_only_sock(sk);
index d954638..68afc53 100644 (file)
@@ -167,6 +167,7 @@ lookup_protocol:
                sk->sk_reuse = 1;
 
        inet = inet_sk(sk);
+       inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
 
        if (SOCK_RAW == sock->type) {
                inet->num = protocol;
@@ -389,6 +390,8 @@ int inet6_destroy_sock(struct sock *sk)
        return 0;
 }
 
+EXPORT_SYMBOL_GPL(inet6_destroy_sock);
+
 /*
  *     This does both peername and sockname.
  */
@@ -431,7 +434,6 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
 int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
-       int err = -EINVAL;
 
        switch(cmd) 
        {
@@ -450,16 +452,15 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case SIOCSIFDSTADDR:
                return addrconf_set_dstaddr((void __user *) arg);
        default:
-               if (!sk->sk_prot->ioctl ||
-                   (err = sk->sk_prot->ioctl(sk, cmd, arg)) == -ENOIOCTLCMD)
-                       return(dev_ioctl(cmd,(void __user *) arg));             
-               return err;
+               if (!sk->sk_prot->ioctl)
+                       return -ENOIOCTLCMD;
+               return sk->sk_prot->ioctl(sk, cmd, arg);
        }
        /*NOTREACHED*/
        return(0);
 }
 
-struct proto_ops inet6_stream_ops = {
+const struct proto_ops inet6_stream_ops = {
        .family =       PF_INET6,
        .owner =        THIS_MODULE,
        .release =      inet6_release,
@@ -480,7 +481,7 @@ struct proto_ops inet6_stream_ops = {
        .sendpage =     tcp_sendpage
 };
 
-struct proto_ops inet6_dgram_ops = {
+const struct proto_ops inet6_dgram_ops = {
        .family =       PF_INET6,
        .owner =        THIS_MODULE,
        .release =      inet6_release,
@@ -508,7 +509,7 @@ static struct net_proto_family inet6_family_ops = {
 };
 
 /* Same as inet6_dgram_ops, sans udp_poll.  */
-static struct proto_ops inet6_sockraw_ops = {
+static const struct proto_ops inet6_sockraw_ops = {
        .family =       PF_INET6,
        .owner =        THIS_MODULE,
        .release =      inet6_release,
@@ -609,6 +610,79 @@ inet6_unregister_protosw(struct inet_protosw *p)
        }
 }
 
+int inet6_sk_rebuild_header(struct sock *sk)
+{
+       int err;
+       struct dst_entry *dst;
+       struct ipv6_pinfo *np = inet6_sk(sk);
+
+       dst = __sk_dst_check(sk, np->dst_cookie);
+
+       if (dst == NULL) {
+               struct inet_sock *inet = inet_sk(sk);
+               struct in6_addr *final_p = NULL, final;
+               struct flowi fl;
+
+               memset(&fl, 0, sizeof(fl));
+               fl.proto = sk->sk_protocol;
+               ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+               ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+               fl.fl6_flowlabel = np->flow_label;
+               fl.oif = sk->sk_bound_dev_if;
+               fl.fl_ip_dport = inet->dport;
+               fl.fl_ip_sport = inet->sport;
+
+               if (np->opt && np->opt->srcrt) {
+                       struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
+                       ipv6_addr_copy(&final, &fl.fl6_dst);
+                       ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+                       final_p = &final;
+               }
+
+               err = ip6_dst_lookup(sk, &dst, &fl);
+               if (err) {
+                       sk->sk_route_caps = 0;
+                       return err;
+               }
+               if (final_p)
+                       ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+               if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+                       sk->sk_err_soft = -err;
+                       return err;
+               }
+
+               ip6_dst_store(sk, dst, NULL);
+               sk->sk_route_caps = dst->dev->features &
+                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+       }
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header);
+
+int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
+{
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct inet6_skb_parm *opt = IP6CB(skb);
+
+       if (np->rxopt.all) {
+               if ((opt->hop && (np->rxopt.bits.hopopts ||
+                                 np->rxopt.bits.ohopopts)) ||
+                   ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) &&
+                    np->rxopt.bits.rxflow) ||
+                   (opt->srcrt && (np->rxopt.bits.srcrt ||
+                    np->rxopt.bits.osrcrt)) ||
+                   ((opt->dst1 || opt->dst0) &&
+                    (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
+                       return 1;
+       }
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
+
 int
 snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign)
 {
index f362973..13cc7f8 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <net/xfrm.h>
 #include <asm/scatterlist.h>
 
index 8bfbe99..6de8ee1 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/random.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <linux/icmpv6.h>
 
 static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
index be6faf3..113374d 100644 (file)
@@ -413,6 +413,8 @@ ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
        return opt;
 }
 
+EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
+
 /**********************************
   Hop-by-hop options.
  **********************************/
@@ -579,6 +581,8 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
        return opt2;
 }
 
+EXPORT_SYMBOL_GPL(ipv6_dup_options);
+
 static int ipv6_renew_option(void *ohdr,
                             struct ipv6_opt_hdr __user *newopt, int newoptlen,
                             int inherit,
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
new file mode 100644 (file)
index 0000000..792f90f
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * INET        An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             Support for INET6 connection oriented protocols.
+ *
+ * Authors:    See the TCPv6 sources
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or(at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/in6.h>
+#include <linux/ipv6.h>
+#include <linux/jhash.h>
+
+#include <net/addrconf.h>
+#include <net/inet_connection_sock.h>
+#include <net/inet_ecn.h>
+#include <net/inet_hashtables.h>
+#include <net/ip6_route.h>
+#include <net/sock.h>
+
+int inet6_csk_bind_conflict(const struct sock *sk,
+                           const struct inet_bind_bucket *tb)
+{
+       const struct sock *sk2;
+       const struct hlist_node *node;
+
+       /* We must walk the whole port owner list in this case. -DaveM */
+       sk_for_each_bound(sk2, node, &tb->owners) {
+               if (sk != sk2 &&
+                   (!sk->sk_bound_dev_if ||
+                    !sk2->sk_bound_dev_if ||
+                    sk->sk_bound_dev_if == sk2->sk_bound_dev_if) &&
+                   (!sk->sk_reuse || !sk2->sk_reuse ||
+                    sk2->sk_state == TCP_LISTEN) &&
+                    ipv6_rcv_saddr_equal(sk, sk2))
+                       break;
+       }
+
+       return node != NULL;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
+
+/*
+ * request_sock (formerly open request) hash tables.
+ */
+static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport,
+                          const u32 rnd, const u16 synq_hsize)
+{
+       u32 a = raddr->s6_addr32[0];
+       u32 b = raddr->s6_addr32[1];
+       u32 c = raddr->s6_addr32[2];
+
+       a += JHASH_GOLDEN_RATIO;
+       b += JHASH_GOLDEN_RATIO;
+       c += rnd;
+       __jhash_mix(a, b, c);
+
+       a += raddr->s6_addr32[3];
+       b += (u32)rport;
+       __jhash_mix(a, b, c);
+
+       return c & (synq_hsize - 1);
+}
+
+struct request_sock *inet6_csk_search_req(const struct sock *sk,
+                                         struct request_sock ***prevp,
+                                         const __u16 rport,
+                                         const struct in6_addr *raddr,
+                                         const struct in6_addr *laddr,
+                                         const int iif)
+{
+       const struct inet_connection_sock *icsk = inet_csk(sk);
+       struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
+       struct request_sock *req, **prev;
+
+       for (prev = &lopt->syn_table[inet6_synq_hash(raddr, rport,
+                                                    lopt->hash_rnd,
+                                                    lopt->nr_table_entries)];
+            (req = *prev) != NULL;
+            prev = &req->dl_next) {
+               const struct inet6_request_sock *treq = inet6_rsk(req);
+
+               if (inet_rsk(req)->rmt_port == rport &&
+                   req->rsk_ops->family == AF_INET6 &&
+                   ipv6_addr_equal(&treq->rmt_addr, raddr) &&
+                   ipv6_addr_equal(&treq->loc_addr, laddr) &&
+                   (!treq->iif || treq->iif == iif)) {
+                       BUG_TRAP(req->sk == NULL);
+                       *prevp = prev;
+                       return req;
+               }
+       }
+
+       return NULL;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_search_req);
+
+void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
+                                   struct request_sock *req,
+                                   const unsigned long timeout)
+{
+       struct inet_connection_sock *icsk = inet_csk(sk);
+       struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
+       const u32 h = inet6_synq_hash(&inet6_rsk(req)->rmt_addr,
+                                     inet_rsk(req)->rmt_port,
+                                     lopt->hash_rnd, lopt->nr_table_entries);
+
+       reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, timeout);
+       inet_csk_reqsk_queue_added(sk, timeout);
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_reqsk_queue_hash_add);
+
+void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
+{
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
+
+       sin6->sin6_family = AF_INET6;
+       ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
+       sin6->sin6_port = inet_sk(sk)->dport;
+       /* We do not store received flowlabel for TCP */
+       sin6->sin6_flowinfo = 0;
+       sin6->sin6_scope_id = 0;
+       if (sk->sk_bound_dev_if &&
+           ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+               sin6->sin6_scope_id = sk->sk_bound_dev_if;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
+
+int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
+{
+       struct sock *sk = skb->sk;
+       struct inet_sock *inet = inet_sk(sk);
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct flowi fl;
+       struct dst_entry *dst;
+       struct in6_addr *final_p = NULL, final;
+
+       memset(&fl, 0, sizeof(fl));
+       fl.proto = sk->sk_protocol;
+       ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+       ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+       fl.fl6_flowlabel = np->flow_label;
+       IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
+       fl.oif = sk->sk_bound_dev_if;
+       fl.fl_ip_sport = inet->sport;
+       fl.fl_ip_dport = inet->dport;
+
+       if (np->opt && np->opt->srcrt) {
+               struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+               ipv6_addr_copy(&final, &fl.fl6_dst);
+               ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+               final_p = &final;
+       }
+
+       dst = __sk_dst_check(sk, np->dst_cookie);
+
+       if (dst == NULL) {
+               int err = ip6_dst_lookup(sk, &dst, &fl);
+
+               if (err) {
+                       sk->sk_err_soft = -err;
+                       return err;
+               }
+
+               if (final_p)
+                       ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+               if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+                       sk->sk_route_caps = 0;
+                       return err;
+               }
+
+               ip6_dst_store(sk, dst, NULL);
+               sk->sk_route_caps = dst->dev->features &
+                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+       }
+
+       skb->dst = dst_clone(dst);
+
+       /* Restore final destination back after routing done */
+       ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+
+       return ip6_xmit(sk, skb, &fl, np->opt, 0);
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_xmit);
index 01d5f46..4154f3a 100644 (file)
@@ -5,7 +5,8 @@
  *
  *             Generic INET6 transport hashtables
  *
- * Authors:    Lotsa people, from code originally in tcp
+ * Authors:    Lotsa people, from code originally in tcp, generalised here
+ *             by Arnaldo Carvalho de Melo <acme@mandriva.com>
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
  */
 
 #include <linux/config.h>
-
 #include <linux/module.h>
+#include <linux/random.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_hashtables.h>
 #include <net/inet6_hashtables.h>
+#include <net/ip.h>
 
 struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
                                   const struct in6_addr *daddr,
@@ -79,3 +81,180 @@ struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
 }
 
 EXPORT_SYMBOL_GPL(inet6_lookup);
+
+static int __inet6_check_established(struct inet_timewait_death_row *death_row,
+                                    struct sock *sk, const __u16 lport,
+                                    struct inet_timewait_sock **twp)
+{
+       struct inet_hashinfo *hinfo = death_row->hashinfo;
+       const struct inet_sock *inet = inet_sk(sk);
+       const struct ipv6_pinfo *np = inet6_sk(sk);
+       const struct in6_addr *daddr = &np->rcv_saddr;
+       const struct in6_addr *saddr = &np->daddr;
+       const int dif = sk->sk_bound_dev_if;
+       const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+       const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
+                                               inet->dport);
+       struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+       struct sock *sk2;
+       const struct hlist_node *node;
+       struct inet_timewait_sock *tw;
+
+       prefetch(head->chain.first);
+       write_lock(&head->lock);
+
+       /* Check TIME-WAIT sockets first. */
+       sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) {
+               const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
+
+               tw = inet_twsk(sk2);
+
+               if(*((__u32 *)&(tw->tw_dport)) == ports          &&
+                  sk2->sk_family              == PF_INET6       &&
+                  ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)     &&
+                  ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
+                  sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
+                       if (twsk_unique(sk, sk2, twp))
+                               goto unique;
+                       else
+                               goto not_unique;
+               }
+       }
+       tw = NULL;
+
+       /* And established part... */
+       sk_for_each(sk2, node, &head->chain) {
+               if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
+                       goto not_unique;
+       }
+
+unique:
+       BUG_TRAP(sk_unhashed(sk));
+       __sk_add_node(sk, &head->chain);
+       sk->sk_hash = hash;
+       sock_prot_inc_use(sk->sk_prot);
+       write_unlock(&head->lock);
+
+       if (twp != NULL) {
+               *twp = tw;
+               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+       } else if (tw != NULL) {
+               /* Silly. Should hash-dance instead... */
+               inet_twsk_deschedule(tw, death_row);
+               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+
+               inet_twsk_put(tw);
+       }
+       return 0;
+
+not_unique:
+       write_unlock(&head->lock);
+       return -EADDRNOTAVAIL;
+}
+
+static inline u32 inet6_sk_port_offset(const struct sock *sk)
+{
+       const struct inet_sock *inet = inet_sk(sk);
+       const struct ipv6_pinfo *np = inet6_sk(sk);
+       return secure_ipv6_port_ephemeral(np->rcv_saddr.s6_addr32,
+                                         np->daddr.s6_addr32,
+                                         inet->dport);
+}
+
+int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+                      struct sock *sk)
+{
+       struct inet_hashinfo *hinfo = death_row->hashinfo;
+       const unsigned short snum = inet_sk(sk)->num;
+       struct inet_bind_hashbucket *head;
+       struct inet_bind_bucket *tb;
+       int ret;
+
+       if (snum == 0) {
+               const int low = sysctl_local_port_range[0];
+               const int high = sysctl_local_port_range[1];
+               const int range = high - low;
+               int i, port;
+               static u32 hint;
+               const u32 offset = hint + inet6_sk_port_offset(sk);
+               struct hlist_node *node;
+               struct inet_timewait_sock *tw = NULL;
+
+               local_bh_disable();
+               for (i = 1; i <= range; i++) {
+                       port = low + (i + offset) % range;
+                       head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
+                       spin_lock(&head->lock);
+
+                       /* Does not bother with rcv_saddr checks,
+                        * because the established check is already
+                        * unique enough.
+                        */
+                       inet_bind_bucket_for_each(tb, node, &head->chain) {
+                               if (tb->port == port) {
+                                       BUG_TRAP(!hlist_empty(&tb->owners));
+                                       if (tb->fastreuse >= 0)
+                                               goto next_port;
+                                       if (!__inet6_check_established(death_row,
+                                                                      sk, port,
+                                                                      &tw))
+                                               goto ok;
+                                       goto next_port;
+                               }
+                       }
+
+                       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+                                                    head, port);
+                       if (!tb) {
+                               spin_unlock(&head->lock);
+                               break;
+                       }
+                       tb->fastreuse = -1;
+                       goto ok;
+
+               next_port:
+                       spin_unlock(&head->lock);
+               }
+               local_bh_enable();
+
+               return -EADDRNOTAVAIL;
+
+ok:
+               hint += i;
+
+               /* Head lock still held and bh's disabled */
+               inet_bind_hash(sk, tb, port);
+               if (sk_unhashed(sk)) {
+                       inet_sk(sk)->sport = htons(port);
+                       __inet6_hash(hinfo, sk);
+               }
+               spin_unlock(&head->lock);
+
+               if (tw) {
+                       inet_twsk_deschedule(tw, death_row);
+                       inet_twsk_put(tw);
+               }
+
+               ret = 0;
+               goto out;
+       }
+
+       head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
+       tb   = inet_csk(sk)->icsk_bind_hash;
+       spin_lock_bh(&head->lock);
+
+       if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
+               __inet6_hash(hinfo, sk);
+               spin_unlock_bh(&head->lock);
+               return 0;
+       } else {
+               spin_unlock(&head->lock);
+               /* No definite answer... Walk to established hash table */
+               ret = __inet6_check_established(death_row, sk, snum, NULL);
+out:
+               local_bh_enable();
+               return ret;
+       }
+}
+
+EXPORT_SYMBOL_GPL(inet6_hash_connect);
index 1cf0276..89d12b4 100644 (file)
@@ -200,6 +200,8 @@ struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, u32 label)
        return NULL;
 }
 
+EXPORT_SYMBOL_GPL(fl6_sock_lookup);
+
 void fl6_free_socklist(struct sock *sk)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
index 8523c76..b4c4beb 100644 (file)
@@ -775,6 +775,8 @@ out_err_release:
        return err;
 }
 
+EXPORT_SYMBOL_GPL(ip6_dst_lookup);
+
 static inline int ip6_ufo_append_data(struct sock *sk,
                        int getfrag(void *from, char *to, int offset, int len,
                        int odd, struct sk_buff *skb),
index 55917fb..626dd39 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 
index 3620718..c63868d 100644 (file)
@@ -163,17 +163,17 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
                        sk_refcnt_debug_dec(sk);
 
                        if (sk->sk_protocol == IPPROTO_TCP) {
-                               struct tcp_sock *tp = tcp_sk(sk);
+                               struct inet_connection_sock *icsk = inet_csk(sk);
 
                                local_bh_disable();
                                sock_prot_dec_use(sk->sk_prot);
                                sock_prot_inc_use(&tcp_prot);
                                local_bh_enable();
                                sk->sk_prot = &tcp_prot;
-                               tp->af_specific = &ipv4_specific;
+                               icsk->icsk_af_ops = &ipv4_specific;
                                sk->sk_socket->ops = &inet_stream_ops;
                                sk->sk_family = PF_INET;
-                               tcp_sync_mss(sk, tp->pmtu_cookie);
+                               tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
                        } else {
                                local_bh_disable();
                                sock_prot_dec_use(sk->sk_prot);
@@ -317,14 +317,15 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
                }
 
                retv = 0;
-               if (sk->sk_type == SOCK_STREAM) {
+               if (inet_sk(sk)->is_icsk) {
                        if (opt) {
-                               struct tcp_sock *tp = tcp_sk(sk);
+                               struct inet_connection_sock *icsk = inet_csk(sk);
                                if (!((1 << sk->sk_state) &
                                      (TCPF_LISTEN | TCPF_CLOSE))
                                    && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
-                                       tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
-                                       tcp_sync_mss(sk, tp->pmtu_cookie);
+                                       icsk->icsk_ext_hdr_len =
+                                               opt->opt_flen + opt->opt_nflen;
+                                       icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
                                }
                        }
                        opt = xchg(&np->opt, opt);
@@ -380,14 +381,15 @@ sticky_done:
                        goto done;
 update:
                retv = 0;
-               if (sk->sk_type == SOCK_STREAM) {
+               if (inet_sk(sk)->is_icsk) {
                        if (opt) {
-                               struct tcp_sock *tp = tcp_sk(sk);
+                               struct inet_connection_sock *icsk = inet_csk(sk);
                                if (!((1 << sk->sk_state) &
                                      (TCPF_LISTEN | TCPF_CLOSE))
                                    && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
-                                       tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
-                                       tcp_sync_mss(sk, tp->pmtu_cookie);
+                                       icsk->icsk_ext_hdr_len =
+                                               opt->opt_flen + opt->opt_nflen;
+                                       icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
                                }
                        }
                        opt = xchg(&np->opt, opt);
index f829a4a..1cf305a 100644 (file)
@@ -224,7 +224,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
 
        mc_lst->ifindex = dev->ifindex;
        mc_lst->sfmode = MCAST_EXCLUDE;
-       mc_lst->sflock = RW_LOCK_UNLOCKED;
+       rwlock_init(&mc_lst->sflock);
        mc_lst->sflist = NULL;
 
        /*
index 95d4692..ea43ef1 100644 (file)
@@ -15,6 +15,7 @@
  *      - new extension header parser code
  */
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/skbuff.h>
 #include <linux/kmod.h>
 #include <linux/vmalloc.h>
@@ -86,11 +87,6 @@ static DECLARE_MUTEX(ip6t_mutex);
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -108,20 +104,15 @@ struct ip6t_table_info
        unsigned int underflow[NF_IP6_NUMHOOKS];
 
        /* ip6t_entry tables: one per CPU */
-       char entries[0] ____cacheline_aligned;
+       void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ip6t_target);
 static LIST_HEAD(ip6t_match);
 static LIST_HEAD(ip6t_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
 #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
@@ -376,8 +367,7 @@ ip6t_do_table(struct sk_buff **pskb,
 
        read_lock_bh(&table->lock);
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-       table_base = (void *)table->private->entries
-               + TABLE_OFFSET(table->private, smp_processor_id());
+       table_base = (void *)table->private->entries[smp_processor_id()];
        e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -649,7 +639,8 @@ unconditional(const struct ip6t_ip6 *ipv6)
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
-mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks)
+mark_source_chains(struct ip6t_table_info *newinfo,
+                  unsigned int valid_hooks, void *entry0)
 {
        unsigned int hook;
 
@@ -658,7 +649,7 @@ mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks)
        for (hook = 0; hook < NF_IP6_NUMHOOKS; hook++) {
                unsigned int pos = newinfo->hook_entry[hook];
                struct ip6t_entry *e
-                       = (struct ip6t_entry *)(newinfo->entries + pos);
+                       = (struct ip6t_entry *)(entry0 + pos);
 
                if (!(valid_hooks & (1 << hook)))
                        continue;
@@ -708,13 +699,13 @@ mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks)
                                                goto next;
 
                                        e = (struct ip6t_entry *)
-                                               (newinfo->entries + pos);
+                                               (entry0 + pos);
                                } while (oldpos == pos + e->next_offset);
 
                                /* Move along one */
                                size = e->next_offset;
                                e = (struct ip6t_entry *)
-                                       (newinfo->entries + pos + size);
+                                       (entry0 + pos + size);
                                e->counters.pcnt = pos;
                                pos += size;
                        } else {
@@ -731,7 +722,7 @@ mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks)
                                        newpos = pos + e->next_offset;
                                }
                                e = (struct ip6t_entry *)
-                                       (newinfo->entries + newpos);
+                                       (entry0 + newpos);
                                e->counters.pcnt = pos;
                                pos = newpos;
                        }
@@ -941,6 +932,7 @@ static int
 translate_table(const char *name,
                unsigned int valid_hooks,
                struct ip6t_table_info *newinfo,
+               void *entry0,
                unsigned int size,
                unsigned int number,
                const unsigned int *hook_entries,
@@ -961,11 +953,11 @@ translate_table(const char *name,
        duprintf("translate_table: size %u\n", newinfo->size);
        i = 0;
        /* Walk through entries, checking offsets. */
-       ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+       ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry_size_and_hooks,
                                newinfo,
-                               newinfo->entries,
-                               newinfo->entries + size,
+                               entry0,
+                               entry0 + size,
                                hook_entries, underflows, &i);
        if (ret != 0)
                return ret;
@@ -993,27 +985,24 @@ translate_table(const char *name,
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks))
+       if (!mark_source_chains(newinfo, valid_hooks, entry0))
                return -ELOOP;
 
        /* Finally, each sanity check must pass */
        i = 0;
-       ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+       ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry, name, size, &i);
 
        if (ret != 0) {
-               IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+               IP6T_ENTRY_ITERATE(entry0, newinfo->size,
                                  cleanup_entry, &i);
                return ret;
        }
 
        /* And one copy for every other CPU */
        for_each_cpu(i) {
-               if (i == 0)
-                       continue;
-               memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-                      newinfo->entries,
-                      SMP_ALIGN(newinfo->size));
+               if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+                       memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
        return ret;
@@ -1029,15 +1018,12 @@ replace_table(struct ip6t_table *table,
 
 #ifdef CONFIG_NETFILTER_DEBUG
        {
-               struct ip6t_entry *table_base;
-               unsigned int i;
+               int cpu;
 
-               for_each_cpu(i) {
-                       table_base =
-                               (void *)newinfo->entries
-                               + TABLE_OFFSET(newinfo, i);
-
-                       table_base->comefrom = 0xdead57ac;
+               for_each_cpu(cpu) {
+                       struct ip6t_entry *table_base = newinfo->entries[cpu];
+                       if (table_base)
+                               table_base->comefrom = 0xdead57ac;
                }
        }
 #endif
@@ -1072,16 +1058,44 @@ add_entry_to_counter(const struct ip6t_entry *e,
        return 0;
 }
 
+static inline int
+set_entry_to_counter(const struct ip6t_entry *e,
+                    struct ip6t_counters total[],
+                    unsigned int *i)
+{
+       SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+       (*i)++;
+       return 0;
+}
+
 static void
 get_counters(const struct ip6t_table_info *t,
             struct ip6t_counters counters[])
 {
        unsigned int cpu;
        unsigned int i;
+       unsigned int curcpu;
+
+       /* Instead of clearing (by a previous call to memset())
+        * the counters and using adds, we set the counters
+        * with data used by 'current' CPU
+        * We dont care about preemption here.
+        */
+       curcpu = raw_smp_processor_id();
+
+       i = 0;
+       IP6T_ENTRY_ITERATE(t->entries[curcpu],
+                          t->size,
+                          set_entry_to_counter,
+                          counters,
+                          &i);
 
        for_each_cpu(cpu) {
+               if (cpu == curcpu)
+                       continue;
                i = 0;
-               IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+               IP6T_ENTRY_ITERATE(t->entries[cpu],
                                  t->size,
                                  add_entry_to_counter,
                                  counters,
@@ -1098,6 +1112,7 @@ copy_entries_to_user(unsigned int total_size,
        struct ip6t_entry *e;
        struct ip6t_counters *counters;
        int ret = 0;
+       void *loc_cpu_entry;
 
        /* We need atomic snapshot of counters: rest doesn't change
           (other than comefrom, which userspace doesn't care
@@ -1109,13 +1124,13 @@ copy_entries_to_user(unsigned int total_size,
                return -ENOMEM;
 
        /* First, sum counters... */
-       memset(counters, 0, countersize);
        write_lock_bh(&table->lock);
        get_counters(table->private, counters);
        write_unlock_bh(&table->lock);
 
-       /* ... then copy entire thing from CPU 0... */
-       if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+       /* choose the copy that is on ourc node/cpu */
+       loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+       if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
                ret = -EFAULT;
                goto free_counters;
        }
@@ -1127,7 +1142,7 @@ copy_entries_to_user(unsigned int total_size,
                struct ip6t_entry_match *m;
                struct ip6t_entry_target *t;
 
-               e = (struct ip6t_entry *)(table->private->entries + off);
+               e = (struct ip6t_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
                                 + offsetof(struct ip6t_entry, counters),
                                 &counters[num],
@@ -1196,6 +1211,46 @@ get_entries(const struct ip6t_get_entries *entries,
        return ret;
 }
 
+static void free_table_info(struct ip6t_table_info *info)
+{
+       int cpu;
+       for_each_cpu(cpu) {
+               if (info->size <= PAGE_SIZE)
+                       kfree(info->entries[cpu]);
+               else
+                       vfree(info->entries[cpu]);
+       }
+       kfree(info);
+}
+
+static struct ip6t_table_info *alloc_table_info(unsigned int size)
+{
+       struct ip6t_table_info *newinfo;
+       int cpu;
+
+       newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL);
+       if (!newinfo)
+               return NULL;
+
+       newinfo->size = size;
+
+       for_each_cpu(cpu) {
+               if (size <= PAGE_SIZE)
+                       newinfo->entries[cpu] = kmalloc_node(size,
+                                                       GFP_KERNEL,
+                                                       cpu_to_node(cpu));
+               else
+                       newinfo->entries[cpu] = vmalloc_node(size,
+                                                            cpu_to_node(cpu));
+               if (newinfo->entries[cpu] == NULL) {
+                       free_table_info(newinfo);
+                       return NULL;
+               }
+       }
+
+       return newinfo;
+}
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1204,6 +1259,7 @@ do_replace(void __user *user, unsigned int len)
        struct ip6t_table *t;
        struct ip6t_table_info *newinfo, *oldinfo;
        struct ip6t_counters *counters;
+       void *loc_cpu_entry, *loc_cpu_old_entry;
 
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
@@ -1212,13 +1268,13 @@ do_replace(void __user *user, unsigned int len)
        if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
                return -ENOMEM;
 
-       newinfo = vmalloc(sizeof(struct ip6t_table_info)
-                         + SMP_ALIGN(tmp.size) *
-                                       (highest_possible_processor_id()+1));
+       newinfo = alloc_table_info(tmp.size);
        if (!newinfo)
                return -ENOMEM;
 
-       if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+       /* choose the copy that is on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
                           tmp.size) != 0) {
                ret = -EFAULT;
                goto free_newinfo;
@@ -1229,10 +1285,9 @@ do_replace(void __user *user, unsigned int len)
                ret = -ENOMEM;
                goto free_newinfo;
        }
-       memset(counters, 0, tmp.num_counters * sizeof(struct ip6t_counters));
 
        ret = translate_table(tmp.name, tmp.valid_hooks,
-                             newinfo, tmp.size, tmp.num_entries,
+                             newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
                              tmp.hook_entry, tmp.underflow);
        if (ret != 0)
                goto free_newinfo_counters;
@@ -1271,8 +1326,9 @@ do_replace(void __user *user, unsigned int len)
        /* Get the old counters. */
        get_counters(oldinfo, counters);
        /* Decrease module usage counts and free resource */
-       IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-       vfree(oldinfo);
+       loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+       IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+       free_table_info(oldinfo);
        if (copy_to_user(tmp.counters, counters,
                         sizeof(struct ip6t_counters) * tmp.num_counters) != 0)
                ret = -EFAULT;
@@ -1284,11 +1340,11 @@ do_replace(void __user *user, unsigned int len)
        module_put(t->me);
        up(&ip6t_mutex);
  free_newinfo_counters_untrans:
-       IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
        vfree(counters);
  free_newinfo:
-       vfree(newinfo);
+       free_table_info(newinfo);
        return ret;
 }
 
@@ -1321,6 +1377,7 @@ do_add_counters(void __user *user, unsigned int len)
        struct ip6t_counters_info tmp, *paddc;
        struct ip6t_table *t;
        int ret = 0;
+       void *loc_cpu_entry;
 
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
@@ -1350,7 +1407,9 @@ do_add_counters(void __user *user, unsigned int len)
        }
 
        i = 0;
-       IP6T_ENTRY_ITERATE(t->private->entries,
+       /* Choose the copy that is on our node */
+       loc_cpu_entry = t->private->entries[smp_processor_id()];
+       IP6T_ENTRY_ITERATE(loc_cpu_entry,
                          t->private->size,
                          add_counter_to_entry,
                          paddc->counters,
@@ -1543,28 +1602,29 @@ int ip6t_register_table(struct ip6t_table *table,
        struct ip6t_table_info *newinfo;
        static struct ip6t_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
+       void *loc_cpu_entry;
 
-       newinfo = vmalloc(sizeof(struct ip6t_table_info)
-                         + SMP_ALIGN(repl->size) *
-                                       (highest_possible_processor_id()+1));
+       newinfo = alloc_table_info(repl->size);
        if (!newinfo)
                return -ENOMEM;
 
-       memcpy(newinfo->entries, repl->entries, repl->size);
+       /* choose the copy on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       memcpy(loc_cpu_entry, repl->entries, repl->size);
 
        ret = translate_table(table->name, table->valid_hooks,
-                             newinfo, repl->size,
+                             newinfo, loc_cpu_entry, repl->size,
                              repl->num_entries,
                              repl->hook_entry,
                              repl->underflow);
        if (ret != 0) {
-               vfree(newinfo);
+               free_table_info(newinfo);
                return ret;
        }
 
        ret = down_interruptible(&ip6t_mutex);
        if (ret != 0) {
-               vfree(newinfo);
+               free_table_info(newinfo);
                return ret;
        }
 
@@ -1593,20 +1653,23 @@ int ip6t_register_table(struct ip6t_table *table,
        return ret;
 
  free_unlock:
-       vfree(newinfo);
+       free_table_info(newinfo);
        goto unlock;
 }
 
 void ip6t_unregister_table(struct ip6t_table *table)
 {
+       void *loc_cpu_entry;
+
        down(&ip6t_mutex);
        LIST_DELETE(&ip6t_tables, table);
        up(&ip6t_mutex);
 
        /* Decrease module usage counts and free resources */
-       IP6T_ENTRY_ITERATE(table->private->entries, table->private->size,
+       loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+       IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
                          cleanup_entry, NULL);
-       vfree(table->private);
+       free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
index 0cd1d1b..ae4653b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/ip.h>
 #include <linux/spinlock.h>
 #include <linux/icmpv6.h>
index dde3779..268918d 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/types.h>
 #include <net/checksum.h>
index 24bc0cd..65937de 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/types.h>
 #include <net/checksum.h>
index c2c52af..f3e5ffb 100644 (file)
@@ -98,7 +98,7 @@ struct nf_ct_frag6_queue
 #define FRAG6Q_HASHSZ  64
 
 static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
-static rwlock_t nf_ct_frag6_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(nf_ct_frag6_lock);
 static u32 nf_ct_frag6_hash_rnd;
 static LIST_HEAD(nf_ct_frag6_lru_list);
 int nf_ct_frag6_nqueues = 0;
@@ -371,7 +371,7 @@ nf_ct_frag6_create(unsigned int hash, u32 id, struct in6_addr *src,                            struct
        init_timer(&fq->timer);
        fq->timer.function = nf_ct_frag6_expire;
        fq->timer.data = (long) fq;
-       fq->lock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&fq->lock);
        atomic_set(&fq->refcnt, 1);
 
        return nf_ct_frag6_intern(hash, fq);
index a66900c..66f1d12 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/icmpv6.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 #include <asm/bug.h>
@@ -433,25 +434,14 @@ out:
        return err;
 
 csum_copy_err:
-       /* Clear queue. */
-       if (flags&MSG_PEEK) {
-               int clear = 0;
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               if (skb == skb_peek(&sk->sk_receive_queue)) {
-                       __skb_unlink(skb, &sk->sk_receive_queue);
-                       clear = 1;
-               }
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
-               if (clear)
-                       kfree_skb(skb);
-       }
+       skb_kill_datagram(sk, skb, flags);
 
        /* Error for blocking case is chosen to masquerade
           as some normal condition.
         */
        err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
        /* FIXME: increment a raw6 drops counter here */
-       goto out_free;
+       goto out;
 }
 
 static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
index 8827389..2947bc5 100644 (file)
@@ -48,6 +48,7 @@
 #include <net/tcp.h>
 #include <net/ndisc.h>
 #include <net/inet6_hashtables.h>
+#include <net/inet6_connection_sock.h>
 #include <net/ipv6.h>
 #include <net/transp_v6.h>
 #include <net/addrconf.h>
@@ -59,6 +60,7 @@
 #include <net/addrconf.h>
 #include <net/snmp.h>
 #include <net/dsfield.h>
+#include <net/timewait_sock.h>
 
 #include <asm/uaccess.h>
 
 
 static void    tcp_v6_send_reset(struct sk_buff *skb);
 static void    tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
-static void    tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
+static void    tcp_v6_send_check(struct sock *sk, int len, 
                                  struct sk_buff *skb);
 
 static int     tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
-static int     tcp_v6_xmit(struct sk_buff *skb, int ipfragok);
 
-static struct tcp_func ipv6_mapped;
-static struct tcp_func ipv6_specific;
+static struct inet_connection_sock_af_ops ipv6_mapped;
+static struct inet_connection_sock_af_ops ipv6_specific;
 
-static inline int tcp_v6_bind_conflict(const struct sock *sk,
-                                      const struct inet_bind_bucket *tb)
-{
-       const struct sock *sk2;
-       const struct hlist_node *node;
-
-       /* We must walk the whole port owner list in this case. -DaveM */
-       sk_for_each_bound(sk2, node, &tb->owners) {
-               if (sk != sk2 &&
-                   (!sk->sk_bound_dev_if ||
-                    !sk2->sk_bound_dev_if ||
-                    sk->sk_bound_dev_if == sk2->sk_bound_dev_if) &&
-                   (!sk->sk_reuse || !sk2->sk_reuse ||
-                    sk2->sk_state == TCP_LISTEN) &&
-                    ipv6_rcv_saddr_equal(sk, sk2))
-                       break;
-       }
-
-       return node != NULL;
-}
-
-/* Grrr, addr_type already calculated by caller, but I don't want
- * to add some silly "cookie" argument to this method just for that.
- * But it doesn't matter, the recalculation is in the rarest path
- * this function ever takes.
- */
 static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 {
-       struct inet_bind_hashbucket *head;
-       struct inet_bind_bucket *tb;
-       struct hlist_node *node;
-       int ret;
-
-       local_bh_disable();
-       if (snum == 0) {
-               int low = sysctl_local_port_range[0];
-               int high = sysctl_local_port_range[1];
-               int remaining = (high - low) + 1;
-               int rover = net_random() % (high - low) + low;
-
-               do {
-                       head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)];
-                       spin_lock(&head->lock);
-                       inet_bind_bucket_for_each(tb, node, &head->chain)
-                               if (tb->port == rover)
-                                       goto next;
-                       break;
-               next:
-                       spin_unlock(&head->lock);
-                       if (++rover > high)
-                               rover = low;
-               } while (--remaining > 0);
-
-               /* Exhausted local port range during search?  It is not
-                * possible for us to be holding one of the bind hash
-                * locks if this test triggers, because if 'remaining'
-                * drops to zero, we broke out of the do/while loop at
-                * the top level, not from the 'break;' statement.
-                */
-               ret = 1;
-               if (unlikely(remaining <= 0))
-                       goto fail;
-
-               /* OK, here is the one we will use. */
-               snum = rover;
-       } else {
-               head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
-               spin_lock(&head->lock);
-               inet_bind_bucket_for_each(tb, node, &head->chain)
-                       if (tb->port == snum)
-                               goto tb_found;
-       }
-       tb = NULL;
-       goto tb_not_found;
-tb_found:
-       if (tb && !hlist_empty(&tb->owners)) {
-               if (tb->fastreuse > 0 && sk->sk_reuse &&
-                   sk->sk_state != TCP_LISTEN) {
-                       goto success;
-               } else {
-                       ret = 1;
-                       if (tcp_v6_bind_conflict(sk, tb))
-                               goto fail_unlock;
-               }
-       }
-tb_not_found:
-       ret = 1;
-       if (tb == NULL) {
-               tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, snum);
-               if (tb == NULL)
-                       goto fail_unlock;
-       }
-       if (hlist_empty(&tb->owners)) {
-               if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
-                       tb->fastreuse = 1;
-               else
-                       tb->fastreuse = 0;
-       } else if (tb->fastreuse &&
-                  (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
-               tb->fastreuse = 0;
-
-success:
-       if (!inet_csk(sk)->icsk_bind_hash)
-               inet_bind_hash(sk, tb, snum);
-       BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb);
-       ret = 0;
-
-fail_unlock:
-       spin_unlock(&head->lock);
-fail:
-       local_bh_enable();
-       return ret;
-}
-
-static __inline__ void __tcp_v6_hash(struct sock *sk)
-{
-       struct hlist_head *list;
-       rwlock_t *lock;
-
-       BUG_TRAP(sk_unhashed(sk));
-
-       if (sk->sk_state == TCP_LISTEN) {
-               list = &tcp_hashinfo.listening_hash[inet_sk_listen_hashfn(sk)];
-               lock = &tcp_hashinfo.lhash_lock;
-               inet_listen_wlock(&tcp_hashinfo);
-       } else {
-               unsigned int hash;
-               sk->sk_hash = hash = inet6_sk_ehashfn(sk);
-               hash &= (tcp_hashinfo.ehash_size - 1);
-               list = &tcp_hashinfo.ehash[hash].chain;
-               lock = &tcp_hashinfo.ehash[hash].lock;
-               write_lock(lock);
-       }
-
-       __sk_add_node(sk, list);
-       sock_prot_inc_use(sk->sk_prot);
-       write_unlock(lock);
+       return inet_csk_get_port(&tcp_hashinfo, sk, snum,
+                                inet6_csk_bind_conflict);
 }
 
-
 static void tcp_v6_hash(struct sock *sk)
 {
        if (sk->sk_state != TCP_CLOSE) {
-               struct tcp_sock *tp = tcp_sk(sk);
-
-               if (tp->af_specific == &ipv6_mapped) {
+               if (inet_csk(sk)->icsk_af_ops == &ipv6_mapped) {
                        tcp_prot.hash(sk);
                        return;
                }
                local_bh_disable();
-               __tcp_v6_hash(sk);
+               __inet6_hash(&tcp_hashinfo, sk);
                local_bh_enable();
        }
 }
 
-/*
- * Open request hash tables.
- */
-
-static u32 tcp_v6_synq_hash(const struct in6_addr *raddr, const u16 rport, const u32 rnd)
-{
-       u32 a, b, c;
-
-       a = raddr->s6_addr32[0];
-       b = raddr->s6_addr32[1];
-       c = raddr->s6_addr32[2];
-
-       a += JHASH_GOLDEN_RATIO;
-       b += JHASH_GOLDEN_RATIO;
-       c += rnd;
-       __jhash_mix(a, b, c);
-
-       a += raddr->s6_addr32[3];
-       b += (u32) rport;
-       __jhash_mix(a, b, c);
-
-       return c & (TCP_SYNQ_HSIZE - 1);
-}
-
-static struct request_sock *tcp_v6_search_req(const struct sock *sk,
-                                             struct request_sock ***prevp,
-                                             __u16 rport,
-                                             struct in6_addr *raddr,
-                                             struct in6_addr *laddr,
-                                             int iif)
-{
-       const struct inet_connection_sock *icsk = inet_csk(sk);
-       struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
-       struct request_sock *req, **prev;  
-
-       for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
-            (req = *prev) != NULL;
-            prev = &req->dl_next) {
-               const struct tcp6_request_sock *treq = tcp6_rsk(req);
-
-               if (inet_rsk(req)->rmt_port == rport &&
-                   req->rsk_ops->family == AF_INET6 &&
-                   ipv6_addr_equal(&treq->rmt_addr, raddr) &&
-                   ipv6_addr_equal(&treq->loc_addr, laddr) &&
-                   (!treq->iif || treq->iif == iif)) {
-                       BUG_TRAP(req->sk == NULL);
-                       *prevp = prev;
-                       return req;
-               }
-       }
-
-       return NULL;
-}
-
 static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len,
                                   struct in6_addr *saddr, 
                                   struct in6_addr *daddr, 
@@ -308,195 +119,12 @@ static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
        }
 }
 
-static int __tcp_v6_check_established(struct sock *sk, const __u16 lport,
-                                     struct inet_timewait_sock **twp)
-{
-       struct inet_sock *inet = inet_sk(sk);
-       const struct ipv6_pinfo *np = inet6_sk(sk);
-       const struct in6_addr *daddr = &np->rcv_saddr;
-       const struct in6_addr *saddr = &np->daddr;
-       const int dif = sk->sk_bound_dev_if;
-       const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-       unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport);
-       struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
-       struct sock *sk2;
-       const struct hlist_node *node;
-       struct inet_timewait_sock *tw;
-
-       prefetch(head->chain.first);
-       write_lock(&head->lock);
-
-       /* Check TIME-WAIT sockets first. */
-       sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
-               const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk2);
-
-               tw = inet_twsk(sk2);
-
-               if(*((__u32 *)&(tw->tw_dport))  == ports        &&
-                  sk2->sk_family               == PF_INET6     &&
-                  ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr) &&
-                  ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr)     &&
-                  sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
-                       const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
-                       struct tcp_sock *tp = tcp_sk(sk);
-
-                       if (tcptw->tw_ts_recent_stamp &&
-                           (!twp ||
-                            (sysctl_tcp_tw_reuse &&
-                             xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) {
-                               /* See comment in tcp_ipv4.c */
-                               tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
-                               if (!tp->write_seq)
-                                       tp->write_seq = 1;
-                               tp->rx_opt.ts_recent       = tcptw->tw_ts_recent;
-                               tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
-                               sock_hold(sk2);
-                               goto unique;
-                       } else
-                               goto not_unique;
-               }
-       }
-       tw = NULL;
-
-       /* And established part... */
-       sk_for_each(sk2, node, &head->chain) {
-               if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
-                       goto not_unique;
-       }
-
-unique:
-       BUG_TRAP(sk_unhashed(sk));
-       __sk_add_node(sk, &head->chain);
-       sk->sk_hash = hash;
-       sock_prot_inc_use(sk->sk_prot);
-       write_unlock(&head->lock);
-
-       if (twp) {
-               *twp = tw;
-               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-       } else if (tw) {
-               /* Silly. Should hash-dance instead... */
-               inet_twsk_deschedule(tw, &tcp_death_row);
-               NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-               inet_twsk_put(tw);
-       }
-       return 0;
-
-not_unique:
-       write_unlock(&head->lock);
-       return -EADDRNOTAVAIL;
-}
-
-static inline u32 tcpv6_port_offset(const struct sock *sk)
-{
-       const struct inet_sock *inet = inet_sk(sk);
-       const struct ipv6_pinfo *np = inet6_sk(sk);
-
-       return secure_tcpv6_port_ephemeral(np->rcv_saddr.s6_addr32,
-                                          np->daddr.s6_addr32,
-                                          inet->dport);
-}
-
-static int tcp_v6_hash_connect(struct sock *sk)
-{
-       unsigned short snum = inet_sk(sk)->num;
-       struct inet_bind_hashbucket *head;
-       struct inet_bind_bucket *tb;
-       int ret;
-
-       if (!snum) {
-               int low = sysctl_local_port_range[0];
-               int high = sysctl_local_port_range[1];
-               int range = high - low;
-               int i;
-               int port;
-               static u32 hint;
-               u32 offset = hint + tcpv6_port_offset(sk);
-               struct hlist_node *node;
-               struct inet_timewait_sock *tw = NULL;
-
-               local_bh_disable();
-               for (i = 1; i <= range; i++) {
-                       port = low + (i + offset) % range;
-                       head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)];
-                       spin_lock(&head->lock);
-
-                       /* Does not bother with rcv_saddr checks,
-                        * because the established check is already
-                        * unique enough.
-                        */
-                       inet_bind_bucket_for_each(tb, node, &head->chain) {
-                               if (tb->port == port) {
-                                       BUG_TRAP(!hlist_empty(&tb->owners));
-                                       if (tb->fastreuse >= 0)
-                                               goto next_port;
-                                       if (!__tcp_v6_check_established(sk,
-                                                                       port,
-                                                                       &tw))
-                                               goto ok;
-                                       goto next_port;
-                               }
-                       }
-
-                       tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port);
-                       if (!tb) {
-                               spin_unlock(&head->lock);
-                               break;
-                       }
-                       tb->fastreuse = -1;
-                       goto ok;
-
-               next_port:
-                       spin_unlock(&head->lock);
-               }
-               local_bh_enable();
-
-               return -EADDRNOTAVAIL;
-
-ok:
-               hint += i;
-
-               /* Head lock still held and bh's disabled */
-               inet_bind_hash(sk, tb, port);
-               if (sk_unhashed(sk)) {
-                       inet_sk(sk)->sport = htons(port);
-                       __tcp_v6_hash(sk);
-               }
-               spin_unlock(&head->lock);
-
-               if (tw) {
-                       inet_twsk_deschedule(tw, &tcp_death_row);
-                       inet_twsk_put(tw);
-               }
-
-               ret = 0;
-               goto out;
-       }
-
-       head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
-       tb   = inet_csk(sk)->icsk_bind_hash;
-       spin_lock_bh(&head->lock);
-
-       if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-               __tcp_v6_hash(sk);
-               spin_unlock_bh(&head->lock);
-               return 0;
-       } else {
-               spin_unlock(&head->lock);
-               /* No definite answer... Walk to established hash table */
-               ret = __tcp_v6_check_established(sk, snum, NULL);
-out:
-               local_bh_enable();
-               return ret;
-       }
-}
-
 static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
                          int addr_len)
 {
        struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
-       struct inet_sock *inet = inet_sk(sk);
+       struct inet_sock *inet = inet_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        struct in6_addr *saddr = NULL, *final_p = NULL, final;
@@ -571,7 +199,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
         */
 
        if (addr_type == IPV6_ADDR_MAPPED) {
-               u32 exthdrlen = tp->ext_header_len;
+               u32 exthdrlen = icsk->icsk_ext_hdr_len;
                struct sockaddr_in sin;
 
                SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
@@ -583,14 +211,14 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
                sin.sin_port = usin->sin6_port;
                sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
 
-               tp->af_specific = &ipv6_mapped;
+               icsk->icsk_af_ops = &ipv6_mapped;
                sk->sk_backlog_rcv = tcp_v4_do_rcv;
 
                err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
 
                if (err) {
-                       tp->ext_header_len = exthdrlen;
-                       tp->af_specific = &ipv6_specific;
+                       icsk->icsk_ext_hdr_len = exthdrlen;
+                       icsk->icsk_af_ops = &ipv6_specific;
                        sk->sk_backlog_rcv = tcp_v6_do_rcv;
                        goto failure;
                } else {
@@ -643,16 +271,17 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        sk->sk_route_caps = dst->dev->features &
                ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
 
-       tp->ext_header_len = 0;
+       icsk->icsk_ext_hdr_len = 0;
        if (np->opt)
-               tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen;
+               icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
+                                         np->opt->opt_nflen);
 
        tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
        inet->dport = usin->sin6_port;
 
        tcp_set_state(sk, TCP_SYN_SENT);
-       err = tcp_v6_hash_connect(sk);
+       err = inet6_hash_connect(&tcp_death_row, sk);
        if (err)
                goto late_failure;
 
@@ -758,7 +387,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                } else
                        dst_hold(dst);
 
-               if (tp->pmtu_cookie > dst_mtu(dst)) {
+               if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
                        tcp_sync_mss(sk, dst_mtu(dst));
                        tcp_simple_retransmit(sk);
                } /* else let the usual retransmit timer handle it */
@@ -775,8 +404,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                if (sock_owned_by_user(sk))
                        goto out;
 
-               req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr,
-                                       &hdr->saddr, inet6_iif(skb));
+               req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr,
+                                          &hdr->saddr, inet6_iif(skb));
                if (!req)
                        goto out;
 
@@ -822,7 +451,7 @@ out:
 static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
                              struct dst_entry *dst)
 {
-       struct tcp6_request_sock *treq = tcp6_rsk(req);
+       struct inet6_request_sock *treq = inet6_rsk(req);
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct sk_buff * skb;
        struct ipv6_txoptions *opt = NULL;
@@ -888,8 +517,8 @@ done:
 
 static void tcp_v6_reqsk_destructor(struct request_sock *req)
 {
-       if (tcp6_rsk(req)->pktopts)
-               kfree_skb(tcp6_rsk(req)->pktopts);
+       if (inet6_rsk(req)->pktopts)
+               kfree_skb(inet6_rsk(req)->pktopts);
 }
 
 static struct request_sock_ops tcp6_request_sock_ops = {
@@ -901,26 +530,15 @@ static struct request_sock_ops tcp6_request_sock_ops = {
        .send_reset     =       tcp_v6_send_reset
 };
 
-static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
-{
-       struct ipv6_pinfo *np = inet6_sk(sk);
-       struct inet6_skb_parm *opt = IP6CB(skb);
-
-       if (np->rxopt.all) {
-               if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
-                   ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
-                   (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
-                   ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
-                       return 1;
-       }
-       return 0;
-}
-
+static struct timewait_sock_ops tcp6_timewait_sock_ops = {
+       .twsk_obj_size  = sizeof(struct tcp6_timewait_sock),
+       .twsk_unique    = tcp_twsk_unique,
+};
 
-static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
-                             struct sk_buff *skb)
+static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
+       struct tcphdr *th = skb->h.th;
 
        if (skb->ip_summed == CHECKSUM_HW) {
                th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,  0);
@@ -1091,8 +709,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
        struct sock *nsk;
 
        /* Find possible connection requests. */
-       req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr,
-                               &skb->nh.ipv6h->daddr, inet6_iif(skb));
+       req = inet6_csk_search_req(sk, &prev, th->source,
+                                  &skb->nh.ipv6h->saddr,
+                                  &skb->nh.ipv6h->daddr, inet6_iif(skb));
        if (req)
                return tcp_check_req(sk, skb, req, prev);
 
@@ -1116,23 +735,12 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
        return sk;
 }
 
-static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
-{
-       struct inet_connection_sock *icsk = inet_csk(sk);
-       struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
-       const u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
-
-       reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, TCP_TIMEOUT_INIT);
-       inet_csk_reqsk_queue_added(sk, TCP_TIMEOUT_INIT);
-}
-
-
 /* FIXME: this is substantially similar to the ipv4 code.
  * Can some kind of merge be done? -- erics
  */
 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
-       struct tcp6_request_sock *treq;
+       struct inet6_request_sock *treq;
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct tcp_options_received tmp_opt;
        struct tcp_sock *tp = tcp_sk(sk);
@@ -1157,7 +765,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
                goto drop;
 
-       req = reqsk_alloc(&tcp6_request_sock_ops);
+       req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
        if (req == NULL)
                goto drop;
 
@@ -1170,7 +778,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
        tcp_openreq_init(req, &tmp_opt, skb);
 
-       treq = tcp6_rsk(req);
+       treq = inet6_rsk(req);
        ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr);
        ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr);
        TCP_ECN_create_request(req, skb->h.th);
@@ -1196,8 +804,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (tcp_v6_send_synack(sk, req, NULL))
                goto drop;
 
-       tcp_v6_synq_add(sk, req);
-
+       inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
        return 0;
 
 drop:
@@ -1212,7 +819,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
                                          struct request_sock *req,
                                          struct dst_entry *dst)
 {
-       struct tcp6_request_sock *treq = tcp6_rsk(req);
+       struct inet6_request_sock *treq = inet6_rsk(req);
        struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
        struct tcp6_sock *newtcp6sk;
        struct inet_sock *newinet;
@@ -1247,7 +854,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
                ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
 
-               newtp->af_specific = &ipv6_mapped;
+               inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
                newsk->sk_backlog_rcv = tcp_v4_do_rcv;
                newnp->pktoptions  = NULL;
                newnp->opt         = NULL;
@@ -1261,10 +868,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
                 */
 
                /* It is tricky place. Until this moment IPv4 tcp
-                  worked with IPv6 af_tcp.af_specific.
+                  worked with IPv6 icsk.icsk_af_ops.
                   Sync it now.
                 */
-               tcp_sync_mss(newsk, newtp->pmtu_cookie);
+               tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
 
                return newsk;
        }
@@ -1371,10 +978,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
                        sock_kfree_s(sk, opt, opt->tot_len);
        }
 
-       newtp->ext_header_len = 0;
+       inet_csk(newsk)->icsk_ext_hdr_len = 0;
        if (newnp->opt)
-               newtp->ext_header_len = newnp->opt->opt_nflen +
-                                       newnp->opt->opt_flen;
+               inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
+                                                    newnp->opt->opt_flen);
 
        tcp_sync_mss(newsk, dst_mtu(dst));
        newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
@@ -1382,7 +989,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
        newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
 
-       __tcp_v6_hash(newsk);
+       __inet6_hash(&tcp_hashinfo, newsk);
        inet_inherit_port(&tcp_hashinfo, sk, newsk);
 
        return newsk;
@@ -1679,139 +1286,16 @@ do_time_wait:
        goto discard_it;
 }
 
-static int tcp_v6_rebuild_header(struct sock *sk)
-{
-       int err;
-       struct dst_entry *dst;
-       struct ipv6_pinfo *np = inet6_sk(sk);
-
-       dst = __sk_dst_check(sk, np->dst_cookie);
-
-       if (dst == NULL) {
-               struct inet_sock *inet = inet_sk(sk);
-               struct in6_addr *final_p = NULL, final;
-               struct flowi fl;
-
-               memset(&fl, 0, sizeof(fl));
-               fl.proto = IPPROTO_TCP;
-               ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-               ipv6_addr_copy(&fl.fl6_src, &np->saddr);
-               fl.fl6_flowlabel = np->flow_label;
-               fl.oif = sk->sk_bound_dev_if;
-               fl.fl_ip_dport = inet->dport;
-               fl.fl_ip_sport = inet->sport;
-
-               if (np->opt && np->opt->srcrt) {
-                       struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-                       ipv6_addr_copy(&final, &fl.fl6_dst);
-                       ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
-                       final_p = &final;
-               }
-
-               err = ip6_dst_lookup(sk, &dst, &fl);
-               if (err) {
-                       sk->sk_route_caps = 0;
-                       return err;
-               }
-               if (final_p)
-                       ipv6_addr_copy(&fl.fl6_dst, final_p);
-
-               if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-                       sk->sk_err_soft = -err;
-                       return err;
-               }
-
-               ip6_dst_store(sk, dst, NULL);
-               sk->sk_route_caps = dst->dev->features &
-                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
-       }
-
-       return 0;
-}
-
-static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
-{
-       struct sock *sk = skb->sk;
-       struct inet_sock *inet = inet_sk(sk);
-       struct ipv6_pinfo *np = inet6_sk(sk);
-       struct flowi fl;
-       struct dst_entry *dst;
-       struct in6_addr *final_p = NULL, final;
-
-       memset(&fl, 0, sizeof(fl));
-       fl.proto = IPPROTO_TCP;
-       ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-       ipv6_addr_copy(&fl.fl6_src, &np->saddr);
-       fl.fl6_flowlabel = np->flow_label;
-       IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
-       fl.oif = sk->sk_bound_dev_if;
-       fl.fl_ip_sport = inet->sport;
-       fl.fl_ip_dport = inet->dport;
-
-       if (np->opt && np->opt->srcrt) {
-               struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-               ipv6_addr_copy(&final, &fl.fl6_dst);
-               ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
-               final_p = &final;
-       }
-
-       dst = __sk_dst_check(sk, np->dst_cookie);
-
-       if (dst == NULL) {
-               int err = ip6_dst_lookup(sk, &dst, &fl);
-
-               if (err) {
-                       sk->sk_err_soft = -err;
-                       return err;
-               }
-
-               if (final_p)
-                       ipv6_addr_copy(&fl.fl6_dst, final_p);
-
-               if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-                       sk->sk_route_caps = 0;
-                       return err;
-               }
-
-               ip6_dst_store(sk, dst, NULL);
-               sk->sk_route_caps = dst->dev->features &
-                       ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
-       }
-
-       skb->dst = dst_clone(dst);
-
-       /* Restore final destination back after routing done */
-       ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-
-       return ip6_xmit(sk, skb, &fl, np->opt, 0);
-}
-
-static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
-{
-       struct ipv6_pinfo *np = inet6_sk(sk);
-       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
-
-       sin6->sin6_family = AF_INET6;
-       ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
-       sin6->sin6_port = inet_sk(sk)->dport;
-       /* We do not store received flowlabel for TCP */
-       sin6->sin6_flowinfo = 0;
-       sin6->sin6_scope_id = 0;
-       if (sk->sk_bound_dev_if &&
-           ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
-               sin6->sin6_scope_id = sk->sk_bound_dev_if;
-}
-
 static int tcp_v6_remember_stamp(struct sock *sk)
 {
        /* Alas, not yet... */
        return 0;
 }
 
-static struct tcp_func ipv6_specific = {
-       .queue_xmit     =       tcp_v6_xmit,
+static struct inet_connection_sock_af_ops ipv6_specific = {
+       .queue_xmit     =       inet6_csk_xmit,
        .send_check     =       tcp_v6_send_check,
-       .rebuild_header =       tcp_v6_rebuild_header,
+       .rebuild_header =       inet6_sk_rebuild_header,
        .conn_request   =       tcp_v6_conn_request,
        .syn_recv_sock  =       tcp_v6_syn_recv_sock,
        .remember_stamp =       tcp_v6_remember_stamp,
@@ -1819,7 +1303,7 @@ static struct tcp_func ipv6_specific = {
 
        .setsockopt     =       ipv6_setsockopt,
        .getsockopt     =       ipv6_getsockopt,
-       .addr2sockaddr  =       v6_addr2sockaddr,
+       .addr2sockaddr  =       inet6_csk_addr2sockaddr,
        .sockaddr_len   =       sizeof(struct sockaddr_in6)
 };
 
@@ -1827,7 +1311,7 @@ static struct tcp_func ipv6_specific = {
  *     TCP over IPv4 via INET6 API
  */
 
-static struct tcp_func ipv6_mapped = {
+static struct inet_connection_sock_af_ops ipv6_mapped = {
        .queue_xmit     =       ip_queue_xmit,
        .send_check     =       tcp_v4_send_check,
        .rebuild_header =       inet_sk_rebuild_header,
@@ -1838,7 +1322,7 @@ static struct tcp_func ipv6_mapped = {
 
        .setsockopt     =       ipv6_setsockopt,
        .getsockopt     =       ipv6_getsockopt,
-       .addr2sockaddr  =       v6_addr2sockaddr,
+       .addr2sockaddr  =       inet6_csk_addr2sockaddr,
        .sockaddr_len   =       sizeof(struct sockaddr_in6)
 };
 
@@ -1877,8 +1361,9 @@ static int tcp_v6_init_sock(struct sock *sk)
 
        sk->sk_state = TCP_CLOSE;
 
-       tp->af_specific = &ipv6_specific;
+       icsk->icsk_af_ops = &ipv6_specific;
        icsk->icsk_ca_ops = &tcp_init_congestion_ops;
+       icsk->icsk_sync_mss = tcp_sync_mss;
        sk->sk_write_space = sk_stream_write_space;
        sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
@@ -1900,14 +1385,13 @@ static int tcp_v6_destroy_sock(struct sock *sk)
 static void get_openreq6(struct seq_file *seq, 
                         struct sock *sk, struct request_sock *req, int i, int uid)
 {
-       struct in6_addr *dest, *src;
        int ttd = req->expires - jiffies;
+       struct in6_addr *src = &inet6_rsk(req)->loc_addr;
+       struct in6_addr *dest = &inet6_rsk(req)->rmt_addr;
 
        if (ttd < 0)
                ttd = 0;
 
-       src = &tcp6_rsk(req)->loc_addr;
-       dest = &tcp6_rsk(req)->rmt_addr;
        seq_printf(seq,
                   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
                   "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n",
@@ -1988,14 +1472,14 @@ static void get_timewait6_sock(struct seq_file *seq,
 {
        struct in6_addr *dest, *src;
        __u16 destp, srcp;
-       struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw);
+       struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
        int ttd = tw->tw_ttd - jiffies;
 
        if (ttd < 0)
                ttd = 0;
 
-       dest = &tcp6tw->tw_v6_daddr;
-       src  = &tcp6tw->tw_v6_rcv_saddr;
+       dest = &tw6->tw_v6_daddr;
+       src  = &tw6->tw_v6_rcv_saddr;
        destp = ntohs(tw->tw_dport);
        srcp  = ntohs(tw->tw_sport);
 
@@ -2093,7 +1577,7 @@ struct proto tcpv6_prot = {
        .sysctl_rmem            = sysctl_tcp_rmem,
        .max_header             = MAX_TCP_HEADER,
        .obj_size               = sizeof(struct tcp6_sock),
-       .twsk_obj_size          = sizeof(struct tcp6_timewait_sock),
+       .twsk_prot              = &tcp6_timewait_sock_ops,
        .rsk_prot               = &tcp6_request_sock_ops,
 };
 
@@ -2110,7 +1594,8 @@ static struct inet_protosw tcpv6_protosw = {
        .ops            =       &inet6_stream_ops,
        .capability     =       -1,
        .no_check       =       0,
-       .flags          =       INET_PROTOSW_PERMANENT,
+       .flags          =       INET_PROTOSW_PERMANENT |
+                               INET_PROTOSW_ICSK,
 };
 
 void __init tcpv6_init(void)
index 5cc8731..d8538dc 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/init.h>
+#include <linux/skbuff.h>
 #include <asm/uaccess.h>
 
 #include <net/sock.h>
@@ -300,20 +301,7 @@ out:
        return err;
 
 csum_copy_err:
-       /* Clear queue. */
-       if (flags&MSG_PEEK) {
-               int clear = 0;
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               if (skb == skb_peek(&sk->sk_receive_queue)) {
-                       __skb_unlink(skb, &sk->sk_receive_queue);
-                       clear = 1;
-               }
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
-               if (clear)
-                       kfree_skb(skb);
-       }
-
-       skb_free_datagram(sk, skb);
+       skb_kill_datagram(sk, skb, flags);
 
        if (flags & MSG_DONTWAIT) {
                UDP6_INC_STATS_USER(UDP_MIB_INERRORS);
index 34b3bb8..0dc519b 100644 (file)
@@ -75,7 +75,7 @@ static struct datalink_proto *pEII_datalink;
 static struct datalink_proto *p8023_datalink;
 static struct datalink_proto *pSNAP_datalink;
 
-static struct proto_ops ipx_dgram_ops;
+static const struct proto_ops ipx_dgram_ops;
 
 LIST_HEAD(ipx_interfaces);
 DEFINE_SPINLOCK(ipx_interfaces_lock);
@@ -1884,7 +1884,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                rc = -EINVAL;
                break;
        default:
-               rc = dev_ioctl(cmd, argp);
+               rc = -ENOIOCTLCMD;
                break;
        }
 
@@ -1901,7 +1901,7 @@ static struct net_proto_family ipx_family_ops = {
        .owner          = THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
        .family         = PF_IPX,
        .owner          = THIS_MODULE,
        .release        = ipx_release,
index 6f92f9c..fbfa967 100644 (file)
 
 static int irda_create(struct socket *sock, int protocol);
 
-static struct proto_ops irda_stream_ops;
-static struct proto_ops irda_seqpacket_ops;
-static struct proto_ops irda_dgram_ops;
+static const struct proto_ops irda_stream_ops;
+static const struct proto_ops irda_seqpacket_ops;
+static const struct proto_ops irda_dgram_ops;
 
 #ifdef CONFIG_IRDA_ULTRA
-static struct proto_ops irda_ultra_ops;
+static const struct proto_ops irda_ultra_ops;
 #define ULTRA_MAX_DATA 382
 #endif /* CONFIG_IRDA_ULTRA */
 
@@ -1438,8 +1438,9 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
                        /*
                         *      POSIX 1003.1g mandates this order.
                         */
-                       if (sk->sk_err)
-                               ret = sock_error(sk);
+                       ret = sock_error(sk);
+                       if (ret)
+                               break;
                        else if (sk->sk_shutdown & RCV_SHUTDOWN)
                                ;
                        else if (noblock)
@@ -1821,7 +1822,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                return -EINVAL;
        default:
                IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__);
-               return dev_ioctl(cmd, (void __user *) arg);
+               return -ENOIOCTLCMD;
        }
 
        /*NOTREACHED*/
@@ -2463,7 +2464,7 @@ static struct net_proto_family irda_family_ops = {
        .owner  = THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
@@ -2484,7 +2485,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
        .sendpage =     sock_no_sendpage,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
@@ -2505,7 +2506,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
        .sendpage =     sock_no_sendpage,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
@@ -2527,7 +2528,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
 };
 
 #ifdef CONFIG_IRDA_ULTRA
-static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
        .family =       PF_IRDA,
        .owner =        THIS_MODULE,
        .release =      irda_release,
index 3903168..52efd04 100644 (file)
@@ -113,7 +113,7 @@ static __inline__ void pfkey_unlock_table(void)
 }
 
 
-static struct proto_ops pfkey_ops;
+static const struct proto_ops pfkey_ops;
 
 static void pfkey_insert(struct sock *sk)
 {
@@ -336,6 +336,7 @@ static u8 sadb_ext_min_len[] = {
        [SADB_X_EXT_NAT_T_SPORT]        = (u8) sizeof(struct sadb_x_nat_t_port),
        [SADB_X_EXT_NAT_T_DPORT]        = (u8) sizeof(struct sadb_x_nat_t_port),
        [SADB_X_EXT_NAT_T_OA]           = (u8) sizeof(struct sadb_address),
+       [SADB_X_EXT_SEC_CTX]            = (u8) sizeof(struct sadb_x_sec_ctx),
 };
 
 /* Verify sadb_address_{len,prefixlen} against sa_family.  */
@@ -383,6 +384,55 @@ static int verify_address_len(void *p)
        return 0;
 }
 
+static inline int pfkey_sec_ctx_len(struct sadb_x_sec_ctx *sec_ctx)
+{
+       int len = 0;
+
+       len += sizeof(struct sadb_x_sec_ctx);
+       len += sec_ctx->sadb_x_ctx_len;
+       len += sizeof(uint64_t) - 1;
+       len /= sizeof(uint64_t);
+
+       return len;
+}
+
+static inline int verify_sec_ctx_len(void *p)
+{
+       struct sadb_x_sec_ctx *sec_ctx = (struct sadb_x_sec_ctx *)p;
+       int len;
+
+       if (sec_ctx->sadb_x_ctx_len > PAGE_SIZE)
+               return -EINVAL;
+
+       len = pfkey_sec_ctx_len(sec_ctx);
+
+       if (sec_ctx->sadb_x_sec_len != len)
+               return -EINVAL;
+
+       return 0;
+}
+
+static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(struct sadb_x_sec_ctx *sec_ctx)
+{
+       struct xfrm_user_sec_ctx *uctx = NULL;
+       int ctx_size = sec_ctx->sadb_x_ctx_len;
+
+       uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL);
+
+       if (!uctx)
+               return NULL;
+
+       uctx->len = pfkey_sec_ctx_len(sec_ctx);
+       uctx->exttype = sec_ctx->sadb_x_sec_exttype;
+       uctx->ctx_doi = sec_ctx->sadb_x_ctx_doi;
+       uctx->ctx_alg = sec_ctx->sadb_x_ctx_alg;
+       uctx->ctx_len = sec_ctx->sadb_x_ctx_len;
+       memcpy(uctx + 1, sec_ctx + 1,
+              uctx->ctx_len);
+
+       return uctx;
+}
+
 static int present_and_same_family(struct sadb_address *src,
                                   struct sadb_address *dst)
 {
@@ -438,6 +488,10 @@ static int parse_exthdrs(struct sk_buff *skb, struct sadb_msg *hdr, void **ext_h
                                if (verify_address_len(p))
                                        return -EINVAL;
                        }                               
+                       if (ext_type == SADB_X_EXT_SEC_CTX) {
+                               if (verify_sec_ctx_len(p))
+                                       return -EINVAL;
+                       }
                        ext_hdrs[ext_type-1] = p;
                }
                p   += ext_len;
@@ -586,6 +640,9 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
        struct sadb_key *key;
        struct sadb_x_sa2 *sa2;
        struct sockaddr_in *sin;
+       struct sadb_x_sec_ctx *sec_ctx;
+       struct xfrm_sec_ctx *xfrm_ctx;
+       int ctx_size = 0;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        struct sockaddr_in6 *sin6;
 #endif
@@ -609,6 +666,12 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
                        sizeof(struct sadb_address)*2 + 
                                sockaddr_size*2 +
                                        sizeof(struct sadb_x_sa2);
+
+       if ((xfrm_ctx = x->security)) {
+               ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
+               size += sizeof(struct sadb_x_sec_ctx) + ctx_size;
+       }
+
        /* identity & sensitivity */
 
        if ((x->props.family == AF_INET &&
@@ -899,6 +962,20 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
                n_port->sadb_x_nat_t_port_reserved = 0;
        }
 
+       /* security context */
+       if (xfrm_ctx) {
+               sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb,
+                               sizeof(struct sadb_x_sec_ctx) + ctx_size);
+               sec_ctx->sadb_x_sec_len =
+                 (sizeof(struct sadb_x_sec_ctx) + ctx_size) / sizeof(uint64_t);
+               sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+               sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
+               sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
+               sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
+               memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
+                      xfrm_ctx->ctx_len);
+       }
+
        return skb;
 }
 
@@ -909,6 +986,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
        struct sadb_lifetime *lifetime;
        struct sadb_sa *sa;
        struct sadb_key *key;
+       struct sadb_x_sec_ctx *sec_ctx;
        uint16_t proto;
        int err;
        
@@ -993,6 +1071,21 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
                x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime;
                x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;
        }
+
+       sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+       if (sec_ctx != NULL) {
+               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+               if (!uctx)
+                       goto out;
+
+               err = security_xfrm_state_alloc(x, uctx);
+               kfree(uctx);
+
+               if (err)
+                       goto out;
+       }
+
        key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];
        if (sa->sadb_sa_auth) {
                int keysize = 0;
@@ -1720,6 +1813,18 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol)
        return 0;
 }
 
+static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
+{
+  struct xfrm_sec_ctx *xfrm_ctx = xp->security;
+
+       if (xfrm_ctx) {
+               int len = sizeof(struct sadb_x_sec_ctx);
+               len += xfrm_ctx->ctx_len;
+               return PFKEY_ALIGN8(len);
+       }
+       return 0;
+}
+
 static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
 {
        int sockaddr_size = pfkey_sockaddr_size(xp->family);
@@ -1733,7 +1838,8 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
                (sockaddr_size * 2) +
                sizeof(struct sadb_x_policy) +
                (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
-                               (socklen * 2)));
+                               (socklen * 2))) +
+               pfkey_xfrm_policy2sec_ctx_size(xp);
 }
 
 static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
@@ -1757,6 +1863,8 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
        struct sadb_lifetime *lifetime;
        struct sadb_x_policy *pol;
        struct sockaddr_in   *sin;
+       struct sadb_x_sec_ctx *sec_ctx;
+       struct xfrm_sec_ctx *xfrm_ctx;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        struct sockaddr_in6  *sin6;
 #endif
@@ -1941,6 +2049,21 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
                        }
                }
        }
+
+       /* security context */
+       if ((xfrm_ctx = xp->security)) {
+               int ctx_size = pfkey_xfrm_policy2sec_ctx_size(xp);
+
+               sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb, ctx_size);
+               sec_ctx->sadb_x_sec_len = ctx_size / sizeof(uint64_t);
+               sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+               sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
+               sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
+               sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
+               memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
+                      xfrm_ctx->ctx_len);
+       }
+
        hdr->sadb_msg_len = size / sizeof(uint64_t);
        hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
 }
@@ -1976,12 +2099,13 @@ out:
 
 static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
-       int err;
+       int err = 0;
        struct sadb_lifetime *lifetime;
        struct sadb_address *sa;
        struct sadb_x_policy *pol;
        struct xfrm_policy *xp;
        struct km_event c;
+       struct sadb_x_sec_ctx *sec_ctx;
 
        if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
                                     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2028,6 +2152,22 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        if (xp->selector.dport)
                xp->selector.dport_mask = ~0;
 
+       sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+       if (sec_ctx != NULL) {
+               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+               if (!uctx) {
+                       err = -ENOBUFS;
+                       goto out;
+               }
+
+               err = security_xfrm_policy_alloc(xp, uctx);
+               kfree(uctx);
+
+               if (err)
+                       goto out;
+       }
+
        xp->lft.soft_byte_limit = XFRM_INF;
        xp->lft.hard_byte_limit = XFRM_INF;
        xp->lft.soft_packet_limit = XFRM_INF;
@@ -2051,10 +2191,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
 
        err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
                                 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
-       if (err) {
-               kfree(xp);
-               return err;
-       }
+
+       if (err)
+               goto out;
 
        if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
                c.event = XFRM_MSG_UPDPOLICY;
@@ -2069,6 +2208,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        return 0;
 
 out:
+       security_xfrm_policy_free(xp);
        kfree(xp);
        return err;
 }
@@ -2078,9 +2218,10 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
        int err;
        struct sadb_address *sa;
        struct sadb_x_policy *pol;
-       struct xfrm_policy *xp;
+       struct xfrm_policy *xp, tmp;
        struct xfrm_selector sel;
        struct km_event c;
+       struct sadb_x_sec_ctx *sec_ctx;
 
        if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
                                     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2109,7 +2250,24 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
        if (sel.dport)
                sel.dport_mask = ~0;
 
-       xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1);
+       sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+       memset(&tmp, 0, sizeof(struct xfrm_policy));
+
+       if (sec_ctx != NULL) {
+               struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+               if (!uctx)
+                       return -ENOMEM;
+
+               err = security_xfrm_policy_alloc(&tmp, uctx);
+               kfree(uctx);
+
+               if (err)
+                       return err;
+       }
+
+       xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1);
+       security_xfrm_policy_free(&tmp);
        if (xp == NULL)
                return -ENOENT;
 
@@ -2660,6 +2818,7 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
 {
        struct xfrm_policy *xp;
        struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
+       struct sadb_x_sec_ctx *sec_ctx;
 
        switch (family) {
        case AF_INET:
@@ -2709,10 +2868,32 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
            (*dir = parse_ipsecrequests(xp, pol)) < 0)
                goto out;
 
+       /* security context too */
+       if (len >= (pol->sadb_x_policy_len*8 +
+           sizeof(struct sadb_x_sec_ctx))) {
+               char *p = (char *)pol;
+               struct xfrm_user_sec_ctx *uctx;
+
+               p += pol->sadb_x_policy_len*8;
+               sec_ctx = (struct sadb_x_sec_ctx *)p;
+               if (len < pol->sadb_x_policy_len*8 +
+                   sec_ctx->sadb_x_sec_len)
+                       goto out;
+               if ((*dir = verify_sec_ctx_len(p)))
+                       goto out;
+               uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+               *dir = security_xfrm_policy_alloc(xp, uctx);
+               kfree(uctx);
+
+               if (*dir)
+                       goto out;
+       }
+
        *dir = pol->sadb_x_policy_dir-1;
        return xp;
 
 out:
+       security_xfrm_policy_free(xp);
        kfree(xp);
        return NULL;
 }
@@ -2946,7 +3127,7 @@ out:
        return err;
 }
 
-static struct proto_ops pfkey_ops = {
+static const struct proto_ops pfkey_ops = {
        .family         =       PF_KEY,
        .owner          =       THIS_MODULE,
        /* Operations that make no sense on pfkey sockets. */
index c3f0b07..8171c53 100644 (file)
@@ -36,7 +36,7 @@
 static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 static u16 llc_ui_sap_link_no_max[256];
 static struct sockaddr_llc llc_ui_addrnull;
-static struct proto_ops llc_ui_ops;
+static const struct proto_ops llc_ui_ops;
 
 static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
 static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
@@ -566,10 +566,9 @@ static int llc_wait_data(struct sock *sk, long timeo)
                /*
                 * POSIX 1003.1g mandates this order.
                 */
-               if (sk->sk_err) {
-                       rc = sock_error(sk);
+               rc = sock_error(sk);
+               if (rc)
                        break;
-               }
                rc = 0;
                if (sk->sk_shutdown & RCV_SHUTDOWN)
                        break;
@@ -960,7 +959,7 @@ out:
 static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
                        unsigned long arg)
 {
-       return dev_ioctl(cmd, (void __user *)arg);
+       return -ENOIOCTLCMD;
 }
 
 /**
@@ -1099,7 +1098,7 @@ static struct net_proto_family llc_ui_family_ops = {
        .owner  = THIS_MODULE,
 };
 
-static struct proto_ops llc_ui_ops = {
+static const struct proto_ops llc_ui_ops = {
        .family      = PF_LLC,
        .owner       = THIS_MODULE,
        .release     = llc_ui_release,
index cba6372..e10512e 100644 (file)
@@ -151,7 +151,7 @@ instance_create(u_int16_t group_num, int pid)
                goto out_unlock;
 
        INIT_HLIST_NODE(&inst->hlist);
-       inst->lock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&inst->lock);
        /* needs to be two, since we _put() after creation */
        atomic_set(&inst->use, 2);
 
index f28460b..55afdda 100644 (file)
@@ -148,7 +148,7 @@ instance_create(u_int16_t queue_num, int pid)
        atomic_set(&inst->id_sequence, 0);
        /* needs to be two, since we _put() after creation */
        atomic_set(&inst->use, 2);
-       inst->lock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&inst->lock);
        INIT_LIST_HEAD(&inst->queue_list);
 
        if (!try_module_get(THIS_MODULE))
index 96020d7..7849cac 100644 (file)
@@ -293,7 +293,7 @@ static inline int nl_pid_hash_dilute(struct nl_pid_hash *hash, int len)
        return 0;
 }
 
-static struct proto_ops netlink_ops;
+static const struct proto_ops netlink_ops;
 
 static int netlink_insert(struct sock *sk, u32 pid)
 {
@@ -1656,7 +1656,7 @@ int netlink_unregister_notifier(struct notifier_block *nb)
        return notifier_chain_unregister(&netlink_chain, nb);
 }
                 
-static struct proto_ops netlink_ops = {
+static const struct proto_ops netlink_ops = {
        .family =       PF_NETLINK,
        .owner =        THIS_MODULE,
        .release =      netlink_release,
index 287cfcc..3b13784 100644 (file)
@@ -441,7 +441,7 @@ errout:
 }
 
 static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
-                                     int seq, int cmd)
+                                     int seq, u8 cmd)
 {
        struct sk_buff *skb;
        int err;
index e5d82d7..63b0e4a 100644 (file)
@@ -63,7 +63,7 @@ static unsigned short circuit = 0x101;
 static HLIST_HEAD(nr_list);
 static DEFINE_SPINLOCK(nr_list_lock);
 
-static struct proto_ops nr_proto_ops;
+static const struct proto_ops nr_proto_ops;
 
 /*
  *     Socket removal during an interrupt is now safe.
@@ -1166,10 +1166,11 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        void __user *argp = (void __user *)arg;
        int ret;
 
-       lock_sock(sk);
        switch (cmd) {
        case TIOCOUTQ: {
                long amount;
+
+               lock_sock(sk);
                amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
                if (amount < 0)
                        amount = 0;
@@ -1180,6 +1181,8 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case TIOCINQ: {
                struct sk_buff *skb;
                long amount = 0L;
+
+               lock_sock(sk);
                /* These two are safe on a single CPU system as only user tasks fiddle here */
                if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
                        amount = skb->len;
@@ -1188,6 +1191,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        }
 
        case SIOCGSTAMP:
+               lock_sock(sk);
                ret = sock_get_timestamp(sk, argp);
                release_sock(sk);
                return ret;
@@ -1202,21 +1206,17 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case SIOCSIFNETMASK:
        case SIOCGIFMETRIC:
        case SIOCSIFMETRIC:
-               release_sock(sk);
                return -EINVAL;
 
        case SIOCADDRT:
        case SIOCDELRT:
        case SIOCNRDECOBS:
-               release_sock(sk);
                if (!capable(CAP_NET_ADMIN)) return -EPERM;
                return nr_rt_ioctl(cmd, argp);
 
        default:
-               release_sock(sk);
-               return dev_ioctl(cmd, argp);
+               return -ENOIOCTLCMD;
        }
-       release_sock(sk);
 
        return 0;
 }
@@ -1337,7 +1337,7 @@ static struct net_proto_family nr_family_ops = {
        .owner          =       THIS_MODULE,
 };
 
-static struct proto_ops nr_proto_ops = {
+static const struct proto_ops nr_proto_ops = {
        .family         =       PF_NETROM,
        .owner          =       THIS_MODULE,
        .release        =       nr_release,
index e5241dc..1230f0a 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 
-void __init sock_init(void)
-{
-       printk(KERN_INFO "Linux NoNET1.0 for Linux 2.6\n");
-}
-
 static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
 {
        return -ENXIO;
index 3e24627..f69e5ed 100644 (file)
@@ -251,10 +251,10 @@ static void packet_sock_destruct(struct sock *sk)
 }
 
 
-static struct proto_ops packet_ops;
+static const struct proto_ops packet_ops;
 
 #ifdef CONFIG_SOCK_PACKET
-static struct proto_ops packet_ops_spkt;
+static const struct proto_ops packet_ops_spkt;
 
 static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt, struct net_device *orig_dev)
 {
@@ -1521,7 +1521,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
 #endif
 
                default:
-                       return dev_ioctl(cmd, (void __user *)arg);
+                       return -ENOIOCTLCMD;
        }
        return 0;
 }
@@ -1784,7 +1784,7 @@ out:
 
 
 #ifdef CONFIG_SOCK_PACKET
-static struct proto_ops packet_ops_spkt = {
+static const struct proto_ops packet_ops_spkt = {
        .family =       PF_PACKET,
        .owner =        THIS_MODULE,
        .release =      packet_release,
@@ -1806,7 +1806,7 @@ static struct proto_ops packet_ops_spkt = {
 };
 #endif
 
-static struct proto_ops packet_ops = {
+static const struct proto_ops packet_ops = {
        .family =       PF_PACKET,
        .owner =        THIS_MODULE,
        .release =      packet_release,
index 829fdbc..63090be 100644 (file)
@@ -1320,7 +1320,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                return 0;
 
        default:
-               return dev_ioctl(cmd, argp);
+               return -ENOIOCTLCMD;
        }
 
        return 0;
index 82fb07a..ba52832 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <net/pkt_sched.h>
 
-#define VERSION "1.1"
+#define VERSION "1.2"
 
 /*     Network Emulation Queuing algorithm.
        ====================================
@@ -65,11 +65,12 @@ struct netem_sched_data {
        u32 jitter;
        u32 duplicate;
        u32 reorder;
+       u32 corrupt;
 
        struct crndstate {
                unsigned long last;
                unsigned long rho;
-       } delay_cor, loss_cor, dup_cor, reorder_cor;
+       } delay_cor, loss_cor, dup_cor, reorder_cor, corrupt_cor;
 
        struct disttable {
                u32  size;
@@ -183,6 +184,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                q->duplicate = dupsave;
        }
 
+       /*
+        * Randomized packet corruption.
+        * Make copy if needed since we are modifying
+        * If packet is going to be hardware checksummed, then
+        * do it now in software before we mangle it.
+        */
+       if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
+               if (!(skb = skb_unshare(skb, GFP_ATOMIC))
+                   || (skb->ip_summed == CHECKSUM_HW
+                       && skb_checksum_help(skb, 0))) {
+                       sch->qstats.drops++;
+                       return NET_XMIT_DROP;
+               }
+
+               skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
+       }
+
        if (q->gap == 0                 /* not doing reordering */
            || q->counter < q->gap      /* inside last reordering gap */
            || q->reorder < get_crandom(&q->reorder_cor)) {
@@ -382,6 +400,20 @@ static int get_reorder(struct Qdisc *sch, const struct rtattr *attr)
        return 0;
 }
 
+static int get_corrupt(struct Qdisc *sch, const struct rtattr *attr)
+{
+       struct netem_sched_data *q = qdisc_priv(sch);
+       const struct tc_netem_corrupt *r = RTA_DATA(attr);
+
+       if (RTA_PAYLOAD(attr) != sizeof(*r))
+               return -EINVAL;
+
+       q->corrupt = r->probability;
+       init_crandom(&q->corrupt_cor, r->correlation);
+       return 0;
+}
+
+/* Parse netlink message to set options */
 static int netem_change(struct Qdisc *sch, struct rtattr *opt)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
@@ -432,13 +464,19 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
                        if (ret)
                                return ret;
                }
+
                if (tb[TCA_NETEM_REORDER-1]) {
                        ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]);
                        if (ret)
                                return ret;
                }
-       }
 
+               if (tb[TCA_NETEM_CORRUPT-1]) {
+                       ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT-1]);
+                       if (ret)
+                               return ret;
+               }
+       }
 
        return 0;
 }
@@ -564,6 +602,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
        struct tc_netem_qopt qopt;
        struct tc_netem_corr cor;
        struct tc_netem_reorder reorder;
+       struct tc_netem_corrupt corrupt;
 
        qopt.latency = q->latency;
        qopt.jitter = q->jitter;
@@ -582,6 +621,10 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
        reorder.correlation = q->reorder_cor.rho;
        RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
 
+       corrupt.probability = q->corrupt;
+       corrupt.correlation = q->corrupt_cor.rho;
+       RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
+
        rta->rta_len = skb->tail - b;
 
        return skb->len;
index 6cf0342..c4a2a8c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index dec68a6..9d05e13 100644 (file)
@@ -110,7 +110,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
        asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000;
        asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000)
                                        * 1000;
-       asoc->pmtu = 0;
        asoc->frag_point = 0;
 
        /* Set the association max_retrans and RTO values from the
@@ -123,6 +122,25 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 
        asoc->overall_error_count = 0;
 
+       /* Initialize the association's heartbeat interval based on the
+        * sock configured value.
+        */
+       asoc->hbinterval = msecs_to_jiffies(sp->hbinterval);
+
+       /* Initialize path max retrans value. */
+       asoc->pathmaxrxt = sp->pathmaxrxt;
+
+       /* Initialize default path MTU. */
+       asoc->pathmtu = sp->pathmtu;
+
+       /* Set association default SACK delay */
+       asoc->sackdelay = msecs_to_jiffies(sp->sackdelay);
+
+       /* Set the association default flags controlling
+        * Heartbeat, SACK delay, and Path MTU Discovery.
+        */
+       asoc->param_flags = sp->param_flags;
+
        /* Initialize the maximum mumber of new data packets that can be sent
         * in a burst.
         */
@@ -144,8 +162,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
                = 5 * asoc->rto_max;
 
        asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
-       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
-               SCTP_DEFAULT_TIMEOUT_SACK;
+       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
        asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
                sp->autoclose * HZ;
        
@@ -540,23 +557,46 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 
        sctp_transport_set_owner(peer, asoc);
 
+       /* Initialize the peer's heartbeat interval based on the
+        * association configured value.
+        */
+       peer->hbinterval = asoc->hbinterval;
+
+       /* Set the path max_retrans.  */
+       peer->pathmaxrxt = asoc->pathmaxrxt;
+
+       /* Initialize the peer's SACK delay timeout based on the
+        * association configured value.
+        */
+       peer->sackdelay = asoc->sackdelay;
+
+       /* Enable/disable heartbeat, SACK delay, and path MTU discovery
+        * based on association setting.
+        */
+       peer->param_flags = asoc->param_flags;
+
        /* Initialize the pmtu of the transport. */
-       sctp_transport_pmtu(peer);
+       if (peer->param_flags & SPP_PMTUD_ENABLE)
+               sctp_transport_pmtu(peer);
+       else if (asoc->pathmtu)
+               peer->pathmtu = asoc->pathmtu;
+       else
+               peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 
        /* If this is the first transport addr on this association,
         * initialize the association PMTU to the peer's PMTU.
         * If not and the current association PMTU is higher than the new
         * peer's PMTU, reset the association PMTU to the new peer's PMTU.
         */
-       if (asoc->pmtu)
-               asoc->pmtu = min_t(int, peer->pmtu, asoc->pmtu);
+       if (asoc->pathmtu)
+               asoc->pathmtu = min_t(int, peer->pathmtu, asoc->pathmtu);
        else
-               asoc->pmtu = peer->pmtu;
+               asoc->pathmtu = peer->pathmtu;
 
        SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to "
-                         "%d\n", asoc, asoc->pmtu);
+                         "%d\n", asoc, asoc->pathmtu);
 
-       asoc->frag_point = sctp_frag_point(sp, asoc->pmtu);
+       asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
 
        /* The asoc->peer.port might not be meaningful yet, but
         * initialize the packet structure anyway.
@@ -574,7 +614,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
         *   (for example, implementations MAY use the size of the
         *   receiver advertised window).
         */
-       peer->cwnd = min(4*asoc->pmtu, max_t(__u32, 2*asoc->pmtu, 4380));
+       peer->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
 
        /* At this point, we may not have the receiver's advertised window,
         * so initialize ssthresh to the default value and it will be set
@@ -585,17 +625,6 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
        peer->partial_bytes_acked = 0;
        peer->flight_size = 0;
 
-       /* By default, enable heartbeat for peer address. */
-       peer->hb_allowed = 1;
-
-       /* Initialize the peer's heartbeat interval based on the
-        * sock configured value.
-        */
-       peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval);
-
-       /* Set the path max_retrans.  */
-       peer->max_retrans = sp->paddrparam.spp_pathmaxrxt;
-
        /* Set the transport's RTO.initial value */
        peer->rto = asoc->rto_initial;
 
@@ -1155,18 +1184,18 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
        /* Get the lowest pmtu of all the transports. */
        list_for_each(pos, &asoc->peer.transport_addr_list) {
                t = list_entry(pos, struct sctp_transport, transports);
-               if (!pmtu || (t->pmtu < pmtu))
-                       pmtu = t->pmtu;
+               if (!pmtu || (t->pathmtu < pmtu))
+                       pmtu = t->pathmtu;
        }
 
        if (pmtu) {
                struct sctp_sock *sp = sctp_sk(asoc->base.sk);
-               asoc->pmtu = pmtu;
+               asoc->pathmtu = pmtu;
                asoc->frag_point = sctp_frag_point(sp, pmtu);
        }
 
        SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n",
-                         __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point);
+                         __FUNCTION__, asoc, asoc->pathmtu, asoc->frag_point);
 }
 
 /* Should we send a SACK to update our peer? */
@@ -1179,7 +1208,7 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
        case SCTP_STATE_SHUTDOWN_SENT:
                if ((asoc->rwnd > asoc->a_rwnd) &&
                    ((asoc->rwnd - asoc->a_rwnd) >=
-                    min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu)))
+                    min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu)))
                        return 1;
                break;
        default:
index b24ff2c..238f1bf 100644 (file)
@@ -305,18 +305,36 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
                           struct sctp_transport *t, __u32 pmtu)
 {
-       if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
-               printk(KERN_WARNING "%s: Reported pmtu %d too low, "
-                      "using default minimum of %d\n", __FUNCTION__, pmtu,
-                      SCTP_DEFAULT_MINSEGMENT);
-               pmtu = SCTP_DEFAULT_MINSEGMENT;
-       }
+       if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu))
+               return;
 
-       if (!sock_owned_by_user(sk) && t && (t->pmtu != pmtu)) {
-               t->pmtu = pmtu;
+       if (t->param_flags & SPP_PMTUD_ENABLE) {
+               if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
+                       printk(KERN_WARNING "%s: Reported pmtu %d too low, "
+                              "using default minimum of %d\n",
+                              __FUNCTION__, pmtu,
+                              SCTP_DEFAULT_MINSEGMENT);
+                       /* Use default minimum segment size and disable
+                        * pmtu discovery on this transport.
+                        */
+                       t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
+                       t->param_flags = (t->param_flags & ~SPP_HB) |
+                               SPP_PMTUD_DISABLE;
+               } else {
+                       t->pathmtu = pmtu;
+               }
+
+               /* Update association pmtu. */
                sctp_assoc_sync_pmtu(asoc);
-               sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
        }
+
+       /* Retransmit with the new pmtu setting.
+        * Normally, if PMTU discovery is disabled, an ICMP Fragmentation
+        * Needed will never be sent, but if a message was sent before
+        * PMTU discovery was disabled that was larger than the PMTU, it
+        * would not be fragmented, so it must be re-transmitted fragmented.     
+        */
+       sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
 }
 
 /*
index fa3be2b..15c0516 100644 (file)
@@ -866,7 +866,7 @@ static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
        return 2;
 }
 
-static struct proto_ops inet6_seqpacket_ops = {
+static const struct proto_ops inet6_seqpacket_ops = {
        .family     = PF_INET6,
        .owner      = THIS_MODULE,
        .release    = inet6_release,
index 9313716..a40991e 100644 (file)
@@ -234,8 +234,8 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
                goto finish;
 
        pmtu  = ((packet->transport->asoc) ?
-                (packet->transport->asoc->pmtu) :
-                (packet->transport->pmtu));
+                (packet->transport->asoc->pathmtu) :
+                (packet->transport->pathmtu));
 
        too_big = (psize + chunk_len > pmtu);
 
@@ -482,7 +482,9 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        if (!dst || (dst->obsolete > 1)) {
                dst_release(dst);
                sctp_transport_route(tp, NULL, sctp_sk(sk));
-               sctp_assoc_sync_pmtu(asoc);
+               if (asoc->param_flags & SPP_PMTUD_ENABLE) {
+                       sctp_assoc_sync_pmtu(asoc);
+               }
        }
 
        nskb->dst = dst_clone(tp->dst);
@@ -492,7 +494,10 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
                          nskb->len);
 
-       (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
+       if (tp->param_flags & SPP_PMTUD_ENABLE)
+               (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
+       else
+               (*tp->af_specific->sctp_xmit)(nskb, tp, 1);
 
 out:
        packet->size = packet->overhead;
@@ -577,7 +582,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
         *      if ((flightsize + Max.Burst * MTU) < cwnd)
         *              cwnd = flightsize + Max.Burst * MTU
         */
-       max_burst_bytes = asoc->max_burst * asoc->pmtu;
+       max_burst_bytes = asoc->max_burst * asoc->pathmtu;
        if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
                transport->cwnd = transport->flight_size + max_burst_bytes;
                SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
@@ -622,7 +627,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
                 * data will fit or delay in hopes of bundling a full
                 * sized packet.
                 */
-               if (len < asoc->pmtu - packet->overhead) {
+               if (len < asoc->pathmtu - packet->overhead) {
                        retval = SCTP_XMIT_NAGLE_DELAY;
                        goto finish;
                }
index f775d78..de693b4 100644 (file)
@@ -54,6 +54,7 @@
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
+#include <net/route.h>
 #include <net/sctp/sctp.h>
 #include <net/addrconf.h>
 #include <net/inet_common.h>
@@ -829,7 +830,7 @@ static struct notifier_block sctp_inetaddr_notifier = {
 };
 
 /* Socket operations.  */
-static struct proto_ops inet_seqpacket_ops = {
+static const struct proto_ops inet_seqpacket_ops = {
        .family      = PF_INET,
        .owner       = THIS_MODULE,
        .release     = inet_release,       /* Needs to be wrapped... */
index 8239471..2d7d8a5 100644 (file)
@@ -157,9 +157,12 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
 {
        __u32 ctsn, max_tsn_seen;
        struct sctp_chunk *sack;
+       struct sctp_transport *trans = asoc->peer.last_data_from;
        int error = 0;
 
-       if (force)
+       if (force || 
+           (!trans && (asoc->param_flags & SPP_SACKDELAY_DISABLE)) ||
+           (trans && (trans->param_flags & SPP_SACKDELAY_DISABLE)))
                asoc->peer.sack_needed = 1;
 
        ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
@@ -189,7 +192,22 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
        if (!asoc->peer.sack_needed) {
                /* We will need a SACK for the next packet.  */
                asoc->peer.sack_needed = 1;
-               goto out;
+
+               /* Set the SACK delay timeout based on the
+                * SACK delay for the last transport
+                * data was received from, or the default
+                * for the association.
+                */
+               if (trans)
+                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+                               trans->sackdelay;
+               else
+                       asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+                               asoc->sackdelay;
+
+               /* Restart the SACK timer. */
+               sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
+                               SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
        } else {
                if (asoc->a_rwnd > asoc->rwnd)
                        asoc->a_rwnd = asoc->rwnd;
@@ -205,7 +223,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
        }
-out:
+
        return error;
 nomem:
        error = -ENOMEM;
@@ -415,7 +433,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
        asoc->overall_error_count++;
 
        if (transport->state != SCTP_INACTIVE &&
-           (transport->error_count++ >= transport->max_retrans)) {
+           (transport->error_count++ >= transport->pathmaxrxt)) {
                SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
                                         " transport IP: port:%d failed.\n",
                                         asoc,
index 475bfb4..557a7d9 100644 (file)
@@ -900,7 +900,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
         * HEARTBEAT is sent (see Section 8.3).
         */
 
-       if (transport->hb_allowed) {
+       if (transport->param_flags & SPP_HB_ENABLE) {
                if (SCTP_DISPOSITION_NOMEM ==
                                sctp_sf_heartbeat(ep, asoc, type, arg,
                                                  commands))
@@ -1051,7 +1051,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
                return SCTP_DISPOSITION_DISCARD;
        }
 
-       max_interval = link->hb_interval + link->rto;
+       max_interval = link->hbinterval + link->rto;
 
        /* Check if the timestamp looks valid.  */
        if (time_after(hbinfo->sent_at, jiffies) ||
@@ -2691,14 +2691,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
         * document allow. However, an SCTP transmitter MUST NOT be
         * more aggressive than the following algorithms allow.
         */
-       if (chunk->end_of_packet) {
+       if (chunk->end_of_packet)
                sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
 
-               /* Start the SACK timer.  */
-               sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-                               SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
-       }
-
        return SCTP_DISPOSITION_CONSUME;
 
 discard_force:
@@ -2721,13 +2716,9 @@ discard_force:
        return SCTP_DISPOSITION_DISCARD;
 
 discard_noforce:
-       if (chunk->end_of_packet) {
+       if (chunk->end_of_packet)
                sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
 
-               /* Start the SACK timer.  */
-               sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-                               SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
-       }
        return SCTP_DISPOSITION_DISCARD;
 consume:
        return SCTP_DISPOSITION_CONSUME;
@@ -3442,9 +3433,6 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
         * send another. 
         */
        sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
-       /* Start the SACK timer.  */
-       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-                       SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 
        return SCTP_DISPOSITION_CONSUME;
 
index 9df888e..fc04d18 100644 (file)
@@ -1941,107 +1941,379 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
  * address's parameters:
  *
  *  struct sctp_paddrparams {
- *      sctp_assoc_t            spp_assoc_id;
- *      struct sockaddr_storage spp_address;
- *      uint32_t                spp_hbinterval;
- *      uint16_t                spp_pathmaxrxt;
- *  };
- *
- *   spp_assoc_id    - (UDP style socket) This is filled in the application,
- *                     and identifies the association for this query.
+ *     sctp_assoc_t            spp_assoc_id;
+ *     struct sockaddr_storage spp_address;
+ *     uint32_t                spp_hbinterval;
+ *     uint16_t                spp_pathmaxrxt;
+ *     uint32_t                spp_pathmtu;
+ *     uint32_t                spp_sackdelay;
+ *     uint32_t                spp_flags;
+ * };
+ *
+ *   spp_assoc_id    - (one-to-many style socket) This is filled in the
+ *                     application, and identifies the association for
+ *                     this query.
  *   spp_address     - This specifies which address is of interest.
  *   spp_hbinterval  - This contains the value of the heartbeat interval,
- *                     in milliseconds.  A value of 0, when modifying the
- *                     parameter, specifies that the heartbeat on this
- *                     address should be disabled. A value of UINT32_MAX
- *                     (4294967295), when modifying the parameter,
- *                     specifies that a heartbeat should be sent
- *                     immediately to the peer address, and the current
- *                     interval should remain unchanged.
+ *                     in milliseconds.  If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
- *                     considered unreachable.
+ *                     considered unreachable. If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
+ *   spp_pathmtu     - When Path MTU discovery is disabled the value
+ *                     specified here will be the "fixed" path mtu.
+ *                     Note that if the spp_address field is empty
+ *                     then all associations on this address will
+ *                     have this fixed path mtu set upon them.
+ *
+ *   spp_sackdelay   - When delayed sack is enabled, this value specifies
+ *                     the number of milliseconds that sacks will be delayed
+ *                     for. This value will apply to all addresses of an
+ *                     association if the spp_address field is empty. Note
+ *                     also, that if delayed sack is enabled and this
+ *                     value is set to 0, no change is made to the last
+ *                     recorded delayed sack timer value.
+ *
+ *   spp_flags       - These flags are used to control various features
+ *                     on an association. The flag field may contain
+ *                     zero or more of the following options.
+ *
+ *                     SPP_HB_ENABLE  - Enable heartbeats on the
+ *                     specified address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     have heartbeats enabled upon them.
+ *
+ *                     SPP_HB_DISABLE - Disable heartbeats on the
+ *                     speicifed address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     will have their heartbeats disabled. Note also
+ *                     that SPP_HB_ENABLE and SPP_HB_DISABLE are
+ *                     mutually exclusive, only one of these two should
+ *                     be specified. Enabling both fields will have
+ *                     undetermined results.
+ *
+ *                     SPP_HB_DEMAND - Request a user initiated heartbeat
+ *                     to be made immediately.
+ *
+ *                     SPP_PMTUD_ENABLE - This field will enable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected.
+ *
+ *                     SPP_PMTUD_DISABLE - This field will disable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected. Not also that
+ *                     SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+ *                     exclusive. Enabling both will have undetermined
+ *                     results.
+ *
+ *                     SPP_SACKDELAY_ENABLE - Setting this flag turns
+ *                     on delayed sack. The time specified in spp_sackdelay
+ *                     is used to specify the sack delay for this address. Note
+ *                     that if spp_address is empty then all addresses will
+ *                     enable delayed sack and take on the sack delay
+ *                     value specified in spp_sackdelay.
+ *                     SPP_SACKDELAY_DISABLE - Setting this flag turns
+ *                     off delayed sack. If the spp_address field is blank then
+ *                     delayed sack is disabled for the entire association. Note
+ *                     also that this field is mutually exclusive to
+ *                     SPP_SACKDELAY_ENABLE, setting both will have undefined
+ *                     results.
  */
+int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
+                               struct sctp_transport   *trans,
+                               struct sctp_association *asoc,
+                               struct sctp_sock        *sp,
+                               int                      hb_change,
+                               int                      pmtud_change,
+                               int                      sackdelay_change)
+{
+       int error;
+
+       if (params->spp_flags & SPP_HB_DEMAND && trans) {
+               error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans);
+               if (error)
+                       return error;
+       }
+
+       if (params->spp_hbinterval) {
+               if (trans) {
+                       trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
+               } else if (asoc) {
+                       asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
+               } else {
+                       sp->hbinterval = params->spp_hbinterval;
+               }
+       }
+
+       if (hb_change) {
+               if (trans) {
+                       trans->param_flags =
+                               (trans->param_flags & ~SPP_HB) | hb_change;
+               } else if (asoc) {
+                       asoc->param_flags =
+                               (asoc->param_flags & ~SPP_HB) | hb_change;
+               } else {
+                       sp->param_flags =
+                               (sp->param_flags & ~SPP_HB) | hb_change;
+               }
+       }
+
+       if (params->spp_pathmtu) {
+               if (trans) {
+                       trans->pathmtu = params->spp_pathmtu;
+                       sctp_assoc_sync_pmtu(asoc);
+               } else if (asoc) {
+                       asoc->pathmtu = params->spp_pathmtu;
+                       sctp_frag_point(sp, params->spp_pathmtu);
+               } else {
+                       sp->pathmtu = params->spp_pathmtu;
+               }
+       }
+
+       if (pmtud_change) {
+               if (trans) {
+                       int update = (trans->param_flags & SPP_PMTUD_DISABLE) &&
+                               (params->spp_flags & SPP_PMTUD_ENABLE);
+                       trans->param_flags =
+                               (trans->param_flags & ~SPP_PMTUD) | pmtud_change;
+                       if (update) {
+                               sctp_transport_pmtu(trans);
+                               sctp_assoc_sync_pmtu(asoc);
+                       }
+               } else if (asoc) {
+                       asoc->param_flags =
+                               (asoc->param_flags & ~SPP_PMTUD) | pmtud_change;
+               } else {
+                       sp->param_flags =
+                               (sp->param_flags & ~SPP_PMTUD) | pmtud_change;
+               }
+       }
+
+       if (params->spp_sackdelay) {
+               if (trans) {
+                       trans->sackdelay =
+                               msecs_to_jiffies(params->spp_sackdelay);
+               } else if (asoc) {
+                       asoc->sackdelay =
+                               msecs_to_jiffies(params->spp_sackdelay);
+               } else {
+                       sp->sackdelay = params->spp_sackdelay;
+               }
+       }
+
+       if (sackdelay_change) {
+               if (trans) {
+                       trans->param_flags =
+                               (trans->param_flags & ~SPP_SACKDELAY) |
+                               sackdelay_change;
+               } else if (asoc) {
+                       asoc->param_flags =
+                               (asoc->param_flags & ~SPP_SACKDELAY) |
+                               sackdelay_change;
+               } else {
+                       sp->param_flags =
+                               (sp->param_flags & ~SPP_SACKDELAY) |
+                               sackdelay_change;
+               }
+       }
+
+       if (params->spp_pathmaxrxt) {
+               if (trans) {
+                       trans->pathmaxrxt = params->spp_pathmaxrxt;
+               } else if (asoc) {
+                       asoc->pathmaxrxt = params->spp_pathmaxrxt;
+               } else {
+                       sp->pathmaxrxt = params->spp_pathmaxrxt;
+               }
+       }
+
+       return 0;
+}
+
 static int sctp_setsockopt_peer_addr_params(struct sock *sk,
                                            char __user *optval, int optlen)
 {
-       struct sctp_paddrparams params;
-       struct sctp_transport *trans;
+       struct sctp_paddrparams  params;
+       struct sctp_transport   *trans = NULL;
+       struct sctp_association *asoc = NULL;
+       struct sctp_sock        *sp = sctp_sk(sk);
        int error;
+       int hb_change, pmtud_change, sackdelay_change;
 
        if (optlen != sizeof(struct sctp_paddrparams))
-               return -EINVAL;
+               return - EINVAL;
+
        if (copy_from_user(&params, optval, optlen))
                return -EFAULT;
 
-       /*
-        * API 7. Socket Options (setting the default value for the endpoint)
-        * All options that support specific settings on an association by
-        * filling in either an association id variable or a sockaddr_storage
-        * SHOULD also support setting of the same value for the entire endpoint
-        * (i.e. future associations). To accomplish this the following logic is
-        * used when setting one of these options:
-
-        * c) If neither the sockaddr_storage or association identification is
-        *    set i.e. the sockaddr_storage is set to all 0's (INADDR_ANY) and
-        *    the association identification is 0, the settings are a default
-        *    and to be applied to the endpoint (all future associations).
-        */
+       /* Validate flags and value parameters. */
+       hb_change        = params.spp_flags & SPP_HB;
+       pmtud_change     = params.spp_flags & SPP_PMTUD;
+       sackdelay_change = params.spp_flags & SPP_SACKDELAY;
+
+       if (hb_change        == SPP_HB ||
+           pmtud_change     == SPP_PMTUD ||
+           sackdelay_change == SPP_SACKDELAY ||
+           params.spp_sackdelay > 500 ||
+           (params.spp_pathmtu
+           && params.spp_pathmtu < SCTP_DEFAULT_MINSEGMENT))
+               return -EINVAL;
 
-       /* update default value for endpoint (all future associations) */
-       if (!params.spp_assoc_id && 
-           sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-               /* Manual heartbeat on an endpoint is invalid. */
-               if (0xffffffff == params.spp_hbinterval)
+       /* If an address other than INADDR_ANY is specified, and
+        * no transport is found, then the request is invalid.
+        */
+       if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+               trans = sctp_addr_id2transport(sk, &params.spp_address,
+                                              params.spp_assoc_id);
+               if (!trans)
                        return -EINVAL;
-               else if (params.spp_hbinterval)
-                       sctp_sk(sk)->paddrparam.spp_hbinterval =
-                                               params.spp_hbinterval;
-               if (params.spp_pathmaxrxt)
-                       sctp_sk(sk)->paddrparam.spp_pathmaxrxt =
-                                               params.spp_pathmaxrxt;
-               return 0;
        }
 
-       trans = sctp_addr_id2transport(sk, &params.spp_address,
-                                      params.spp_assoc_id);
-       if (!trans)
+       /* Get association, if assoc_id != 0 and the socket is a one
+        * to many style socket, and an association was not found, then
+        * the id was invalid.
+        */
+       asoc = sctp_id2assoc(sk, params.spp_assoc_id);
+       if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP))
                return -EINVAL;
 
-       /* Applications can enable or disable heartbeats for any peer address
-        * of an association, modify an address's heartbeat interval, force a
-        * heartbeat to be sent immediately, and adjust the address's maximum
-        * number of retransmissions sent before an address is considered
-        * unreachable.
-        *
-        * The value of the heartbeat interval, in milliseconds. A value of
-        * UINT32_MAX (4294967295), when modifying the parameter, specifies
-        * that a heartbeat should be sent immediately to the peer address,
-        * and the current interval should remain unchanged.
+       /* Heartbeat demand can only be sent on a transport or
+        * association, but not a socket.
         */
-       if (0xffffffff == params.spp_hbinterval) {
-               error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans);
-               if (error)
-                       return error;
-       } else {
-       /* The value of the heartbeat interval, in milliseconds. A value of 0,
-        * when modifying the parameter, specifies that the heartbeat on this
-        * address should be disabled.
+       if (params.spp_flags & SPP_HB_DEMAND && !trans && !asoc)
+               return -EINVAL;
+
+       /* Process parameters. */
+       error = sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+                                           hb_change, pmtud_change,
+                                           sackdelay_change);
+
+       if (error)
+               return error;
+
+       /* If changes are for association, also apply parameters to each
+        * transport.
         */
-               if (params.spp_hbinterval) {
-                       trans->hb_allowed = 1;
-                       trans->hb_interval = 
-                               msecs_to_jiffies(params.spp_hbinterval);
-               } else
-                       trans->hb_allowed = 0;
+       if (!trans && asoc) {
+               struct list_head *pos;
+
+               list_for_each(pos, &asoc->peer.transport_addr_list) {
+                       trans = list_entry(pos, struct sctp_transport,
+                                          transports);
+                       sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+                                                   hb_change, pmtud_change,
+                                                   sackdelay_change);
+               }
        }
 
-       /* spp_pathmaxrxt contains the maximum number of retransmissions
-        * before this address shall be considered unreachable.
-        */
-       if (params.spp_pathmaxrxt)
-               trans->max_retrans = params.spp_pathmaxrxt;
+       return 0;
+}
+
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ *
+ *   struct sctp_assoc_value {
+ *       sctp_assoc_t            assoc_id;
+ *       uint32_t                assoc_value;
+ *   };
+ *
+ *     assoc_id    - This parameter, indicates which association the
+ *                   user is preforming an action upon. Note that if
+ *                   this field's value is zero then the endpoints
+ *                   default value is changed (effecting future
+ *                   associations only).
+ *
+ *     assoc_value - This parameter contains the number of milliseconds
+ *                   that the user is requesting the delayed ACK timer
+ *                   be set to. Note that this value is defined in
+ *                   the standard to be between 200 and 500 milliseconds.
+ *
+ *                   Note: a value of zero will leave the value alone,
+ *                   but disable SACK delay. A non-zero value will also
+ *                   enable SACK delay.
+ */
 
+static int sctp_setsockopt_delayed_ack_time(struct sock *sk,
+                                           char __user *optval, int optlen)
+{
+       struct sctp_assoc_value  params;
+       struct sctp_transport   *trans = NULL;
+       struct sctp_association *asoc = NULL;
+       struct sctp_sock        *sp = sctp_sk(sk);
+
+       if (optlen != sizeof(struct sctp_assoc_value))
+               return - EINVAL;
+
+       if (copy_from_user(&params, optval, optlen))
+               return -EFAULT;
+
+       /* Validate value parameter. */
+       if (params.assoc_value > 500)
+               return -EINVAL;
+
+       /* Get association, if assoc_id != 0 and the socket is a one
+        * to many style socket, and an association was not found, then
+        * the id was invalid.
+        */
+       asoc = sctp_id2assoc(sk, params.assoc_id);
+       if (!asoc && params.assoc_id && sctp_style(sk, UDP))
+               return -EINVAL;
+
+       if (params.assoc_value) {
+               if (asoc) {
+                       asoc->sackdelay =
+                               msecs_to_jiffies(params.assoc_value);
+                       asoc->param_flags = 
+                               (asoc->param_flags & ~SPP_SACKDELAY) |
+                               SPP_SACKDELAY_ENABLE;
+               } else {
+                       sp->sackdelay = params.assoc_value;
+                       sp->param_flags = 
+                               (sp->param_flags & ~SPP_SACKDELAY) |
+                               SPP_SACKDELAY_ENABLE;
+               }
+       } else {
+               if (asoc) {
+                       asoc->param_flags = 
+                               (asoc->param_flags & ~SPP_SACKDELAY) |
+                               SPP_SACKDELAY_DISABLE;
+               } else {
+                       sp->param_flags = 
+                               (sp->param_flags & ~SPP_SACKDELAY) |
+                               SPP_SACKDELAY_DISABLE;
+               }
+       }
+
+       /* If change is for association, also apply to each transport. */
+       if (asoc) {
+               struct list_head *pos;
+
+               list_for_each(pos, &asoc->peer.transport_addr_list) {
+                       trans = list_entry(pos, struct sctp_transport,
+                                          transports);
+                       if (params.assoc_value) {
+                               trans->sackdelay =
+                                       msecs_to_jiffies(params.assoc_value);
+                               trans->param_flags = 
+                                       (trans->param_flags & ~SPP_SACKDELAY) |
+                                       SPP_SACKDELAY_ENABLE;
+                       } else {
+                               trans->param_flags = 
+                                       (trans->param_flags & ~SPP_SACKDELAY) |
+                                       SPP_SACKDELAY_DISABLE;
+                       }
+               }
+       }
        return 0;
 }
 
@@ -2334,7 +2606,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl
        /* Update the frag_point of the existing associations. */
        list_for_each(pos, &(sp->ep->asocs)) {
                asoc = list_entry(pos, struct sctp_association, asocs);
-               asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); 
+               asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); 
        }
 
        return 0;
@@ -2491,6 +2763,10 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
                retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
                break;
 
+       case SCTP_DELAYED_ACK_TIME:
+               retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen);
+               break;
+
        case SCTP_INITMSG:
                retval = sctp_setsockopt_initmsg(sk, optval, optlen);
                break;
@@ -2715,8 +2991,13 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
        /* Default Peer Address Parameters.  These defaults can
         * be modified via SCTP_PEER_ADDR_PARAMS
         */
-       sp->paddrparam.spp_hbinterval = jiffies_to_msecs(sctp_hb_interval);
-       sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path;
+       sp->hbinterval  = jiffies_to_msecs(sctp_hb_interval);
+       sp->pathmaxrxt  = sctp_max_retrans_path;
+       sp->pathmtu     = 0; // allow default discovery
+       sp->sackdelay   = sctp_sack_timeout;
+       sp->param_flags = SPP_HB_ENABLE |
+                         SPP_PMTUD_ENABLE |
+                         SPP_SACKDELAY_ENABLE;
 
        /* If enabled no SCTP message fragmentation will be performed.
         * Configure through SCTP_DISABLE_FRAGMENTS socket option.
@@ -2865,7 +3146,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
        status.sstat_primary.spinfo_cwnd = transport->cwnd;
        status.sstat_primary.spinfo_srtt = transport->srtt;
        status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto);
-       status.sstat_primary.spinfo_mtu = transport->pmtu;
+       status.sstat_primary.spinfo_mtu = transport->pathmtu;
 
        if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN)
                status.sstat_primary.spinfo_state = SCTP_ACTIVE;
@@ -2924,7 +3205,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len,
        pinfo.spinfo_cwnd = transport->cwnd;
        pinfo.spinfo_srtt = transport->srtt;
        pinfo.spinfo_rto = jiffies_to_msecs(transport->rto);
-       pinfo.spinfo_mtu = transport->pmtu;
+       pinfo.spinfo_mtu = transport->pathmtu;
 
        if (pinfo.spinfo_state == SCTP_UNKNOWN)
                pinfo.spinfo_state = SCTP_ACTIVE;
@@ -3086,69 +3367,227 @@ out:
  * address's parameters:
  *
  *  struct sctp_paddrparams {
- *      sctp_assoc_t            spp_assoc_id;
- *      struct sockaddr_storage spp_address;
- *      uint32_t                spp_hbinterval;
- *      uint16_t                spp_pathmaxrxt;
- *  };
- *
- *   spp_assoc_id    - (UDP style socket) This is filled in the application,
- *                     and identifies the association for this query.
+ *     sctp_assoc_t            spp_assoc_id;
+ *     struct sockaddr_storage spp_address;
+ *     uint32_t                spp_hbinterval;
+ *     uint16_t                spp_pathmaxrxt;
+ *     uint32_t                spp_pathmtu;
+ *     uint32_t                spp_sackdelay;
+ *     uint32_t                spp_flags;
+ * };
+ *
+ *   spp_assoc_id    - (one-to-many style socket) This is filled in the
+ *                     application, and identifies the association for
+ *                     this query.
  *   spp_address     - This specifies which address is of interest.
  *   spp_hbinterval  - This contains the value of the heartbeat interval,
- *                     in milliseconds.  A value of 0, when modifying the
- *                     parameter, specifies that the heartbeat on this
- *                     address should be disabled. A value of UINT32_MAX
- *                     (4294967295), when modifying the parameter,
- *                     specifies that a heartbeat should be sent
- *                     immediately to the peer address, and the current
- *                     interval should remain unchanged.
+ *                     in milliseconds.  If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
- *                     considered unreachable.
+ *                     considered unreachable. If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
+ *   spp_pathmtu     - When Path MTU discovery is disabled the value
+ *                     specified here will be the "fixed" path mtu.
+ *                     Note that if the spp_address field is empty
+ *                     then all associations on this address will
+ *                     have this fixed path mtu set upon them.
+ *
+ *   spp_sackdelay   - When delayed sack is enabled, this value specifies
+ *                     the number of milliseconds that sacks will be delayed
+ *                     for. This value will apply to all addresses of an
+ *                     association if the spp_address field is empty. Note
+ *                     also, that if delayed sack is enabled and this
+ *                     value is set to 0, no change is made to the last
+ *                     recorded delayed sack timer value.
+ *
+ *   spp_flags       - These flags are used to control various features
+ *                     on an association. The flag field may contain
+ *                     zero or more of the following options.
+ *
+ *                     SPP_HB_ENABLE  - Enable heartbeats on the
+ *                     specified address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     have heartbeats enabled upon them.
+ *
+ *                     SPP_HB_DISABLE - Disable heartbeats on the
+ *                     speicifed address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     will have their heartbeats disabled. Note also
+ *                     that SPP_HB_ENABLE and SPP_HB_DISABLE are
+ *                     mutually exclusive, only one of these two should
+ *                     be specified. Enabling both fields will have
+ *                     undetermined results.
+ *
+ *                     SPP_HB_DEMAND - Request a user initiated heartbeat
+ *                     to be made immediately.
+ *
+ *                     SPP_PMTUD_ENABLE - This field will enable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected.
+ *
+ *                     SPP_PMTUD_DISABLE - This field will disable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected. Not also that
+ *                     SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+ *                     exclusive. Enabling both will have undetermined
+ *                     results.
+ *
+ *                     SPP_SACKDELAY_ENABLE - Setting this flag turns
+ *                     on delayed sack. The time specified in spp_sackdelay
+ *                     is used to specify the sack delay for this address. Note
+ *                     that if spp_address is empty then all addresses will
+ *                     enable delayed sack and take on the sack delay
+ *                     value specified in spp_sackdelay.
+ *                     SPP_SACKDELAY_DISABLE - Setting this flag turns
+ *                     off delayed sack. If the spp_address field is blank then
+ *                     delayed sack is disabled for the entire association. Note
+ *                     also that this field is mutually exclusive to
+ *                     SPP_SACKDELAY_ENABLE, setting both will have undefined
+ *                     results.
  */
 static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
-                                               char __user *optval, int __user *optlen)
+                                           char __user *optval, int __user *optlen)
 {
-       struct sctp_paddrparams params;
-       struct sctp_transport *trans;
+       struct sctp_paddrparams  params;
+       struct sctp_transport   *trans = NULL;
+       struct sctp_association *asoc = NULL;
+       struct sctp_sock        *sp = sctp_sk(sk);
 
        if (len != sizeof(struct sctp_paddrparams))
                return -EINVAL;
+
        if (copy_from_user(&params, optval, len))
                return -EFAULT;
 
-       /* If no association id is specified retrieve the default value
-        * for the endpoint that will be used for all future associations
+       /* If an address other than INADDR_ANY is specified, and
+        * no transport is found, then the request is invalid.
         */
-       if (!params.spp_assoc_id &&
-           sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-               params.spp_hbinterval = sctp_sk(sk)->paddrparam.spp_hbinterval;
-               params.spp_pathmaxrxt = sctp_sk(sk)->paddrparam.spp_pathmaxrxt;
-
-               goto done;
+       if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+               trans = sctp_addr_id2transport(sk, &params.spp_address,
+                                              params.spp_assoc_id);
+               if (!trans) {
+                       SCTP_DEBUG_PRINTK("Failed no transport\n");
+                       return -EINVAL;
+               }
        }
 
-       trans = sctp_addr_id2transport(sk, &params.spp_address,
-                                      params.spp_assoc_id);
-       if (!trans)
+       /* Get association, if assoc_id != 0 and the socket is a one
+        * to many style socket, and an association was not found, then
+        * the id was invalid.
+        */
+       asoc = sctp_id2assoc(sk, params.spp_assoc_id);
+       if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) {
+               SCTP_DEBUG_PRINTK("Failed no association\n");
                return -EINVAL;
+       }
 
-       /* The value of the heartbeat interval, in milliseconds. A value of 0,
-        * when modifying the parameter, specifies that the heartbeat on this
-        * address should be disabled.
-        */
-       if (!trans->hb_allowed)
-               params.spp_hbinterval = 0;
-       else
-               params.spp_hbinterval = jiffies_to_msecs(trans->hb_interval);
+       if (trans) {
+               /* Fetch transport values. */
+               params.spp_hbinterval = jiffies_to_msecs(trans->hbinterval);
+               params.spp_pathmtu    = trans->pathmtu;
+               params.spp_pathmaxrxt = trans->pathmaxrxt;
+               params.spp_sackdelay  = jiffies_to_msecs(trans->sackdelay);
+
+               /*draft-11 doesn't say what to return in spp_flags*/
+               params.spp_flags      = trans->param_flags;
+       } else if (asoc) {
+               /* Fetch association values. */
+               params.spp_hbinterval = jiffies_to_msecs(asoc->hbinterval);
+               params.spp_pathmtu    = asoc->pathmtu;
+               params.spp_pathmaxrxt = asoc->pathmaxrxt;
+               params.spp_sackdelay  = jiffies_to_msecs(asoc->sackdelay);
+
+               /*draft-11 doesn't say what to return in spp_flags*/
+               params.spp_flags      = asoc->param_flags;
+       } else {
+               /* Fetch socket values. */
+               params.spp_hbinterval = sp->hbinterval;
+               params.spp_pathmtu    = sp->pathmtu;
+               params.spp_sackdelay  = sp->sackdelay;
+               params.spp_pathmaxrxt = sp->pathmaxrxt;
+
+               /*draft-11 doesn't say what to return in spp_flags*/
+               params.spp_flags      = sp->param_flags;
+       }
 
-       /* spp_pathmaxrxt contains the maximum number of retransmissions
-        * before this address shall be considered unreachable.
-        */
-       params.spp_pathmaxrxt = trans->max_retrans;
+       if (copy_to_user(optval, &params, len))
+               return -EFAULT;
+
+       if (put_user(len, optlen))
+               return -EFAULT;
+
+       return 0;
+}
+
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ *
+ *   struct sctp_assoc_value {
+ *       sctp_assoc_t            assoc_id;
+ *       uint32_t                assoc_value;
+ *   };
+ *
+ *     assoc_id    - This parameter, indicates which association the
+ *                   user is preforming an action upon. Note that if
+ *                   this field's value is zero then the endpoints
+ *                   default value is changed (effecting future
+ *                   associations only).
+ *
+ *     assoc_value - This parameter contains the number of milliseconds
+ *                   that the user is requesting the delayed ACK timer
+ *                   be set to. Note that this value is defined in
+ *                   the standard to be between 200 and 500 milliseconds.
+ *
+ *                   Note: a value of zero will leave the value alone,
+ *                   but disable SACK delay. A non-zero value will also
+ *                   enable SACK delay.
+ */
+static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len,
+                                           char __user *optval,
+                                           int __user *optlen)
+{
+       struct sctp_assoc_value  params;
+       struct sctp_association *asoc = NULL;
+       struct sctp_sock        *sp = sctp_sk(sk);
+
+       if (len != sizeof(struct sctp_assoc_value))
+               return - EINVAL;
+
+       if (copy_from_user(&params, optval, len))
+               return -EFAULT;
+
+       /* Get association, if assoc_id != 0 and the socket is a one
+        * to many style socket, and an association was not found, then
+        * the id was invalid.
+        */
+       asoc = sctp_id2assoc(sk, params.assoc_id);
+       if (!asoc && params.assoc_id && sctp_style(sk, UDP))
+               return -EINVAL;
+
+       if (asoc) {
+               /* Fetch association values. */
+               if (asoc->param_flags & SPP_SACKDELAY_ENABLE)
+                       params.assoc_value = jiffies_to_msecs(
+                               asoc->sackdelay);
+               else
+                       params.assoc_value = 0;
+       } else {
+               /* Fetch socket values. */
+               if (sp->param_flags & SPP_SACKDELAY_ENABLE)
+                       params.assoc_value  = sp->sackdelay;
+               else
+                       params.assoc_value  = 0;
+       }
 
-done:
        if (copy_to_user(optval, &params, len))
                return -EFAULT;
 
@@ -4015,6 +4454,10 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
                retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
                                                          optlen);
                break;
+       case SCTP_DELAYED_ACK_TIME:
+               retval = sctp_getsockopt_delayed_ack_time(sk, len, optval,
+                                                         optlen);
+               break;
        case SCTP_INITMSG:
                retval = sctp_getsockopt_initmsg(sk, len, optval, optlen);
                break;
index 268ddaf..68d73e2 100644 (file)
@@ -86,10 +86,13 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
        peer->init_sent_count = 0;
 
        peer->state = SCTP_ACTIVE;
-       peer->hb_allowed = 0;
+       peer->param_flags = SPP_HB_DISABLE |
+                           SPP_PMTUD_ENABLE |
+                           SPP_SACKDELAY_ENABLE;
+       peer->hbinterval  = 0;
 
        /* Initialize the default path max_retrans.  */
-       peer->max_retrans = sctp_max_retrans_path;
+       peer->pathmaxrxt  = sctp_max_retrans_path;
        peer->error_count = 0;
 
        INIT_LIST_HEAD(&peer->transmitted);
@@ -229,10 +232,10 @@ void sctp_transport_pmtu(struct sctp_transport *transport)
        dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL);
 
        if (dst) {
-               transport->pmtu = dst_mtu(dst);
+               transport->pathmtu = dst_mtu(dst);
                dst_release(dst);
        } else
-               transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
+               transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 }
 
 /* Caches the dst entry and source address for a transport's destination
@@ -254,8 +257,11 @@ void sctp_transport_route(struct sctp_transport *transport,
                af->get_saddr(asoc, dst, daddr, &transport->saddr);
 
        transport->dst = dst;
+       if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) {
+               return;
+       }
        if (dst) {
-               transport->pmtu = dst_mtu(dst);
+               transport->pathmtu = dst_mtu(dst);
 
                /* Initialize sk->sk_rcv_saddr, if the transport is the
                 * association's active path for getsockname().
@@ -264,7 +270,7 @@ void sctp_transport_route(struct sctp_transport *transport,
                        opt->pf->af->to_sk_saddr(&transport->saddr,
                                                 asoc->base.sk);
        } else
-               transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
+               transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 }
 
 /* Hold a reference to a transport.  */
@@ -369,7 +375,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport,
 
        ssthresh = transport->ssthresh;
        pba = transport->partial_bytes_acked;
-       pmtu = transport->asoc->pmtu;
+       pmtu = transport->asoc->pathmtu;
 
        if (cwnd <= ssthresh) {
                /* RFC 2960 7.2.1, sctpimpguide-05 2.14.2 When cwnd is less
@@ -441,8 +447,8 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
                 *      partial_bytes_acked = 0
                 */
                transport->ssthresh = max(transport->cwnd/2,
-                                         4*transport->asoc->pmtu);
-               transport->cwnd = transport->asoc->pmtu;
+                                         4*transport->asoc->pathmtu);
+               transport->cwnd = transport->asoc->pathmtu;
                break;
 
        case SCTP_LOWER_CWND_FAST_RTX:
@@ -459,7 +465,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
                 *      partial_bytes_acked = 0
                 */
                transport->ssthresh = max(transport->cwnd/2,
-                                         4*transport->asoc->pmtu);
+                                         4*transport->asoc->pathmtu);
                transport->cwnd = transport->ssthresh;
                break;
 
@@ -479,7 +485,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
                if ((jiffies - transport->last_time_ecne_reduced) >
                    transport->rtt) {
                        transport->ssthresh = max(transport->cwnd/2,
-                                                 4*transport->asoc->pmtu);
+                                                 4*transport->asoc->pathmtu);
                        transport->cwnd = transport->ssthresh;
                        transport->last_time_ecne_reduced = jiffies;
                }
@@ -496,7 +502,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
                 */
                if ((jiffies - transport->last_time_used) > transport->rto)
                        transport->cwnd = max(transport->cwnd/2,
-                                                4*transport->asoc->pmtu);
+                                                4*transport->asoc->pathmtu);
                break;
        };
 
@@ -511,7 +517,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
 unsigned long sctp_transport_timeout(struct sctp_transport *t)
 {
        unsigned long timeout;
-       timeout = t->hb_interval + t->rto + sctp_jitter(t->rto);
+       timeout = t->hbinterval + t->rto + sctp_jitter(t->rto);
        timeout += jiffies;
        return timeout;
 }
index 3145103..06fa217 100644 (file)
@@ -640,154 +640,150 @@ static void sock_aio_dtor(struct kiocb *iocb)
        kfree(iocb->private);
 }
 
-/*
- *     Read data from a socket. ubuf is a user mode pointer. We make sure the user
- *     area ubuf...ubuf+size-1 is writable before asking the protocol.
- */
-
-static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
-                        size_t size, loff_t pos)
+static ssize_t sock_sendpage(struct file *file, struct page *page,
+                            int offset, size_t size, loff_t *ppos, int more)
 {
-       struct sock_iocb *x, siocb;
        struct socket *sock;
        int flags;
 
-       if (pos != 0)
-               return -ESPIPE;
-       if (size==0)            /* Match SYS5 behaviour */
-               return 0;
+       sock = file->private_data;
 
-       if (is_sync_kiocb(iocb))
-               x = &siocb;
-       else {
-               x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL);
-               if (!x)
-                       return -ENOMEM;
+       flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
+       if (more)
+               flags |= MSG_MORE;
+
+       return sock->ops->sendpage(sock, page, offset, size, flags);
+}
+
+static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
+               char __user *ubuf, size_t size, struct sock_iocb *siocb)
+{
+       if (!is_sync_kiocb(iocb)) {
+               siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
+               if (!siocb)
+                       return NULL;
                iocb->ki_dtor = sock_aio_dtor;
        }
-       iocb->private = x;
-       x->kiocb = iocb;
-       sock = iocb->ki_filp->private_data; 
 
-       x->async_msg.msg_name = NULL;
-       x->async_msg.msg_namelen = 0;
-       x->async_msg.msg_iov = &x->async_iov;
-       x->async_msg.msg_iovlen = 1;
-       x->async_msg.msg_control = NULL;
-       x->async_msg.msg_controllen = 0;
-       x->async_iov.iov_base = ubuf;
-       x->async_iov.iov_len = size;
-       flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
+       siocb->kiocb = iocb;
+       siocb->async_iov.iov_base = ubuf;
+       siocb->async_iov.iov_len = size;
 
-       return __sock_recvmsg(iocb, sock, &x->async_msg, size, flags);
+       iocb->private = siocb;
+       return siocb;
 }
 
+static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
+               struct file *file, struct iovec *iov, unsigned long nr_segs)
+{
+       struct socket *sock = file->private_data;
+       size_t size = 0;
+       int i;
 
-/*
- *     Write data to a socket. We verify that the user area ubuf..ubuf+size-1
- *     is readable by the user process.
- */
+        for (i = 0 ; i < nr_segs ; i++)
+                size += iov[i].iov_len;
 
-static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
-                         size_t size, loff_t pos)
+       msg->msg_name = NULL;
+       msg->msg_namelen = 0;
+       msg->msg_control = NULL;
+       msg->msg_controllen = 0;
+       msg->msg_iov = (struct iovec *) iov;
+       msg->msg_iovlen = nr_segs;
+       msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+
+       return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
+}
+
+static ssize_t sock_readv(struct file *file, const struct iovec *iov,
+                         unsigned long nr_segs, loff_t *ppos)
 {
-       struct sock_iocb *x, siocb;
-       struct socket *sock;
-       
+       struct kiocb iocb;
+       struct sock_iocb siocb;
+       struct msghdr msg;
+       int ret;
+
+        init_sync_kiocb(&iocb, NULL);
+       iocb.private = &siocb;
+
+       ret = do_sock_read(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
+       if (-EIOCBQUEUED == ret)
+               ret = wait_on_sync_kiocb(&iocb);
+       return ret;
+}
+
+static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
+                        size_t count, loff_t pos)
+{
+       struct sock_iocb siocb, *x;
+
        if (pos != 0)
                return -ESPIPE;
-       if(size==0)             /* Match SYS5 behaviour */
+       if (count == 0)         /* Match SYS5 behaviour */
                return 0;
 
-       if (is_sync_kiocb(iocb))
-               x = &siocb;
-       else {
-               x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL);
-               if (!x)
-                       return -ENOMEM;
-               iocb->ki_dtor = sock_aio_dtor;
-       }
-       iocb->private = x;
-       x->kiocb = iocb;
-       sock = iocb->ki_filp->private_data; 
-
-       x->async_msg.msg_name = NULL;
-       x->async_msg.msg_namelen = 0;
-       x->async_msg.msg_iov = &x->async_iov;
-       x->async_msg.msg_iovlen = 1;
-       x->async_msg.msg_control = NULL;
-       x->async_msg.msg_controllen = 0;
-       x->async_msg.msg_flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-       if (sock->type == SOCK_SEQPACKET)
-               x->async_msg.msg_flags |= MSG_EOR;
-       x->async_iov.iov_base = (void __user *)ubuf;
-       x->async_iov.iov_len = size;
-       
-       return __sock_sendmsg(iocb, sock, &x->async_msg, size);
+       x = alloc_sock_iocb(iocb, ubuf, count, &siocb);
+       if (!x)
+               return -ENOMEM;
+       return do_sock_read(&x->async_msg, iocb, iocb->ki_filp,
+                       &x->async_iov, 1);
 }
 
-static ssize_t sock_sendpage(struct file *file, struct page *page,
-                            int offset, size_t size, loff_t *ppos, int more)
+static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
+               struct file *file, struct iovec *iov, unsigned long nr_segs)
 {
-       struct socket *sock;
-       int flags;
+       struct socket *sock = file->private_data;
+       size_t size = 0;
+       int i;
 
-       sock = file->private_data;
+        for (i = 0 ; i < nr_segs ; i++)
+                size += iov[i].iov_len;
 
-       flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-       if (more)
-               flags |= MSG_MORE;
+       msg->msg_name = NULL;
+       msg->msg_namelen = 0;
+       msg->msg_control = NULL;
+       msg->msg_controllen = 0;
+       msg->msg_iov = (struct iovec *) iov;
+       msg->msg_iovlen = nr_segs;
+       msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+       if (sock->type == SOCK_SEQPACKET)
+               msg->msg_flags |= MSG_EOR;
 
-       return sock->ops->sendpage(sock, page, offset, size, flags);
+       return __sock_sendmsg(iocb, sock, msg, size);
 }
 
-static int sock_readv_writev(int type,
-                            struct file * file, const struct iovec * iov,
-                            long count, size_t size)
+static ssize_t sock_writev(struct file *file, const struct iovec *iov,
+                          unsigned long nr_segs, loff_t *ppos)
 {
        struct msghdr msg;
-       struct socket *sock;
+       struct kiocb iocb;
+       struct sock_iocb siocb;
+       int ret;
 
-       sock = file->private_data;
+       init_sync_kiocb(&iocb, NULL);
+       iocb.private = &siocb;
 
-       msg.msg_name = NULL;
-       msg.msg_namelen = 0;
-       msg.msg_control = NULL;
-       msg.msg_controllen = 0;
-       msg.msg_iov = (struct iovec *) iov;
-       msg.msg_iovlen = count;
-       msg.msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+       ret = do_sock_write(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
+       if (-EIOCBQUEUED == ret)
+               ret = wait_on_sync_kiocb(&iocb);
+       return ret;
+}
 
-       /* read() does a VERIFY_WRITE */
-       if (type == VERIFY_WRITE)
-               return sock_recvmsg(sock, &msg, size, msg.msg_flags);
+static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
+                         size_t count, loff_t pos)
+{
+       struct sock_iocb siocb, *x;
 
-       if (sock->type == SOCK_SEQPACKET)
-               msg.msg_flags |= MSG_EOR;
+       if (pos != 0)
+               return -ESPIPE;
+       if (count == 0)         /* Match SYS5 behaviour */
+               return 0;
 
-       return sock_sendmsg(sock, &msg, size);
-}
+       x = alloc_sock_iocb(iocb, (void __user *)ubuf, count, &siocb);
+       if (!x)
+               return -ENOMEM;
 
-static ssize_t sock_readv(struct file *file, const struct iovec *vector,
-                         unsigned long count, loff_t *ppos)
-{
-       size_t tot_len = 0;
-       int i;
-        for (i = 0 ; i < count ; i++)
-                tot_len += vector[i].iov_len;
-       return sock_readv_writev(VERIFY_WRITE,
-                                file, vector, count, tot_len);
-}
-       
-static ssize_t sock_writev(struct file *file, const struct iovec *vector,
-                          unsigned long count, loff_t *ppos)
-{
-       size_t tot_len = 0;
-       int i;
-        for (i = 0 ; i < count ; i++)
-                tot_len += vector[i].iov_len;
-       return sock_readv_writev(VERIFY_READ,
-                                file, vector, count, tot_len);
+       return do_sock_write(&x->async_msg, iocb, iocb->ki_filp,
+                       &x->async_iov, 1);
 }
 
 
@@ -904,6 +900,13 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
                        break;
                default:
                        err = sock->ops->ioctl(sock, cmd, arg);
+
+                       /*
+                        * If this ioctl is unknown try to hand it down
+                        * to the NIC driver.
+                        */
+                       if (err == -ENOIOCTLCMD)
+                               err = dev_ioctl(cmd, argp);
                        break;
        }
        return err;
@@ -2036,7 +2039,7 @@ int sock_unregister(int family)
        return 0;
 }
 
-void __init sock_init(void)
+static int __init sock_init(void)
 {
        /*
         *      Initialize sock SLAB cache.
@@ -2044,12 +2047,10 @@ void __init sock_init(void)
         
        sk_init();
 
-#ifdef SLAB_SKB
        /*
         *      Initialize skbuff SLAB cache 
         */
        skb_init();
-#endif
 
        /*
         *      Initialize the protocols module. 
@@ -2058,15 +2059,19 @@ void __init sock_init(void)
        init_inodecache();
        register_filesystem(&sock_fs_type);
        sock_mnt = kern_mount(&sock_fs_type);
-       /* The real protocol initialization is performed when
-        *  do_initcalls is run.  
+
+       /* The real protocol initialization is performed in later initcalls.
         */
 
 #ifdef CONFIG_NETFILTER
        netfilter_init();
 #endif
+
+       return 0;
 }
 
+core_initcall(sock_init);      /* early initcall */
+
 #ifdef CONFIG_PROC_FS
 void socket_seq_show(struct seq_file *seq)
 {
index c6a5191..d68eba4 100644 (file)
@@ -758,7 +758,7 @@ svc_tcp_accept(struct svc_sock *svsk)
        struct svc_serv *serv = svsk->sk_server;
        struct socket   *sock = svsk->sk_sock;
        struct socket   *newsock;
-       struct proto_ops *ops;
+       const struct proto_ops *ops;
        struct svc_sock *newsvsk;
        int             err, slen;
 
index acc73ba..5f6ae79 100644 (file)
 int sysctl_unix_max_dgram_qlen = 10;
 
 struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-DEFINE_RWLOCK(unix_table_lock);
+DEFINE_SPINLOCK(unix_table_lock);
 static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 #define unix_sockets_unbound   (&unix_socket_table[UNIX_HASH_SIZE])
@@ -130,7 +130,7 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 /*
  *  SMP locking strategy:
- *    hash table is protected with rwlock unix_table_lock
+ *    hash table is protected with spinlock unix_table_lock
  *    each socket state is protected by separate rwlock.
  */
 
@@ -214,16 +214,16 @@ static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
 
 static inline void unix_remove_socket(struct sock *sk)
 {
-       write_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
        __unix_remove_socket(sk);
-       write_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
 }
 
 static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
 {
-       write_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
        __unix_insert_socket(list, sk);
-       write_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
 }
 
 static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
@@ -250,11 +250,11 @@ static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname,
 {
        struct sock *s;
 
-       read_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
        s = __unix_find_socket_byname(sunname, len, type, hash);
        if (s)
                sock_hold(s);
-       read_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
        return s;
 }
 
@@ -263,7 +263,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
        struct sock *s;
        struct hlist_node *node;
 
-       read_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
        sk_for_each(s, node,
                    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
                struct dentry *dentry = unix_sk(s)->dentry;
@@ -276,7 +276,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
        }
        s = NULL;
 found:
-       read_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
        return s;
 }
 
@@ -473,7 +473,7 @@ static int unix_dgram_connect(struct socket *, struct sockaddr *,
 static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
                                  struct msghdr *, size_t);
 
-static struct proto_ops unix_stream_ops = {
+static const struct proto_ops unix_stream_ops = {
        .family =       PF_UNIX,
        .owner =        THIS_MODULE,
        .release =      unix_release,
@@ -494,7 +494,7 @@ static struct proto_ops unix_stream_ops = {
        .sendpage =     sock_no_sendpage,
 };
 
-static struct proto_ops unix_dgram_ops = {
+static const struct proto_ops unix_dgram_ops = {
        .family =       PF_UNIX,
        .owner =        THIS_MODULE,
        .release =      unix_release,
@@ -515,7 +515,7 @@ static struct proto_ops unix_dgram_ops = {
        .sendpage =     sock_no_sendpage,
 };
 
-static struct proto_ops unix_seqpacket_ops = {
+static const struct proto_ops unix_seqpacket_ops = {
        .family =       PF_UNIX,
        .owner =        THIS_MODULE,
        .release =      unix_release,
@@ -564,7 +564,7 @@ static struct sock * unix_create1(struct socket *sock)
        u         = unix_sk(sk);
        u->dentry = NULL;
        u->mnt    = NULL;
-       rwlock_init(&u->lock);
+       spin_lock_init(&u->lock);
        atomic_set(&u->inflight, sock ? 0 : -1);
        init_MUTEX(&u->readsem); /* single task reading lock */
        init_waitqueue_head(&u->peer_wait);
@@ -642,12 +642,12 @@ retry:
        addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
        addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
 
-       write_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
        ordernum = (ordernum+1)&0xFFFFF;
 
        if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
                                      addr->hash)) {
-               write_unlock(&unix_table_lock);
+               spin_unlock(&unix_table_lock);
                /* Sanity yield. It is unusual case, but yet... */
                if (!(ordernum&0xFF))
                        yield();
@@ -658,7 +658,7 @@ retry:
        __unix_remove_socket(sk);
        u->addr = addr;
        __unix_insert_socket(&unix_socket_table[addr->hash], sk);
-       write_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
        err = 0;
 
 out:   up(&u->readsem);
@@ -791,7 +791,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                addr->hash = UNIX_HASH_SIZE;
        }
 
-       write_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
 
        if (!sunaddr->sun_path[0]) {
                err = -EADDRINUSE;
@@ -814,7 +814,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        __unix_insert_socket(list, sk);
 
 out_unlock:
-       write_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
 out_up:
        up(&u->readsem);
 out:
@@ -1063,10 +1063,12 @@ restart:
        /* Set credentials */
        sk->sk_peercred = other->sk_peercred;
 
-       sock_hold(newsk);
-       unix_peer(sk)   = newsk;
        sock->state     = SS_CONNECTED;
        sk->sk_state    = TCP_ESTABLISHED;
+       sock_hold(newsk);
+
+       smp_mb__after_atomic_inc();     /* sock_hold() does an atomic_inc() */
+       unix_peer(sk)   = newsk;
 
        unix_state_wunlock(sk);
 
@@ -1414,7 +1416,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        } else {
                sunaddr = NULL;
                err = -ENOTCONN;
-               other = unix_peer_get(sk);
+               other = unix_peer(sk);
                if (!other)
                        goto out_err;
        }
@@ -1476,7 +1478,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                other->sk_data_ready(other, size);
                sent+=size;
        }
-       sock_put(other);
 
        scm_destroy(siocb->scm);
        siocb->scm = NULL;
@@ -1491,8 +1492,6 @@ pipe_err:
                send_sig(SIGPIPE,current,0);
        err = -EPIPE;
 out_err:
-        if (other)
-               sock_put(other);
        scm_destroy(siocb->scm);
        siocb->scm = NULL;
        return sent ? : err;
@@ -1860,7 +1859,7 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                }
 
                default:
-                       err = dev_ioctl(cmd, (void __user *)arg);
+                       err = -ENOIOCTLCMD;
                        break;
        }
        return err;
@@ -1917,7 +1916,7 @@ static struct sock *unix_seq_idx(int *iter, loff_t pos)
 
 static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       read_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
        return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
 }
 
@@ -1932,7 +1931,7 @@ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
 static void unix_seq_stop(struct seq_file *seq, void *v)
 {
-       read_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
 }
 
 static int unix_seq_show(struct seq_file *seq, void *v)
index 6ffc64e..411802b 100644 (file)
@@ -182,7 +182,7 @@ void unix_gc(void)
        if (down_trylock(&unix_gc_sem))
                return;
 
-       read_lock(&unix_table_lock);
+       spin_lock(&unix_table_lock);
 
        forall_unix_sockets(i, s)
        {
@@ -301,7 +301,7 @@ void unix_gc(void)
                }
                u->gc_tree = GC_ORPHAN;
        }
-       read_unlock(&unix_table_lock);
+       spin_unlock(&unix_table_lock);
 
        /*
         *      Here we are. Hitlist is filled. Die.
index 59fec59..7a43ae4 100644 (file)
@@ -181,7 +181,7 @@ struct wanpipe_opt
 #endif
 
 static int sk_count;
-extern struct proto_ops wanpipe_ops;
+extern const struct proto_ops wanpipe_ops;
 static unsigned long find_free_critical;
 
 static void wanpipe_unlink_driver(struct sock *sk);
@@ -1839,7 +1839,7 @@ static int wanpipe_ioctl(struct socket *sock, unsigned int cmd, unsigned long ar
 #endif
 
                default:
-                       return dev_ioctl(cmd,(void __user *) arg);
+                       return -ENOIOCTLCMD;
        }
        /*NOTREACHED*/
 }
@@ -2546,7 +2546,7 @@ static int wanpipe_connect(struct socket *sock, struct sockaddr *uaddr, int addr
        return 0;
 }
 
-struct proto_ops wanpipe_ops = {
+const struct proto_ops wanpipe_ops = {
        .family =       PF_WANPIPE,
        .owner =        THIS_MODULE,
        .release =      wanpipe_release,
index 020d73c..16459c7 100644 (file)
@@ -64,7 +64,7 @@ int sysctl_x25_ack_holdback_timeout    = X25_DEFAULT_T2;
 HLIST_HEAD(x25_list);
 DEFINE_RWLOCK(x25_list_lock);
 
-static struct proto_ops x25_proto_ops;
+static const struct proto_ops x25_proto_ops;
 
 static struct x25_address null_x25_address = {"               "};
 
@@ -1378,7 +1378,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                }
 
                default:
-                       rc = dev_ioctl(cmd, argp);
+                       rc = -ENOIOCTLCMD;
                        break;
        }
 
@@ -1391,7 +1391,7 @@ static struct net_proto_family x25_family_ops = {
        .owner  =       THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
        .family =       AF_X25,
        .owner =        THIS_MODULE,
        .release =      x25_release,
index d19e274..64a4473 100644 (file)
@@ -10,7 +10,7 @@
  *     YOSHIFUJI Hideaki
  *             Split up af-specific portion
  *     Derek Atkins <derek@ihtfp.com>          Add the post_input processor
- *     
+ *
  */
 
 #include <asm/bug.h>
@@ -256,6 +256,7 @@ void __xfrm_policy_destroy(struct xfrm_policy *policy)
        if (del_timer(&policy->timer))
                BUG();
 
+       security_xfrm_policy_free(policy);
        kfree(policy);
 }
 EXPORT_SYMBOL(__xfrm_policy_destroy);
@@ -350,7 +351,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 
        write_lock_bh(&xfrm_policy_lock);
        for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) {
-               if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) {
+               if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 &&
+                   xfrm_sec_ctx_match(pol->security, policy->security)) {
                        if (excl) {
                                write_unlock_bh(&xfrm_policy_lock);
                                return -EEXIST;
@@ -416,14 +418,15 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 }
 EXPORT_SYMBOL(xfrm_policy_insert);
 
-struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
-                                     int delete)
+struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
+                                         struct xfrm_sec_ctx *ctx, int delete)
 {
        struct xfrm_policy *pol, **p;
 
        write_lock_bh(&xfrm_policy_lock);
        for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
-               if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) {
+               if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) &&
+                   (xfrm_sec_ctx_match(ctx, pol->security))) {
                        xfrm_pol_hold(pol);
                        if (delete)
                                *p = pol->next;
@@ -438,7 +441,7 @@ struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
        }
        return pol;
 }
-EXPORT_SYMBOL(xfrm_policy_bysel);
+EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
 {
@@ -519,7 +522,7 @@ EXPORT_SYMBOL(xfrm_policy_walk);
 
 /* Find policy to apply to this flow. */
 
-static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
+static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir,
                               void **objp, atomic_t **obj_refp)
 {
        struct xfrm_policy *pol;
@@ -533,9 +536,12 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
                        continue;
 
                match = xfrm_selector_match(sel, fl, family);
+
                if (match) {
-                       xfrm_pol_hold(pol);
-                       break;
+                       if (!security_xfrm_policy_lookup(pol, sk_sid, dir)) {
+                               xfrm_pol_hold(pol);
+                               break;
+                       }
                }
        }
        read_unlock_bh(&xfrm_policy_lock);
@@ -543,15 +549,37 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
                *obj_refp = &pol->refcnt;
 }
 
-static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl)
+static inline int policy_to_flow_dir(int dir)
+{
+       if (XFRM_POLICY_IN == FLOW_DIR_IN &&
+           XFRM_POLICY_OUT == FLOW_DIR_OUT &&
+           XFRM_POLICY_FWD == FLOW_DIR_FWD)
+               return dir;
+       switch (dir) {
+       default:
+       case XFRM_POLICY_IN:
+               return FLOW_DIR_IN;
+       case XFRM_POLICY_OUT:
+               return FLOW_DIR_OUT;
+       case XFRM_POLICY_FWD:
+               return FLOW_DIR_FWD;
+       };
+}
+
+static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl, u32 sk_sid)
 {
        struct xfrm_policy *pol;
 
        read_lock_bh(&xfrm_policy_lock);
        if ((pol = sk->sk_policy[dir]) != NULL) {
-               int match = xfrm_selector_match(&pol->selector, fl,
+               int match = xfrm_selector_match(&pol->selector, fl,
                                                sk->sk_family);
+               int err = 0;
+
                if (match)
+                 err = security_xfrm_policy_lookup(pol, sk_sid, policy_to_flow_dir(dir));
+
+               if (match && !err)
                        xfrm_pol_hold(pol);
                else
                        pol = NULL;
@@ -624,6 +652,10 @@ static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir)
 
        if (newp) {
                newp->selector = old->selector;
+               if (security_xfrm_policy_clone(old, newp)) {
+                       kfree(newp);
+                       return NULL;  /* ENOMEM */
+               }
                newp->lft = old->lft;
                newp->curlft = old->curlft;
                newp->action = old->action;
@@ -735,22 +767,6 @@ xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
        return err;
 }
 
-static inline int policy_to_flow_dir(int dir)
-{
-       if (XFRM_POLICY_IN == FLOW_DIR_IN &&
-           XFRM_POLICY_OUT == FLOW_DIR_OUT &&
-           XFRM_POLICY_FWD == FLOW_DIR_FWD)
-               return dir;
-       switch (dir) {
-       default:
-       case XFRM_POLICY_IN:
-               return FLOW_DIR_IN;
-       case XFRM_POLICY_OUT:
-               return FLOW_DIR_OUT;
-       case XFRM_POLICY_FWD:
-               return FLOW_DIR_FWD;
-       };
-}
 
 static int stale_bundle(struct dst_entry *dst);
 
@@ -769,19 +785,20 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
        int err;
        u32 genid;
        u16 family = dst_orig->ops->family;
+       u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
+       u32 sk_sid = security_sk_sid(sk, fl, dir);
 restart:
        genid = atomic_read(&flow_cache_genid);
        policy = NULL;
        if (sk && sk->sk_policy[1])
-               policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
+               policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, sk_sid);
 
        if (!policy) {
                /* To accelerate a bit...  */
                if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
                        return 0;
 
-               policy = flow_cache_lookup(fl, family,
-                                          policy_to_flow_dir(XFRM_POLICY_OUT),
+               policy = flow_cache_lookup(fl, sk_sid, family, dir,
                                           xfrm_policy_lookup);
        }
 
@@ -962,16 +979,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 {
        struct xfrm_policy *pol;
        struct flowi fl;
+       u8 fl_dir = policy_to_flow_dir(dir);
+       u32 sk_sid;
 
        if (_decode_session(skb, &fl, family) < 0)
                return 0;
 
+       sk_sid = security_sk_sid(sk, &fl, fl_dir);
+
        /* First, check used SA against their selectors. */
        if (skb->sp) {
                int i;
 
                for (i=skb->sp->len-1; i>=0; i--) {
-                 struct sec_decap_state *xvec = &(skb->sp->x[i]);
+                       struct sec_decap_state *xvec = &(skb->sp->x[i]);
                        if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family))
                                return 0;
 
@@ -986,11 +1007,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 
        pol = NULL;
        if (sk && sk->sk_policy[dir])
-               pol = xfrm_sk_policy_lookup(sk, dir, &fl);
+               pol = xfrm_sk_policy_lookup(sk, dir, &fl, sk_sid);
 
        if (!pol)
-               pol = flow_cache_lookup(&fl, family,
-                                       policy_to_flow_dir(dir),
+               pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir,
                                        xfrm_policy_lookup);
 
        if (!pol)
index 479effc..e12d0be 100644 (file)
@@ -10,7 +10,7 @@
  *             Split up af-specific functions
  *     Derek Atkins <derek@ihtfp.com>
  *             Add UDP Encapsulation
- *     
+ *
  */
 
 #include <linux/workqueue.h>
@@ -70,6 +70,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
                x->type->destructor(x);
                xfrm_put_type(x->type);
        }
+       security_xfrm_state_free(x);
        kfree(x);
 }
 
@@ -343,7 +344,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
                              selector.
                         */
                        if (x->km.state == XFRM_STATE_VALID) {
-                               if (!xfrm_selector_match(&x->sel, fl, family))
+                               if (!xfrm_selector_match(&x->sel, fl, family) ||
+                                   !xfrm_sec_ctx_match(pol->security, x->security))
                                        continue;
                                if (!best ||
                                    best->km.dying > x->km.dying ||
@@ -354,7 +356,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
                                acquire_in_progress = 1;
                        } else if (x->km.state == XFRM_STATE_ERROR ||
                                   x->km.state == XFRM_STATE_EXPIRED) {
-                               if (xfrm_selector_match(&x->sel, fl, family))
+                               if (xfrm_selector_match(&x->sel, fl, family) &&
+                                   xfrm_sec_ctx_match(pol->security, x->security))
                                        error = -ESRCH;
                        }
                }
index 0cdd9a0..92e2b80 100644 (file)
@@ -7,7 +7,7 @@
  *     Kazunori MIYAZAWA @USAGI
  *     Kunihiro Ishiguro <kunihiro@ipinfusion.com>
  *             IPv6 support
- *     
+ *
  */
 
 #include <linux/module.h>
@@ -88,6 +88,34 @@ static int verify_encap_tmpl(struct rtattr **xfrma)
        return 0;
 }
 
+
+static inline int verify_sec_ctx_len(struct rtattr **xfrma)
+{
+       struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
+       struct xfrm_user_sec_ctx *uctx;
+       int len = 0;
+
+       if (!rt)
+               return 0;
+
+       if (rt->rta_len < sizeof(*uctx))
+               return -EINVAL;
+
+       uctx = RTA_DATA(rt);
+
+       if (uctx->ctx_len > PAGE_SIZE)
+               return -EINVAL;
+
+       len += sizeof(struct xfrm_user_sec_ctx);
+       len += uctx->ctx_len;
+
+       if (uctx->len != len)
+               return -EINVAL;
+
+       return 0;
+}
+
+
 static int verify_newsa_info(struct xfrm_usersa_info *p,
                             struct rtattr **xfrma)
 {
@@ -145,6 +173,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
                goto out;
        if ((err = verify_encap_tmpl(xfrma)))
                goto out;
+       if ((err = verify_sec_ctx_len(xfrma)))
+               goto out;
 
        err = -EINVAL;
        switch (p->mode) {
@@ -209,6 +239,30 @@ static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_a
        return 0;
 }
 
+
+static inline int xfrm_user_sec_ctx_size(struct xfrm_policy *xp)
+{
+       struct xfrm_sec_ctx *xfrm_ctx = xp->security;
+       int len = 0;
+
+       if (xfrm_ctx) {
+               len += sizeof(struct xfrm_user_sec_ctx);
+               len += xfrm_ctx->ctx_len;
+       }
+       return len;
+}
+
+static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg)
+{
+       struct xfrm_user_sec_ctx *uctx;
+
+       if (!u_arg)
+               return 0;
+
+       uctx = RTA_DATA(u_arg);
+       return security_xfrm_state_alloc(x, uctx);
+}
+
 static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
 {
        memcpy(&x->id, &p->id, sizeof(x->id));
@@ -253,6 +307,9 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
        if (err)
                goto error;
 
+       if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX-1])))
+               goto error;
+
        x->km.seq = p->seq;
 
        return x;
@@ -272,11 +329,11 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
        int err;
        struct km_event c;
 
-       err = verify_newsa_info(p, (struct rtattr **) xfrma);
+       err = verify_newsa_info(p, (struct rtattr **)xfrma);
        if (err)
                return err;
 
-       x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err);
+       x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err);
        if (!x)
                return err;
 
@@ -390,6 +447,19 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
        if (x->encap)
                RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
 
+       if (x->security) {
+               int ctx_size = sizeof(struct xfrm_sec_ctx) +
+                               x->security->ctx_len;
+               struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
+               struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+               uctx->exttype = XFRMA_SEC_CTX;
+               uctx->len = ctx_size;
+               uctx->ctx_doi = x->security->ctx_doi;
+               uctx->ctx_alg = x->security->ctx_alg;
+               uctx->ctx_len = x->security->ctx_len;
+               memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
+       }
        nlh->nlmsg_len = skb->tail - b;
 out:
        sp->this_idx++;
@@ -603,6 +673,18 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
        return verify_policy_dir(p->dir);
 }
 
+static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma)
+{
+       struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
+       struct xfrm_user_sec_ctx *uctx;
+
+       if (!rt)
+               return 0;
+
+       uctx = RTA_DATA(rt);
+       return security_xfrm_policy_alloc(pol, uctx);
+}
+
 static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
                           int nr)
 {
@@ -681,7 +763,10 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
        }
 
        copy_from_user_policy(xp, p);
-       err = copy_from_user_tmpl(xp, xfrma);
+
+       if (!(err = copy_from_user_tmpl(xp, xfrma)))
+               err = copy_from_user_sec_ctx(xp, xfrma);
+
        if (err) {
                *errp = err;
                kfree(xp);
@@ -700,10 +785,13 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
        int excl;
 
        err = verify_newpolicy_info(p);
+       if (err)
+               return err;
+       err = verify_sec_ctx_len((struct rtattr **)xfrma);
        if (err)
                return err;
 
-       xp = xfrm_policy_construct(p, (struct rtattr **) xfrma, &err);
+       xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err);
        if (!xp)
                return err;
 
@@ -761,6 +849,27 @@ rtattr_failure:
        return -1;
 }
 
+static int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *skb)
+{
+       if (xp->security) {
+               int ctx_size = sizeof(struct xfrm_sec_ctx) +
+                               xp->security->ctx_len;
+               struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
+               struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+               uctx->exttype = XFRMA_SEC_CTX;
+               uctx->len = ctx_size;
+               uctx->ctx_doi = xp->security->ctx_doi;
+               uctx->ctx_alg = xp->security->ctx_alg;
+               uctx->ctx_len = xp->security->ctx_len;
+               memcpy(uctx + 1, xp->security->ctx_str, xp->security->ctx_len);
+       }
+       return 0;
+
+ rtattr_failure:
+       return -1;
+}
+
 static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
 {
        struct xfrm_dump_info *sp = ptr;
@@ -782,6 +891,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
        copy_to_user_policy(xp, p, dir);
        if (copy_to_user_tmpl(xp, skb) < 0)
                goto nlmsg_failure;
+       if (copy_to_user_sec_ctx(xp, skb))
+               goto nlmsg_failure;
 
        nlh->nlmsg_len = skb->tail - b;
 out:
@@ -852,8 +963,25 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
 
        if (p->index)
                xp = xfrm_policy_byid(p->dir, p->index, delete);
-       else
-               xp = xfrm_policy_bysel(p->dir, &p->sel, delete);
+       else {
+               struct rtattr **rtattrs = (struct rtattr **)xfrma;
+               struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
+               struct xfrm_policy tmp;
+
+               err = verify_sec_ctx_len(rtattrs);
+               if (err)
+                       return err;
+
+               memset(&tmp, 0, sizeof(struct xfrm_policy));
+               if (rt) {
+                       struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+                       if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
+                               return err;
+               }
+               xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
+               security_xfrm_policy_free(&tmp);
+       }
        if (xp == NULL)
                return -ENOENT;
 
@@ -1224,6 +1352,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
 
        if (copy_to_user_tmpl(xp, skb) < 0)
                goto nlmsg_failure;
+       if (copy_to_user_sec_ctx(xp, skb))
+               goto nlmsg_failure;
 
        nlh->nlmsg_len = skb->tail - b;
        return skb->len;
@@ -1241,6 +1371,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
 
        len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
        len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
+       len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
        skb = alloc_skb(len, GFP_ATOMIC);
        if (skb == NULL)
                return -ENOMEM;
@@ -1324,6 +1455,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
        copy_to_user_policy(xp, &upe->pol, dir);
        if (copy_to_user_tmpl(xp, skb) < 0)
                goto nlmsg_failure;
+       if (copy_to_user_sec_ctx(xp, skb))
+               goto nlmsg_failure;
        upe->hard = !!hard;
 
        nlh->nlmsg_len = skb->tail - b;
@@ -1341,6 +1474,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
 
        len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
        len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
+       len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
        skb = alloc_skb(len, GFP_ATOMIC);
        if (skb == NULL)
                return -ENOMEM;
index 64d3f1e..34f5934 100644 (file)
@@ -54,6 +54,19 @@ config SECURITY_NETWORK
          implement socket and networking access controls.
          If you are unsure how to answer this question, answer N.
 
+config SECURITY_NETWORK_XFRM
+       bool "XFRM (IPSec) Networking Security Hooks"
+       depends on XFRM && SECURITY_NETWORK
+       help
+         This enables the XFRM (IPSec) networking security hooks.
+         If enabled, a security module can use these hooks to
+         implement per-packet access controls based on labels
+         derived from IPSec policy.  Non-IPSec communications are
+         designated as unlabelled, and only sockets authorized
+         to communicate unlabelled data can send without using
+         IPSec.
+         If you are unsure how to answer this question, answer N.
+
 config SECURITY_CAPABILITIES
        tristate "Default Linux Capabilities"
        depends on SECURITY
index 3ca5f2b..a15c547 100644 (file)
@@ -776,8 +776,42 @@ static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t pr
 static inline void dummy_sk_free_security (struct sock *sk)
 {
 }
+
+static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+       return 0;
+}
 #endif /* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+       return 0;
+}
+
+static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+       return 0;
+}
+
+static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp)
+{
+}
+
+static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+       return 0;
+}
+
+static void dummy_xfrm_state_free_security(struct xfrm_state *x)
+{
+}
+
+static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+       return 0;
+}
+#endif /* CONFIG_SECURITY_NETWORK_XFRM */
 static int dummy_register_security (const char *name, struct security_operations *ops)
 {
        return -EINVAL;
@@ -970,7 +1004,16 @@ void security_fixup_ops (struct security_operations *ops)
        set_to_dummy_if_null(ops, socket_getpeersec);
        set_to_dummy_if_null(ops, sk_alloc_security);
        set_to_dummy_if_null(ops, sk_free_security);
-#endif /* CONFIG_SECURITY_NETWORK */
+       set_to_dummy_if_null(ops, sk_getsid);
+ #endif        /* CONFIG_SECURITY_NETWORK */
+#ifdef  CONFIG_SECURITY_NETWORK_XFRM
+       set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
+       set_to_dummy_if_null(ops, xfrm_policy_clone_security);
+       set_to_dummy_if_null(ops, xfrm_policy_free_security);
+       set_to_dummy_if_null(ops, xfrm_state_alloc_security);
+       set_to_dummy_if_null(ops, xfrm_state_free_security);
+       set_to_dummy_if_null(ops, xfrm_policy_lookup);
+#endif /* CONFIG_SECURITY_NETWORK_XFRM */
 #ifdef CONFIG_KEYS
        set_to_dummy_if_null(ops, key_alloc);
        set_to_dummy_if_null(ops, key_free);
index b038cd0..06d54d9 100644 (file)
@@ -8,5 +8,7 @@ selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o
 
 selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
 
+selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
+
 EXTRA_CFLAGS += -Isecurity/selinux/include
 
index fc77443..3d496ea 100644 (file)
@@ -73,6 +73,7 @@
 #include "avc.h"
 #include "objsec.h"
 #include "netif.h"
+#include "xfrm.h"
 
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
@@ -3349,6 +3350,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
                err = avc_has_perm(sock_sid, port_sid,
                                   sock_class, recv_perm, &ad);
        }
+
+       if (!err)
+               err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
+
 out:   
        return err;
 }
@@ -3401,6 +3406,24 @@ static void selinux_sk_free_security(struct sock *sk)
        sk_free_security(sk);
 }
 
+static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)
+{
+       struct inode_security_struct *isec;
+       u32 sock_sid = SECINITSID_ANY_SOCKET;
+
+       if (!sk)
+               return selinux_no_sk_sid(fl);
+
+       read_lock_bh(&sk->sk_callback_lock);
+       isec = get_sock_isec(sk);
+
+       if (isec)
+               sock_sid = isec->sid;
+
+       read_unlock_bh(&sk->sk_callback_lock);
+       return sock_sid;
+}
+
 static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
 {
        int err = 0;
@@ -3536,6 +3559,11 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
                                   send_perm, &ad) ? NF_DROP : NF_ACCEPT;
        }
 
+       if (err != NF_ACCEPT)
+               goto out;
+
+       err = selinux_xfrm_postroute_last(isec->sid, skb);
+
 out:
        return err;
 }
@@ -4380,6 +4408,16 @@ static struct security_operations selinux_ops = {
        .socket_getpeersec =            selinux_socket_getpeersec,
        .sk_alloc_security =            selinux_sk_alloc_security,
        .sk_free_security =             selinux_sk_free_security,
+       .sk_getsid =                    selinux_sk_getsid_security,
+#endif
+
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+       .xfrm_policy_alloc_security =   selinux_xfrm_policy_alloc,
+       .xfrm_policy_clone_security =   selinux_xfrm_policy_clone,
+       .xfrm_policy_free_security =    selinux_xfrm_policy_free,
+       .xfrm_state_alloc_security =    selinux_xfrm_state_alloc,
+       .xfrm_state_free_security =     selinux_xfrm_state_free,
+       .xfrm_policy_lookup =           selinux_xfrm_policy_lookup,
 #endif
 };
 
@@ -4491,6 +4529,7 @@ static int __init selinux_nf_ip_init(void)
                panic("SELinux: nf_register_hook for IPv6: error %d\n", err);
 
 #endif /* IPV6 */
+
 out:
        return err;
 }
index 1deb59e..71aeb12 100644 (file)
    S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
+   S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELFROM, "relabelfrom")
+   S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELTO, "relabelto")
index a78b5d5..d1d0996 100644 (file)
 
 #define ASSOCIATION__SENDTO                       0x00000001UL
 #define ASSOCIATION__RECVFROM                     0x00000002UL
+#define ASSOCIATION__RELABELFROM                  0x00000004UL
+#define ASSOCIATION__RELABELTO                    0x00000008UL
 
 #define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL      0x00000001UL
 #define NETLINK_KOBJECT_UEVENT_SOCKET__READ       0x00000002UL
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
new file mode 100644 (file)
index 0000000..8e87996
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * SELinux support for the XFRM LSM hooks
+ *
+ * Author : Trent Jaeger, <jaegert@us.ibm.com>
+ */
+#ifndef _SELINUX_XFRM_H_
+#define _SELINUX_XFRM_H_
+
+int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
+int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
+void selinux_xfrm_policy_free(struct xfrm_policy *xp);
+int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
+void selinux_xfrm_state_free(struct xfrm_state *x);
+int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
+
+/*
+ * Extract the security blob from the sock (it's actually on the socket)
+ */
+static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
+{
+       if (!sk->sk_socket)
+               return NULL;
+
+       return SOCK_INODE(sk->sk_socket)->i_security;
+}
+
+
+static inline u32 selinux_no_sk_sid(struct flowi *fl)
+{
+       /* NOTE: no sock occurs on ICMP reply, forwards, ... */
+       /* icmp_reply: authorize as kernel packet */
+       if (fl && fl->proto == IPPROTO_ICMP) {
+               return SECINITSID_KERNEL;
+       }
+
+       return SECINITSID_ANY_SOCKET;
+}
+
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb);
+int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb);
+#else
+static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
+{
+       return 0;
+}
+
+static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
+{
+       return NF_ACCEPT;
+}
+#endif
+
+#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
new file mode 100644 (file)
index 0000000..c4d87d4
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ *  NSA Security-Enhanced Linux (SELinux) security module
+ *
+ *  This file contains the SELinux XFRM hook function implementations.
+ *
+ *  Authors:  Serge Hallyn <sergeh@us.ibm.com>
+ *           Trent Jaeger <jaegert@us.ibm.com>
+ *
+ *  Copyright (C) 2005 International Business Machines Corporation
+ *
+ *     This program is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License version 2,
+ *     as published by the Free Software Foundation.
+ */
+
+/*
+ * USAGE:
+ * NOTES:
+ *   1. Make sure to enable the following options in your kernel config:
+ *     CONFIG_SECURITY=y
+ *     CONFIG_SECURITY_NETWORK=y
+ *     CONFIG_SECURITY_NETWORK_XFRM=y
+ *     CONFIG_SECURITY_SELINUX=m/y
+ * ISSUES:
+ *   1. Caching packets, so they are not dropped during negotiation
+ *   2. Emulating a reasonable SO_PEERSEC across machines
+ *   3. Testing addition of sk_policy's with security context via setsockopt
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/security.h>
+#include <linux/types.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/xfrm.h>
+#include <net/xfrm.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+#include <asm/semaphore.h>
+
+#include "avc.h"
+#include "objsec.h"
+#include "xfrm.h"
+
+
+/*
+ * Returns true if an LSM/SELinux context
+ */
+static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
+{
+       return (ctx &&
+               (ctx->ctx_doi == XFRM_SC_DOI_LSM) &&
+               (ctx->ctx_alg == XFRM_SC_ALG_SELINUX));
+}
+
+/*
+ * Returns true if the xfrm contains a security blob for SELinux
+ */
+static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
+{
+       return selinux_authorizable_ctx(x->security);
+}
+
+/*
+ * LSM hook implementation that authorizes that a socket can be used
+ * with the corresponding xfrm_sec_ctx and direction.
+ */
+int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+       int rc = 0;
+       u32 sel_sid = SECINITSID_UNLABELED;
+       struct xfrm_sec_ctx *ctx;
+
+       /* Context sid is either set to label or ANY_ASSOC */
+       if ((ctx = xp->security)) {
+               if (!selinux_authorizable_ctx(ctx))
+                       return -EINVAL;
+
+               sel_sid = ctx->ctx_sid;
+       }
+
+       rc = avc_has_perm(sk_sid, sel_sid, SECCLASS_ASSOCIATION,
+                         ((dir == FLOW_DIR_IN) ? ASSOCIATION__RECVFROM :
+                          ((dir == FLOW_DIR_OUT) ?  ASSOCIATION__SENDTO :
+                           (ASSOCIATION__SENDTO | ASSOCIATION__RECVFROM))),
+                         NULL);
+
+       return rc;
+}
+
+/*
+ * Security blob allocation for xfrm_policy and xfrm_state
+ * CTX does not have a meaningful value on input
+ */
+static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx)
+{
+       int rc = 0;
+       struct task_security_struct *tsec = current->security;
+       struct xfrm_sec_ctx *ctx;
+
+       BUG_ON(!uctx);
+       BUG_ON(uctx->ctx_doi != XFRM_SC_ALG_SELINUX);
+
+       if (uctx->ctx_len >= PAGE_SIZE)
+               return -ENOMEM;
+
+       *ctxp = ctx = kmalloc(sizeof(*ctx) +
+                             uctx->ctx_len,
+                             GFP_KERNEL);
+
+       if (!ctx)
+               return -ENOMEM;
+
+       ctx->ctx_doi = uctx->ctx_doi;
+       ctx->ctx_len = uctx->ctx_len;
+       ctx->ctx_alg = uctx->ctx_alg;
+
+       memcpy(ctx->ctx_str,
+              uctx+1,
+              ctx->ctx_len);
+       rc = security_context_to_sid(ctx->ctx_str,
+                                    ctx->ctx_len,
+                                    &ctx->ctx_sid);
+
+       if (rc)
+               goto out;
+
+       /*
+        * Does the subject have permission to set security or permission to
+        * do the relabel?
+        * Must be permitted to relabel from default socket type (process type)
+        * to specified context
+        */
+       rc = avc_has_perm(tsec->sid, tsec->sid,
+                         SECCLASS_ASSOCIATION,
+                         ASSOCIATION__RELABELFROM, NULL);
+       if (rc)
+               goto out;
+
+       rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+                         SECCLASS_ASSOCIATION,
+                         ASSOCIATION__RELABELTO, NULL);
+       if (rc)
+               goto out;
+
+       return rc;
+
+out:
+       *ctxp = 0;
+       kfree(ctx);
+       return rc;
+}
+
+/*
+ * LSM hook implementation that allocs and transfers uctx spec to
+ * xfrm_policy.
+ */
+int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx)
+{
+       int err;
+
+       BUG_ON(!xp);
+
+       err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx);
+       return err;
+}
+
+
+/*
+ * LSM hook implementation that copies security data structure from old to
+ * new for policy cloning.
+ */
+int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+       struct xfrm_sec_ctx *old_ctx, *new_ctx;
+
+       old_ctx = old->security;
+
+       if (old_ctx) {
+               new_ctx = new->security = kmalloc(sizeof(*new_ctx) +
+                                                 old_ctx->ctx_len,
+                                                 GFP_KERNEL);
+
+               if (!new_ctx)
+                       return -ENOMEM;
+
+               memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
+               memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
+       }
+       return 0;
+}
+
+/*
+ * LSM hook implementation that frees xfrm_policy security information.
+ */
+void selinux_xfrm_policy_free(struct xfrm_policy *xp)
+{
+       struct xfrm_sec_ctx *ctx = xp->security;
+       if (ctx)
+               kfree(ctx);
+}
+
+/*
+ * LSM hook implementation that allocs and transfers sec_ctx spec to
+ * xfrm_state.
+ */
+int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx)
+{
+       int err;
+
+       BUG_ON(!x);
+
+       err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx);
+       return err;
+}
+
+/*
+ * LSM hook implementation that frees xfrm_state security information.
+ */
+void selinux_xfrm_state_free(struct xfrm_state *x)
+{
+       struct xfrm_sec_ctx *ctx = x->security;
+       if (ctx)
+               kfree(ctx);
+}
+
+/*
+ * LSM hook that controls access to unlabelled packets.  If
+ * a xfrm_state is authorizable (defined by macro) then it was
+ * already authorized by the IPSec process.  If not, then
+ * we need to check for unlabelled access since this may not have
+ * gone thru the IPSec process.
+ */
+int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
+{
+       int i, rc = 0;
+       struct sec_path *sp;
+
+       sp = skb->sp;
+
+       if (sp) {
+               /*
+                * __xfrm_policy_check does not approve unless xfrm_policy_ok
+                * says that spi's match for policy and the socket.
+                *
+                *  Only need to verify the existence of an authorizable sp.
+                */
+               for (i = 0; i < sp->len; i++) {
+                       struct xfrm_state *x = sp->x[i].xvec;
+
+                       if (x && selinux_authorizable_xfrm(x))
+                               goto accept;
+               }
+       }
+
+       /* check SELinux sock for unlabelled access */
+       rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
+                         ASSOCIATION__RECVFROM, NULL);
+       if (rc)
+               goto drop;
+
+accept:
+       return 0;
+
+drop:
+       return rc;
+}
+
+/*
+ * POSTROUTE_LAST hook's XFRM processing:
+ * If we have no security association, then we need to determine
+ * whether the socket is allowed to send to an unlabelled destination.
+ * If we do have a authorizable security association, then it has already been
+ * checked in xfrm_policy_lookup hook.
+ */
+int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
+{
+       struct dst_entry *dst;
+       int rc = 0;
+
+       dst = skb->dst;
+
+       if (dst) {
+               struct dst_entry *dst_test;
+
+               for (dst_test = dst; dst_test != 0;
+                    dst_test = dst_test->child) {
+                       struct xfrm_state *x = dst_test->xfrm;
+
+                       if (x && selinux_authorizable_xfrm(x))
+                               goto accept;
+               }
+       }
+
+       rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
+                         ASSOCIATION__SENDTO, NULL);
+       if (rc)
+               goto drop;
+
+accept:
+       return NF_ACCEPT;
+
+drop:
+       return NF_DROP;
+}
index 99dae02..22f8bb6 100644 (file)
@@ -1996,7 +1996,6 @@ static struct usb_device_id usb_audio_ids [] = {
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
-       .owner =        THIS_MODULE,
        .name =         "snd-usb-audio",
        .probe =        usb_audio_probe,
        .disconnect =   usb_audio_disconnect,
index cf77313..a3967f7 100644 (file)
@@ -409,7 +409,6 @@ static void snd_usX2Y_disconnect(struct usb_interface *intf)
 
 MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);
 static struct usb_driver snd_usX2Y_usb_driver = {
-       .owner =        THIS_MODULE,
        .name =         "snd-usb-usx2y",
        .probe =        snd_usX2Y_probe,
        .disconnect =   snd_usX2Y_disconnect,