]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 5 Jan 2006 00:38:36 +0000 (16:38 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 5 Jan 2006 00:38:36 +0000 (16:38 -0800)
743 files changed:
.gitignore
Documentation/DocBook/usb.tmpl
Documentation/SubmittingPatches
Documentation/block/biodoc.txt
Documentation/cpu-freq/governors.txt
Documentation/filesystems/00-INDEX
Documentation/filesystems/vfs.txt
Documentation/kbuild/modules.txt
Documentation/kernel-parameters.txt
Documentation/networking/gianfar.txt [new file with mode: 0644]
Documentation/networking/ip-sysctl.txt
Documentation/scsi/ChangeLog.megaraid
Documentation/scsi/scsi_mid_low_api.txt
Documentation/sysrq.txt
MAINTAINERS
Makefile
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/pxa27x.c
arch/arm26/nwfpe/fpmodule.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/boot/.gitignore [new file with mode: 0644]
arch/x86_64/boot/tools/.gitignore [new file with mode: 0644]
arch/x86_64/ia32/.gitignore [new file with mode: 0644]
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/.gitignore
drivers/char/ip2/i2pack.h
drivers/char/n_hdlc.c
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/ieee1394/.gitignore [new file with mode: 0644]
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/.gitignore [new file with mode: 0644]
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/8139too.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/bonding/Makefile
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.h
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_alb.h
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c [new file with mode: 0644]
drivers/net/bonding/bonding.h
drivers/net/chelsio/sge.c
drivers/net/chelsio/sge.h
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_ethtool.c
drivers/net/gianfar_mii.h
drivers/net/gianfar_sysfs.c [new file with mode: 0644]
drivers/net/irda/irda-usb.c
drivers/net/irda/stir4200.c
drivers/net/ixp2000/Kconfig [new file with mode: 0644]
drivers/net/ixp2000/Makefile [new file with mode: 0644]
drivers/net/ixp2000/caleb.c [new file with mode: 0644]
drivers/net/ixp2000/caleb.h [new file with mode: 0644]
drivers/net/ixp2000/enp2611.c [new file with mode: 0644]
drivers/net/ixp2000/ixp2400-msf.c [new file with mode: 0644]
drivers/net/ixp2000/ixp2400-msf.h [new file with mode: 0644]
drivers/net/ixp2000/ixp2400_rx.uc [new file with mode: 0644]
drivers/net/ixp2000/ixp2400_rx.ucode [new file with mode: 0644]
drivers/net/ixp2000/ixp2400_tx.uc [new file with mode: 0644]
drivers/net/ixp2000/ixp2400_tx.ucode [new file with mode: 0644]
drivers/net/ixp2000/ixpdev.c [new file with mode: 0644]
drivers/net/ixp2000/ixpdev.h [new file with mode: 0644]
drivers/net/ixp2000/ixpdev_priv.h [new file with mode: 0644]
drivers/net/ixp2000/pm3386.c [new file with mode: 0644]
drivers/net/ixp2000/pm3386.h [new file with mode: 0644]
drivers/net/ns83820.c
drivers/net/pppoe.c
drivers/net/pppox.c
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/sis900.c
drivers/net/sis900.h
drivers/net/sk98lin/Makefile
drivers/net/sk98lin/h/skdrv2nd.h
drivers/net/sk98lin/h/skvpd.h
drivers/net/sk98lin/skethtool.c
drivers/net/sk98lin/skge.c
drivers/net/sk98lin/skproc.c [deleted file]
drivers/net/skge.c
drivers/net/skge.h
drivers/net/sky2.c [new file with mode: 0644]
drivers/net/sky2.h [new file with mode: 0644]
drivers/net/tg3.c
drivers/net/tlan.c
drivers/net/wan/.gitignore [new file with mode: 0644]
drivers/net/wan/lmc/lmc_prot.h [deleted file]
drivers/net/wireless/Kconfig
drivers/net/wireless/airo.c
drivers/net/wireless/atmel.c
drivers/net/wireless/hostap/Makefile
drivers/net/wireless/hostap/hostap_main.c [moved from drivers/net/wireless/hostap/hostap.c with 100% similarity]
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2100.h
drivers/net/wireless/ipw2200.c
drivers/net/wireless/ipw2200.h
drivers/pci/quirks.c
drivers/scsi/.gitignore [new file with mode: 0644]
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/ahci.c
drivers/scsi/aic7xxx/.gitignore [new file with mode: 0644]
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/arm/Kconfig
drivers/scsi/arm/acornscsi.c
drivers/scsi/ata_piix.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/libata-core.c
drivers/scsi/libata-scsi.c
drivers/scsi/libata.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/pdc_adma.c
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/sata_mv.c
drivers/scsi/sata_promise.c
drivers/scsi/sata_qstor.c
drivers/scsi/sata_sil.c
drivers/scsi/sata_sil24.c
drivers/scsi/sata_sx4.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/video/aty/radeon_base.c
drivers/w1/dscore.c
fs/9p/trans_sock.c
fs/bio.c
fs/compat.c
fs/nfs/callback.c
fs/ntfs/ChangeLog
fs/qnx4/bitmap.c
fs/read_write.c
fs/reiserfs/xattr.c
fs/udf/balloc.c
fs/udf/crc.c
fs/udf/dir.c
fs/udf/directory.c
fs/udf/file.c
fs/udf/fsync.c
fs/udf/ialloc.c
fs/udf/inode.c
fs/udf/lowlevel.c
fs/udf/misc.c
fs/udf/namei.c
fs/udf/partition.c
fs/udf/super.c
fs/udf/symlink.c
fs/udf/truncate.c
fs/udf/unicode.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/.gitignore [deleted file]
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/libata.h
include/linux/net.h
include/linux/netdevice.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/spinlock.h
include/linux/sysctl.h
include/linux/tcp.h
include/linux/udf_fs.h
include/linux/udf_fs_i.h
include/linux/udf_fs_sb.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/Kconfig
init/main.c
kernel/.gitignore [new file with mode: 0644]
kernel/configs.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/core/utils.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/irda/iriap.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
scripts/.gitignore
scripts/Makefile
scripts/Makefile.lib
scripts/basic/fixdep.c
scripts/binoffset.c
scripts/checkversion.pl
scripts/genksyms/.gitignore [new file with mode: 0644]
scripts/genksyms/keywords.c_shipped
scripts/genksyms/lex.c_shipped
scripts/genksyms/parse.c_shipped
scripts/genksyms/parse.h_shipped
scripts/genksyms/parse.y
scripts/kconfig/.gitignore
scripts/kconfig/Makefile
scripts/kconfig/lxdialog/.gitignore [new file with mode: 0644]
scripts/kconfig/lxdialog/BIG.FAT.WARNING [moved from scripts/lxdialog/BIG.FAT.WARNING with 100% similarity]
scripts/kconfig/lxdialog/Makefile [moved from scripts/lxdialog/Makefile with 100% similarity]
scripts/kconfig/lxdialog/checklist.c [new file with mode: 0644]
scripts/kconfig/lxdialog/colors.h [moved from scripts/lxdialog/colors.h with 99% similarity]
scripts/kconfig/lxdialog/dialog.h [moved from scripts/lxdialog/dialog.h with 75% similarity]
scripts/kconfig/lxdialog/inputbox.c [new file with mode: 0644]
scripts/kconfig/lxdialog/lxdialog.c [new file with mode: 0644]
scripts/kconfig/lxdialog/menubox.c [new file with mode: 0644]
scripts/kconfig/lxdialog/msgbox.c [new file with mode: 0644]
scripts/kconfig/lxdialog/textbox.c [new file with mode: 0644]
scripts/kconfig/lxdialog/util.c [new file with mode: 0644]
scripts/kconfig/lxdialog/yesno.c [new file with mode: 0644]
scripts/kconfig/mconf.c
scripts/kconfig/util.c
scripts/lxdialog/checklist.c [deleted file]
scripts/lxdialog/inputbox.c [deleted file]
scripts/lxdialog/lxdialog.c [deleted file]
scripts/lxdialog/menubox.c [deleted file]
scripts/lxdialog/msgbox.c [deleted file]
scripts/lxdialog/textbox.c [deleted file]
scripts/lxdialog/util.c [deleted file]
scripts/lxdialog/yesno.c [deleted file]
scripts/mod/modpost.c
scripts/package/Makefile
scripts/package/buildtar
scripts/patch-kernel
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 5014bfa48ac169e0748e1e9651897788feb306dc..a4b576eb9c00311392c203755663f9f4a29e8477 100644 (file)
@@ -23,6 +23,7 @@ Module.symvers
 # Generated include files
 #
 include/asm
+include/asm-*/asm-offsets.h
 include/config
 include/linux/autoconf.h
 include/linux/compile.h
index 15ce0f21e5e0c04c28e095941a21606192d8404b..320af25de3a276fd5b77aa830b08549c2c523793 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 237d54c44bc5ee504dc57f8d5f65edc389081e04..1d47e6c09dc60c7a1c2330c09b458b5af0871852 100644 (file)
@@ -158,7 +158,7 @@ Even if the maintainer did not respond in step #4, make sure to ALWAYS
 copy the maintainer when you change their code.
 
 For small patches you may want to CC the Trivial Patch Monkey
-trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial"
+trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
 patches. Trivial patches must qualify for one of the following rules:
  Spelling fixes in documentation
  Spelling fixes which could break grep(1).
@@ -171,7 +171,7 @@ patches. Trivial patches must qualify for one of the following rules:
  since people copy, as long as it's trivial)
  Any fix by the author/maintainer of the file. (ie. patch monkey
  in re-transmission mode)
-URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/>
+URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>
 
 
 
index 0fe01c805480563f8544fe157ccd8064cfe2f07a..303c57a7fad95216fe6cecff723cd15cf5574d0b 100644 (file)
@@ -31,7 +31,7 @@ The following people helped with review comments and inputs for this
 document:
        Christoph Hellwig <hch@infradead.org>
        Arjan van de Ven <arjanv@redhat.com>
-       Randy Dunlap <rddunlap@osdl.org>
+       Randy Dunlap <rdunlap@xenotime.net>
        Andre Hedrick <andre@linux-ide.org>
 
 The following people helped with fixes/contributions to the bio patches
index 933fae74c3379cba1fd7d066a2ab7f6daead76a3..f4b8dc4237e6a83b6f0cf44cfc3861f924baec10 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 bcfbab899b370509175af4e9bca4f0cb68624324..7e17712f32290182f34e7a2df4db431ab4f54a5d 100644 (file)
@@ -18,8 +18,6 @@ devfs/
        - directory containing devfs documentation.
 ext2.txt
        - info, mount options and specifications for the Ext2 filesystem.
-fat_cvf.txt
-       - info on the Compressed Volume Files extension to the FAT filesystem
 hpfs.txt
        - info and mount options for the OS/2 HPFS.
 isofs.txt
index ee4c0a8b8db7a663169fd97c57ce472a1a790398..e56e842847d3ee3e48c79b4099bc0d6040d730a1 100644 (file)
@@ -162,9 +162,8 @@ get_sb() method fills in is the "s_op" field. This is a pointer to
 a "struct super_operations" which describes the next level of the
 filesystem implementation.
 
-Usually, a filesystem uses generic one of the generic get_sb()
-implementations and provides a fill_super() method instead. The
-generic methods are:
+Usually, a filesystem uses one of the generic get_sb() implementations
+and provides a fill_super() method instead. The generic methods are:
 
   get_sb_bdev: mount a filesystem residing on a block device
 
index c91caf7eb3036624e88d5e6c37fefb7aaf95f167..1c0db652b3661f01d36d8dffa53d9947e1e5c55b 100644 (file)
@@ -38,7 +38,7 @@ included in the kernel tree.
 What is covered within this file is mainly information to authors
 of modules. The author of an external modules should supply
 a makefile that hides most of the complexity so one only has to type
-'make' to buld the module. A complete example will be present in
+'make' to build the module. A complete example will be present in
 chapter Â¤. Creating a kbuild file for an external module".
 
 
@@ -69,7 +69,7 @@ when building an external module.
 
 --- 2.2 Available targets
 
-       $KDIR refers to path to kernel source top-level directory
+       $KDIR refers to the path to the kernel source top-level directory
 
        make -C $KDIR M=`pwd`
                Will build the module(s) located in current directory.
@@ -87,11 +87,11 @@ when building an external module.
        make -C $KDIR M=$PWD modules_install
                Install the external module(s).
                Installation default is in /lib/modules/<kernel-version>/extra,
-               but may be prefixed with INSTALL_MOD_PATH - see separate chater.
+               but may be prefixed with INSTALL_MOD_PATH - see separate chapter.
 
        make -C $KDIR M=$PWD clean
                Remove all generated files for the module - the kernel
-               source directory is not moddified.
+               source directory is not modified.
 
        make -C $KDIR M=`pwd` help
                help will list the available target when building external
@@ -99,7 +99,7 @@ when building an external module.
 
 --- 2.3 Available options:
 
-       $KDIR refer to path to kernel src
+       $KDIR refers to the path to the kernel source top-level directory
 
        make -C $KDIR
                Used to specify where to find the kernel source.
@@ -206,11 +206,11 @@ following files:
 
                KERNELDIR := /lib/modules/`uname -r`/build
                all::
-                       $(MAKE) -C $KERNELDIR M=`pwd` $@
+                       $(MAKE) -C $(KERNELDIR) M=`pwd` $@
 
                # Module specific targets
                genbin:
-                       echo "X" > 8123_bini.o_shipped
+                       echo "X" > 8123_bin.o_shipped
 
                endif
 
@@ -341,13 +341,13 @@ directory and therefore needs to deal with this in their kbuild file.
                EXTRA_CFLAGS := -Iinclude
                8123-y := 8123_if.o 8123_pci.o 8123_bin.o
 
-       Note that in the assingment there is no space between -I and the path.
-       This is a kbuild limitation and no space must be present.
+       Note that in the assignment there is no space between -I and the path.
+       This is a kbuild limitation:  there must be no space present.
 
 
 === 6. Module installation
 
-Modules which are included in the kernel is installed in the directory:
+Modules which are included in the kernel are installed in the directory:
 
        /lib/modules/$(KERNELRELEASE)/kernel
 
@@ -365,7 +365,7 @@ External modules are installed in the directory:
                => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
 
        INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
-       example above be specified on the commandline when calling make.
+       example above be specified on the command line when calling make.
        INSTALL_MOD_PATH has effect both when installing modules included in
        the kernel as well as when installing external modules.
 
@@ -384,7 +384,7 @@ External modules are installed in the directory:
 
 === 7. Module versioning
 
-Module versioning are enabled by the CONFIG_MODVERSIONS tag.
+Module versioning is enabled by the CONFIG_MODVERSIONS tag.
 
 Module versioning is used as a simple ABI consistency check. The Module
 versioning creates a CRC value of the full prototype for an exported symbol and
index 5dffcfefc3c715698eca24b519df8eab6d8a799d..61a56b100c62d287e05ec52c42636c6345159f14 100644 (file)
@@ -633,6 +633,14 @@ running once the system is up.
        inport.irq=     [HW] Inport (ATI XL and Microsoft) busmouse driver
                        Format: <irq>
 
+       combined_mode=  [HW] control which driver uses IDE ports in combined
+                       mode: legacy IDE driver, libata, or both
+                       (in the libata case, libata.atapi_enabled=1 may be
+                       useful as well).  Note that using the ide or libata
+                       options may affect your device naming (e.g. by
+                       changing hdc to sdb).
+                       Format: combined (default), ide, or libata
+
        inttest=        [IA64]
 
        io7=            [HW] IO7 for Marvel based alpha systems
diff --git a/Documentation/networking/gianfar.txt b/Documentation/networking/gianfar.txt
new file mode 100644 (file)
index 0000000..ad474ea
--- /dev/null
@@ -0,0 +1,72 @@
+The Gianfar Ethernet Driver
+Sysfs File description
+
+Author: Andy Fleming <afleming@freescale.com>
+Updated: 2005-07-28
+
+SYSFS
+
+Several of the features of the gianfar driver are controlled
+through sysfs files.  These are:
+
+bd_stash:
+To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
+bd_stash, echo 'off' or '0' to disable
+
+rx_stash_len:
+To stash the first n bytes of the packet in L2, echo the number
+of bytes to buf_stash_len.  echo 0 to disable.
+
+WARNING: You could really screw these up if you set them too low or high!
+fifo_threshold:
+To change the number of bytes the controller needs in the
+fifo before it starts transmission, echo the number of bytes to 
+fifo_thresh.  Range should be 0-511.
+
+fifo_starve:
+When the FIFO has less than this many bytes during a transmit, it
+enters starve mode, and increases the priority of TX memory
+transactions.  To change, echo the number of bytes to
+fifo_starve.  Range should be 0-511.
+
+fifo_starve_off:
+Once in starve mode, the FIFO remains there until it has this
+many bytes.  To change, echo the number of bytes to
+fifo_starve_off.  Range should be 0-511.
+
+CHECKSUM OFFLOADING
+
+The eTSEC controller (first included in parts from late 2005 like
+the 8548) has the ability to perform TCP, UDP, and IP checksums
+in hardware.  The Linux kernel only offloads the TCP and UDP
+checksums (and always performs the pseudo header checksums), so
+the driver only supports checksumming for TCP/IP and UDP/IP
+packets.  Use ethtool to enable or disable this feature for RX
+and TX.
+
+VLAN
+
+In order to use VLAN, please consult Linux documentation on
+configuring VLANs.  The gianfar driver supports hardware insertion and
+extraction of VLAN headers, but not filtering.  Filtering will be
+done by the kernel.
+
+MULTICASTING
+
+The gianfar driver supports using the group hash table on the
+TSEC (and the extended hash table on the eTSEC) for multicast
+filtering.  On the eTSEC, the exact-match MAC registers are used
+before the hash tables.  See Linux documentation on how to join
+multicast groups.
+
+PADDING
+
+The gianfar driver supports padding received frames with 2 bytes
+to align the IP header to a 16-byte boundary, when supported by
+hardware.
+
+ETHTOOL
+
+The gianfar driver supports the use of ethtool for many
+configuration options.  You must run ethtool only on currently
+open interfaces.  See ethtool documentation for details.
index ebc09a159f6220d995ab39c3bbff812291f4659d..2b7cf19a06adc03435b84a04ae1dee46aae7e9a1 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 5331d91432c76cb7d598165ee89db51236f27e75..09f6300eda4bef7262c5955abbe9e0bc5b41f905 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 66565d42288fc446ad08930b8839a7285dee37e6..8bbae3e1abdfa1c1a35f9c00f4b118cae9afdbf2 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
@@ -1433,7 +1452,7 @@ The following people have contributed to this document:
         Christoph Hellwig <hch at infradead dot org>
         Doug Ledford <dledford at redhat dot com>
         Andries Brouwer <Andries dot Brouwer at cwi dot nl>
-        Randy Dunlap <rddunlap at osdl dot org>
+        Randy Dunlap <rdunlap at xenotime dot net>
         Alan Stern <stern at rowland dot harvard dot edu>
 
 
index baf17b381588d0899512b0e65b29adda91aa49bc..ad0bedf678b39cbddfb00d23523f4a3e02a851df 100644 (file)
@@ -202,17 +202,13 @@ you must call __handle_sysrq_nolock instead.
 
 *  I have more questions, who can I ask?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-You may feel free to send email to myrdraal@deathsdoor.com, and I will
-respond as soon as possible.
- -Myrdraal
-
 And I'll answer any questions about the registration system you got, also
 responding as soon as possible.
  -Crutcher
 
 *  Credits
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Written by Mydraal <myrdraal@deathsdoor.com>
+Written by Mydraal <vulpyne@vulpyne.net>
 Updated by Adam Sulmicki <adam@cfar.umd.edu>
 Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
 Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>
index 93f97b3afac501e144e89389ee1e7d38e1fe0324..1e59d39660128571019911431840acb2c06dd757 100644 (file)
@@ -1470,7 +1470,6 @@ P:        Several
 L:     kernel-janitors@osdl.org
 W:     http://www.kerneljanitors.org/
 W:     http://sf.net/projects/kernel-janitor/
-W:     http://developer.osdl.org/rddunlap/kj-patches/
 S:     Maintained
 
 KERNEL NFSD
@@ -1491,7 +1490,7 @@ KEXEC
 P:     Eric Biederman
 P:     Randy Dunlap
 M:     ebiederm@xmission.com
-M:     rddunlap@osdl.org
+M:     rdunlap@xenotime.net
 W:     http://www.xmission.com/~ebiederm/files/kexec/
 L:     linux-kernel@vger.kernel.org
 L:     fastboot@osdl.org
@@ -2592,7 +2591,6 @@ S:        Maintained
 UDF FILESYSTEM
 P:     Ben Fennema
 M:     bfennema@falcon.csc.calpoly.edu
-L:     linux_udf@hpesjro.fc.hp.com
 W:     http://linux-udf.sourceforge.net
 S:     Maintained
 
@@ -2645,6 +2643,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
@@ -2656,7 +2660,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 497884d3d556d93961b440da31dca97de4dc1dd9..599e744d3e33d0156e3060cb8c05b76f294d7166 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -286,10 +286,6 @@ export quiet Q KBUILD_VERBOSE
 cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
              > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
 
-# For backward compatibility
-check_gcc = $(warning check_gcc is deprecated - use cc-option) \
-            $(call cc-option, $(1),$(2))
-
 # cc-option-yn
 # Usage: flag := $(call cc-option-yn, -march=winchip-c6)
 cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
@@ -481,18 +477,20 @@ ifeq ($(dot-config),1)
 
 # Read in dependencies to all Kconfig* files, make sure to run
 # oldconfig if changes are detected.
--include .config.cmd
+-include .kconfig.d
 
 include .config
 
 # If .config needs to be updated, it will be done via the dependency
 # that autoconf has on .config.
 # To avoid any implicit rule to kick in, define an empty command
-.config: ;
+.config .kconfig.d: ;
 
 # If .config is newer than include/linux/autoconf.h, someone tinkered
-# with it and forgot to run make oldconfig
-include/linux/autoconf.h: .config
+# with it and forgot to run make oldconfig.
+# If kconfig.d is missing then we are probarly in a cleaned tree so
+# we execute the config step to be sure to catch updated Kconfig files
+include/linux/autoconf.h: .kconfig.d .config
        $(Q)mkdir -p include/linux
        $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
 else
@@ -1066,7 +1064,7 @@ help:
        @echo  '  all             - Build all targets marked with [*]'
        @echo  '* vmlinux         - Build the bare kernel'
        @echo  '* modules         - Build all modules'
-       @echo  '  modules_install - Install all modules'
+       @echo  '  modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
        @echo  '  dir/            - Build all files in dir and below'
        @echo  '  dir/file.[ois]  - Build specified target only'
        @echo  '  dir/file.ko     - Build module including final link'
@@ -1240,8 +1238,11 @@ cscope: FORCE
 quiet_cmd_TAGS = MAKE   $@
 define cmd_TAGS
        rm -f $@; \
-       ETAGSF=`etags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
-       $(all-sources) | xargs etags $$ETAGSF -a
+       ETAGSF=`etags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs etags $$ETAGSF -a
 endef
 
 TAGS: FORCE
@@ -1251,8 +1252,11 @@ TAGS: FORCE
 quiet_cmd_tags = MAKE   $@
 define cmd_tags
        rm -f $@; \
-       CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
-       $(all-sources) | xargs ctags $$CTAGSF -a
+       CTAGSF=`ctags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs ctags $$CTAGSF -a
 endef
 
 tags: FORCE
index 07892f4012d8a2cd5d2bbddddc9ab203d78207f0..277498ae5b6c12d4911564ee4d4d999853c9c283 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 c722a9a91fcce243b9fce9a77f2c15f3e50b939a..b41b1efaa2cf9088e30fe8fe9ee1d4dda6fd46c7 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 528fa710aa3464cd6bc6ba1f11f9ea36f70bb836..5258c6096fb9b5551da66d1fe5f3b43b07636e12 100644 (file)
@@ -46,10 +46,9 @@ typedef struct task_struct*  PTASK;
 
 #ifdef MODULE
 void fp_send_sig(unsigned long sig, PTASK p, int priv);
-#if LINUX_VERSION_CODE > 0x20115
+
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
 MODULE_DESCRIPTION("NWFPE floating point emulator");
-#endif
 
 #else
 #define fp_send_sig    send_sig
index 04a405345203424388d15b050310642b723f00aa..2b62dee35c6c83299105b46ffc5e00b8969b3c5d 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 68a1fc87f4cabb6cb63b71a9c84bc0132494365a..0fbbd4c1072e6c19045d513af0acc9af9ad82a22 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 b1e85bb36396578fe8402dd2365277b32fb6e7e0..d0de37d58e9a2abe2839dd57206e5598745c54e0 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 5b7d18a06afaeee09b090c20d3bb6b7c7016f0f4..b425cd3d1838377aee89ad50411b2f51b6d40306 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 d368b3f5fce85397e9e139eb4f5b0314ac15c178..7c47005a1805c41dec67157c18c103dd6720f3c3 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 261a2c9b7f6b875bbded0143ba87011660a4c0c1..6a727fd3a77e099e863bc982309cd1028fd2e55e 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 2718fb6f6aba89467467e48f1dd24fba465fae08..28cc5d524afcd18a2dce1ee4f5ccb3d2c737faf1 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 e7921315ae9d8fe5df562cc745f908b6081ed1ab..6d91b274589c7fff2bef8e0d35aaa90c41de71a6 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 5add0bcf87a7a338974d39fbff41fe68ce3d6956..088e5dded8dc1c2be9706ffd5819499b433f8513 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 330cf84d21feaf298636fe09b6d9be10d2637d03..60353f5acc48a42794bc9f5d19635a507e638176 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))
diff --git a/arch/x86_64/boot/.gitignore b/arch/x86_64/boot/.gitignore
new file mode 100644 (file)
index 0000000..495f20c
--- /dev/null
@@ -0,0 +1,3 @@
+bootsect
+bzImage
+setup
diff --git a/arch/x86_64/boot/tools/.gitignore b/arch/x86_64/boot/tools/.gitignore
new file mode 100644 (file)
index 0000000..378eac2
--- /dev/null
@@ -0,0 +1 @@
+build
diff --git a/arch/x86_64/ia32/.gitignore b/arch/x86_64/ia32/.gitignore
new file mode 100644 (file)
index 0000000..48ab174
--- /dev/null
@@ -0,0 +1 @@
+vsyscall*.so
index 750e01dcbdf49f364940c87f5ab6b4bc158d460a..64c4534b930c74bc118cf1530a812401456f3d4e 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 99c9ca6d5992ab18b3e40fa201423bd3e36a0055..d4beb9a89ee0b08b0b681ca5a09e5cda59b7e99f 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 6e7db2e79f427833bb1ca06086d7ed1c81c40dfb..1d8852f7bbff077d14209b850b6d64e35186f81c 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 7b1cd93892be4e271d5f94ef60982607020efa76..c4b9d2adfc08bce861a9078945c4e0acf63628a4 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 bfb23d543ff7a71d1bba7b22de0ba5a5157cfaaf..10740a065088d73218b2306f2cd6acd6ff6a21b8 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 8e7fb355177528fe544d32a990d5d7849ed85fda..3e7a067cc0871dafce5f0427f2690c383983a2c3 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 067e27893e4a8e4d5b1cbcc1692edd26d0034228..8947c8837dacf8bc64ebf202e87f1da87b58e730 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 394796315adcb18decd1ca61d13b62e1aae4ffe6..9446960ac742914f3c912eb15a2870bb4dc42432 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 057cb2b6e6d1f537723051c122eca2d59fec0c82..92382e8232855188a1f588a739c5c98a03b055ef 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 2b6b1d772ed776fff87927fc34adc2e40500218e..73dfdcebfbba64a725a99fbb637242e07c1c5071 100644 (file)
@@ -1,3 +1,3 @@
 consolemap_deftbl.c
 defkeymap.c
-
+qtronixmap.c
index e9b87a78622ce2be0771a68cda679b7861c35ea4..00342a677c90c473bb670c5e026d8c1aaa6f187c 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 c3660d8781a4ef35e6fce62532d2629bfa4039ab..a133a62f3d5528a1ad93d6d2ee181cdaaebac295 100644 (file)
@@ -562,7 +562,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
 }      /* end of n_hdlc_tty_receive() */
 
 /**
- * n_hdlc_tty_read - Called to retreive one frame of data (if available)
+ * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
  * @tty - pointer to tty instance data
  * @file - pointer to open file object
  * @buf - pointer to returned data buffer
index 7999da25fe40afb035c4342cd1f227f0b4d21078..bdfdfd28594d17d648b5346c273217c097974dff 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 092e9b133750f67f56d803df1ce06039ab6c78cf..1533f56baa42f8304e889b280994510c380cabec 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 815902c2c856bd08df4da65daaf996f78f07e419..a9163d02983af68f069887a520330e84470cc58b 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 2ed5c4363b536220843d942af2e84276b9a1dbd0..39543a2bed0f43c232e724ce809f1c89d438f6e1 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 17741111246b9f21362710cdc1099c31cb69512d..e69fd8dd1f1cb7bf6042a878b2545a714c7df133 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
 };
 
diff --git a/drivers/ieee1394/.gitignore b/drivers/ieee1394/.gitignore
new file mode 100644 (file)
index 0000000..33da10a
--- /dev/null
@@ -0,0 +1 @@
+oui.c
index 475d98fa9e26645c2b76b001d08bbea0fc6d12a7..780009c7eaa651f908e78def9a8106eea752cd81 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 ef3ee035bbc8e03f7930df570620368882be5fd3..ed0c2ead8bc16f0c215a054f0c765d4d2a440eee 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 64b4a308098521ee6d01cc6893a4e938759aa6a3..bc2fce60f9f8012484d8600fe9a8121065664498 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 f8457ef488260bc4e4af7db6a3cdc9c672c15b5a..ca5b4a3b683e67c1fc2d04df730302890048d195 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 8e192a3a34906ca80118f30c2b4ecff3bb6b2019..99cb0f3d59a15ff4e4a65748b9bb309858dc5d21 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,
diff --git a/drivers/md/.gitignore b/drivers/md/.gitignore
new file mode 100644 (file)
index 0000000..a7afec6
--- /dev/null
@@ -0,0 +1,4 @@
+mktables
+raid6altivec*.c
+raid6int*.c
+raid6tables.c
index a6d3baa46f6168e7f9143191abe22ffa5e2a65c2..a6f2dc66c3db12b09606218e1595e147b20c8a57 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 0a78ba3737a58d85a64a7d902b30e9dfeeae4579..a6c91db40ad693b17a323a49034cf5b501f62eb0 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 336fc284fa523138d2bfd923146039ce8855db6a..b996fb59b7e44bfbda4b448ade43995c870984fb 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 8c7beffb045fd1335bdd23f2c7e6a47e0c538daa..ce44aa6bbb838da936e9c41466819a9d226d64cf 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 3fe383f4bb4cea3d69a69bc191a4356c6bb0d979..d05fab01cccdb9b34093b0dfdda028b45ad27275 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 aa271a2496d5faaa27cc25c172a4682d6443b099..52ac3e5adf5dd99de63a18821f57e258f8fcab69 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 6a0912eab396085cd99b30064d949362fca6b2b8..55802fba3c29ee71bc320cf056b6fa1a0c665eb7 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 f98e306a5759ed6d78fa927212706157ff4d2654..450417a9e64b6632fd62cc3affd346a55203da9d 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 b595476332cd9dba9006c6bcb94761122cc7ba97..6e2bac873445700e7d83b1e5317763b3e16263db 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 1841a66427bfe550c7ef7d3646b487e24f2c01ce..fac48fc7a4aca3e2b7df0f455be0190d48eb8133 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 6fd67657c2693a277567aa95cdd9fee70514b26a..14f1911c79bb29061817eec9ffb209083677896c 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 de13c04e8e64ce66b7806e7872fb85da31bfff5b..afa00fdb5ec0c3686fb3a6e1c49f6ac7ff3dfa9b 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 75765e3a569c811f2f93f5fd25983caf5437b055..3835235b68dff0f18793c0b711af42c3160ed6cd 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 9774e94d1e7d94ae7e8a8eb46a7e72b936680e8d..1439cb752874c23ef5fdf265c73d136f4f4ba895 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 06d76879bde27abf1c55af5396e90167af4ae725..3a56120397aeb45791f36fe23fd14480ca64c84a 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 4262a22adc22d469a4a1e4991714443c04c03ec2..537836068c493736d1efc7a3139974d16faeacc1 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 bac8eb4186d2f83cada0550f07ca319d584a2b17..6c48d1f54ac92552b4fdf42f4ebbf66c74d5eda9 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 602138f8544db665ded8957738b1dcca7208a772..959d2c5951b8beb072b4c00b0fbc34ac836c6acc 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 a628be9bbbadd0070326e5af78f9dadfb2f6934a..ba61e18288585679d4915c9ec22abd82804496b7 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 e0a8bb8ba7d8f15bfdd3214a63f035884295129b..17e9757e728be780211d1e7a0008aaa9e2724d18 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 b7b9846ff3fd960859bd077f2716e95a9ab23dd7..93a16fa3c4baeab822056108f9e622e906b10d5c 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 971fda4b8b57998c56ffeb2fb7aaa3a2d4ae5236..d3cba12f4bd95c38c110327bfbde76d9d6ecf1af 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 5c0e307d1d5d4c4c9440b5625b754b0ead959ff1..ce332a6085e5345e2b64a259da1d44a04eec693d 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 30bee11c48bd2d8364ac8f8e93abe47c5467593e..d2102a27d3071492dd4c3cd686e286c6dffaf8f4 100644 (file)
@@ -586,16 +586,16 @@ struct rtl8139_private {
        dma_addr_t tx_bufs_dma;
        signed char phys[4];            /* MII device addresses. */
        char twistie, twist_row, twist_col;     /* Twister tune state. */
-       unsigned int default_port:4;    /* Last dev->if_port value. */
+       unsigned int default_port : 4;  /* Last dev->if_port value. */
+       unsigned int have_thread : 1;
        spinlock_t lock;
        spinlock_t rx_lock;
        chip_t chipset;
-       pid_t thr_pid;
-       wait_queue_head_t thr_wait;
-       struct completion thr_exited;
        u32 rx_config;
        struct rtl_extra_stats xstats;
-       int time_to_die;
+
+       struct work_struct thread;
+
        struct mii_if_info mii;
        unsigned int regs_len;
        unsigned long fifo_copy_timeout;
@@ -620,7 +620,7 @@ static int rtl8139_open (struct net_device *dev);
 static int mdio_read (struct net_device *dev, int phy_id, int location);
 static void mdio_write (struct net_device *dev, int phy_id, int location,
                        int val);
-static void rtl8139_start_thread(struct net_device *dev);
+static void rtl8139_start_thread(struct rtl8139_private *tp);
 static void rtl8139_tx_timeout (struct net_device *dev);
 static void rtl8139_init_ring (struct net_device *dev);
 static int rtl8139_start_xmit (struct sk_buff *skb,
@@ -637,6 +637,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
 static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
+static void rtl8139_thread (void *_data);
 static struct ethtool_ops rtl8139_ethtool_ops;
 
 /* write MMIO register, with flush */
@@ -1007,8 +1008,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
                (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
        spin_lock_init (&tp->lock);
        spin_lock_init (&tp->rx_lock);
-       init_waitqueue_head (&tp->thr_wait);
-       init_completion (&tp->thr_exited);
+       INIT_WORK(&tp->thread, rtl8139_thread, dev);
        tp->mii.dev = dev;
        tp->mii.mdio_read = mdio_read;
        tp->mii.mdio_write = mdio_write;
@@ -1345,7 +1345,7 @@ static int rtl8139_open (struct net_device *dev)
                        dev->irq, RTL_R8 (MediaStatus),
                        tp->mii.full_duplex ? "full" : "half");
 
-       rtl8139_start_thread(dev);
+       rtl8139_start_thread(tp);
 
        return 0;
 }
@@ -1594,55 +1594,43 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
                 RTL_R8 (Config1));
 }
 
-static int rtl8139_thread (void *data)
+static void rtl8139_thread (void *_data)
 {
-       struct net_device *dev = data;
+       struct net_device *dev = _data;
        struct rtl8139_private *tp = netdev_priv(dev);
-       unsigned long timeout;
-
-       daemonize("%s", dev->name);
-       allow_signal(SIGTERM);
-
-       while (1) {
-               timeout = next_tick;
-               do {
-                       timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
-                       /* make swsusp happy with our thread */
-                       try_to_freeze();
-               } while (!signal_pending (current) && (timeout > 0));
-
-               if (signal_pending (current)) {
-                       flush_signals(current);
-               }
+       unsigned long thr_delay;
 
-               if (tp->time_to_die)
-                       break;
-
-               if (rtnl_lock_interruptible ())
-                       break;
+       if (rtnl_shlock_nowait() == 0) {
                rtl8139_thread_iter (dev, tp, tp->mmio_addr);
                rtnl_unlock ();
+
+               thr_delay = next_tick;
+       } else {
+               /* unlikely race.  mitigate with fast poll. */
+               thr_delay = HZ / 2;
        }
 
-       complete_and_exit (&tp->thr_exited, 0);
+       schedule_delayed_work(&tp->thread, thr_delay);
 }
 
-static void rtl8139_start_thread(struct net_device *dev)
+static void rtl8139_start_thread(struct rtl8139_private *tp)
 {
-       struct rtl8139_private *tp = netdev_priv(dev);
-
-       tp->thr_pid = -1;
        tp->twistie = 0;
-       tp->time_to_die = 0;
        if (tp->chipset == CH_8139_K)
                tp->twistie = 1;
        else if (tp->drv_flags & HAS_LNK_CHNG)
                return;
 
-       tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES);
-       if (tp->thr_pid < 0) {
-               printk (KERN_WARNING "%s: unable to start kernel thread\n",
-                       dev->name);
+       tp->have_thread = 1;
+
+       schedule_delayed_work(&tp->thread, next_tick);
+}
+
+static void rtl8139_stop_thread(struct rtl8139_private *tp)
+{
+       if (tp->have_thread) {
+               cancel_rearming_delayed_work(&tp->thread);
+               tp->have_thread = 0;
        }
 }
 
@@ -2224,22 +2212,12 @@ static int rtl8139_close (struct net_device *dev)
 {
        struct rtl8139_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
-       int ret = 0;
        unsigned long flags;
 
        netif_stop_queue (dev);
 
-       if (tp->thr_pid >= 0) {
-               tp->time_to_die = 1;
-               wmb();
-               ret = kill_proc (tp->thr_pid, SIGTERM, 1);
-               if (ret) {
-                       printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
-                       return ret;
-               }
-               wait_for_completion (&tp->thr_exited);
-       }
-       
+       rtl8139_stop_thread(tp);
+
        if (netif_msg_ifdown(tp))
                printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
                        dev->name, RTL_R16 (IntrStatus));
index ebd7313d7fc1c1652d26c37e9c984b92c57bcbe7..e2fa29b612cdffbea7c7488ebcd0a77ddf62f726 100644 (file)
@@ -1901,6 +1901,8 @@ config E1000_NAPI
 
          If in doubt, say N.
 
+source "drivers/net/ixp2000/Kconfig"
+
 config MYRI_SBUS
        tristate "MyriCOM Gigabit Ethernet support"
        depends on SBUS
@@ -2008,7 +2010,18 @@ config SKGE
 
          It does not support the link failover and network management 
          features that "portable" vendor supplied sk98lin driver does.
-       
+
+
+config SKY2
+       tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       ---help---
+         This driver support the Marvell Yukon 2 Gigabit Ethernet adapter.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sky2.  This is recommended.
+
 config SK98LIN
        tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
        depends on PCI
@@ -2120,7 +2133,7 @@ config BNX2
 
 config SPIDER_NET
        tristate "Spider Gigabit Ethernet driver"
-       depends on PCI && PPC_BPA
+       depends on PCI && PPC_CELL
        help
          This driver supports the Gigabit Ethernet chips present on the
          Cell Processor-Based Blades from IBM.
index 4cffd34442aafaddc00865df86c26f410ccd61a2..b74a7cb5bae6e163c518199e28eb6269b5dc15d5 100644 (file)
@@ -13,7 +13,10 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
 obj-$(CONFIG_BONDING) += bonding/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
 
-gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
+gianfar_driver-objs := gianfar.o \
+               gianfar_ethtool.o \
+               gianfar_mii.o \
+               gianfar_sysfs.o
 
 #
 # link order important here
@@ -59,6 +62,7 @@ spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
+obj-$(CONFIG_SKY2) += sky2.o
 obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
@@ -202,6 +206,7 @@ obj-$(CONFIG_NET_TULIP) += tulip/
 obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_IRDA) += irda/
 obj-$(CONFIG_ETRAX_ETHERNET) += cris/
+obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
 
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
 
index cf50384b469e9c83f8e3ed81c4258f706176e017..5cdae2bc055a9c27d679af0793d97bce459c0fd1 100644 (file)
@@ -4,5 +4,5 @@
 
 obj-$(CONFIG_BONDING) += bonding.o
 
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
 
index d2f34d5a80835c786122a4ba359164d524b5bde6..f3f5825469d63c43b58df4851e8c56754ba7e800 100644 (file)
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Amir Noam <amir.noam at intel dot com>
- *     - Added support for lacp_rate module param.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Based on discussion on mailing list, changed locking scheme
- *       to use lock/unlock or lock_bh/unlock_bh appropriately instead
- *       of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
- *       hidden bugs and solves system hangs that occurred due to the fact
- *       that holding lock_irqsave doesn't prevent softirqs from running.
- *       This also increases total throughput since interrupts are not
- *       blocked on each transmitted packets or monitor timeout.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Renamed bond_3ad_link_status_changed() to
- *       bond_3ad_handle_link_change() for compatibility with TLB.
- *
- * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
- *     - Fix long fail over time when releasing last slave of an active
- *       aggregator - send LACPDU on unbind of slave to tell partner this
- *       port is no longer aggregatable.
- *
- * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
- *     - Send LACPDU as highest priority packet to further fix the above
- *       problem on very high Tx traffic load where packets may get dropped
- *       by the slave.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Code cleanup and style changes
  */
 
 //#define BONDING_DEBUG 1
@@ -1198,10 +1166,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
                        // detect loopback situation
                        if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
                                // INFO_RECEIVED_LOOPBACK_FRAMES
-                               printk(KERN_ERR DRV_NAME ": An illegal loopback occurred on adapter (%s)\n",
-                                               port->slave->dev->name);
-                               printk(KERN_ERR "Check the configuration to verify that all Adapters "
-                                               "are connected to 802.3ad compliant switch ports\n");
+                               printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
+                                      "adapter (%s). Check the configuration to verify that all "
+                                      "Adapters are connected to 802.3ad compliant switch ports\n",
+                                      port->slave->dev->master->name, port->slave->dev->name);
                                __release_rx_machine_lock(port);
                                return;
                        }
@@ -1378,8 +1346,9 @@ static void ad_port_selection_logic(struct port *port)
                        }
                }
                if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
-                       printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
+                       printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
                               "related to aggregator %d but was not on its port list\n",
+                              port->slave->dev->master->name,
                               port->actor_port_number, port->slave->dev->name,
                               port->aggregator->aggregator_identifier);
                }
@@ -1450,7 +1419,8 @@ static void ad_port_selection_logic(struct port *port)
 
                        dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
                } else {
-                       printk(KERN_ERR DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
+                       printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
+                              port->slave->dev->master->name,
                               port->actor_port_number, port->slave->dev->name);
                }
        }
@@ -1582,8 +1552,9 @@ static void ad_agg_selection_logic(struct aggregator *aggregator)
 
                // check if any partner replys
                if (best_aggregator->is_individual) {
-                       printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
-                                       "for any adapters in the bond\n");
+                       printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
+                              "the link partner for any adapters in the bond\n",
+                              best_aggregator->slave->dev->master->name);
                }
 
                // check if there are more than one aggregator
@@ -1915,7 +1886,8 @@ int bond_3ad_bind_slave(struct slave *slave)
        struct aggregator *aggregator;
 
        if (bond == NULL) {
-               printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
+               printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
+                      slave->dev->master->name, slave->dev->name);
                return -1;
        }
 
@@ -1990,7 +1962,9 @@ void bond_3ad_unbind_slave(struct slave *slave)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-               printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
+               printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
+                      "unbind an uninitialized port on %s\n",
+                      slave->dev->master->name, slave->dev->name);
                return;
        }
 
@@ -2021,7 +1995,8 @@ void bond_3ad_unbind_slave(struct slave *slave)
                                dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
 
                                if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
-                                       printk(KERN_INFO DRV_NAME ": Removing an active aggregator\n");
+                                       printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+                                              aggregator->slave->dev->master->name);
                                        // select new active aggregator
                                         select_new_active_agg = 1;
                                }
@@ -2051,15 +2026,17 @@ void bond_3ad_unbind_slave(struct slave *slave)
                                        ad_agg_selection_logic(__get_first_agg(port));
                                }
                        } else {
-                               printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
-                                      "and could not find a new aggregator for its ports\n");
+                               printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
+                                      "and could not find a new aggregator for its ports\n",
+                                      slave->dev->master->name);
                        }
                } else { // in case that the only port related to this aggregator is the one we want to remove
                        select_new_active_agg = aggregator->is_active;
                        // clear the aggregator
                        ad_clear_agg(aggregator);
                        if (select_new_active_agg) {
-                               printk(KERN_INFO "Removing an active aggregator\n");
+                               printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+                                      slave->dev->master->name);
                                // select new active aggregator
                                ad_agg_selection_logic(__get_first_agg(port));
                        }
@@ -2085,7 +2062,8 @@ void bond_3ad_unbind_slave(struct slave *slave)
                                        // clear the aggregator
                                        ad_clear_agg(temp_aggregator);
                                        if (select_new_active_agg) {
-                                               printk(KERN_INFO "Removing an active aggregator\n");
+                                               printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+                                                      slave->dev->master->name);
                                                // select new active aggregator
                                                ad_agg_selection_logic(__get_first_agg(port));
                                        }
@@ -2131,7 +2109,8 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
                // select the active aggregator for the bond
                if ((port = __get_first_port(bond))) {
                        if (!port->slave) {
-                               printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
+                               printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
+                                      "uninitialized\n", bond->dev->name);
                                goto re_arm;
                        }
 
@@ -2143,7 +2122,8 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
        // for each port run the state machines
        for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
                if (!port->slave) {
-                       printk(KERN_WARNING DRV_NAME ": Warning: Found an uninitialized port\n");
+                       printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
+                              "port\n", bond->dev->name);
                        goto re_arm;
                }
 
@@ -2184,7 +2164,8 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
                port = &(SLAVE_AD_INFO(slave).port);
 
                if (!port->slave) {
-                       printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
+                       printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
+                              "uninitialized\n", slave->dev->name, slave->dev->master->name);
                        return;
                }
 
@@ -2230,8 +2211,9 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-               printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
-                      slave->dev->name);
+               printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
+                      "changed for uninitialized port on %s\n",
+                      slave->dev->master->name, slave->dev->name);
                return;
        }
 
@@ -2257,8 +2239,9 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-               printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
-                      slave->dev->name);
+               printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
+                      "for uninitialized port on %s\n",
+                      slave->dev->master->name, slave->dev->name);
                return;
        }
 
@@ -2285,8 +2268,9 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
 
        // if slave is null, the whole port is not initialized
        if (!port->slave) {
-               printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
-                       slave->dev->name);
+               printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
+                      "uninitialized port on %s\n",
+                       slave->dev->master->name, slave->dev->name);
                return;
        }
 
@@ -2363,7 +2347,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
        }
 
        if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
-               printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
+               printk(KERN_DEBUG DRV_NAME ": %s: Error: "
+                      "bond_3ad_get_active_agg_info failed\n", dev->name);
                goto out;
        }
 
@@ -2372,7 +2357,9 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 
        if (slaves_in_agg == 0) {
                /*the aggregator is empty*/
-               printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
+               printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
+                      "aggregator is empty\n",
+                      dev->name);
                goto out;
        }
 
@@ -2390,7 +2377,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
        }
 
        if (slave_agg_no >= 0) {
-               printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
+               printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
+                      "for aggregator ID %d\n", dev->name, agg_id);
                goto out;
        }
 
index 673a30af5660f58a096f1253c34fb10bd40bcbec..5ee2cef5b037f9d5f0b41ff2015a34c3067af2a0 100644 (file)
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Amir Noam <amir.noam at intel dot com>
- *     - Added support for lacp_rate module param.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Renamed bond_3ad_link_status_changed() to
- *       bond_3ad_handle_link_change() for compatibility with TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Code cleanup and style changes
  */
 
 #ifndef __BOND_3AD_H__
index f8fce39611972f18fefdd8524368955425d84466..854ddfb90da19139bfcdbbe47810117772c4f8ef 100644 (file)
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Fixed signed/unsigned calculation errors that caused load sharing
- *       to collapse to one slave under very heavy UDP Tx stress.
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- *     - Add support for setting bond's MAC address with special
- *       handling required for ALB/TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Code cleanup and style changes
- *
- * 2003/12/30 - Amir Noam <amir.noam at intel dot com>
- *     - Fixed: Cannot remove and re-enslave the original active slave.
- *
- * 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Add capability to tag self generated packets in ALB/TLB modes.
  */
 
 //#define BONDING_DEBUG 1
@@ -198,20 +179,21 @@ static int tlb_initialize(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
        int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
+       struct tlb_client_info *new_hashtbl;
        int i;
 
        spin_lock_init(&(bond_info->tx_hashtbl_lock));
 
-       _lock_tx_hashtbl(bond);
-
-       bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
-       if (!bond_info->tx_hashtbl) {
+       new_hashtbl = kmalloc(size, GFP_KERNEL);
+       if (!new_hashtbl) {
                printk(KERN_ERR DRV_NAME
-                      ": Error: %s: Failed to allocate TLB hash table\n",
+                      ": %s: Error: Failed to allocate TLB hash table\n",
                       bond->dev->name);
-               _unlock_tx_hashtbl(bond);
                return -1;
        }
+       _lock_tx_hashtbl(bond);
+
+       bond_info->tx_hashtbl = new_hashtbl;
 
        memset(bond_info->tx_hashtbl, 0, size);
 
@@ -513,7 +495,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
                                 client_info->mac_dst);
                if (!skb) {
                        printk(KERN_ERR DRV_NAME
-                              ": Error: failed to create an ARP packet\n");
+                              ": %s: Error: failed to create an ARP packet\n",
+                              client_info->slave->dev->master->name);
                        continue;
                }
 
@@ -523,7 +506,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
                        skb = vlan_put_tag(skb, client_info->vlan_id);
                        if (!skb) {
                                printk(KERN_ERR DRV_NAME
-                                      ": Error: failed to insert VLAN tag\n");
+                                      ": %s: Error: failed to insert VLAN tag\n",
+                                      client_info->slave->dev->master->name);
                                continue;
                        }
                }
@@ -606,8 +590,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
 
                if (!client_info->slave) {
                        printk(KERN_ERR DRV_NAME
-                              ": Error: found a client with no channel in "
-                              "the client's hash table\n");
+                              ": %s: Error: found a client with no channel in "
+                              "the client's hash table\n",
+                              bond->dev->name);
                        continue;
                }
                /*update all clients using this src_ip, that are not assigned
@@ -797,21 +782,22 @@ static int rlb_initialize(struct bonding *bond)
 {
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
        struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
+       struct rlb_client_info  *new_hashtbl;
        int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
        int i;
 
        spin_lock_init(&(bond_info->rx_hashtbl_lock));
 
-       _lock_rx_hashtbl(bond);
-
-       bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
-       if (!bond_info->rx_hashtbl) {
+       new_hashtbl = kmalloc(size, GFP_KERNEL);
+       if (!new_hashtbl) {
                printk(KERN_ERR DRV_NAME
-                      ": Error: %s: Failed to allocate RLB hash table\n",
+                      ": %s: Error: Failed to allocate RLB hash table\n",
                       bond->dev->name);
-               _unlock_rx_hashtbl(bond);
                return -1;
        }
+       _lock_rx_hashtbl(bond);
+
+       bond_info->rx_hashtbl = new_hashtbl;
 
        bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
 
@@ -927,7 +913,8 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
                        skb = vlan_put_tag(skb, vlan->vlan_id);
                        if (!skb) {
                                printk(KERN_ERR DRV_NAME
-                                      ": Error: failed to insert VLAN tag\n");
+                                      ": %s: Error: failed to insert VLAN tag\n",
+                                      bond->dev->name);
                                continue;
                        }
                }
@@ -956,11 +943,11 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
        s_addr.sa_family = dev->type;
        if (dev_set_mac_address(dev, &s_addr)) {
                printk(KERN_ERR DRV_NAME
-                      ": Error: dev_set_mac_address of dev %s failed! ALB "
+                      ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
                       "mode requires that the base driver support setting "
                       "the hw address also when the network device's "
                       "interface is open\n",
-                      dev->name);
+                      dev->master->name, dev->name);
                return -EOPNOTSUPP;
        }
        return 0;
@@ -1153,16 +1140,16 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
                                       bond->alb_info.rlb_enabled);
 
                printk(KERN_WARNING DRV_NAME
-                      ": Warning: the hw address of slave %s is in use by "
+                      ": %s: Warning: the hw address of slave %s is in use by "
                       "the bond; giving it the hw address of %s\n",
-                      slave->dev->name, free_mac_slave->dev->name);
+                      bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
 
        } else if (has_bond_addr) {
                printk(KERN_ERR DRV_NAME
-                      ": Error: the hw address of slave %s is in use by the "
+                      ": %s: Error: the hw address of slave %s is in use by the "
                       "bond; couldn't find a slave with a free hw address to "
                       "give it (this should not have happened)\n",
-                      slave->dev->name);
+                      bond->dev->name, slave->dev->name);
                return -EFAULT;
        }
 
@@ -1250,6 +1237,8 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
                        tlb_deinitialize(bond);
                        return res;
                }
+       } else {
+               bond->alb_info.rlb_enabled = 0;
        }
 
        return 0;
@@ -1409,7 +1398,7 @@ void bond_alb_monitor(struct bonding *bond)
                read_lock(&bond->curr_slave_lock);
 
                bond_for_each_slave(bond, slave, i) {
-                       alb_send_learning_packets(slave,slave->dev->dev_addr);
+                       alb_send_learning_packets(slave, slave->dev->dev_addr);
                }
 
                read_unlock(&bond->curr_slave_lock);
index e4091cd8d6547e6474c622f71283f794c8557f5e..28f2a2fd1b5a956cb896561d2646690ed49bf230 100644 (file)
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- *     - Add support for setting bond's MAC address with special
- *       handling required for ALB/TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Code cleanup and style changes
  */
 
 #ifndef __BOND_ALB_H__
index 94cec3cf2a1304b994b8279daf0cd01cbf7c2dbc..2582d98ef5c3308c16214b75f520ec1abb1b97e4 100644 (file)
  *     b: if a hw mac address already is there, eth0's hw mac address
  *        will then be set from bond0.
  *
- * v0.1 - first working version.
- * v0.2 - changed stats to be calculated by summing slaves stats.
- *
- * Changes:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * - fix leaks on failure at bond_init
- *
- * 2000/09/30 - Willy Tarreau <willy at meta-x.org>
- *     - added trivial code to release a slave device.
- *     - fixed security bug (CAP_NET_ADMIN not checked)
- *     - implemented MII link monitoring to disable dead links :
- *       All MII capable slaves are checked every <miimon> milliseconds
- *       (100 ms seems good). This value can be changed by passing it to
- *       insmod. A value of zero disables the monitoring (default).
- *     - fixed an infinite loop in bond_xmit_roundrobin() when there's no
- *       good slave.
- *     - made the code hopefully SMP safe
- *
- * 2000/10/03 - Willy Tarreau <willy at meta-x.org>
- *     - optimized slave lists based on relevant suggestions from Thomas Davis
- *     - implemented active-backup method to obtain HA with two switches:
- *       stay as long as possible on the same active interface, while we
- *       also monitor the backup one (MII link status) because we want to know
- *       if we are able to switch at any time. ( pass "mode=1" to insmod )
- *     - lots of stress testings because we need it to be more robust than the
- *       wires ! :->
- *
- * 2000/10/09 - Willy Tarreau <willy at meta-x.org>
- *     - added up and down delays after link state change.
- *     - optimized the slaves chaining so that when we run forward, we never
- *       repass through the bond itself, but we can find it by searching
- *       backwards. Renders the deletion more difficult, but accelerates the
- *       scan.
- *     - smarter enslaving and releasing.
- *     - finer and more robust SMP locking
- *
- * 2000/10/17 - Willy Tarreau <willy at meta-x.org>
- *     - fixed two potential SMP race conditions
- *
- * 2000/10/18 - Willy Tarreau <willy at meta-x.org>
- *     - small fixes to the monitoring FSM in case of zero delays
- * 2000/11/01 - Willy Tarreau <willy at meta-x.org>
- *     - fixed first slave not automatically used in trunk mode.
- * 2000/11/10 : spelling of "EtherChannel" corrected.
- * 2000/11/13 : fixed a race condition in case of concurrent accesses to ioctl().
- * 2000/12/16 : fixed improper usage of rtnl_exlock_nowait().
- *
- * 2001/1/3 - Chad N. Tindel <ctindel at ieee dot org>
- *     - The bonding driver now simulates MII status monitoring, just like
- *       a normal network device.  It will show that the link is down iff
- *       every slave in the bond shows that their links are down.  If at least
- *       one slave is up, the bond's MII status will appear as up.
- *
- * 2001/2/7 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Applications can now query the bond from user space to get
- *       information which may be useful.  They do this by calling
- *       the BOND_INFO_QUERY ioctl.  Once the app knows how many slaves
- *       are in the bond, it can call the BOND_SLAVE_INFO_QUERY ioctl to
- *       get slave specific information (# link failures, etc).  See
- *       <linux/if_bonding.h> for more details.  The structs of interest
- *       are ifbond and ifslave.
- *
- * 2001/4/5 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Ported to 2.4 Kernel
- *
- * 2001/5/2 - Jeffrey E. Mast <jeff at mastfamily dot com>
- *     - When a device is detached from a bond, the slave device is no longer
- *       left thinking that is has a master.
- *
- * 2001/5/16 - Jeffrey E. Mast <jeff at mastfamily dot com>
- *     - memset did not appropriately initialized the bond rw_locks. Used
- *       rwlock_init to initialize to unlocked state to prevent deadlock when
- *       first attempting a lock
- *     - Called SET_MODULE_OWNER for bond device
- *
- * 2001/5/17 - Tim Anderson <tsa at mvista.com>
- *     - 2 paths for releasing for slave release; 1 through ioctl
- *       and 2) through close. Both paths need to release the same way.
- *     - the free slave in bond release is changing slave status before
- *       the free. The netdev_set_master() is intended to change slave state
- *       so it should not be done as part of the release process.
- *     - Simple rule for slave state at release: only the active in A/B and
- *       only one in the trunked case.
- *
- * 2001/6/01 - Tim Anderson <tsa at mvista.com>
- *     - Now call dev_close when releasing a slave so it doesn't screw up
- *       out routing table.
- *
- * 2001/6/01 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Added /proc support for getting bond and slave information.
- *       Information is in /proc/net/<bond device>/info.
- *     - Changed the locking when calling bond_close to prevent deadlock.
- *
- * 2001/8/05 - Janice Girouard <girouard at us.ibm.com>
- *     - correct problem where refcnt of slave is not incremented in bond_ioctl
- *       so the system hangs when halting.
- *     - correct locking problem when unable to malloc in bond_enslave.
- *     - adding bond_xmit_xor logic.
- *     - adding multiple bond device support.
- *
- * 2001/8/13 - Erik Habbinga <erik_habbinga at hp dot com>
- *     - correct locking problem with rtnl_exlock_nowait
- *
- * 2001/8/23 - Janice Girouard <girouard at us.ibm.com>
- *     - bzero initial dev_bonds, to correct oops
- *     - convert SIOCDEVPRIVATE to new MII ioctl calls
- *
- * 2001/9/13 - Takao Indoh <indou dot takao at jp dot fujitsu dot com>
- *     - Add the BOND_CHANGE_ACTIVE ioctl implementation
- *
- * 2001/9/14 - Mark Huth <mhuth at mvista dot com>
- *     - Change MII_LINK_READY to not check for end of auto-negotiation,
- *       but only for an up link.
- *
- * 2001/9/20 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Add the device field to bonding_t.  Previously the net_device
- *       corresponding to a bond wasn't available from the bonding_t
- *       structure.
- *
- * 2001/9/25 - Janice Girouard <girouard at us.ibm.com>
- *     - add arp_monitor for active backup mode
- *
- * 2001/10/23 - Takao Indoh <indou dot takao at jp dot fujitsu dot com>
- *     - Various memory leak fixes
- *
- * 2001/11/5 - Mark Huth <mark dot huth at mvista dot com>
- *     - Don't take rtnl lock in bond_mii_monitor as it deadlocks under
- *       certain hotswap conditions.
- *       Note:  this same change may be required in bond_arp_monitor ???
- *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
- *     - Handle hot swap ethernet interface deregistration events to remove
- *       kernel oops following hot swap of enslaved interface
- *
- * 2002/1/2 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Restore original slave flags at release time.
- *
- * 2002/02/18 - Erik Habbinga <erik_habbinga at hp dot com>
- *     - bond_release(): calling kfree on our_slave after call to
- *       bond_restore_slave_flags, not before
- *     - bond_enslave(): saving slave flags into original_flags before
- *       call to netdev_set_master, so the IFF_SLAVE flag doesn't end
- *       up in original_flags
- *
- * 2002/04/05 - Mark Smith <mark.smith at comdev dot cc> and
- *              Steve Mead <steve.mead at comdev dot cc>
- *     - Port Gleb Natapov's multicast support patchs from 2.4.12
- *       to 2.4.18 adding support for multicast.
- *
- * 2002/06/10 - Tony Cureington <tony.cureington * hp_com>
- *     - corrected uninitialized pointer (ifr.ifr_data) in bond_check_dev_link;
- *       actually changed function to use MIIPHY, then MIIREG, and finally
- *       ETHTOOL to determine the link status
- *     - fixed bad ifr_data pointer assignments in bond_ioctl
- *     - corrected mode 1 being reported as active-backup in bond_get_info;
- *       also added text to distinguish type of load balancing (rr or xor)
- *     - change arp_ip_target module param from "1-12s" (array of 12 ptrs)
- *       to "s" (a single ptr)
- *
- * 2002/08/30 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Removed acquisition of xmit_lock in set_multicast_list; caused
- *       deadlock on SMP (lock is held by caller).
- *     - Revamped SIOCGMIIPHY, SIOCGMIIREG portion of bond_check_dev_link().
- *
- * 2002/09/18 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Fixed up bond_check_dev_link() (and callers): removed some magic
- *      numbers, banished local MII_ defines, wrapped ioctl calls to
- *      prevent EFAULT errors
- *
- * 2002/9/30 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - make sure the ip target matches the arp_target before saving the
- *      hw address.
- *
- * 2002/9/30 - Dan Eisner <eisner at 2robots dot com>
- *     - make sure my_ip is set before taking down the link, since
- *      not all switches respond if the source ip is not set.
- *
- * 2002/10/8 - Janice Girouard <girouard at us dot ibm dot com>
- *     - read in the local ip address when enslaving a device
- *     - add primary support
- *     - make sure 2*arp_interval has passed when a new device
- *       is brought on-line before taking it down.
- *
- * 2002/09/11 - Philippe De Muyter <phdm at macqel dot be>
- *     - Added bond_xmit_broadcast logic.
- *     - Added bond_mode() support function.
- *
- * 2002/10/26 - Laurent Deniel <laurent.deniel at free.fr>
- *     - allow to register multicast addresses only on active slave
- *       (useful in active-backup mode)
- *     - add multicast module parameter
- *     - fix deletion of multicast groups after unloading module
- *
- * 2002/11/06 - Kameshwara Rayaprolu <kameshwara.rao * wipro_com>
- *     - Changes to prevent panic from closing the device twice; if we close
- *       the device in bond_release, we must set the original_flags to down
- *       so it won't be closed again by the network layer.
- *
- * 2002/11/07 - Tony Cureington <tony.cureington * hp_com>
- *     - Fix arp_target_hw_addr memory leak
- *     - Created activebackup_arp_monitor function to handle arp monitoring
- *       in active backup mode - the bond_arp_monitor had several problems...
- *       such as allowing slaves to tx arps sequentially without any delay
- *       for a response
- *     - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote
- *       this function to just handle arp monitoring in load-balancing mode;
- *       it is a lot more compact now
- *     - Changes to ensure one and only one slave transmits in active-backup
- *       mode
- *     - Robustesize parameters; warn users about bad combinations of
- *       parameters; also if miimon is specified and a network driver does
- *       not support MII or ETHTOOL, inform the user of this
- *     - Changes to support link_failure_count when in arp monitoring mode
- *     - Fix up/down delay reported in /proc
- *     - Added version; log version; make version available from "modinfo -d"
- *     - Fixed problem in bond_check_dev_link - if the first IOCTL (SIOCGMIIPH)
- *      failed, the ETHTOOL ioctl never got a chance
- *
- * 2002/11/16 - Laurent Deniel <laurent.deniel at free.fr>
- *     - fix multicast handling in activebackup_arp_monitor
- *     - remove one unnecessary and confusing curr_active_slave == slave test
- *      in activebackup_arp_monitor
- *
- *  2002/11/17 - Laurent Deniel <laurent.deniel at free.fr>
- *     - fix bond_slave_info_query when slave_id = num_slaves
- *
- *  2002/11/19 - Janice Girouard <girouard at us dot ibm dot com>
- *     - correct ifr_data reference.  Update ifr_data reference
- *       to mii_ioctl_data struct values to avoid confusion.
- *
- *  2002/11/22 - Bert Barbe <bert.barbe at oracle dot com>
- *      - Add support for multiple arp_ip_target
- *
- *  2002/12/13 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Changed to allow text strings for mode and multicast, e.g.,
- *       insmod bonding mode=active-backup.  The numbers still work.
- *       One change: an invalid choice will cause module load failure,
- *       rather than the previous behavior of just picking one.
- *     - Minor cleanups; got rid of dup ctype stuff, atoi function
- *
- * 2003/02/07 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Added use_carrier module parameter that causes miimon to
- *       use netif_carrier_ok() test instead of MII/ETHTOOL ioctls.
- *     - Minor cleanups; consolidated ioctl calls to one function.
- *
- * 2003/02/07 - Tony Cureington <tony.cureington * hp_com>
- *     - Fix bond_mii_monitor() logic error that could result in
- *       bonding round-robin mode ignoring links after failover/recovery
- *
- * 2003/03/17 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - kmalloc fix (GFP_KERNEL to GFP_ATOMIC) reported by
- *       Shmulik dot Hen at intel.com.
- *     - Based on discussion on mailing list, changed use of
- *       update_slave_cnt(), created wrapper functions for adding/removing
- *       slaves, changed bond_xmit_xor() to check slave_cnt instead of
- *       checking slave and slave->dev (which only worked by accident).
- *     - Misc code cleanup: get arp_send() prototype from header file,
- *       add max_bonds to bonding.txt.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Shmulik Hen <shmulik.hen at intel dot com>
- *     - Make sure only bond_attach_slave() and bond_detach_slave() can
- *       manipulate the slave list, including slave_cnt, even when in
- *       bond_release_all().
- *     - Fixed hang in bond_release() with traffic running:
- *       netdev_set_master() must not be called from within the bond lock.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Shmulik Hen <shmulik.hen at intel dot com>
- *     - Fixed hang in bond_enslave() with traffic running:
- *       netdev_set_master() must not be called from within the bond lock.
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>
- *     - Added support for getting slave's speed and duplex via ethtool.
- *       Needed for 802.3ad and other future modes.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Shmulik Hen <shmulik.hen at intel dot com>
- *     - Enable support of modes that need to use the unique mac address of
- *       each slave.
- *       * bond_enslave(): Moved setting the slave's mac address, and
- *         openning it, from the application to the driver. This breaks
- *         backward comaptibility with old versions of ifenslave that open
- *          the slave before enalsving it !!!.
- *       * bond_release(): The driver also takes care of closing the slave
- *         and restoring its original mac address.
- *     - Removed the code that restores all base driver's flags.
- *       Flags are automatically restored once all undo stages are done
- *       properly.
- *     - Block possibility of enslaving before the master is up. This
- *       prevents putting the system in an unstable state.
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
- *             Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Shmulik Hen <shmulik.hen at intel dot com>
- *     - Added support for IEEE 802.3ad Dynamic link aggregation mode.
- *
- * 2003/05/01 - Amir Noam <amir.noam at intel dot com>
- *     - Added ABI version control to restore compatibility between
- *       new/old ifenslave and new/old bonding.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Fixed bug in bond_release_all(): save old value of curr_active_slave
- *       before setting it to NULL.
- *     - Changed driver versioning scheme to include version number instead
- *       of release date (that is already in another field). There are 3
- *       fields X.Y.Z where:
- *             X - Major version - big behavior changes
- *             Y - Minor version - addition of features
- *             Z - Extra version - minor changes and bug fixes
- *       The current version is 1.0.0 as a base line.
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Amir Noam <amir.noam at intel dot com>
- *     - Added support for lacp_rate module param.
- *     - Code beautification and style changes (mainly in comments).
- *       new version - 1.0.1
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Based on discussion on mailing list, changed locking scheme
- *       to use lock/unlock or lock_bh/unlock_bh appropriately instead
- *       of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
- *       hidden bugs and solves system hangs that occurred due to the fact
- *       that holding lock_irqsave doesn't prevent softirqs from running.
- *       This also increases total throughput since interrupts are not
- *       blocked on each transmitted packets or monitor timeout.
- *       new version - 2.0.0
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Added support for Transmit load balancing mode.
- *     - Concentrate all assignments of curr_active_slave to a single point
- *       so specific modes can take actions when the primary adapter is
- *       changed.
- *     - Take the updelay parameter into consideration during bond_enslave
- *       since some adapters loose their link during setting the device.
- *     - Renamed bond_3ad_link_status_changed() to
- *       bond_3ad_handle_link_change() for compatibility with TLB.
- *       new version - 2.1.0
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
- *     - Added support for Adaptive load balancing mode which is
- *       equivalent to Transmit load balancing + Receive load balancing.
- *       new version - 2.2.0
- *
- * 2003/05/15 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Applied fix to activebackup_arp_monitor posted to bonding-devel
- *       by Tony Cureington <tony.cureington * hp_com>.  Fixes ARP
- *       monitor endless failover bug.  Version to 2.2.10
- *
- * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
- *     - Fixed bug in ABI version control - Don't commit to a specific
- *       ABI version if receiving unsupported ioctl commands.
- *
- * 2003/05/22 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Fix ifenslave -c causing bond to loose existing routes;
- *       added bond_set_mac_address() that doesn't require the
- *       bond to be down.
- *     - In conjunction with fix for ifenslave -c, in
- *       bond_change_active(), changing to the already active slave
- *       is no longer an error (it successfully does nothing).
- *
- * 2003/06/30 - Amir Noam <amir.noam at intel dot com>
- *     - Fixed bond_change_active() for ALB/TLB modes.
- *       Version to 2.2.14.
- *
- * 2003/07/29 - Amir Noam <amir.noam at intel dot com>
- *     - Fixed ARP monitoring bug.
- *       Version to 2.2.15.
- *
- * 2003/07/31 - Willy Tarreau <willy at ods dot org>
- *     - Fixed kernel panic when using ARP monitoring without
- *       setting bond's IP address.
- *       Version to 2.2.16.
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- *     - Back port from 2.6: use alloc_netdev(); fix /proc handling;
- *       made stats a part of bond struct so no need to allocate
- *       and free it separately; use standard list operations instead
- *       of pre-allocated array of bonds.
- *       Version to 2.3.0.
- *
- * 2003/08/07 - Jay Vosburgh <fubar at us dot ibm dot com>,
- *            Amir Noam <amir.noam at intel dot com> and
- *            Shmulik Hen <shmulik.hen at intel dot com>
- *     - Propagating master's settings: Distinguish between modes that
- *       use a primary slave from those that don't, and propagate settings
- *       accordingly; Consolidate change_active opeartions and add
- *       reselect_active and find_best opeartions; Decouple promiscuous
- *       handling from the multicast mode setting; Add support for changing
- *       HW address and MTU with proper unwind; Consolidate procfs code,
- *       add CHANGENAME handler; Enhance netdev notification handling.
- *       Version to 2.4.0.
- *
- * 2003/09/15 - Stephen Hemminger <shemminger at osdl dot org>,
- *            Amir Noam <amir.noam at intel dot com>
- *     - Convert /proc to seq_file interface.
- *       Change /proc/net/bondX/info to /proc/net/bonding/bondX.
- *       Set version to 2.4.1.
- *
- * 2003/11/20 - Amir Noam <amir.noam at intel dot com>
- *     - Fix /proc creation/destruction.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Massive cleanup - Set version to 2.5.0
- *       Code changes:
- *       o Consolidate format of prints and debug prints.
- *       o Remove bonding_t/slave_t typedefs and consolidate all casts.
- *       o Remove dead code and unnecessary checks.
- *       o Consolidate starting/stopping timers.
- *       o Consolidate handling of primary module param throughout the code.
- *       o Removed multicast module param support - all settings are done
- *         according to mode.
- *       o Slave list iteration - bond is no longer part of the list,
- *         added cyclic list iteration macros.
- *       o Consolidate error handling in all xmit functions.
- *       Style changes:
- *       o Consolidate function naming and declarations.
- *       o Consolidate function params and local variables names.
- *       o Consolidate return values.
- *       o Consolidate curly braces.
- *       o Consolidate conditionals format.
- *       o Change struct member names and types.
- *       o Chomp trailing spaces, remove empty lines, fix indentations.
- *       o Re-organize code according to context.
- *
- * 2003/12/30 - Amir Noam <amir.noam at intel dot com>
- *     - Fixed: Cannot remove and re-enslave the original active slave.
- *     - Fixed: Releasing the original active slave causes mac address
- *              duplication.
- *     - Add support for slaves that use ethtool_ops.
- *       Set version to 2.5.3.
- *
- * 2004/01/05 - Amir Noam <amir.noam at intel dot com>
- *     - Save bonding parameters per bond instead of using the global values.
- *       Set version to 2.5.4.
- *
- * 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Enhance VLAN support:
- *       * Add support for VLAN hardware acceleration capable slaves.
- *       * Add capability to tag self generated packets in ALB/TLB modes.
- *       Set version to 2.6.0.
- * 2004/10/29 - Mitch Williams <mitch.a.williams at intel dot com>
- *      - Fixed bug when unloading module while using 802.3ad.  If
- *        spinlock debugging is turned on, this causes a stack dump.
- *        Solution is to move call to dev_remove_pack outside of the
- *        spinlock.
- *        Set version to 2.6.1.
- * 2005/06/05 - Jay Vosburgh <fubar@us.ibm.com>
- *     - Support for generating gratuitous ARPs in active-backup mode.
- *       Includes support for VLAN tagging all bonding-generated ARPs
- *       as needed.  Set version to 2.6.2.
- * 2005/06/08 - Jason Gabler <jygabler at lbl dot gov>
- *     - alternate hashing policy support for mode 2
- *       * Added kernel parameter "xmit_hash_policy" to allow the selection
- *         of different hashing policies for mode 2.  The original mode 2
- *         policy is the default, now found in xmit_hash_policy_layer2().
- *       * Added xmit_hash_policy_layer34()
- *     - Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4.
- *       Set version to 2.6.3.
- * 2005/09/26 - Jay Vosburgh <fubar@us.ibm.com>
- *     - Removed backwards compatibility for old ifenslaves.  Version 2.6.4.
  */
 
 //#define BONDING_DEBUG 1
@@ -557,6 +97,7 @@ static char *lacp_rate       = NULL;
 static char *xmit_hash_policy = NULL;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
+struct bond_params bonding_defaults;
 
 module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -565,17 +106,24 @@ MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
 module_param(updelay, int, 0);
 MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
 module_param(downdelay, int, 0);
-MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
+MODULE_PARM_DESC(downdelay, "Delay before considering link down, "
+                           "in milliseconds");
 module_param(use_carrier, int, 0);
-MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
+MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
+                             "0 for off, 1 for on (default)");
 module_param(mode, charp, 0);
-MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
+MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
+                      "1 for active-backup, 2 for balance-xor, "
+                      "3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
+                      "6 for balance-alb");
 module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
 module_param(lacp_rate, charp, 0);
-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
+MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
+                           "(slow/fast)");
 module_param(xmit_hash_policy, charp, 0);
-MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4");
+MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
+                                  ", 1 for layer 3+4");
 module_param(arp_interval, int, 0);
 MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
 module_param_array(arp_ip_target, charp, NULL, 0);
@@ -586,30 +134,27 @@ MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
 static const char *version =
        DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
-static LIST_HEAD(bond_dev_list);
+LIST_HEAD(bond_dev_list);
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *bond_proc_dir = NULL;
 #endif
 
+extern struct rw_semaphore bonding_rwsem;
 static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
 static int arp_ip_count        = 0;
 static int bond_mode   = BOND_MODE_ROUNDROBIN;
 static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
 static int lacp_fast   = 0;
 
-struct bond_parm_tbl {
-       char *modename;
-       int mode;
-};
 
-static struct bond_parm_tbl bond_lacp_tbl[] = {
+struct bond_parm_tbl bond_lacp_tbl[] = {
 {      "slow",         AD_LACP_SLOW},
 {      "fast",         AD_LACP_FAST},
 {      NULL,           -1},
 };
 
-static struct bond_parm_tbl bond_mode_tbl[] = {
+struct bond_parm_tbl bond_mode_tbl[] = {
 {      "balance-rr",           BOND_MODE_ROUNDROBIN},
 {      "active-backup",        BOND_MODE_ACTIVEBACKUP},
 {      "balance-xor",          BOND_MODE_XOR},
@@ -620,7 +165,7 @@ static struct bond_parm_tbl bond_mode_tbl[] = {
 {      NULL,                   -1},
 };
 
-static struct bond_parm_tbl xmit_hashtype_tbl[] = {
+struct bond_parm_tbl xmit_hashtype_tbl[] = {
 {      "layer2",               BOND_XMIT_POLICY_LAYER2},
 {      "layer3+4",             BOND_XMIT_POLICY_LAYER34},
 {      NULL,                   -1},
@@ -628,12 +173,11 @@ static struct bond_parm_tbl xmit_hashtype_tbl[] = {
 
 /*-------------------------- Forward declarations ---------------------------*/
 
-static inline void bond_set_mode_ops(struct bonding *bond, int mode);
 static void bond_send_gratuitous_arp(struct bonding *bond);
 
 /*---------------------------- General routines -----------------------------*/
 
-static const char *bond_mode_name(int mode)
+const char *bond_mode_name(int mode)
 {
        switch (mode) {
        case BOND_MODE_ROUNDROBIN :
@@ -910,7 +454,7 @@ static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
        res = bond_add_vlan(bond, vid);
        if (res) {
                printk(KERN_ERR DRV_NAME
-                      ": %s: Failed to add vlan id %d\n",
+                      ": %s: Error: Failed to add vlan id %d\n",
                       bond_dev->name, vid);
        }
 }
@@ -944,7 +488,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
        res = bond_del_vlan(bond, vid);
        if (res) {
                printk(KERN_ERR DRV_NAME
-                      ": %s: Failed to remove vlan id %d\n",
+                      ": %s: Error: Failed to remove vlan id %d\n",
                       bond_dev->name, vid);
        }
 }
@@ -1449,7 +993,7 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
  *
  * Warning: Caller must hold curr_slave_lock for writing.
  */
-static void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 {
        struct slave *old_active = bond->curr_active_slave;
 
@@ -1523,7 +1067,7 @@ static void bond_change_active_slave(struct bonding *bond, struct slave *new_act
  *
  * Warning: Caller must hold curr_slave_lock for writing.
  */
-static void bond_select_active_slave(struct bonding *bond)
+void bond_select_active_slave(struct bonding *bond)
 {
        struct slave *best_slave;
 
@@ -1591,7 +1135,7 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
 
 /*---------------------------------- IOCTL ----------------------------------*/
 
-static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
 {
        dprintk("bond_dev=%p\n", bond_dev);
        dprintk("slave_dev=%p\n", slave_dev);
@@ -1631,7 +1175,7 @@ static int bond_compute_features(struct bonding *bond)
 }
 
 /* enslave device <slave> to bond device <master> */
-static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 {
        struct bonding *bond = bond_dev->priv;
        struct slave *new_slave = NULL;
@@ -1644,8 +1188,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
        if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
                slave_dev->do_ioctl == NULL) {
                printk(KERN_WARNING DRV_NAME
-                      ": Warning : no link monitoring support for %s\n",
-                      slave_dev->name);
+                      ": %s: Warning: no link monitoring support for %s\n",
+                      bond_dev->name, slave_dev->name);
        }
 
        /* bond must be initialized by bond_open() before enslaving */
@@ -1666,17 +1210,17 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
                dprintk("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
                if (!list_empty(&bond->vlan_list)) {
                        printk(KERN_ERR DRV_NAME
-                              ": Error: cannot enslave VLAN "
+                              ": %s: Error: cannot enslave VLAN "
                               "challenged slave %s on VLAN enabled "
-                              "bond %s\n", slave_dev->name,
+                              "bond %s\n", bond_dev->name, slave_dev->name,
                               bond_dev->name);
                        return -EPERM;
                } else {
                        printk(KERN_WARNING DRV_NAME
-                              ": Warning: enslaved VLAN challenged "
+                              ": %s: Warning: enslaved VLAN challenged "
                               "slave %s. Adding VLANs will be blocked as "
                               "long as %s is part of bond %s\n",
-                              slave_dev->name, slave_dev->name,
+                              bond_dev->name, slave_dev->name, slave_dev->name,
                               bond_dev->name);
                        bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
                }
@@ -1706,12 +1250,11 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
 
        if (slave_dev->set_mac_address == NULL) {
                printk(KERN_ERR DRV_NAME
-                      ": Error: The slave device you specified does "
-                      "not support setting the MAC address.\n");
-               printk(KERN_ERR
-                      "Your kernel likely does not support slave devices.\n");
-
-               res = -EOPNOTSUPP;
+                       ": %s: Error: The slave device you specified does "
+                       "not support setting the MAC address. "
+                       "Your kernel likely does not support slave "
+                       "devices.\n", bond_dev->name);
+               res = -EOPNOTSUPP;
                goto err_undo_flags;
        }
 
@@ -1827,21 +1370,21 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
                         * the messages for netif_carrier.
                         */
                        printk(KERN_WARNING DRV_NAME
-                              ": Warning: MII and ETHTOOL support not "
+                              ": %s: Warning: MII and ETHTOOL support not "
                               "available for interface %s, and "
                               "arp_interval/arp_ip_target module parameters "
                               "not specified, thus bonding will not detect "
                               "link failures! see bonding.txt for details.\n",
-                              slave_dev->name);
+                              bond_dev->name, slave_dev->name);
                } else if (link_reporting == -1) {
                        /* unable get link status using mii/ethtool */
                        printk(KERN_WARNING DRV_NAME
-                              ": Warning: can't get link status from "
+                              ": %s: Warning: can't get link status from "
                               "interface %s; the network driver associated "
                               "with this interface does not support MII or "
                               "ETHTOOL link status reporting, thus miimon "
                               "has no effect on this interface.\n",
-                              slave_dev->name);
+                              bond_dev->name, slave_dev->name);
                }
        }
 
@@ -1868,15 +1411,15 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
        if (bond_update_speed_duplex(new_slave) &&
            (new_slave->link != BOND_LINK_DOWN)) {
                printk(KERN_WARNING DRV_NAME
-                      ": Warning: failed to get speed and duplex from %s, "
+                      ": %s: Warning: failed to get speed and duplex from %s, "
                       "assumed to be 100Mb/sec and Full.\n",
-                      new_slave->dev->name);
+                      bond_dev->name, new_slave->dev->name);
 
                if (bond->params.mode == BOND_MODE_8023AD) {
-                       printk(KERN_WARNING
-                              "Operation of 802.3ad mode requires ETHTOOL "
+                       printk(KERN_WARNING DRV_NAME
+                              ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
                               "support in base driver for proper aggregator "
-                              "selection.\n");
+                              "selection.\n", bond_dev->name);
                }
        }
 
@@ -1958,6 +1501,10 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
 
        write_unlock_bh(&bond->lock);
 
+       res = bond_create_slave_symlinks(bond_dev, slave_dev);
+       if (res)
+               goto err_unset_master;
+
        printk(KERN_INFO DRV_NAME
               ": %s: enslaving %s as a%s interface with a%s link.\n",
               bond_dev->name, slave_dev->name,
@@ -1999,7 +1546,7 @@ err_undo_flags:
  *   for Bonded connections:
  *     The first up interface should be left on and all others downed.
  */
-static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 {
        struct bonding *bond = bond_dev->priv;
        struct slave *slave, *oldcurrent;
@@ -2010,7 +1557,7 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
        if (!(slave_dev->flags & IFF_SLAVE) ||
            (slave_dev->master != bond_dev)) {
                printk(KERN_ERR DRV_NAME
-                      ": Error: %s: cannot release %s.\n",
+                      ": %s: Error: cannot release %s.\n",
                       bond_dev->name, slave_dev->name);
                return -EINVAL;
        }
@@ -2031,11 +1578,12 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
                                 ETH_ALEN);
        if (!mac_addr_differ && (bond->slave_cnt > 1)) {
                printk(KERN_WARNING DRV_NAME
-                      ": Warning: the permanent HWaddr of %s "
+                      ": %s: Warning: the permanent HWaddr of %s "
                       "- %02X:%02X:%02X:%02X:%02X:%02X - is "
                       "still in use by %s. Set the HWaddr of "
                       "%s to a different address to avoid "
                       "conflicts.\n",
+                      bond_dev->name,
                       slave_dev->name,
                       slave->perm_hwaddr[0],
                       slave->perm_hwaddr[1],
@@ -2111,24 +1659,28 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
                        bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
                } else {
                        printk(KERN_WARNING DRV_NAME
-                              ": Warning: clearing HW address of %s while it "
+                              ": %s: Warning: clearing HW address of %s while it "
                               "still has VLANs.\n",
-                              bond_dev->name);
+                              bond_dev->name, bond_dev->name);
                        printk(KERN_WARNING DRV_NAME
-                              ": When re-adding slaves, make sure the bond's "
-                              "HW address matches its VLANs'.\n");
+                              ": %s: When re-adding slaves, make sure the bond's "
+                              "HW address matches its VLANs'.\n",
+                              bond_dev->name);
                }
        } else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
                   !bond_has_challenged_slaves(bond)) {
                printk(KERN_INFO DRV_NAME
-                      ": last VLAN challenged slave %s "
+                      ": %s: last VLAN challenged slave %s "
                       "left bond %s. VLAN blocking is removed\n",
-                      slave_dev->name, bond_dev->name);
+                      bond_dev->name, slave_dev->name, bond_dev->name);
                bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
        }
 
        write_unlock_bh(&bond->lock);
 
+       /* must do this from outside any spinlocks */
+       bond_destroy_slave_symlinks(bond_dev, slave_dev);
+
        bond_del_vlans_from_slave(bond, slave_dev);
 
        /* If the mode USES_PRIMARY, then we should only remove its
@@ -2220,6 +1772,7 @@ static int bond_release_all(struct net_device *bond_dev)
                 */
                write_unlock_bh(&bond->lock);
 
+               bond_destroy_slave_symlinks(bond_dev, slave_dev);
                bond_del_vlans_from_slave(bond, slave_dev);
 
                /* If the mode USES_PRIMARY, then we should only remove its
@@ -2274,12 +1827,13 @@ static int bond_release_all(struct net_device *bond_dev)
                bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
        } else {
                printk(KERN_WARNING DRV_NAME
-                      ": Warning: clearing HW address of %s while it "
+                      ": %s: Warning: clearing HW address of %s while it "
                       "still has VLANs.\n",
-                      bond_dev->name);
+                      bond_dev->name, bond_dev->name);
                printk(KERN_WARNING DRV_NAME
-                      ": When re-adding slaves, make sure the bond's "
-                      "HW address matches its VLANs'.\n");
+                      ": %s: When re-adding slaves, make sure the bond's "
+                      "HW address matches its VLANs'.\n",
+                      bond_dev->name);
        }
 
        printk(KERN_INFO DRV_NAME
@@ -2397,7 +1951,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
 /*-------------------------------- Monitoring -------------------------------*/
 
 /* this function is called regularly to monitor each slave's link. */
-static void bond_mii_monitor(struct net_device *bond_dev)
+void bond_mii_monitor(struct net_device *bond_dev)
 {
        struct bonding *bond = bond_dev->priv;
        struct slave *slave, *oldcurrent;
@@ -2596,8 +2150,11 @@ static void bond_mii_monitor(struct net_device *bond_dev)
                        break;
                default:
                        /* Should not happen */
-                       printk(KERN_ERR "bonding: Error: %s  Illegal value (link=%d)\n",
-                              slave->dev->name, slave->link);
+                       printk(KERN_ERR DRV_NAME
+                              ": %s: Error: %s Illegal value (link=%d)\n",
+                              bond_dev->name,
+                              slave->dev->name,
+                              slave->link);
                        goto out;
                } /* end of switch (slave->link) */
 
@@ -2721,7 +2278,9 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
        struct flowi fl;
        struct rtable *rt;
 
-       for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
+       for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+               if (!targets[i])
+                       continue;
                dprintk("basa: target %x\n", targets[i]);
                if (list_empty(&bond->vlan_list)) {
                        dprintk("basa: empty vlan: arp_send\n");
@@ -2825,7 +2384,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
  * arp is transmitted to generate traffic. see activebackup_arp_monitor for
  * arp monitoring in active backup mode.
  */
-static void bond_loadbalance_arp_mon(struct net_device *bond_dev)
+void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 {
        struct bonding *bond = bond_dev->priv;
        struct slave *slave, *oldcurrent;
@@ -2963,7 +2522,7 @@ out:
  * may have received.
  * see loadbalance_arp_monitor for arp monitoring in load balancing mode
  */
-static void bond_activebackup_arp_mon(struct net_device *bond_dev)
+void bond_activebackup_arp_mon(struct net_device *bond_dev)
 {
        struct bonding *bond = bond_dev->priv;
        struct slave *slave;
@@ -3249,6 +2808,8 @@ static void bond_info_show_master(struct seq_file *seq)
 {
        struct bonding *bond = seq->private;
        struct slave *curr;
+       int i;
+       u32 target;
 
        read_lock(&bond->curr_slave_lock);
        curr = bond->curr_active_slave;
@@ -3257,10 +2818,17 @@ static void bond_info_show_master(struct seq_file *seq)
        seq_printf(seq, "Bonding Mode: %s\n",
                   bond_mode_name(bond->params.mode));
 
+       if (bond->params.mode == BOND_MODE_XOR ||
+               bond->params.mode == BOND_MODE_8023AD) {
+               seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
+                       xmit_hashtype_tbl[bond->params.xmit_policy].modename,
+                       bond->params.xmit_policy);
+       }
+
        if (USES_PRIMARY(bond->params.mode)) {
                seq_printf(seq, "Primary Slave: %s\n",
-                          (bond->params.primary[0]) ?
-                               bond->params.primary : "None");
+                          (bond->primary_slave) ?
+                          bond->primary_slave->dev->name : "None");
 
                seq_printf(seq, "Currently Active Slave: %s\n",
                           (curr) ? curr->dev->name : "None");
@@ -3273,6 +2841,27 @@ static void bond_info_show_master(struct seq_file *seq)
        seq_printf(seq, "Down Delay (ms): %d\n",
                   bond->params.downdelay * bond->params.miimon);
 
+
+       /* ARP information */
+       if(bond->params.arp_interval > 0) {
+               int printed=0;
+               seq_printf(seq, "ARP Polling Interval (ms): %d\n",
+                               bond->params.arp_interval);
+
+               seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
+
+               for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
+                       if (!bond->params.arp_targets[i])
+                               continue;
+                       if (printed)
+                               seq_printf(seq, ",");
+                       target = ntohl(bond->params.arp_targets[i]);
+                       seq_printf(seq, " %d.%d.%d.%d", HIPQUAD(target));
+                       printed = 1;
+               }
+               seq_printf(seq, "\n");
+       }
+
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
 
@@ -3478,7 +3067,10 @@ static int bond_event_changename(struct bonding *bond)
        bond_remove_proc_entry(bond);
        bond_create_proc_entry(bond);
 #endif
-
+       down_write(&(bonding_rwsem));
+        bond_destroy_sysfs_entry(bond);
+        bond_create_sysfs_entry(bond);
+       up_write(&(bonding_rwsem));
        return NOTIFY_DONE;
 }
 
@@ -3955,6 +3547,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                return -EPERM;
        }
 
+       down_write(&(bonding_rwsem));
        slave_dev = dev_get_by_name(ifr->ifr_slave);
 
        dprintk("slave_dev=%p: \n", slave_dev);
@@ -3987,6 +3580,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                dev_put(slave_dev);
        }
 
+       up_write(&(bonding_rwsem));
        return res;
 }
 
@@ -4071,6 +3665,7 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
        bond_for_each_slave(bond, slave, i) {
                dprintk("s %p s->p %p c_m %p\n", slave,
                        slave->prev, slave->dev->change_mtu);
+
                res = dev_set_mtu(slave->dev, new_mtu);
 
                if (res) {
@@ -4397,8 +3992,9 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
                                struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
                                if (!skb2) {
                                        printk(KERN_ERR DRV_NAME
-                                              ": Error: bond_xmit_broadcast(): "
-                                              "skb_clone() failed\n");
+                                              ": %s: Error: bond_xmit_broadcast(): "
+                                              "skb_clone() failed\n",
+                                              bond_dev->name);
                                        continue;
                                }
 
@@ -4431,7 +4027,7 @@ out:
 /*
  * set bond mode specific net device operations
  */
-static inline void bond_set_mode_ops(struct bonding *bond, int mode)
+void bond_set_mode_ops(struct bonding *bond, int mode)
 {
        struct net_device *bond_dev = bond->dev;
 
@@ -4467,7 +4063,8 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode)
        default:
                /* Should never happen, mode already checked */
                printk(KERN_ERR DRV_NAME
-                      ": Error: Unknown bonding mode %d\n",
+                      ": %s: Error: Unknown bonding mode %d\n",
+                      bond_dev->name,
                       mode);
                break;
        }
@@ -4491,7 +4088,7 @@ static struct ethtool_ops bond_ethtool_ops = {
  * Does not allocate but creates a /proc entry.
  * Allowed to fail.
  */
-static int __init bond_init(struct net_device *bond_dev, struct bond_params *params)
+static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 {
        struct bonding *bond = bond_dev->priv;
 
@@ -4565,7 +4162,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
 /* De-initialize device specific data.
  * Caller must hold rtnl_lock.
  */
-static inline void bond_deinit(struct net_device *bond_dev)
+void bond_deinit(struct net_device *bond_dev)
 {
        struct bonding *bond = bond_dev->priv;
 
@@ -4601,7 +4198,7 @@ static void bond_free_all(void)
  * Convert string input module parms.  Accept either the
  * number of the mode or its string name.
  */
-static inline int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
 {
        int i;
 
@@ -4670,7 +4267,7 @@ static int bond_check_params(struct bond_params *params)
        if (max_bonds < 1 || max_bonds > INT_MAX) {
                printk(KERN_WARNING DRV_NAME
                       ": Warning: max_bonds (%d) not in range %d-%d, so it "
-                      "was reset to BOND_DEFAULT_MAX_BONDS (%d)",
+                      "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
                       max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
                max_bonds = BOND_DEFAULT_MAX_BONDS;
        }
@@ -4881,81 +4478,96 @@ static int bond_check_params(struct bond_params *params)
        return 0;
 }
 
+/* Create a new bond based on the specified name and bonding parameters.
+ * Caller must NOT hold rtnl_lock; we need to release it here before we
+ * set up our sysfs entries.
+ */
+int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
+{
+       struct net_device *bond_dev;
+       int res;
+
+       rtnl_lock();
+       bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup);
+       if (!bond_dev) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: eek! can't alloc netdev!\n",
+                      name);
+               res = -ENOMEM;
+               goto out_rtnl;
+       }
+
+       /* bond_init() must be called after dev_alloc_name() (for the
+        * /proc files), but before register_netdevice(), because we
+        * need to set function pointers.
+        */
+
+       res = bond_init(bond_dev, params);
+       if (res < 0) {
+               goto out_netdev;
+       }
+
+       SET_MODULE_OWNER(bond_dev);
+
+       res = register_netdevice(bond_dev);
+       if (res < 0) {
+               goto out_bond;
+       }
+       if (newbond)
+               *newbond = bond_dev->priv;
+
+       rtnl_unlock(); /* allows sysfs registration of net device */
+       res = bond_create_sysfs_entry(bond_dev->priv);
+       goto done;
+out_bond:
+       bond_deinit(bond_dev);
+out_netdev:
+       free_netdev(bond_dev);
+out_rtnl:
+       rtnl_unlock();
+done:
+       return res;
+}
+
 static int __init bonding_init(void)
 {
-       struct bond_params params;
        int i;
        int res;
+       char new_bond_name[8];  /* Enough room for 999 bonds at init. */
 
        printk(KERN_INFO "%s", version);
 
-       res = bond_check_params(&params);
+       res = bond_check_params(&bonding_defaults);
        if (res) {
-               return res;
+               goto out;
        }
 
-       rtnl_lock();
-
 #ifdef CONFIG_PROC_FS
        bond_create_proc_dir();
 #endif
-
        for (i = 0; i < max_bonds; i++) {
-               struct net_device *bond_dev;
-
-               bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
-               if (!bond_dev) {
-                       res = -ENOMEM;
-                       goto out_err;
-               }
-
-               res = dev_alloc_name(bond_dev, "bond%d");
-               if (res < 0) {
-                       free_netdev(bond_dev);
-                       goto out_err;
-               }
-
-               /* bond_init() must be called after dev_alloc_name() (for the
-                * /proc files), but before register_netdevice(), because we
-                * need to set function pointers.
-                */
-               res = bond_init(bond_dev, &params);
-               if (res < 0) {
-                       free_netdev(bond_dev);
-                       goto out_err;
-               }
-
-               SET_MODULE_OWNER(bond_dev);
-
-               res = register_netdevice(bond_dev);
-               if (res < 0) {
-                       bond_deinit(bond_dev);
-                       free_netdev(bond_dev);
-                       goto out_err;
-               }
+               sprintf(new_bond_name, "bond%d",i);
+               res = bond_create(new_bond_name,&bonding_defaults, NULL);
+               if (res)
+                       goto err;
        }
 
-       rtnl_unlock();
+       res = bond_create_sysfs();
+       if (res)
+               goto err;
+
        register_netdevice_notifier(&bond_netdev_notifier);
        register_inetaddr_notifier(&bond_inetaddr_notifier);
 
-       return 0;
-
-out_err:
-       /*
-        * rtnl_unlock() will run netdev_run_todo(), putting the
-        * thus-far-registered bonding devices into a state which
-        * unregigister_netdevice() will accept
-        */
-       rtnl_unlock();
+       goto out;
+err:
        rtnl_lock();
-
-       /* free and unregister all bonds that were successfully added */
        bond_free_all();
-
+       bond_destroy_sysfs();
        rtnl_unlock();
-
+out:
        return res;
+
 }
 
 static void __exit bonding_exit(void)
@@ -4965,6 +4577,7 @@ static void __exit bonding_exit(void)
 
        rtnl_lock();
        bond_free_all();
+       bond_destroy_sysfs();
        rtnl_unlock();
 }
 
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
new file mode 100644 (file)
index 0000000..32d13da
--- /dev/null
@@ -0,0 +1,1358 @@
+
+/*
+ * Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/in.h>
+#include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/inet.h>
+#include <linux/rtnetlink.h>
+
+/* #define BONDING_DEBUG 1 */
+#include "bonding.h"
+#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#define to_bond(cd)    ((struct bonding *)(to_net_dev(cd)->priv))
+
+/*---------------------------- Declarations -------------------------------*/
+
+
+extern struct list_head bond_dev_list;
+extern struct bond_params bonding_defaults;
+extern struct bond_parm_tbl bond_mode_tbl[];
+extern struct bond_parm_tbl bond_lacp_tbl[];
+extern struct bond_parm_tbl xmit_hashtype_tbl[];
+
+static int expected_refcount = -1;
+static struct class *netdev_class;
+/*--------------------------- Data Structures -----------------------------*/
+
+/* Bonding sysfs lock.  Why can't we just use the subsytem lock?
+ * Because kobject_register tries to acquire the subsystem lock.  If
+ * we already hold the lock (which we would if the user was creating
+ * a new bond through the sysfs interface), we deadlock.
+ * This lock is only needed when deleting a bond - we need to make sure
+ * that we don't collide with an ongoing ioctl.
+ */
+
+struct rw_semaphore bonding_rwsem;
+
+
+
+
+/*------------------------------ Functions --------------------------------*/
+
+/*
+ * "show" function for the bond_masters attribute.
+ * The class parameter is ignored.
+ */
+static ssize_t bonding_show_bonds(struct class *cls, char *buffer)
+{
+       int res = 0;
+       struct bonding *bond;
+
+       down_read(&(bonding_rwsem));
+
+       list_for_each_entry(bond, &bond_dev_list, bond_list) {
+               if (res > (PAGE_SIZE - IFNAMSIZ)) {
+                       /* not enough space for another interface name */
+                       if ((PAGE_SIZE - res) > 10)
+                               res = PAGE_SIZE - 10;
+                       res += sprintf(buffer + res, "++more++");
+                       break;
+               }
+               res += sprintf(buffer + res, "%s ",
+                              bond->dev->name);
+       }
+       res += sprintf(buffer + res, "\n");
+       res++;
+       up_read(&(bonding_rwsem));
+       return res;
+}
+
+/*
+ * "store" function for the bond_masters attribute.  This is what
+ * creates and deletes entire bonds.
+ *
+ * The class parameter is ignored.
+ *
+ */
+
+static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t count)
+{
+       char command[IFNAMSIZ + 1] = {0, };
+       char *ifname;
+       int res = count;
+       struct bonding *bond;
+       struct bonding *nxt;
+
+       down_write(&(bonding_rwsem));
+       sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
+       ifname = command + 1;
+       if ((strlen(command) <= 1) ||
+           !dev_valid_name(ifname))
+               goto err_no_cmd;
+
+       if (command[0] == '+') {
+
+               /* Check to see if the bond already exists. */
+               list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+                       if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
+                               printk(KERN_ERR DRV_NAME
+                                       ": cannot add bond %s; it already exists\n",
+                                       ifname);
+                               res = -EPERM;
+                               goto out;
+                       }
+
+               printk(KERN_INFO DRV_NAME
+                       ": %s is being created...\n", ifname);
+               if (bond_create(ifname, &bonding_defaults, &bond)) {
+                       printk(KERN_INFO DRV_NAME
+                       ": %s interface already exists. Bond creation failed.\n",
+                       ifname);
+                       res = -EPERM;
+               }
+               goto out;
+       }
+
+       if (command[0] == '-') {
+               list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+                       if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
+                               rtnl_lock();
+                               /* check the ref count on the bond's kobject.
+                                * If it's > expected, then there's a file open,
+                                * and we have to fail.
+                                */
+                               if (atomic_read(&bond->dev->class_dev.kobj.kref.refcount)
+                                                       > expected_refcount){
+                                       rtnl_unlock();
+                                       printk(KERN_INFO DRV_NAME
+                                               ": Unable remove bond %s due to open references.\n",
+                                               ifname);
+                                       res = -EPERM;
+                                       goto out;
+                               }
+                               printk(KERN_INFO DRV_NAME
+                                       ": %s is being deleted...\n",
+                                       bond->dev->name);
+                               unregister_netdevice(bond->dev);
+                               bond_deinit(bond->dev);
+                               bond_destroy_sysfs_entry(bond);
+                               rtnl_unlock();
+                               goto out;
+                       }
+
+               printk(KERN_ERR DRV_NAME
+                       ": unable to delete non-existent bond %s\n", ifname);
+               res = -ENODEV;
+               goto out;
+       }
+
+err_no_cmd:
+       printk(KERN_ERR DRV_NAME
+               ": no command found in bonding_masters. Use +ifname or -ifname.\n");
+       res = -EPERM;
+
+       /* Always return either count or an error.  If you return 0, you'll
+        * get called forever, which is bad.
+        */
+out:
+       up_write(&(bonding_rwsem));
+       return res;
+}
+/* class attribute for bond_masters file.  This ends up in /sys/class/net */
+static CLASS_ATTR(bonding_masters,  S_IWUSR | S_IRUGO,
+                 bonding_show_bonds, bonding_store_bonds);
+
+int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave)
+{
+       char linkname[IFNAMSIZ+7];
+       int ret = 0;
+
+       /* first, create a link from the slave back to the master */
+       ret = sysfs_create_link(&(slave->class_dev.kobj), &(master->class_dev.kobj),
+                               "master");
+       if (ret)
+               return ret;
+       /* next, create a link from the master to the slave */
+       sprintf(linkname,"slave_%s",slave->name);
+       ret = sysfs_create_link(&(master->class_dev.kobj), &(slave->class_dev.kobj),
+                               linkname);
+       return ret;
+
+}
+
+void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave)
+{
+       char linkname[IFNAMSIZ+7];
+
+       sysfs_remove_link(&(slave->class_dev.kobj), "master");
+       sprintf(linkname,"slave_%s",slave->name);
+       sysfs_remove_link(&(master->class_dev.kobj), linkname);
+}
+
+
+/*
+ * Show the slaves in the current bond.
+ */
+static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
+{
+       struct slave *slave;
+       int i, res = 0;
+       struct bonding *bond = to_bond(cd);
+
+       read_lock_bh(&bond->lock);
+       bond_for_each_slave(bond, slave, i) {
+               if (res > (PAGE_SIZE - IFNAMSIZ)) {
+                       /* not enough space for another interface name */
+                       if ((PAGE_SIZE - res) > 10)
+                               res = PAGE_SIZE - 10;
+                       res += sprintf(buf + res, "++more++");
+                       break;
+               }
+               res += sprintf(buf + res, "%s ", slave->dev->name);
+       }
+       read_unlock_bh(&bond->lock);
+       res += sprintf(buf + res, "\n");
+       res++;
+       return res;
+}
+
+/*
+ * Set the slaves in the current bond.  The bond interface must be
+ * up for this to succeed.
+ * This function is largely the same flow as bonding_update_bonds().
+ */
+static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, size_t count)
+{
+       char command[IFNAMSIZ + 1] = { 0, };
+       char *ifname;
+       int i, res, found, ret = count;
+       struct slave *slave;
+       struct net_device *dev = 0;
+       struct bonding *bond = to_bond(cd);
+
+       /* Quick sanity check -- is the bond interface up? */
+       if (!(bond->dev->flags & IFF_UP)) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Unable to update slaves because interface is down.\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       /* Note:  We can't hold bond->lock here, as bond_create grabs it. */
+
+       sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
+       ifname = command + 1;
+       if ((strlen(command) <= 1) ||
+           !dev_valid_name(ifname))
+               goto err_no_cmd;
+
+       if (command[0] == '+') {
+
+               /* Got a slave name in ifname.  Is it already in the list? */
+               found = 0;
+               read_lock_bh(&bond->lock);
+               bond_for_each_slave(bond, slave, i)
+                       if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+                               printk(KERN_ERR DRV_NAME
+                                      ": %s: Interface %s is already enslaved!\n",
+                                      bond->dev->name, ifname);
+                               ret = -EPERM;
+                               read_unlock_bh(&bond->lock);
+                               goto out;
+                       }
+
+               read_unlock_bh(&bond->lock);
+               printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
+                      bond->dev->name, ifname);
+               dev = dev_get_by_name(ifname);
+               if (!dev) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: Interface %s does not exist!\n",
+                              bond->dev->name, ifname);
+                       ret = -EPERM;
+                       goto out;
+               }
+               else
+                       dev_put(dev);
+
+               if (dev->flags & IFF_UP) {
+                       printk(KERN_ERR DRV_NAME
+                              ": %s: Error: Unable to enslave %s "
+                              "because it is already up.\n",
+                              bond->dev->name, dev->name);
+                       ret = -EPERM;
+                       goto out;
+               }
+               /* If this is the first slave, then we need to set
+                  the master's hardware address to be the same as the
+                  slave's. */
+               if (!(*((u32 *) & (bond->dev->dev_addr[0])))) {
+                       memcpy(bond->dev->dev_addr, dev->dev_addr,
+                              dev->addr_len);
+               }
+
+               /* Set the slave's MTU to match the bond */
+               if (dev->mtu != bond->dev->mtu) {
+                       if (dev->change_mtu) {
+                               res = dev->change_mtu(dev,
+                                                     bond->dev->mtu);
+                               if (res) {
+                                       ret = res;
+                                       goto out;
+                               }
+                       } else {
+                               dev->mtu = bond->dev->mtu;
+                       }
+               }
+               rtnl_lock();
+               res = bond_enslave(bond->dev, dev);
+               rtnl_unlock();
+               if (res) {
+                       ret = res;
+               }
+               goto out;
+       }
+
+       if (command[0] == '-') {
+               dev = NULL;
+               bond_for_each_slave(bond, slave, i)
+                       if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+                               dev = slave->dev;
+                               break;
+                       }
+               if (dev) {
+                       printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
+                               bond->dev->name, dev->name);
+                       rtnl_lock();
+                       res = bond_release(bond->dev, dev);
+                       rtnl_unlock();
+                       if (res) {
+                               ret = res;
+                               goto out;
+                       }
+                       /* set the slave MTU to the default */
+                       if (dev->change_mtu) {
+                               dev->change_mtu(dev, 1500);
+                       } else {
+                               dev->mtu = 1500;
+                       }
+               }
+               else {
+                       printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
+                               ifname, bond->dev->name);
+                       ret = -ENODEV;
+               }
+               goto out;
+       }
+
+err_no_cmd:
+       printk(KERN_ERR DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
+       ret = -EPERM;
+
+out:
+       return ret;
+}
+
+static CLASS_DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
+
+/*
+ * Show and set the bonding mode.  The bond interface must be down to
+ * change the mode.
+ */
+static ssize_t bonding_show_mode(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%s %d\n",
+                       bond_mode_tbl[bond->params.mode].modename,
+                       bond->params.mode) + 1;
+}
+
+static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->dev->flags & IFF_UP) {
+               printk(KERN_ERR DRV_NAME
+                      ": unable to update mode of %s because interface is up.\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
+       if (new_value < 0)  {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Ignoring invalid mode value %.*s.\n",
+                      bond->dev->name,
+                      (int)strlen(buf) - 1, buf);
+               ret = -EINVAL;
+               goto out;
+       } else {
+               bond->params.mode = new_value;
+               bond_set_mode_ops(bond, bond->params.mode);
+               printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
+                       bond->dev->name, bond_mode_tbl[new_value].modename, new_value);
+       }
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
+
+/*
+ * Show and set the bonding transmit hash method.  The bond interface must be down to
+ * change the xmit hash policy.
+ */
+static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
+{
+       int count;
+       struct bonding *bond = to_bond(cd);
+
+       if ((bond->params.mode != BOND_MODE_XOR) &&
+           (bond->params.mode != BOND_MODE_8023AD)) {
+               // Not Applicable
+               count = sprintf(buf, "NA\n") + 1;
+       } else {
+               count = sprintf(buf, "%s %d\n",
+                       xmit_hashtype_tbl[bond->params.xmit_policy].modename,
+                       bond->params.xmit_policy) + 1;
+       }
+
+       return count;
+}
+
+static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->dev->flags & IFF_UP) {
+               printk(KERN_ERR DRV_NAME
+                      "%s: Interface is up. Unable to update xmit policy.\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       if ((bond->params.mode != BOND_MODE_XOR) &&
+           (bond->params.mode != BOND_MODE_8023AD)) {
+               printk(KERN_ERR DRV_NAME
+                      "%s: Transmit hash policy is irrelevant in this mode.\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
+       if (new_value < 0)  {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
+                      bond->dev->name,
+                      (int)strlen(buf) - 1, buf);
+               ret = -EINVAL;
+               goto out;
+       } else {
+               bond->params.xmit_policy = new_value;
+               bond_set_mode_ops(bond, bond->params.mode);
+               printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
+                       bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);
+       }
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
+
+/*
+ * Show and set the arp timer interval.  There are two tricky bits
+ * here.  First, if ARP monitoring is activated, then we must disable
+ * MII monitoring.  Second, if the ARP timer isn't running, we must
+ * start it.
+ */
+static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;
+}
+
+static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: no arp_interval value specified.\n",
+                      bond->dev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+       if (new_value < 0) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
+                      bond->dev->name, new_value, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       printk(KERN_INFO DRV_NAME
+              ": %s: Setting ARP monitoring interval to %d.\n",
+              bond->dev->name, new_value);
+       bond->params.arp_interval = new_value;
+       if (bond->params.miimon) {
+               printk(KERN_INFO DRV_NAME
+                      ": %s: ARP monitoring cannot be used with MII monitoring. "
+                      "%s Disabling MII monitoring.\n",
+                      bond->dev->name, bond->dev->name);
+               bond->params.miimon = 0;
+               /* Kill MII timer, else it brings bond's link down */
+               if (bond->arp_timer.function) {
+                       printk(KERN_INFO DRV_NAME
+                       ": %s: Kill MII timer, else it brings bond's link down...\n",
+                      bond->dev->name);
+                       del_timer_sync(&bond->mii_timer);
+               }
+       }
+       if (!bond->params.arp_targets[0]) {
+               printk(KERN_INFO DRV_NAME
+                      ": %s: ARP monitoring has been set up, "
+                      "but no ARP targets have been specified.\n",
+                      bond->dev->name);
+       }
+       if (bond->dev->flags & IFF_UP) {
+               /* If the interface is up, we may need to fire off
+                * the ARP timer.  If the interface is down, the
+                * timer will get fired off when the open function
+                * is called.
+                */
+               if (bond->arp_timer.function) {
+                       /* The timer's already set up, so fire it off */
+                       mod_timer(&bond->arp_timer, jiffies + 1);
+               } else {
+                       /* Set up the timer. */
+                       init_timer(&bond->arp_timer);
+                       bond->arp_timer.expires = jiffies + 1;
+                       bond->arp_timer.data =
+                               (unsigned long) bond->dev;
+                       if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
+                               bond->arp_timer.function =
+                                       (void *)
+                                       &bond_activebackup_arp_mon;
+                       } else {
+                               bond->arp_timer.function =
+                                       (void *)
+                                       &bond_loadbalance_arp_mon;
+                       }
+                       add_timer(&bond->arp_timer);
+               }
+       }
+
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
+
+/*
+ * Show and set the arp targets.
+ */
+static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
+{
+       int i, res = 0;
+       struct bonding *bond = to_bond(cd);
+
+       for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
+               if (bond->params.arp_targets[i])
+                       res += sprintf(buf + res, "%u.%u.%u.%u ",
+                              NIPQUAD(bond->params.arp_targets[i]));
+       }
+       if (res)
+               res--;  /* eat the leftover space */
+       res += sprintf(buf + res, "\n");
+       res++;
+       return res;
+}
+
+static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count)
+{
+       u32 newtarget;
+       int i = 0, done = 0, ret = count;
+       struct bonding *bond = to_bond(cd);
+       u32 *targets;
+
+       targets = bond->params.arp_targets;
+       newtarget = in_aton(buf + 1);
+       /* look for adds */
+       if (buf[0] == '+') {
+               if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
+                       printk(KERN_ERR DRV_NAME
+                              ": %s: invalid ARP target %u.%u.%u.%u specified for addition\n",
+                              bond->dev->name, NIPQUAD(newtarget));
+                       ret = -EINVAL;
+                       goto out;
+               }
+               /* look for an empty slot to put the target in, and check for dupes */
+               for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+                       if (targets[i] == newtarget) { /* duplicate */
+                               printk(KERN_ERR DRV_NAME
+                                      ": %s: ARP target %u.%u.%u.%u is already present\n",
+                                      bond->dev->name, NIPQUAD(newtarget));
+                               if (done)
+                                       targets[i] = 0;
+                               ret = -EINVAL;
+                               goto out;
+                       }
+                       if (targets[i] == 0 && !done) {
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: adding ARP target %d.%d.%d.%d.\n",
+                                      bond->dev->name, NIPQUAD(newtarget));
+                               done = 1;
+                               targets[i] = newtarget;
+                       }
+               }
+               if (!done) {
+                       printk(KERN_ERR DRV_NAME
+                              ": %s: ARP target table is full!\n",
+                              bond->dev->name);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+       }
+       else if (buf[0] == '-') {
+               if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
+                       printk(KERN_ERR DRV_NAME
+                              ": %s: invalid ARP target %d.%d.%d.%d specified for removal\n",
+                              bond->dev->name, NIPQUAD(newtarget));
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+                       if (targets[i] == newtarget) {
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: removing ARP target %d.%d.%d.%d.\n",
+                                      bond->dev->name, NIPQUAD(newtarget));
+                               targets[i] = 0;
+                               done = 1;
+                       }
+               }
+               if (!done) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: unable to remove nonexistent ARP target %d.%d.%d.%d.\n",
+                              bond->dev->name, NIPQUAD(newtarget));
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+       else {
+               printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
+                       bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
+
+/*
+ * Show and set the up and down delays.  These must be multiples of the
+ * MII monitoring value, and are stored internally as the multiplier.
+ * Thus, we must translate to MS for the real world.
+ */
+static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;
+}
+
+static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+       if (!(bond->params.miimon)) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Unable to set down delay as MII monitoring is disabled\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: no down delay value specified.\n",
+                      bond->dev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+       if (new_value < 0) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+                      bond->dev->name, new_value, 1, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+       } else {
+               if ((new_value % bond->params.miimon) != 0) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": %s: Warning: down delay (%d) is not a multiple "
+                              "of miimon (%d), delay rounded to %d ms\n",
+                              bond->dev->name, new_value, bond->params.miimon,
+                              (new_value / bond->params.miimon) *
+                              bond->params.miimon);
+               }
+               bond->params.downdelay = new_value / bond->params.miimon;
+               printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",
+                      bond->dev->name, bond->params.downdelay * bond->params.miimon);
+
+       }
+
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
+
+static ssize_t bonding_show_updelay(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;
+
+}
+
+static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+       if (!(bond->params.miimon)) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Unable to set up delay as MII monitoring is disabled\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: no up delay value specified.\n",
+                      bond->dev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+       if (new_value < 0) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+                      bond->dev->name, new_value, 1, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+       } else {
+               if ((new_value % bond->params.miimon) != 0) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": %s: Warning: up delay (%d) is not a multiple "
+                              "of miimon (%d), updelay rounded to %d ms\n",
+                              bond->dev->name, new_value, bond->params.miimon,
+                              (new_value / bond->params.miimon) *
+                              bond->params.miimon);
+               }
+               bond->params.updelay = new_value / bond->params.miimon;
+               printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",
+                      bond->dev->name, bond->params.updelay * bond->params.miimon);
+
+       }
+
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
+
+/*
+ * Show and set the LACP interval.  Interface must be down, and the mode
+ * must be set to 802.3ad mode.
+ */
+static ssize_t bonding_show_lacp(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%s %d\n",
+               bond_lacp_tbl[bond->params.lacp_fast].modename,
+               bond->params.lacp_fast) + 1;
+}
+
+static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->dev->flags & IFF_UP) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Unable to update LACP rate because interface is up.\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       if (bond->params.mode != BOND_MODE_8023AD) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
+                      bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
+
+       if ((new_value == 1) || (new_value == 0)) {
+               bond->params.lacp_fast = new_value;
+               printk(KERN_INFO DRV_NAME
+                      ": %s: Setting LACP rate to %s (%d).\n",
+                      bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);
+       } else {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Ignoring invalid LACP rate value %.*s.\n",
+                       bond->dev->name, (int)strlen(buf) - 1, buf);
+               ret = -EINVAL;
+       }
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
+
+/*
+ * Show and set the MII monitor interval.  There are two tricky bits
+ * here.  First, if MII monitoring is activated, then we must disable
+ * ARP monitoring.  Second, if the timer isn't running, we must
+ * start it.
+ */
+static ssize_t bonding_show_miimon(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%d\n", bond->params.miimon) + 1;
+}
+
+static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: no miimon value specified.\n",
+                      bond->dev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+       if (new_value < 0) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
+                      bond->dev->name, new_value, 1, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+       } else {
+               printk(KERN_INFO DRV_NAME
+                      ": %s: Setting MII monitoring interval to %d.\n",
+                      bond->dev->name, new_value);
+               bond->params.miimon = new_value;
+               if(bond->params.updelay)
+                       printk(KERN_INFO DRV_NAME
+                             ": %s: Note: Updating updelay (to %d) "
+                             "since it is a multiple of the miimon value.\n",
+                             bond->dev->name,
+                             bond->params.updelay * bond->params.miimon);
+               if(bond->params.downdelay)
+                       printk(KERN_INFO DRV_NAME
+                             ": %s: Note: Updating downdelay (to %d) "
+                             "since it is a multiple of the miimon value.\n",
+                             bond->dev->name,
+                             bond->params.downdelay * bond->params.miimon);
+               if (bond->params.arp_interval) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: MII monitoring cannot be used with "
+                              "ARP monitoring. Disabling ARP monitoring...\n",
+                              bond->dev->name);
+                       bond->params.arp_interval = 0;
+                       /* Kill ARP timer, else it brings bond's link down */
+                       if (bond->mii_timer.function) {
+                               printk(KERN_INFO DRV_NAME
+                               ": %s: Kill ARP timer, else it brings bond's link down...\n",
+                              bond->dev->name);
+                               del_timer_sync(&bond->arp_timer);
+                       }
+               }
+
+               if (bond->dev->flags & IFF_UP) {
+                       /* If the interface is up, we may need to fire off
+                        * the MII timer. If the interface is down, the
+                        * timer will get fired off when the open function
+                        * is called.
+                        */
+                       if (bond->mii_timer.function) {
+                               /* The timer's already set up, so fire it off */
+                               mod_timer(&bond->mii_timer, jiffies + 1);
+                       } else {
+                               /* Set up the timer. */
+                               init_timer(&bond->mii_timer);
+                               bond->mii_timer.expires = jiffies + 1;
+                               bond->mii_timer.data =
+                                       (unsigned long) bond->dev;
+                               bond->mii_timer.function =
+                                       (void *) &bond_mii_monitor;
+                               add_timer(&bond->mii_timer);
+                       }
+               }
+       }
+out:
+       return ret;
+}
+static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
+
+/*
+ * Show and set the primary slave.  The store function is much
+ * simpler than bonding_store_slaves function because it only needs to
+ * handle one interface name.
+ * The bond must be a mode that supports a primary for this be
+ * set.
+ */
+static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
+{
+       int count = 0;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->primary_slave)
+               count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1;
+       else
+               count = sprintf(buf, "\n") + 1;
+
+       return count;
+}
+
+static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count)
+{
+       int i;
+       struct slave *slave;
+       struct bonding *bond = to_bond(cd);
+
+       write_lock_bh(&bond->lock);
+       if (!USES_PRIMARY(bond->params.mode)) {
+               printk(KERN_INFO DRV_NAME
+                      ": %s: Unable to set primary slave; %s is in mode %d\n",
+                      bond->dev->name, bond->dev->name, bond->params.mode);
+       } else {
+               bond_for_each_slave(bond, slave, i) {
+                       if (strnicmp
+                           (slave->dev->name, buf,
+                            strlen(slave->dev->name)) == 0) {
+                               printk(KERN_INFO DRV_NAME
+                                      ": %s: Setting %s as primary slave.\n",
+                                      bond->dev->name, slave->dev->name);
+                               bond->primary_slave = slave;
+                               bond_select_active_slave(bond);
+                               goto out;
+                       }
+               }
+
+               /* if we got here, then we didn't match the name of any slave */
+
+               if (strlen(buf) == 0 || buf[0] == '\n') {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: Setting primary slave to None.\n",
+                              bond->dev->name);
+                       bond->primary_slave = 0;
+                               bond_select_active_slave(bond);
+               } else {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
+                              bond->dev->name, (int)strlen(buf) - 1, buf);
+               }
+       }
+out:
+       write_unlock_bh(&bond->lock);
+       return count;
+}
+static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
+
+/*
+ * Show and set the use_carrier flag.
+ */
+static ssize_t bonding_show_carrier(struct class_device *cd, char *buf)
+{
+       struct bonding *bond = to_bond(cd);
+
+       return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;
+}
+
+static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(cd);
+
+
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: no use_carrier value specified.\n",
+                      bond->dev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+       if ((new_value == 0) || (new_value == 1)) {
+               bond->params.use_carrier = new_value;
+               printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n",
+                      bond->dev->name, new_value);
+       } else {
+               printk(KERN_INFO DRV_NAME
+                      ": %s: Ignoring invalid use_carrier value %d.\n",
+                      bond->dev->name, new_value);
+       }
+out:
+       return count;
+}
+static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
+
+
+/*
+ * Show and set currently active_slave.
+ */
+static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
+{
+       struct slave *curr;
+       struct bonding *bond = to_bond(cd);
+       int count;
+
+
+       read_lock(&bond->curr_slave_lock);
+       curr = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
+
+       if (USES_PRIMARY(bond->params.mode) && curr)
+               count = sprintf(buf, "%s\n", curr->dev->name) + 1;
+       else
+               count = sprintf(buf, "\n") + 1;
+       return count;
+}
+
+static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count)
+{
+       int i;
+       struct slave *slave;
+        struct slave *old_active = NULL;
+        struct slave *new_active = NULL;
+       struct bonding *bond = to_bond(cd);
+
+       write_lock_bh(&bond->lock);
+       if (!USES_PRIMARY(bond->params.mode)) {
+               printk(KERN_INFO DRV_NAME
+                      ": %s: Unable to change active slave; %s is in mode %d\n",
+                      bond->dev->name, bond->dev->name, bond->params.mode);
+       } else {
+               bond_for_each_slave(bond, slave, i) {
+                       if (strnicmp
+                           (slave->dev->name, buf,
+                            strlen(slave->dev->name)) == 0) {
+                               old_active = bond->curr_active_slave;
+                               new_active = slave;
+                               if (new_active && (new_active == old_active)) {
+                                       /* do nothing */
+                                       printk(KERN_INFO DRV_NAME
+                                              ": %s: %s is already the current active slave.\n",
+                                              bond->dev->name, slave->dev->name);
+                                       goto out;
+                               }
+                               else {
+                                       if ((new_active) &&
+                                           (old_active) &&
+                                           (new_active->link == BOND_LINK_UP) &&
+                                           IS_UP(new_active->dev)) {
+                                               printk(KERN_INFO DRV_NAME
+                                                     ": %s: Setting %s as active slave.\n",
+                                                     bond->dev->name, slave->dev->name);
+                                               bond_change_active_slave(bond, new_active);
+                                       }
+                                       else {
+                                               printk(KERN_INFO DRV_NAME
+                                                     ": %s: Could not set %s as active slave; "
+                                                     "either %s is down or the link is down.\n",
+                                                     bond->dev->name, slave->dev->name,
+                                                     slave->dev->name);
+                                       }
+                                       goto out;
+                               }
+                       }
+               }
+
+               /* if we got here, then we didn't match the name of any slave */
+
+               if (strlen(buf) == 0 || buf[0] == '\n') {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: Setting active slave to None.\n",
+                              bond->dev->name);
+                       bond->primary_slave = 0;
+                               bond_select_active_slave(bond);
+               } else {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: Unable to set %.*s as active slave as it is not a slave.\n",
+                              bond->dev->name, (int)strlen(buf) - 1, buf);
+               }
+       }
+out:
+       write_unlock_bh(&bond->lock);
+       return count;
+
+}
+static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
+
+
+/*
+ * Show link status of the bond interface.
+ */
+static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
+{
+       struct slave *curr;
+       struct bonding *bond = to_bond(cd);
+
+       read_lock(&bond->curr_slave_lock);
+       curr = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
+
+       return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;
+}
+static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
+
+
+/*
+ * Show current 802.3ad aggregator ID.
+ */
+static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
+{
+       int count = 0;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->params.mode == BOND_MODE_8023AD) {
+               struct ad_info ad_info;
+               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.aggregator_id) + 1;
+       }
+       else
+               count = sprintf(buf, "\n") + 1;
+
+       return count;
+}
+static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
+
+
+/*
+ * Show number of active 802.3ad ports.
+ */
+static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
+{
+       int count = 0;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->params.mode == BOND_MODE_8023AD) {
+               struct ad_info ad_info;
+               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0: ad_info.ports) + 1;
+       }
+       else
+               count = sprintf(buf, "\n") + 1;
+
+       return count;
+}
+static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
+
+
+/*
+ * Show current 802.3ad actor key.
+ */
+static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
+{
+       int count = 0;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->params.mode == BOND_MODE_8023AD) {
+               struct ad_info ad_info;
+               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.actor_key) + 1;
+       }
+       else
+               count = sprintf(buf, "\n") + 1;
+
+       return count;
+}
+static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
+
+
+/*
+ * Show current 802.3ad partner key.
+ */
+static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
+{
+       int count = 0;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->params.mode == BOND_MODE_8023AD) {
+               struct ad_info ad_info;
+               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.partner_key) + 1;
+       }
+       else
+               count = sprintf(buf, "\n") + 1;
+
+       return count;
+}
+static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
+
+
+/*
+ * Show current 802.3ad partner mac.
+ */
+static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
+{
+       int count = 0;
+       struct bonding *bond = to_bond(cd);
+
+       if (bond->params.mode == BOND_MODE_8023AD) {
+               struct ad_info ad_info;
+               if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
+                       count = sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                      ad_info.partner_system[0],
+                                      ad_info.partner_system[1],
+                                      ad_info.partner_system[2],
+                                      ad_info.partner_system[3],
+                                      ad_info.partner_system[4],
+                                      ad_info.partner_system[5]) + 1;
+               }
+       }
+       else
+               count = sprintf(buf, "\n") + 1;
+
+       return count;
+}
+static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
+
+
+
+static struct attribute *per_bond_attrs[] = {
+       &class_device_attr_slaves.attr,
+       &class_device_attr_mode.attr,
+       &class_device_attr_arp_interval.attr,
+       &class_device_attr_arp_ip_target.attr,
+       &class_device_attr_downdelay.attr,
+       &class_device_attr_updelay.attr,
+       &class_device_attr_lacp_rate.attr,
+       &class_device_attr_xmit_hash_policy.attr,
+       &class_device_attr_miimon.attr,
+       &class_device_attr_primary.attr,
+       &class_device_attr_use_carrier.attr,
+       &class_device_attr_active_slave.attr,
+       &class_device_attr_mii_status.attr,
+       &class_device_attr_ad_aggregator.attr,
+       &class_device_attr_ad_num_ports.attr,
+       &class_device_attr_ad_actor_key.attr,
+       &class_device_attr_ad_partner_key.attr,
+       &class_device_attr_ad_partner_mac.attr,
+       NULL,
+};
+
+static struct attribute_group bonding_group = {
+       .name = "bonding",
+       .attrs = per_bond_attrs,
+};
+
+/*
+ * Initialize sysfs.  This sets up the bonding_masters file in
+ * /sys/class/net.
+ */
+int bond_create_sysfs(void)
+{
+       int ret = 0;
+       struct bonding *firstbond;
+
+       init_rwsem(&bonding_rwsem);
+
+       /* get the netdev class pointer */
+       firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
+       if (!firstbond)
+               return -ENODEV;
+
+       netdev_class = firstbond->dev->class_dev.class;
+       if (!netdev_class)
+               return -ENODEV;
+
+       ret = class_create_file(netdev_class, &class_attr_bonding_masters);
+
+       return ret;
+
+}
+
+/*
+ * Remove /sys/class/net/bonding_masters.
+ */
+void bond_destroy_sysfs(void)
+{
+       if (netdev_class)
+               class_remove_file(netdev_class, &class_attr_bonding_masters);
+}
+
+/*
+ * Initialize sysfs for each bond.  This sets up and registers
+ * the 'bondctl' directory for each individual bond under /sys/class/net.
+ */
+int bond_create_sysfs_entry(struct bonding *bond)
+{
+       struct net_device *dev = bond->dev;
+       int err;
+
+       err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group);
+       if (err) {
+               printk(KERN_EMERG "eek! didn't create group!\n");
+       }
+
+       if (expected_refcount < 1)
+               expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount);
+
+       return err;
+}
+/*
+ * Remove sysfs entries for each bond.
+ */
+void bond_destroy_sysfs_entry(struct bonding *bond)
+{
+       struct net_device *dev = bond->dev;
+
+       sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group);
+}
+
index 1433e91db0f7fb12b3fcec07c83288192202e4c5..015c7f1d1bc0843e3be52454505a8d99ad068fc9 100644 (file)
  *     This software may be used and distributed according to the terms
  *     of the GNU Public License, incorporated herein by reference.
  *
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
- *             Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Shmulik Hen <shmulik.hen at intel dot com>
- *     - Added support for IEEE 802.3ad Dynamic link aggregation mode.
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *             Amir Noam <amir.noam at intel dot com>
- *     - Code beautification and style changes (mainly in comments).
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Added support for Transmit load balancing mode.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *     - Code cleanup and style changes
- *
- * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
- *      - added "xmit_policy" kernel parameter for alternate hashing policy
- *       support for mode 2
  */
 
 #ifndef _LINUX_BONDING_H
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
 #include <linux/if_bonding.h>
+#include <linux/kobject.h>
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION    "2.6.5"
-#define DRV_RELDATE    "November 4, 2005"
+#define DRV_VERSION    "3.0.0"
+#define DRV_RELDATE    "November 8, 2005"
 #define DRV_NAME       "bonding"
 #define DRV_DESCRIPTION        "Ethernet Channel Bonding Driver"
 
@@ -152,6 +134,11 @@ struct bond_params {
        u32 arp_targets[BOND_MAX_ARP_TARGETS];
 };
 
+struct bond_parm_tbl {
+       char *modename;
+       int mode;
+};
+
 struct vlan_entry {
        struct list_head vlan_list;
        u32 vlan_ip;
@@ -159,7 +146,7 @@ struct vlan_entry {
 };
 
 struct slave {
-       struct net_device *dev; /* first - usefull for panic debug */
+       struct net_device *dev; /* first - useful for panic debug */
        struct slave *next;
        struct slave *prev;
        s16    delay;
@@ -185,7 +172,7 @@ struct slave {
  *    beforehand.
  */
 struct bonding {
-       struct   net_device *dev; /* first - usefull for panic debug */
+       struct   net_device *dev; /* first - useful for panic debug */
        struct   slave *first_slave;
        struct   slave *curr_active_slave;
        struct   slave *current_arp_slave;
@@ -255,6 +242,25 @@ extern inline void bond_set_slave_active_flags(struct slave *slave)
 
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
+int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+void bond_deinit(struct net_device *bond_dev);
+int bond_create_sysfs(void);
+void bond_destroy_sysfs(void);
+void bond_destroy_sysfs_entry(struct bonding *bond);
+int bond_create_sysfs_entry(struct bonding *bond);
+int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
+void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
+void bond_mii_monitor(struct net_device *bond_dev);
+void bond_loadbalance_arp_mon(struct net_device *bond_dev);
+void bond_activebackup_arp_mon(struct net_device *bond_dev);
+void bond_set_mode_ops(struct bonding *bond, int mode);
+int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+const char *bond_mode_name(int mode);
+void bond_select_active_slave(struct bonding *bond);
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 
 #endif /* _LINUX_BONDING_H */
 
index 53b41d99b00b2ec48fad8d963f1be24b8269d43e..2c5b849b7ba4fcecc414866940c0316189345c15 100644 (file)
@@ -1332,8 +1332,8 @@ intr_handler_t t1_select_intr_handler(adapter_t *adapter)
  *
  * This runs with softirqs disabled.
  */
-unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
-                      unsigned int qid, struct net_device *dev)
+static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
+                    unsigned int qid, struct net_device *dev)
 {
        struct sge *sge = adapter->sge;
        struct cmdQ *q = &sge->cmdQ[qid];
@@ -1352,9 +1352,10 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
                        set_bit(dev->if_port, &sge->stopped_tx_queues);
                        sge->stats.cmdQ_full[3]++;
                        spin_unlock(&q->lock);
-                       CH_ERR("%s: Tx ring full while queue awake!\n",
-                              adapter->name);
-                       return 1;
+                       if (!netif_queue_stopped(dev))
+                               CH_ERR("%s: Tx ring full while queue awake!\n",
+                                      adapter->name);
+                       return NETDEV_TX_BUSY;
                }
                if (unlikely(credits - count < q->stop_thres)) {
                        sge->stats.cmdQ_full[3]++;
@@ -1389,7 +1390,7 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
                        writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
                }
        }
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 #define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14))
@@ -1449,7 +1450,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (unlikely(skb->len < ETH_HLEN ||
                             skb->len > dev->mtu + eth_hdr_len(skb->data))) {
                        dev_kfree_skb_any(skb);
-                       return NET_XMIT_SUCCESS;
+                       return NETDEV_TX_OK;
                }
 
                /*
@@ -1467,7 +1468,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        skb = skb_realloc_headroom(skb, sizeof(*cpl));
                        dev_kfree_skb_any(orig_skb);
                        if (!skb)
-                               return -ENOMEM;
+                               return NETDEV_TX_OK;
                }
 
                if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
@@ -1475,7 +1476,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
                    skb->nh.iph->protocol == IPPROTO_UDP)
                        if (unlikely(skb_checksum_help(skb, 0))) {
                                dev_kfree_skb_any(skb);
-                               return -ENOMEM;
+                               return NETDEV_TX_OK;
                        }
 
                /* Hmmm, assuming to catch the gratious arp... and we'll use
index 434b255868516045dbd67bc764d7ba8ea35d37e1..6d0d24a6364f75d8dc7908b58d83d6d1672b234e 100644 (file)
@@ -89,8 +89,6 @@ int t1_sge_configure(struct sge *, struct sge_params *);
 int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
 void t1_sge_destroy(struct sge *);
 intr_handler_t t1_select_intr_handler(adapter_t *adapter);
-unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
-                      unsigned int qid, struct net_device *netdev);
 int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void t1_set_vlan_accel(struct adapter *adapter, int on_off);
 void t1_sge_start(struct sge *);
index 3f653a93e1bc78dc9ab7e730bdc9490cac4f5650..e02e9ba2e18b0b66166f2f877a2e282f0a4926f8 100644 (file)
@@ -188,11 +188,13 @@ struct e1000_tx_ring {
        /* array of buffer information structs */
        struct e1000_buffer *buffer_info;
 
-       struct e1000_buffer previous_buffer_info;
        spinlock_t tx_lock;
        uint16_t tdh;
        uint16_t tdt;
        uint64_t pkt;
+
+       boolean_t last_tx_tso;
+
 };
 
 struct e1000_rx_ring {
index 8eae8ba27e84da532250b16756c60456e00dcee1..c88f1a3c1b1db7d58a87a779d6517480e514d31c 100644 (file)
@@ -562,10 +562,29 @@ e1000_get_drvinfo(struct net_device *netdev,
                        struct ethtool_drvinfo *drvinfo)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       char firmware_version[32];
+       uint16_t eeprom_data;
 
        strncpy(drvinfo->driver,  e1000_driver_name, 32);
        strncpy(drvinfo->version, e1000_driver_version, 32);
-       strncpy(drvinfo->fw_version, "N/A", 32);
+       
+       /* EEPROM image version # is reported as firware version # for
+        * 8257{1|2|3} controllers */
+       e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
+       switch (adapter->hw.mac_type) {
+       case e1000_82571:
+       case e1000_82572:
+       case e1000_82573:
+               sprintf(firmware_version, "%d.%d-%d", 
+                       (eeprom_data & 0xF000) >> 12,
+                       (eeprom_data & 0x0FF0) >> 4,
+                       eeprom_data & 0x000F);
+               break;
+       default:
+               sprintf(firmware_version, "n/a");
+       }
+
+       strncpy(drvinfo->fw_version, firmware_version, 32);
        strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
        drvinfo->n_stats = E1000_STATS_LEN;
        drvinfo->testinfo_len = E1000_TEST_LEN;
@@ -960,13 +979,21 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
                }
        }
 
-       if(txdr->desc)
+       if(txdr->desc) {
                pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
-       if(rxdr->desc)
+               txdr->desc = NULL;
+       }
+       if(rxdr->desc) {
                pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
+               rxdr->desc = NULL;
+       }
 
        kfree(txdr->buffer_info);
+       txdr->buffer_info = NULL;
+
        kfree(rxdr->buffer_info);
+       rxdr->buffer_info = NULL;
+
        return;
 }
 
@@ -1301,21 +1328,32 @@ static int
 e1000_setup_loopback_test(struct e1000_adapter *adapter)
 {
        uint32_t rctl;
+       struct e1000_hw *hw = &adapter->hw;
 
-       if(adapter->hw.media_type == e1000_media_type_fiber ||
-          adapter->hw.media_type == e1000_media_type_internal_serdes) {
-               if(adapter->hw.mac_type == e1000_82545 ||
-                  adapter->hw.mac_type == e1000_82546 ||
-                  adapter->hw.mac_type == e1000_82545_rev_3 ||
-                  adapter->hw.mac_type == e1000_82546_rev_3)
+       if (hw->media_type == e1000_media_type_fiber ||
+          hw->media_type == e1000_media_type_internal_serdes) {
+               switch (hw->mac_type) {
+               case e1000_82545:
+               case e1000_82546:
+               case e1000_82545_rev_3:
+               case e1000_82546_rev_3:
                        return e1000_set_phy_loopback(adapter);
-               else {
-                       rctl = E1000_READ_REG(&adapter->hw, RCTL);
+                       break;
+               case e1000_82571:
+               case e1000_82572:
+#define E1000_SERDES_LB_ON 0x410
+                       e1000_set_phy_loopback(adapter);
+                       E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON);
+                       msec_delay(10);
+                       return 0;
+                       break;
+               default:
+                       rctl = E1000_READ_REG(hw, RCTL);
                        rctl |= E1000_RCTL_LBM_TCVR;
-                       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+                       E1000_WRITE_REG(hw, RCTL, rctl);
                        return 0;
                }
-       } else if(adapter->hw.media_type == e1000_media_type_copper)
+       } else if (hw->media_type == e1000_media_type_copper)
                return e1000_set_phy_loopback(adapter);
 
        return 7;
@@ -1326,25 +1364,36 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter)
 {
        uint32_t rctl;
        uint16_t phy_reg;
+       struct e1000_hw *hw = &adapter->hw;
 
        rctl = E1000_READ_REG(&adapter->hw, RCTL);
        rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
        E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
 
-       if(adapter->hw.media_type == e1000_media_type_copper ||
-          ((adapter->hw.media_type == e1000_media_type_fiber ||
-            adapter->hw.media_type == e1000_media_type_internal_serdes) &&
-           (adapter->hw.mac_type == e1000_82545 ||
-            adapter->hw.mac_type == e1000_82546 ||
-            adapter->hw.mac_type == e1000_82545_rev_3 ||
-            adapter->hw.mac_type == e1000_82546_rev_3))) {
-               adapter->hw.autoneg = TRUE;
-               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
-               if(phy_reg & MII_CR_LOOPBACK) {
+       switch (hw->mac_type) {
+       case e1000_82571:
+       case e1000_82572:
+               if (hw->media_type == e1000_media_type_fiber ||
+                  hw->media_type == e1000_media_type_internal_serdes){
+#define E1000_SERDES_LB_OFF 0x400
+                       E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
+                       msec_delay(10);
+                       break;
+               }
+               /* fall thru for Cu adapters */
+       case e1000_82545:
+       case e1000_82546:
+       case e1000_82545_rev_3:
+       case e1000_82546_rev_3:
+       default:
+               hw->autoneg = TRUE;
+               e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
+               if (phy_reg & MII_CR_LOOPBACK) {
                        phy_reg &= ~MII_CR_LOOPBACK;
-                       e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
-                       e1000_phy_reset(&adapter->hw);
+                       e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
+                       e1000_phy_reset(hw);
                }
+               break;
        }
 }
 
@@ -1440,9 +1489,11 @@ static int
 e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
 {
        if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
-       if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback;
+       if((*data = e1000_setup_loopback_test(adapter)))
+               goto err_loopback_setup;
        *data = e1000_run_loopback_test(adapter);
        e1000_loopback_cleanup(adapter);
+err_loopback_setup:
        e1000_free_desc_rings(adapter);
 err_loopback:
        return *data;
@@ -1671,6 +1722,14 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
                msleep_interruptible(data * 1000);
                del_timer_sync(&adapter->blink_timer);
        }
+       else if(adapter->hw.mac_type < e1000_82573) {
+               E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
+                       E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
+                       (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
+                       (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
+                       (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
+               msleep_interruptible(data * 1000);
+       }
        else {
                E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
                        E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | 
index a267c5235fc0d153b08c07a7b4fe3fc41a1df666..136fc031e4ad555d168a8b0ac002b460ebea8ebb 100644 (file)
@@ -563,11 +563,13 @@ e1000_reset_hw(struct e1000_hw *hw)
             msec_delay(20);
             break;
         case e1000_82573:
-            udelay(10);
-            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-            ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-            E1000_WRITE_FLUSH(hw);
+            if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
+                udelay(10);
+                ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+                E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+                E1000_WRITE_FLUSH(hw);
+            }
             /* fall through */
         case e1000_82571:
         case e1000_82572:
@@ -844,19 +846,27 @@ e1000_setup_link(struct e1000_hw *hw)
      * control setting, then the variable hw->fc will
      * be initialized based on a value in the EEPROM.
      */
-    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) {
-        DEBUGOUT("EEPROM Read Error\n");
-        return -E1000_ERR_EEPROM;
-    }
-
-    if(hw->fc == e1000_fc_default) {
-        if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-            hw->fc = e1000_fc_none;
-        else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
-                EEPROM_WORD0F_ASM_DIR)
-            hw->fc = e1000_fc_tx_pause;
-        else
+    if (hw->fc == e1000_fc_default) {
+        switch (hw->mac_type) {
+        case e1000_82573:
             hw->fc = e1000_fc_full;
+            break;
+        default:
+            ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
+                                        1, &eeprom_data);
+            if (ret_val) {
+                DEBUGOUT("EEPROM Read Error\n");
+                return -E1000_ERR_EEPROM;
+            }
+            if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
+                hw->fc = e1000_fc_none;
+            else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
+                    EEPROM_WORD0F_ASM_DIR)
+                hw->fc = e1000_fc_tx_pause;
+            else
+                hw->fc = e1000_fc_full;
+            break;
+        }
     }
 
     /* We want to save off the original Flow Control configuration just
@@ -2962,13 +2972,22 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
     if(hw->mac_type > e1000_82543) {
         /* Read the device control register and assert the E1000_CTRL_PHY_RST
          * bit. Then, take it out of reset.
+         * For pre-e1000_82571 hardware, we delay for 10ms between the assert 
+         * and deassert.  For e1000_82571 hardware and later, we instead delay
+         * for 10ms after the deassertion.
          */
         ctrl = E1000_READ_REG(hw, CTRL);
         E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
         E1000_WRITE_FLUSH(hw);
-        msec_delay(10);
+        
+        if (hw->mac_type < e1000_82571) 
+            msec_delay(10);
+        
         E1000_WRITE_REG(hw, CTRL, ctrl);
         E1000_WRITE_FLUSH(hw);
+        
+        if (hw->mac_type >= e1000_82571)
+            msec_delay(10);
     } else {
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
          * bit to put the PHY into reset. Then, take it out of reset.
@@ -5278,9 +5297,13 @@ e1000_get_bus_info(struct e1000_hw *hw)
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
         break;
-    case e1000_82571:
     case e1000_82572:
     case e1000_82573:
+        hw->bus_type = e1000_bus_type_pci_express;
+        hw->bus_speed = e1000_bus_speed_2500;
+        hw->bus_width = e1000_bus_width_pciex_1;
+        break;
+    case e1000_82571:
         hw->bus_type = e1000_bus_type_pci_express;
         hw->bus_speed = e1000_bus_speed_2500;
         hw->bus_width = e1000_bus_width_pciex_4;
@@ -6650,6 +6673,12 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
         break;
     }
 
+    /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
+     * Need to wait for PHY configuration completion before accessing NVM
+     * and PHY. */
+    if (hw->mac_type == e1000_82573)
+        msec_delay(25);
+
     return E1000_SUCCESS;
 }
 
index 76ce12809a11641cc6788fcc75a99cdca1d5dd70..7caa35748ceac9c8236d1510f9335b2e57f9073b 100644 (file)
@@ -123,6 +123,7 @@ typedef enum {
     e1000_bus_width_32,
     e1000_bus_width_64,
     e1000_bus_width_pciex_1,
+    e1000_bus_width_pciex_2,
     e1000_bus_width_pciex_4,
     e1000_bus_width_reserved
 } e1000_bus_width;
@@ -149,6 +150,7 @@ typedef enum {
     e1000_igp_cable_length_90  = 90,
     e1000_igp_cable_length_100 = 100,
     e1000_igp_cable_length_110 = 110,
+    e1000_igp_cable_length_115 = 115,
     e1000_igp_cable_length_120 = 120,
     e1000_igp_cable_length_130 = 130,
     e1000_igp_cable_length_140 = 140,
@@ -1457,6 +1459,7 @@ struct e1000_hw {
 #define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
 #define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
 #define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
+#define E1000_EECD_SECVAL_SHIFT      22
 #define E1000_STM_OPCODE     0xDB00
 #define E1000_HICR_FW_RESET  0xC0
 
@@ -1951,7 +1954,6 @@ struct e1000_host_command_info {
 
 #define E1000_MDALIGN          4096
 
-#define E1000_GCR_BEM32                 0x00400000
 #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
 /* Function Active and Power State to MNG */
 #define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
index e0ae248b4313084337e07ff85279d4ed8d2de116..438a931fd55df4c6dd57e00d9480f35c4e9fb461 100644 (file)
@@ -711,6 +711,7 @@ e1000_probe(struct pci_dev *pdev,
                break;
        case e1000_82546:
        case e1000_82546_rev_3:
+       case e1000_82571:
                if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
                   && (adapter->hw.media_type == e1000_media_type_copper)) {
                        e1000_read_eeprom(&adapter->hw,
@@ -1158,7 +1159,6 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter,
                return -ENOMEM;
        }
        memset(txdr->buffer_info, 0, size);
-       memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
 
        /* round up to nearest 4K */
 
@@ -1813,11 +1813,6 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
 
        /* Free all the Tx ring sk_buffs */
 
-       if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-               e1000_unmap_and_free_tx_resource(adapter,
-                               &tx_ring->previous_buffer_info);
-       }
-
        for(i = 0; i < tx_ring->count; i++) {
                buffer_info = &tx_ring->buffer_info[i];
                e1000_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -1832,6 +1827,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
 
        tx_ring->next_to_use = 0;
        tx_ring->next_to_clean = 0;
+       tx_ring->last_tx_tso = 0;
 
        writel(0, adapter->hw.hw_addr + tx_ring->tdh);
        writel(0, adapter->hw.hw_addr + tx_ring->tdt);
@@ -2437,6 +2433,16 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                buffer_info = &tx_ring->buffer_info[i];
                size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
+               /* Workaround for Controller erratum --
+                * descriptor for non-tso packet in a linear SKB that follows a
+                * tso gets written back prematurely before the data is fully
+                * DMAd to the controller */
+               if (!skb->data_len && tx_ring->last_tx_tso &&
+                               !skb_shinfo(skb)->tso_size) {
+                       tx_ring->last_tx_tso = 0;
+                       size -= 4;
+               }
+
                /* Workaround for premature desc write-backs
                 * in TSO mode.  Append 4-byte sentinel desc */
                if(unlikely(mss && !nr_frags && size == len && size > 8))
@@ -2693,6 +2699,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        if(skb->ip_summed == CHECKSUM_HW)
                count++;
 #endif
+
+#ifdef NETIF_F_TSO
+       /* Controller Erratum workaround */
+       if (!skb->data_len && tx_ring->last_tx_tso &&
+               !skb_shinfo(skb)->tso_size)
+               count++;
+#endif
+
        count += TXD_USE_COUNT(len, max_txd_pwr);
 
        if(adapter->pcix_82544)
@@ -2774,9 +2788,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                return NETDEV_TX_OK;
        }
 
-       if (likely(tso))
+       if (likely(tso)) {
+               tx_ring->last_tx_tso = 1;
                tx_flags |= E1000_TX_FLAGS_TSO;
-       else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
+       else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
                tx_flags |= E1000_TX_FLAGS_CSUM;
 
        /* Old method was to assume IPv4 packet by default if TSO was enabled.
@@ -3227,37 +3242,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
        eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
        while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-               /* Premature writeback of Tx descriptors clear (free buffers
-                * and unmap pci_mapping) previous_buffer_info */
-               if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-                       e1000_unmap_and_free_tx_resource(adapter,
-                                       &tx_ring->previous_buffer_info);
-               }
-
                for(cleaned = FALSE; !cleaned; ) {
                        tx_desc = E1000_TX_DESC(*tx_ring, i);
                        buffer_info = &tx_ring->buffer_info[i];
                        cleaned = (i == eop);
 
-#ifdef NETIF_F_TSO
-                       if (!(netdev->features & NETIF_F_TSO)) {
-#endif
-                               e1000_unmap_and_free_tx_resource(adapter,
-                                                                buffer_info);
-#ifdef NETIF_F_TSO
-                       } else {
-                               if (cleaned) {
-                                       memcpy(&tx_ring->previous_buffer_info,
-                                              buffer_info,
-                                              sizeof(struct e1000_buffer));
-                                       memset(buffer_info, 0,
-                                              sizeof(struct e1000_buffer));
-                               } else {
-                                       e1000_unmap_and_free_tx_resource(
-                                           adapter, buffer_info);
-                               }
-                       }
-#endif
+                       e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 
                        tx_desc->buffer_addr = 0;
                        tx_desc->lower.data = 0;
@@ -3318,12 +3308,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
                        netif_stop_queue(netdev);
                }
        }
-#ifdef NETIF_F_TSO
-       if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
-           time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
-               e1000_unmap_and_free_tx_resource(
-                   adapter, &tx_ring->previous_buffer_info);
-#endif
        return cleaned;
 }
 
index 0f030b73cbb328b246e170d85e9401182659d860..146f9513aea57f89e04cea2b5f201730590dfc1d 100644 (file)
@@ -2,7 +2,8 @@
  * drivers/net/gianfar.c
  *
  * Gianfar Ethernet Driver
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
+ * This driver is designed for the non-CPM ethernet controllers
+ * on the 85xx and 83xx family of integrated processors
  * Based on 8260_io/fcc_enet.c
  *
  * Author: Andy Fleming
@@ -22,8 +23,6 @@
  *  B-V +1.62
  *
  *  Theory of operation
- *  This driver is designed for the non-CPM ethernet controllers
- *  on the 85xx and 83xx family of integrated processors
  *
  *  The driver is initialized through platform_device.  Structures which
  *  define the configuration needed by the board are defined in a
 #endif
 
 const char gfar_driver_name[] = "Gianfar Ethernet";
-const char gfar_driver_version[] = "1.2";
+const char gfar_driver_version[] = "1.3";
 
 static int gfar_enet_open(struct net_device *dev);
 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -139,6 +138,10 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
 static void gfar_vlan_rx_register(struct net_device *netdev,
                                struct vlan_group *grp);
 static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+void gfar_halt(struct net_device *dev);
+void gfar_start(struct net_device *dev);
+static void gfar_clear_exact_match(struct net_device *dev);
+static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
 
 extern struct ethtool_ops gfar_ethtool_ops;
 
@@ -146,12 +149,10 @@ MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
 MODULE_LICENSE("GPL");
 
-int gfar_uses_fcb(struct gfar_private *priv)
+/* Returns 1 if incoming frames use an FCB */
+static inline int gfar_uses_fcb(struct gfar_private *priv)
 {
-       if (priv->vlan_enable || priv->rx_csum_enable)
-               return 1;
-       else
-               return 0;
+       return (priv->vlan_enable || priv->rx_csum_enable);
 }
 
 /* Set up the ethernet device structure, private data,
@@ -320,15 +321,10 @@ static int gfar_probe(struct platform_device *pdev)
        else
                priv->padding = 0;
 
-       dev->hard_header_len += priv->padding;
-
        if (dev->features & NETIF_F_IP_CSUM)
                dev->hard_header_len += GMAC_FCB_LEN;
 
        priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
-#ifdef CONFIG_GFAR_BUFSTASH
-       priv->rx_stash_size = STASH_LENGTH;
-#endif
        priv->tx_ring_size = DEFAULT_TX_RING_SIZE;
        priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
 
@@ -350,6 +346,9 @@ static int gfar_probe(struct platform_device *pdev)
                goto register_fail;
        }
 
+       /* Create all the sysfs files */
+       gfar_init_sysfs(dev);
+
        /* Print out the device info */
        printk(KERN_INFO DEVICE_NAME, dev->name);
        for (idx = 0; idx < 6; idx++)
@@ -357,8 +356,7 @@ static int gfar_probe(struct platform_device *pdev)
        printk("\n");
 
        /* Even more device info helps when determining which kernel */
-       /* provided which set of benchmarks.  Since this is global for all */
-       /* devices, we only print it once */
+       /* provided which set of benchmarks. */
 #ifdef CONFIG_GFAR_NAPI
        printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
 #else
@@ -463,19 +461,9 @@ static void init_registers(struct net_device *dev)
        /* Initialize the max receive buffer length */
        gfar_write(&priv->regs->mrblr, priv->rx_buffer_size);
 
-#ifdef CONFIG_GFAR_BUFSTASH
-       /* If we are stashing buffers, we need to set the
-        * extraction length to the size of the buffer */
-       gfar_write(&priv->regs->attreli, priv->rx_stash_size << 16);
-#endif
-
        /* Initialize the Minimum Frame Length Register */
        gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS);
 
-       /* Setup Attributes so that snooping is on for rx */
-       gfar_write(&priv->regs->attr, ATTR_INIT_SETTINGS);
-       gfar_write(&priv->regs->attreli, ATTRELI_INIT_SETTINGS);
-
        /* Assign the TBI an address which won't conflict with the PHYs */
        gfar_write(&priv->regs->tbipa, TBIPA_VALUE);
 }
@@ -577,8 +565,7 @@ static void free_skb_resources(struct gfar_private *priv)
                for (i = 0; i < priv->rx_ring_size; i++) {
                        if (priv->rx_skbuff[i]) {
                                dma_unmap_single(NULL, rxbdp->bufPtr,
-                                               priv->rx_buffer_size
-                                               + RXBUF_ALIGNMENT,
+                                               priv->rx_buffer_size,
                                                DMA_FROM_DEVICE);
 
                                dev_kfree_skb_any(priv->rx_skbuff[i]);
@@ -636,6 +623,7 @@ int startup_gfar(struct net_device *dev)
        struct gfar *regs = priv->regs;
        int err = 0;
        u32 rctrl = 0;
+       u32 attrs = 0;
 
        gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
@@ -795,18 +783,50 @@ int startup_gfar(struct net_device *dev)
        if (priv->rx_csum_enable)
                rctrl |= RCTRL_CHECKSUMMING;
 
-       if (priv->extended_hash)
+       if (priv->extended_hash) {
                rctrl |= RCTRL_EXTHASH;
 
+               gfar_clear_exact_match(dev);
+               rctrl |= RCTRL_EMEN;
+       }
+
        if (priv->vlan_enable)
                rctrl |= RCTRL_VLAN;
 
+       if (priv->padding) {
+               rctrl &= ~RCTRL_PAL_MASK;
+               rctrl |= RCTRL_PADDING(priv->padding);
+       }
+
        /* Init rctrl based on our settings */
        gfar_write(&priv->regs->rctrl, rctrl);
 
        if (dev->features & NETIF_F_IP_CSUM)
                gfar_write(&priv->regs->tctrl, TCTRL_INIT_CSUM);
 
+       /* Set the extraction length and index */
+       attrs = ATTRELI_EL(priv->rx_stash_size) |
+               ATTRELI_EI(priv->rx_stash_index);
+
+       gfar_write(&priv->regs->attreli, attrs);
+
+       /* Start with defaults, and add stashing or locking
+        * depending on the approprate variables */
+       attrs = ATTR_INIT_SETTINGS;
+
+       if (priv->bd_stash_en)
+               attrs |= ATTR_BDSTASH;
+
+       if (priv->rx_stash_size != 0)
+               attrs |= ATTR_BUFSTASH;
+
+       gfar_write(&priv->regs->attr, attrs);
+
+       gfar_write(&priv->regs->fifo_tx_thr, priv->fifo_threshold);
+       gfar_write(&priv->regs->fifo_tx_starve, priv->fifo_starve);
+       gfar_write(&priv->regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
+
+       /* Start the controller */
        gfar_start(dev);
 
        return 0;
@@ -851,34 +871,32 @@ static int gfar_enet_open(struct net_device *dev)
        return err;
 }
 
-static struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
+static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
 {
        struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
 
        memset(fcb, 0, GMAC_FCB_LEN);
 
-       /* Flag the bd so the controller looks for the FCB */
-       bdp->status |= TXBD_TOE;
-
        return fcb;
 }
 
 static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
 {
-       int len;
+       u8 flags = 0;
 
        /* If we're here, it's a IP packet with a TCP or UDP
         * payload.  We set it to checksum, using a pseudo-header
         * we provide
         */
-       fcb->ip = 1;
-       fcb->tup = 1;
-       fcb->ctu = 1;
-       fcb->nph = 1;
+       flags = TXFCB_DEFAULT;
 
-       /* Notify the controller what the protocol is */
-       if (skb->nh.iph->protocol == IPPROTO_UDP)
-               fcb->udp = 1;
+       /* Tell the controller what the protocol is */
+       /* And provide the already calculated phcs */
+       if (skb->nh.iph->protocol == IPPROTO_UDP) {
+               flags |= TXFCB_UDP;
+               fcb->phcs = skb->h.uh->check;
+       } else
+               fcb->phcs = skb->h.th->check;
 
        /* l3os is the distance between the start of the
         * frame (skb->data) and the start of the IP hdr.
@@ -887,17 +905,12 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
        fcb->l3os = (u16)(skb->nh.raw - skb->data - GMAC_FCB_LEN);
        fcb->l4os = (u16)(skb->h.raw - skb->nh.raw);
 
-       len = skb->nh.iph->tot_len - fcb->l4os;
-
-       /* Provide the pseudoheader csum */
-       fcb->phcs = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-                       skb->nh.iph->daddr, len,
-                       skb->nh.iph->protocol, 0);
+       fcb->flags = flags;
 }
 
-void gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
+void inline gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
 {
-       fcb->vln = 1;
+       fcb->flags |= TXFCB_VLN;
        fcb->vlctl = vlan_tx_tag_get(skb);
 }
 
@@ -908,6 +921,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct gfar_private *priv = netdev_priv(dev);
        struct txfcb *fcb = NULL;
        struct txbd8 *txbdp;
+       u16 status;
 
        /* Update transmit stats */
        priv->stats.tx_bytes += skb->len;
@@ -919,19 +933,22 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        txbdp = priv->cur_tx;
 
        /* Clear all but the WRAP status flags */
-       txbdp->status &= TXBD_WRAP;
+       status = txbdp->status & TXBD_WRAP;
 
        /* Set up checksumming */
-       if ((dev->features & NETIF_F_IP_CSUM)
-                       && (CHECKSUM_HW == skb->ip_summed)) {
+       if (likely((dev->features & NETIF_F_IP_CSUM)
+                       && (CHECKSUM_HW == skb->ip_summed))) {
                fcb = gfar_add_fcb(skb, txbdp);
+               status |= TXBD_TOE;
                gfar_tx_checksum(skb, fcb);
        }
 
        if (priv->vlan_enable &&
                        unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) {
-               if (NULL == fcb)
+               if (unlikely(NULL == fcb)) {
                        fcb = gfar_add_fcb(skb, txbdp);
+                       status |= TXBD_TOE;
+               }
 
                gfar_tx_vlan(skb, fcb);
        }
@@ -949,14 +966,16 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
            (priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size);
 
        /* Flag the BD as interrupt-causing */
-       txbdp->status |= TXBD_INTERRUPT;
+       status |= TXBD_INTERRUPT;
 
        /* Flag the BD as ready to go, last in frame, and  */
        /* in need of CRC */
-       txbdp->status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
+       status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
 
        dev->trans_start = jiffies;
 
+       txbdp->status = status;
+
        /* If this was the last BD in the ring, the next one */
        /* is at the beginning of the ring */
        if (txbdp->status & TXBD_WRAP)
@@ -1010,21 +1029,7 @@ static struct net_device_stats * gfar_get_stats(struct net_device *dev)
 /* Changes the mac address if the controller is not running. */
 int gfar_set_mac_address(struct net_device *dev)
 {
-       struct gfar_private *priv = netdev_priv(dev);
-       int i;
-       char tmpbuf[MAC_ADDR_LEN];
-       u32 tempval;
-
-       /* Now copy it into the mac registers backwards, cuz */
-       /* little endian is silly */
-       for (i = 0; i < MAC_ADDR_LEN; i++)
-               tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->dev_addr[i];
-
-       gfar_write(&priv->regs->macstnaddr1, *((u32 *) (tmpbuf)));
-
-       tempval = *((u32 *) (tmpbuf + 4));
-
-       gfar_write(&priv->regs->macstnaddr2, tempval);
+       gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
 
        return 0;
 }
@@ -1110,7 +1115,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
            INCREMENTAL_BUFFER_SIZE;
 
        /* Only stop and start the controller if it isn't already
-        * stopped */
+        * stopped, and we changed something */
        if ((oldsize != tempsize) && (dev->flags & IFF_UP))
                stop_gfar(dev);
 
@@ -1220,6 +1225,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs)
 
 struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
 {
+       unsigned int alignamount;
        struct gfar_private *priv = netdev_priv(dev);
        struct sk_buff *skb = NULL;
        unsigned int timeout = SKB_ALLOC_TIMEOUT;
@@ -1231,18 +1237,18 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
        if (NULL == skb)
                return NULL;
 
+       alignamount = RXBUF_ALIGNMENT -
+               (((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1));
+
        /* We need the data buffer to be aligned properly.  We will reserve
         * as many bytes as needed to align the data properly
         */
-       skb_reserve(skb,
-                   RXBUF_ALIGNMENT -
-                   (((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1)));
+       skb_reserve(skb, alignamount);
 
        skb->dev = dev;
 
        bdp->bufPtr = dma_map_single(NULL, skb->data,
-                       priv->rx_buffer_size + RXBUF_ALIGNMENT,
-                       DMA_FROM_DEVICE);
+                       priv->rx_buffer_size, DMA_FROM_DEVICE);
 
        bdp->length = 0;
 
@@ -1350,7 +1356,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
        /* If valid headers were found, and valid sums
         * were verified, then we tell the kernel that no
         * checksumming is necessary.  Otherwise, it is */
-       if (fcb->cip && !fcb->eip && fcb->ctu && !fcb->etu)
+       if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU))
                skb->ip_summed = CHECKSUM_UNNECESSARY;
        else
                skb->ip_summed = CHECKSUM_NONE;
@@ -1401,7 +1407,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
                skb->protocol = eth_type_trans(skb, dev);
 
                /* Send the packet up the stack */
-               if (unlikely(priv->vlgrp && fcb->vln))
+               if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN)))
                        ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl);
                else
                        ret = RECEIVE(skb);
@@ -1620,6 +1626,7 @@ static void adjust_link(struct net_device *dev)
        spin_lock_irqsave(&priv->lock, flags);
        if (phydev->link) {
                u32 tempval = gfar_read(&regs->maccfg2);
+               u32 ecntrl = gfar_read(&regs->ecntrl);
 
                /* Now we make sure that we can be in full duplex mode.
                 * If not, we operate in half-duplex mode. */
@@ -1644,6 +1651,13 @@ static void adjust_link(struct net_device *dev)
                        case 10:
                                tempval =
                                    ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
+
+                               /* Reduced mode distinguishes
+                                * between 10 and 100 */
+                               if (phydev->speed == SPEED_100)
+                                       ecntrl |= ECNTRL_R100;
+                               else
+                                       ecntrl &= ~(ECNTRL_R100);
                                break;
                        default:
                                if (netif_msg_link(priv))
@@ -1657,6 +1671,7 @@ static void adjust_link(struct net_device *dev)
                }
 
                gfar_write(&regs->maccfg2, tempval);
+               gfar_write(&regs->ecntrl, ecntrl);
 
                if (!priv->oldlink) {
                        new_state = 1;
@@ -1721,6 +1736,9 @@ static void gfar_set_multi(struct net_device *dev)
                gfar_write(&regs->gaddr6, 0xffffffff);
                gfar_write(&regs->gaddr7, 0xffffffff);
        } else {
+               int em_num;
+               int idx;
+
                /* zero out the hash */
                gfar_write(&regs->igaddr0, 0x0);
                gfar_write(&regs->igaddr1, 0x0);
@@ -1739,18 +1757,47 @@ static void gfar_set_multi(struct net_device *dev)
                gfar_write(&regs->gaddr6, 0x0);
                gfar_write(&regs->gaddr7, 0x0);
 
+               /* If we have extended hash tables, we need to
+                * clear the exact match registers to prepare for
+                * setting them */
+               if (priv->extended_hash) {
+                       em_num = GFAR_EM_NUM + 1;
+                       gfar_clear_exact_match(dev);
+                       idx = 1;
+               } else {
+                       idx = 0;
+                       em_num = 0;
+               }
+
                if(dev->mc_count == 0)
                        return;
 
                /* Parse the list, and set the appropriate bits */
                for(mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
-                       gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr);
+                       if (idx < em_num) {
+                               gfar_set_mac_for_addr(dev, idx,
+                                               mc_ptr->dmi_addr);
+                               idx++;
+                       } else
+                               gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr);
                }
        }
 
        return;
 }
 
+
+/* Clears each of the exact match registers to zero, so they
+ * don't interfere with normal reception */
+static void gfar_clear_exact_match(struct net_device *dev)
+{
+       int idx;
+       u8 zero_arr[MAC_ADDR_LEN] = {0,0,0,0,0,0};
+
+       for(idx = 1;idx < GFAR_EM_NUM + 1;idx++)
+               gfar_set_mac_for_addr(dev, idx, (u8 *)zero_arr);
+}
+
 /* Set the appropriate hash bit for the given addr */
 /* The algorithm works like so:
  * 1) Take the Destination Address (ie the multicast address), and
@@ -1781,6 +1828,32 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr)
        return;
 }
 
+
+/* There are multiple MAC Address register pairs on some controllers
+ * This function sets the numth pair to a given address
+ */
+static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+       int idx;
+       char tmpbuf[MAC_ADDR_LEN];
+       u32 tempval;
+       u32 *macptr = &priv->regs->macstnaddr1;
+
+       macptr += num*2;
+
+       /* Now copy it into the mac registers backwards, cuz */
+       /* little endian is silly */
+       for (idx = 0; idx < MAC_ADDR_LEN; idx++)
+               tmpbuf[MAC_ADDR_LEN - 1 - idx] = addr[idx];
+
+       gfar_write(macptr, *((u32 *) (tmpbuf)));
+
+       tempval = *((u32 *) (tmpbuf + 4));
+
+       gfar_write(macptr+1, tempval);
+}
+
 /* GFAR error interrupt handler */
 static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
 {
index 5065ba82cb7608324d7b8d6f1a2a37a2b5b3fff2..94a91da84fbb7ac5abe74cd6e63332c48ca9afa5 100644 (file)
@@ -90,12 +90,26 @@ extern const char gfar_driver_version[];
 #define GFAR_RX_MAX_RING_SIZE   256
 #define GFAR_TX_MAX_RING_SIZE   256
 
+#define GFAR_MAX_FIFO_THRESHOLD 511
+#define GFAR_MAX_FIFO_STARVE   511
+#define GFAR_MAX_FIFO_STARVE_OFF 511
+
 #define DEFAULT_RX_BUFFER_SIZE  1536
 #define TX_RING_MOD_MASK(size) (size-1)
 #define RX_RING_MOD_MASK(size) (size-1)
 #define JUMBO_BUFFER_SIZE 9728
 #define JUMBO_FRAME_SIZE 9600
 
+#define DEFAULT_FIFO_TX_THR 0x100
+#define DEFAULT_FIFO_TX_STARVE 0x40
+#define DEFAULT_FIFO_TX_STARVE_OFF 0x80
+#define DEFAULT_BD_STASH 1
+#define DEFAULT_STASH_LENGTH   64
+#define DEFAULT_STASH_INDEX    0
+
+/* The number of Exact Match registers */
+#define GFAR_EM_NUM    15
+
 /* Latency of interface clock in nanoseconds */
 /* Interface clock latency , in this case, means the
  * time described by a value of 1 in the interrupt
@@ -112,11 +126,11 @@ extern const char gfar_driver_version[];
 
 #define DEFAULT_TX_COALESCE 1
 #define DEFAULT_TXCOUNT        16
-#define DEFAULT_TXTIME 400
+#define DEFAULT_TXTIME 4
 
 #define DEFAULT_RX_COALESCE 1
 #define DEFAULT_RXCOUNT        16
-#define DEFAULT_RXTIME 400
+#define DEFAULT_RXTIME 4
 
 #define TBIPA_VALUE            0x1f
 #define MIIMCFG_INIT_VALUE     0x00000007
@@ -147,6 +161,7 @@ extern const char gfar_driver_version[];
 
 #define ECNTRL_INIT_SETTINGS   0x00001000
 #define ECNTRL_TBI_MODE         0x00000020
+#define ECNTRL_R100            0x00000008
 
 #define MRBLR_INIT_SETTINGS    DEFAULT_RX_BUFFER_SIZE
 
@@ -181,10 +196,12 @@ extern const char gfar_driver_version[];
 #define RCTRL_PRSDEP_MASK      0x000000c0
 #define RCTRL_PRSDEP_INIT      0x000000c0
 #define RCTRL_PROM             0x00000008
+#define RCTRL_EMEN             0x00000002
 #define RCTRL_CHECKSUMMING     (RCTRL_IPCSEN \
                | RCTRL_TUCSEN | RCTRL_PRSDEP_INIT)
 #define RCTRL_EXTHASH          (RCTRL_GHTX)
 #define RCTRL_VLAN             (RCTRL_PRSDEP_INIT)
+#define RCTRL_PADDING(x)       ((x << 16) & RCTRL_PAL_MASK)
 
 
 #define RSTAT_CLEAR_RHALT       0x00800000
@@ -251,28 +268,26 @@ extern const char gfar_driver_version[];
                IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
                | IMASK_PERR)
 
+/* Fifo management */
+#define FIFO_TX_THR_MASK       0x01ff
+#define FIFO_TX_STARVE_MASK    0x01ff
+#define FIFO_TX_STARVE_OFF_MASK        0x01ff
 
 /* Attribute fields */
 
 /* This enables rx snooping for buffers and descriptors */
-#ifdef CONFIG_GFAR_BDSTASH
 #define ATTR_BDSTASH           0x00000800
-#else
-#define ATTR_BDSTASH           0x00000000
-#endif
 
-#ifdef CONFIG_GFAR_BUFSTASH
 #define ATTR_BUFSTASH          0x00004000
-#define STASH_LENGTH           64
-#else
-#define ATTR_BUFSTASH          0x00000000
-#endif
 
 #define ATTR_SNOOPING          0x000000c0
-#define ATTR_INIT_SETTINGS      (ATTR_SNOOPING \
-               | ATTR_BDSTASH | ATTR_BUFSTASH)
+#define ATTR_INIT_SETTINGS      ATTR_SNOOPING
 
 #define ATTRELI_INIT_SETTINGS   0x0
+#define ATTRELI_EL_MASK                0x3fff0000
+#define ATTRELI_EL(x) (x << 16)
+#define ATTRELI_EI_MASK                0x00003fff
+#define ATTRELI_EI(x) (x)
 
 
 /* TxBD status field bits */
@@ -328,6 +343,7 @@ extern const char gfar_driver_version[];
 #define RXFCB_CTU              0x0400
 #define RXFCB_EIP              0x0200
 #define RXFCB_ETU              0x0100
+#define RXFCB_CSUM_MASK                0x0f00
 #define RXFCB_PERR_MASK                0x000c
 #define RXFCB_PERR_BADL3       0x0008
 
@@ -339,14 +355,7 @@ struct txbd8
 };
 
 struct txfcb {
-       u8      vln:1,
-               ip:1,
-               ip6:1,
-               tup:1,
-               udp:1,
-               cip:1,
-               ctu:1,
-               nph:1;
+       u8      flags;
        u8      reserved;
        u8      l4os;   /* Level 4 Header Offset */
        u8      l3os;   /* Level 3 Header Offset */
@@ -362,14 +371,7 @@ struct rxbd8
 };
 
 struct rxfcb {
-       u16     vln:1,
-               ip:1,
-               ip6:1,
-               tup:1,
-               cip:1,
-               ctu:1,
-               eip:1,
-               etu:1;
+       u16     flags;
        u8      rq;     /* Receive Queue index */
        u8      pro;    /* Layer 4 Protocol */
        u16     reserved;
@@ -688,12 +690,17 @@ struct gfar_private {
        spinlock_t lock;
        unsigned int rx_buffer_size;
        unsigned int rx_stash_size;
+       unsigned int rx_stash_index;
        unsigned int tx_ring_size;
        unsigned int rx_ring_size;
+       unsigned int fifo_threshold;
+       unsigned int fifo_starve;
+       unsigned int fifo_starve_off;
 
        unsigned char vlan_enable:1,
                rx_csum_enable:1,
-               extended_hash:1;
+               extended_hash:1,
+               bd_stash_en:1;
        unsigned short padding;
        struct vlan_group *vlgrp;
        /* Info structure initialized by board setup code */
@@ -731,6 +738,6 @@ extern void stop_gfar(struct net_device *dev);
 extern void gfar_halt(struct net_device *dev);
 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
                int enable, u32 regnum, u32 read);
-void gfar_setup_stashing(struct net_device *dev);
+void gfar_init_sysfs(struct net_device *dev);
 
 #endif /* __GIANFAR_H */
index cfa3cd7c91a0a9c777851379e1c63d9eeae217a9..765e810620fe95f68834e7fede0019190609a494 100644 (file)
@@ -125,7 +125,7 @@ static char stat_gstrings[][ETH_GSTRING_LEN] = {
 static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       
+
        if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
                memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
        else
index e85eb216fb5be40464e1dfdf0402f77059bfeafb..d527cf2f9c1d7f47398eaac003b361e79428b38b 100644 (file)
@@ -24,6 +24,7 @@
 #define MII_READ_COMMAND       0x00000001
 
 #define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+               | SUPPORTED_10baseT_Full \
                | SUPPORTED_100baseT_Half \
                | SUPPORTED_100baseT_Full \
                | SUPPORTED_Autoneg \
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
new file mode 100644 (file)
index 0000000..10d34cb
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * drivers/net/gianfar_sysfs.c
+ *
+ * Gianfar Ethernet Driver
+ * This driver is designed for the non-CPM ethernet controllers
+ * on the 85xx and 83xx family of integrated processors
+ * Based on 8260_io/fcc_enet.c
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-2005 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Sysfs file creation and management
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+
+#include <asm/uaccess.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include "gianfar.h"
+
+#define GFAR_ATTR(_name) \
+static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
+static ssize_t gfar_set_##_name(struct class_device *cdev, \
+               const char *buf, size_t count); \
+static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
+
+#define GFAR_CREATE_FILE(_dev, _name) \
+       class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
+
+GFAR_ATTR(bd_stash);
+GFAR_ATTR(rx_stash_size);
+GFAR_ATTR(rx_stash_index);
+GFAR_ATTR(fifo_threshold);
+GFAR_ATTR(fifo_starve);
+GFAR_ATTR(fifo_starve_off);
+
+#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
+
+static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+
+       return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
+}
+
+static ssize_t gfar_set_bd_stash(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       int new_setting = 0;
+       u32 temp;
+       unsigned long flags;
+
+       /* Find out the new setting */
+       if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
+               new_setting = 1;
+       else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
+               new_setting = 0;
+       else
+               return count;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Set the new stashing value */
+       priv->bd_stash_en = new_setting;
+
+       temp = gfar_read(&priv->regs->attr);
+       
+       if (new_setting)
+               temp |= ATTR_BDSTASH;
+       else
+               temp &= ~(ATTR_BDSTASH);
+
+       gfar_write(&priv->regs->attr, temp);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return count;
+}
+
+static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+
+       return sprintf(buf, "%d\n", priv->rx_stash_size);
+}
+
+static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned int length = simple_strtoul(buf, NULL, 0);
+       u32 temp;
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (length > priv->rx_buffer_size)
+               return count;
+
+       if (length == priv->rx_stash_size)
+               return count;
+
+       priv->rx_stash_size = length;
+
+       temp = gfar_read(&priv->regs->attreli);
+       temp &= ~ATTRELI_EL_MASK;
+       temp |= ATTRELI_EL(length);
+       gfar_write(&priv->regs->attreli, temp);
+
+       /* Turn stashing on/off as appropriate */
+       temp = gfar_read(&priv->regs->attr);
+
+       if (length)
+               temp |= ATTR_BUFSTASH;
+       else
+               temp &= ~(ATTR_BUFSTASH);
+
+       gfar_write(&priv->regs->attr, temp);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return count;
+}
+
+
+/* Stashing will only be enabled when rx_stash_size != 0 */
+static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+
+       return sprintf(buf, "%d\n", priv->rx_stash_index);
+}
+
+static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned short index = simple_strtoul(buf, NULL, 0);
+       u32 temp;
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (index > priv->rx_stash_size)
+               return count;
+
+       if (index == priv->rx_stash_index)
+               return count;
+
+       priv->rx_stash_index = index;
+
+       temp = gfar_read(&priv->regs->attreli);
+       temp &= ~ATTRELI_EI_MASK;
+       temp |= ATTRELI_EI(index);
+       gfar_write(&priv->regs->attreli, flags);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return count;
+}
+
+static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+
+       return sprintf(buf, "%d\n", priv->fifo_threshold);
+}
+
+static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned int length = simple_strtoul(buf, NULL, 0);
+       u32 temp;
+       unsigned long flags;
+
+       if (length > GFAR_MAX_FIFO_THRESHOLD)
+               return count;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       priv->fifo_threshold = length;
+
+       temp = gfar_read(&priv->regs->fifo_tx_thr);
+       temp &= ~FIFO_TX_THR_MASK;
+       temp |= length;
+       gfar_write(&priv->regs->fifo_tx_thr, temp);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return count;
+}
+
+static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+
+       return sprintf(buf, "%d\n", priv->fifo_starve);
+}
+
+
+static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned int num = simple_strtoul(buf, NULL, 0);
+       u32 temp;
+       unsigned long flags;
+
+       if (num > GFAR_MAX_FIFO_STARVE)
+               return count;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       priv->fifo_starve = num;
+
+       temp = gfar_read(&priv->regs->fifo_tx_starve);
+       temp &= ~FIFO_TX_STARVE_MASK;
+       temp |= num;
+       gfar_write(&priv->regs->fifo_tx_starve, temp);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return count;
+}
+
+static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+
+       return sprintf(buf, "%d\n", priv->fifo_starve_off);
+}
+
+static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       struct net_device *dev = to_net_dev(cdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned int num = simple_strtoul(buf, NULL, 0);
+       u32 temp;
+       unsigned long flags;
+
+       if (num > GFAR_MAX_FIFO_STARVE_OFF)
+               return count;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       priv->fifo_starve_off = num;
+
+       temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
+       temp &= ~FIFO_TX_STARVE_OFF_MASK;
+       temp |= num;
+       gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return count;
+}
+
+void gfar_init_sysfs(struct net_device *dev)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+
+       /* Initialize the default values */
+       priv->rx_stash_size = DEFAULT_STASH_LENGTH;
+       priv->rx_stash_index = DEFAULT_STASH_INDEX;
+       priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
+       priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
+       priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
+       priv->bd_stash_en = DEFAULT_BD_STASH;
+
+       /* Create our sysfs files */
+       GFAR_CREATE_FILE(dev, bd_stash);
+       GFAR_CREATE_FILE(dev, rx_stash_size);
+       GFAR_CREATE_FILE(dev, rx_stash_index);
+       GFAR_CREATE_FILE(dev, fifo_threshold);
+       GFAR_CREATE_FILE(dev, fifo_starve);
+       GFAR_CREATE_FILE(dev, fifo_starve_off);
+
+}
index c22c0517883c2b8566f3b4c1788cbab6b866feda..fa176ffb4ad525b2fe6869df4919734ebd2062c6 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 3961a754e920e37e8a1b310670edcdb48549a46c..31867e4b891b1e582e2490638cc417894337e736 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,
diff --git a/drivers/net/ixp2000/Kconfig b/drivers/net/ixp2000/Kconfig
new file mode 100644 (file)
index 0000000..2fec241
--- /dev/null
@@ -0,0 +1,6 @@
+config ENP2611_MSF_NET
+       tristate "Radisys ENP2611 MSF network interface support"
+       depends on ARCH_ENP2611
+       help
+         This is a driver for the MSF network interface unit in
+         the IXP2400 on the Radisys ENP2611 platform.
diff --git a/drivers/net/ixp2000/Makefile b/drivers/net/ixp2000/Makefile
new file mode 100644 (file)
index 0000000..fd38351
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ENP2611_MSF_NET) += enp2611_mod.o
+
+enp2611_mod-objs := caleb.o enp2611.o ixp2400-msf.o ixpdev.o pm3386.o
diff --git a/drivers/net/ixp2000/caleb.c b/drivers/net/ixp2000/caleb.c
new file mode 100644 (file)
index 0000000..3595e10
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/delay.h>
+#include <asm/io.h>
+#include "caleb.h"
+
+#define CALEB_IDLO             0x00
+#define CALEB_IDHI             0x01
+#define CALEB_RID              0x02
+#define CALEB_RESET            0x03
+#define CALEB_INTREN0          0x04
+#define CALEB_INTREN1          0x05
+#define CALEB_INTRSTAT0                0x06
+#define CALEB_INTRSTAT1                0x07
+#define CALEB_PORTEN           0x08
+#define CALEB_BURST            0x09
+#define CALEB_PORTPAUS         0x0A
+#define CALEB_PORTPAUSD                0x0B
+#define CALEB_PHY0RX           0x10
+#define CALEB_PHY1RX           0x11
+#define CALEB_PHY0TX           0x12
+#define CALEB_PHY1TX           0x13
+#define CALEB_IXPRX_HI_CNTR    0x15
+#define CALEB_PHY0RX_HI_CNTR   0x16
+#define CALEB_PHY1RX_HI_CNTR   0x17
+#define CALEB_IXPRX_CNTR       0x18
+#define CALEB_PHY0RX_CNTR      0x19
+#define CALEB_PHY1RX_CNTR      0x1A
+#define CALEB_IXPTX_CNTR       0x1B
+#define CALEB_PHY0TX_CNTR      0x1C
+#define CALEB_PHY1TX_CNTR      0x1D
+#define CALEB_DEBUG0           0x1E
+#define CALEB_DEBUG1           0x1F
+
+
+static u8 caleb_reg_read(int reg)
+{
+       u8 value;
+
+       value = *((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg));
+
+//     printk(KERN_INFO "caleb_reg_read(%d) = %.2x\n", reg, value);
+
+       return value;
+}
+
+static void caleb_reg_write(int reg, u8 value)
+{
+       u8 dummy;
+
+//     printk(KERN_INFO "caleb_reg_write(%d, %.2x)\n", reg, value);
+
+       *((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg)) = value;
+
+       dummy = *((volatile u8 *)ENP2611_CALEB_VIRT_BASE);
+       __asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+}
+
+
+void caleb_reset(void)
+{
+       /*
+        * Perform a chip reset.
+        */
+       caleb_reg_write(CALEB_RESET, 0x02);
+       udelay(1);
+
+       /*
+        * Enable all interrupt sources.  This is needed to get
+        * meaningful results out of the status bits (register 6
+        * and 7.)
+        */
+       caleb_reg_write(CALEB_INTREN0, 0xff);
+       caleb_reg_write(CALEB_INTREN1, 0x07);
+
+       /*
+        * Set RX and TX FIFO thresholds to 1.5kb.
+        */
+       caleb_reg_write(CALEB_PHY0RX, 0x11);
+       caleb_reg_write(CALEB_PHY1RX, 0x11);
+       caleb_reg_write(CALEB_PHY0TX, 0x11);
+       caleb_reg_write(CALEB_PHY1TX, 0x11);
+
+       /*
+        * Program SPI-3 burst size.
+        */
+       caleb_reg_write(CALEB_BURST, 0);        // 64-byte RBUF mpackets
+//     caleb_reg_write(CALEB_BURST, 1);        // 128-byte RBUF mpackets
+//     caleb_reg_write(CALEB_BURST, 2);        // 256-byte RBUF mpackets
+}
+
+void caleb_enable_rx(int port)
+{
+       u8 temp;
+
+       temp = caleb_reg_read(CALEB_PORTEN);
+       temp |= 1 << port;
+       caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_disable_rx(int port)
+{
+       u8 temp;
+
+       temp = caleb_reg_read(CALEB_PORTEN);
+       temp &= ~(1 << port);
+       caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_enable_tx(int port)
+{
+       u8 temp;
+
+       temp = caleb_reg_read(CALEB_PORTEN);
+       temp |= 1 << (port + 4);
+       caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_disable_tx(int port)
+{
+       u8 temp;
+
+       temp = caleb_reg_read(CALEB_PORTEN);
+       temp &= ~(1 << (port + 4));
+       caleb_reg_write(CALEB_PORTEN, temp);
+}
diff --git a/drivers/net/ixp2000/caleb.h b/drivers/net/ixp2000/caleb.h
new file mode 100644 (file)
index 0000000..e93a1ef
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __CALEB_H
+#define __CALEB_H
+
+void caleb_reset(void);
+void caleb_enable_rx(int port);
+void caleb_disable_rx(int port);
+void caleb_enable_tx(int port);
+void caleb_disable_tx(int port);
+
+
+#endif
diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c
new file mode 100644 (file)
index 0000000..d82651a
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * IXP2400 MSF network device driver for the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <asm/arch/uengine.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include "ixpdev.h"
+#include "caleb.h"
+#include "ixp2400-msf.h"
+#include "pm3386.h"
+
+/***********************************************************************
+ * The Radisys ENP2611 is a PCI form factor board with three SFP GBIC
+ * slots, connected via two PMC/Sierra 3386s and an SPI-3 bridge FPGA
+ * to the IXP2400.
+ *
+ *                +-------------+
+ * SFP GBIC #0 ---+             |       +---------+
+ *                |  PM3386 #0  +-------+         |
+ * SFP GBIC #1 ---+             |       | "Caleb" |         +---------+
+ *                +-------------+       |         |         |         |
+ *                                      | SPI-3   +---------+ IXP2400 |
+ *                +-------------+       | bridge  |         |         |
+ * SFP GBIC #2 ---+             |       | FPGA    |         +---------+
+ *                |  PM3386 #1  +-------+         |
+ *                |             |       +---------+
+ *                +-------------+
+ *              ^                   ^                  ^
+ *              | 1.25Gbaud         | 104MHz           | 104MHz
+ *              | SERDES ea.        | SPI-3 ea.        | SPI-3
+ *
+ ***********************************************************************/
+static struct ixp2400_msf_parameters enp2611_msf_parameters =
+{
+       .rx_mode =              IXP2400_RX_MODE_UTOPIA_POS |
+                               IXP2400_RX_MODE_1x32 |
+                               IXP2400_RX_MODE_MPHY |
+                               IXP2400_RX_MODE_MPHY_32 |
+                               IXP2400_RX_MODE_MPHY_POLLED_STATUS |
+                               IXP2400_RX_MODE_MPHY_LEVEL3 |
+                               IXP2400_RX_MODE_RBUF_SIZE_64,
+
+       .rxclk01_multiplier =   IXP2400_PLL_MULTIPLIER_16,
+
+       .rx_poll_ports =        3,
+
+       .rx_channel_mode = {
+               IXP2400_PORT_RX_MODE_MASTER |
+               IXP2400_PORT_RX_MODE_POS_PHY |
+               IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+               IXP2400_PORT_RX_MODE_ODD_PARITY |
+               IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+               IXP2400_PORT_RX_MODE_MASTER |
+               IXP2400_PORT_RX_MODE_POS_PHY |
+               IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+               IXP2400_PORT_RX_MODE_ODD_PARITY |
+               IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+               IXP2400_PORT_RX_MODE_MASTER |
+               IXP2400_PORT_RX_MODE_POS_PHY |
+               IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+               IXP2400_PORT_RX_MODE_ODD_PARITY |
+               IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+               IXP2400_PORT_RX_MODE_MASTER |
+               IXP2400_PORT_RX_MODE_POS_PHY |
+               IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+               IXP2400_PORT_RX_MODE_ODD_PARITY |
+               IXP2400_PORT_RX_MODE_2_CYCLE_DECODE
+       },
+
+       .tx_mode =              IXP2400_TX_MODE_UTOPIA_POS |
+                               IXP2400_TX_MODE_1x32 |
+                               IXP2400_TX_MODE_MPHY |
+                               IXP2400_TX_MODE_MPHY_32 |
+                               IXP2400_TX_MODE_MPHY_POLLED_STATUS |
+                               IXP2400_TX_MODE_MPHY_LEVEL3 |
+                               IXP2400_TX_MODE_TBUF_SIZE_64,
+
+       .txclk01_multiplier =   IXP2400_PLL_MULTIPLIER_16,
+
+       .tx_poll_ports =        3,
+
+       .tx_channel_mode = {
+               IXP2400_PORT_TX_MODE_MASTER |
+               IXP2400_PORT_TX_MODE_POS_PHY |
+               IXP2400_PORT_TX_MODE_ODD_PARITY |
+               IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+               IXP2400_PORT_TX_MODE_MASTER |
+               IXP2400_PORT_TX_MODE_POS_PHY |
+               IXP2400_PORT_TX_MODE_ODD_PARITY |
+               IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+               IXP2400_PORT_TX_MODE_MASTER |
+               IXP2400_PORT_TX_MODE_POS_PHY |
+               IXP2400_PORT_TX_MODE_ODD_PARITY |
+               IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+               IXP2400_PORT_TX_MODE_MASTER |
+               IXP2400_PORT_TX_MODE_POS_PHY |
+               IXP2400_PORT_TX_MODE_ODD_PARITY |
+               IXP2400_PORT_TX_MODE_2_CYCLE_DECODE
+       }
+};
+
+struct enp2611_ixpdev_priv
+{
+       struct ixpdev_priv              ixpdev_priv;
+       struct net_device_stats         stats;
+};
+
+static struct net_device *nds[3];
+static struct timer_list link_check_timer;
+
+static struct net_device_stats *enp2611_get_stats(struct net_device *dev)
+{
+       struct enp2611_ixpdev_priv *ip = netdev_priv(dev);
+
+       pm3386_get_stats(ip->ixpdev_priv.channel, &(ip->stats));
+
+       return &(ip->stats);
+}
+
+/* @@@ Poll the SFP moddef0 line too.  */
+/* @@@ Try to use the pm3386 DOOL interrupt as well.  */
+static void enp2611_check_link_status(unsigned long __dummy)
+{
+       int i;
+
+       for (i = 0; i < 3; i++) {
+               struct net_device *dev;
+               int status;
+
+               dev = nds[i];
+
+               status = pm3386_is_link_up(i);
+               if (status && !netif_carrier_ok(dev)) {
+                       /* @@@ Should report autonegotiation status.  */
+                       printk(KERN_INFO "%s: NIC Link is Up\n", dev->name);
+
+                       pm3386_enable_tx(i);
+                       caleb_enable_tx(i);
+                       netif_carrier_on(dev);
+               } else if (!status && netif_carrier_ok(dev)) {
+                       printk(KERN_INFO "%s: NIC Link is Down\n", dev->name);
+
+                       netif_carrier_off(dev);
+                       caleb_disable_tx(i);
+                       pm3386_disable_tx(i);
+               }
+       }
+
+       link_check_timer.expires = jiffies + HZ / 10;
+       add_timer(&link_check_timer);
+}
+
+static void enp2611_set_port_admin_status(int port, int up)
+{
+       if (up) {
+               caleb_enable_rx(port);
+
+               pm3386_set_carrier(port, 1);
+               pm3386_enable_rx(port);
+       } else {
+               caleb_disable_tx(port);
+               pm3386_disable_tx(port);
+               /* @@@ Flush out pending packets.  */
+               pm3386_set_carrier(port, 0);
+
+               pm3386_disable_rx(port);
+               caleb_disable_rx(port);
+       }
+}
+
+static int __init enp2611_init_module(void)
+{ 
+       int i;
+
+       if (!machine_is_enp2611())
+               return -ENODEV;
+
+       caleb_reset();
+       pm3386_reset();
+
+       for (i = 0; i < 3; i++) {
+               nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv));
+               if (nds[i] == NULL) {
+                       while (--i >= 0)
+                               free_netdev(nds[i]);
+                       return -ENOMEM;
+               }
+
+               SET_MODULE_OWNER(nds[i]);
+               nds[i]->get_stats = enp2611_get_stats;
+               pm3386_init_port(i);
+               pm3386_get_mac(i, nds[i]->dev_addr);
+       }
+
+       ixp2400_msf_init(&enp2611_msf_parameters);
+
+       if (ixpdev_init(3, nds, enp2611_set_port_admin_status)) {
+               for (i = 0; i < 3; i++)
+                       free_netdev(nds[i]);
+               return -EINVAL;
+       }
+
+       init_timer(&link_check_timer);
+       link_check_timer.function = enp2611_check_link_status;
+       link_check_timer.expires = jiffies;
+       add_timer(&link_check_timer);
+
+       return 0;
+}
+
+static void __exit enp2611_cleanup_module(void)
+{
+       int i;
+
+       del_timer_sync(&link_check_timer);
+
+       ixpdev_deinit();
+       for (i = 0; i < 3; i++)
+               free_netdev(nds[i]);
+}
+
+module_init(enp2611_init_module);
+module_exit(enp2611_cleanup_module);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ixp2000/ixp2400-msf.c b/drivers/net/ixp2000/ixp2400-msf.c
new file mode 100644 (file)
index 0000000..48a3a89
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Generic library functions for the MSF (Media and Switch Fabric) unit
+ * found on the Intel IXP2400 network processor.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/arch/ixp2000-regs.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+#include "ixp2400-msf.h"
+
+/*
+ * This is the Intel recommended PLL init procedure as described on
+ * page 340 of the IXP2400/IXP2800 Programmer's Reference Manual.
+ */
+static void ixp2400_pll_init(struct ixp2400_msf_parameters *mp)
+{
+       int rx_dual_clock;
+       int tx_dual_clock;
+       u32 value;
+
+       /*
+        * If the RX mode is not 1x32, we have to enable both RX PLLs
+        * (#0 and #1.)  The same thing for the TX direction.
+        */
+       rx_dual_clock = !!(mp->rx_mode & IXP2400_RX_MODE_WIDTH_MASK);
+       tx_dual_clock = !!(mp->tx_mode & IXP2400_TX_MODE_WIDTH_MASK);
+
+       /*
+        * Read initial value.
+        */
+       value = ixp2000_reg_read(IXP2000_MSF_CLK_CNTRL);
+
+       /*
+        * Put PLLs in powerdown and bypass mode.
+        */
+       value |= 0x0000f0f0;
+       ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+       /*
+        * Set single or dual clock mode bits.
+        */
+       value &= ~0x03000000;
+       value |= (rx_dual_clock << 24) | (tx_dual_clock << 25);
+
+       /*
+        * Set multipliers.
+        */
+       value &= ~0x00ff0000;
+       value |= mp->rxclk01_multiplier << 16;
+       value |= mp->rxclk23_multiplier << 18;
+       value |= mp->txclk01_multiplier << 20;
+       value |= mp->txclk23_multiplier << 22;
+
+       /*
+        * And write value.
+        */
+       ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+       /*
+        * Disable PLL bypass mode.
+        */
+       value &= ~(0x00005000 | rx_dual_clock << 13 | tx_dual_clock << 15);
+       ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+       /*
+        * Turn on PLLs.
+        */
+       value &= ~(0x00000050 | rx_dual_clock << 5 | tx_dual_clock << 7);
+       ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+       /*
+        * Wait for PLLs to lock.  There are lock status bits, but IXP2400
+        * erratum #65 says that these lock bits should not be relied upon
+        * as they might not accurately reflect the true state of the PLLs.
+        */
+       udelay(100);
+}
+
+/*
+ * Needed according to p480 of Programmer's Reference Manual.
+ */
+static void ixp2400_msf_free_rbuf_entries(struct ixp2400_msf_parameters *mp)
+{
+       int size_bits;
+       int i;
+
+       /*
+        * Work around IXP2400 erratum #69 (silent RBUF-to-DRAM transfer
+        * corruption) in the Intel-recommended way: do not add the RBUF
+        * elements susceptible to corruption to the freelist.
+        */
+       size_bits = mp->rx_mode & IXP2400_RX_MODE_RBUF_SIZE_MASK;
+       if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_64) {
+               for (i = 1; i < 128; i++) {
+                       if (i == 9 || i == 18 || i == 27)
+                               continue;
+                       ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+               }
+       } else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_128) {
+               for (i = 1; i < 64; i++) {
+                       if (i == 4 || i == 9 || i == 13)
+                               continue;
+                       ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+               }
+       } else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_256) {
+               for (i = 1; i < 32; i++) {
+                       if (i == 2 || i == 4 || i == 6)
+                               continue;
+                       ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+               }
+       }
+}
+
+static u32 ixp2400_msf_valid_channels(u32 reg)
+{
+       u32 channels;
+
+       channels = 0;
+       switch (reg & IXP2400_RX_MODE_WIDTH_MASK) {
+       case IXP2400_RX_MODE_1x32:
+               channels = 0x1;
+               if (reg & IXP2400_RX_MODE_MPHY &&
+                   !(reg & IXP2400_RX_MODE_MPHY_32))
+                       channels = 0xf;
+               break;
+
+       case IXP2400_RX_MODE_2x16:
+               channels = 0x5;
+               break;
+
+       case IXP2400_RX_MODE_4x8:
+               channels = 0xf;
+               break;
+
+       case IXP2400_RX_MODE_1x16_2x8:
+               channels = 0xd;
+               break;
+       }
+
+       return channels;
+}
+
+static void ixp2400_msf_enable_rx(struct ixp2400_msf_parameters *mp)
+{
+       u32 value;
+
+       value = ixp2000_reg_read(IXP2000_MSF_RX_CONTROL) & 0x0fffffff;
+       value |= ixp2400_msf_valid_channels(mp->rx_mode) << 28;
+       ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, value);
+}
+
+static void ixp2400_msf_enable_tx(struct ixp2400_msf_parameters *mp)
+{
+       u32 value;
+
+       value = ixp2000_reg_read(IXP2000_MSF_TX_CONTROL) & 0x0fffffff;
+       value |= ixp2400_msf_valid_channels(mp->tx_mode) << 28;
+       ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, value);
+}
+
+
+void ixp2400_msf_init(struct ixp2400_msf_parameters *mp)
+{
+       u32 value;
+       int i;
+
+       /*
+        * Init the RX/TX PLLs based on the passed parameter block.
+        */
+       ixp2400_pll_init(mp);
+
+       /*
+        * Reset MSF.  Bit 7 in IXP_RESET_0 resets the MSF.
+        */
+       value = ixp2000_reg_read(IXP2000_RESET0);
+       ixp2000_reg_write(IXP2000_RESET0, value | 0x80);
+       ixp2000_reg_write(IXP2000_RESET0, value & ~0x80);
+
+       /*
+        * Initialise the RX section.
+        */
+       ixp2000_reg_write(IXP2000_MSF_RX_MPHY_POLL_LIMIT, mp->rx_poll_ports - 1);
+       ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, mp->rx_mode);
+       for (i = 0; i < 4; i++) {
+               ixp2000_reg_write(IXP2000_MSF_RX_UP_CONTROL_0 + i,
+                                               mp->rx_channel_mode[i]);
+       }
+       ixp2400_msf_free_rbuf_entries(mp);
+       ixp2400_msf_enable_rx(mp);
+
+       /*
+        * Initialise the TX section.
+        */
+       ixp2000_reg_write(IXP2000_MSF_TX_MPHY_POLL_LIMIT, mp->tx_poll_ports - 1);
+       ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, mp->tx_mode);
+       for (i = 0; i < 4; i++) {
+               ixp2000_reg_write(IXP2000_MSF_TX_UP_CONTROL_0 + i,
+                                               mp->tx_channel_mode[i]);
+       }
+       ixp2400_msf_enable_tx(mp);
+}
diff --git a/drivers/net/ixp2000/ixp2400-msf.h b/drivers/net/ixp2000/ixp2400-msf.h
new file mode 100644 (file)
index 0000000..3ac1af2
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Generic library functions for the MSF (Media and Switch Fabric) unit
+ * found on the Intel IXP2400 network processor.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#ifndef __IXP2400_MSF_H
+#define __IXP2400_MSF_H
+
+struct ixp2400_msf_parameters
+{
+       u32                             rx_mode;
+       unsigned                        rxclk01_multiplier:2;
+       unsigned                        rxclk23_multiplier:2;
+       unsigned                        rx_poll_ports:6;
+       u32                             rx_channel_mode[4];
+
+       u32                             tx_mode;
+       unsigned                        txclk01_multiplier:2;
+       unsigned                        txclk23_multiplier:2;
+       unsigned                        tx_poll_ports:6;
+       u32                             tx_channel_mode[4];
+};
+
+void ixp2400_msf_init(struct ixp2400_msf_parameters *mp);
+
+#define IXP2400_PLL_MULTIPLIER_48              0x00
+#define IXP2400_PLL_MULTIPLIER_24              0x01
+#define IXP2400_PLL_MULTIPLIER_16              0x02
+#define IXP2400_PLL_MULTIPLIER_12              0x03
+
+#define IXP2400_RX_MODE_CSIX                   0x00400000
+#define IXP2400_RX_MODE_UTOPIA_POS             0x00000000
+#define IXP2400_RX_MODE_WIDTH_MASK             0x00300000
+#define IXP2400_RX_MODE_1x16_2x8               0x00300000
+#define IXP2400_RX_MODE_4x8                    0x00200000
+#define IXP2400_RX_MODE_2x16                   0x00100000
+#define IXP2400_RX_MODE_1x32                   0x00000000
+#define IXP2400_RX_MODE_MPHY                   0x00080000
+#define IXP2400_RX_MODE_SPHY                   0x00000000
+#define IXP2400_RX_MODE_MPHY_32                        0x00040000
+#define IXP2400_RX_MODE_MPHY_4                 0x00000000
+#define IXP2400_RX_MODE_MPHY_POLLED_STATUS     0x00020000
+#define IXP2400_RX_MODE_MPHY_DIRECT_STATUS     0x00000000
+#define IXP2400_RX_MODE_CBUS_FULL_DUPLEX       0x00010000
+#define IXP2400_RX_MODE_CBUS_SIMPLEX           0x00000000
+#define IXP2400_RX_MODE_MPHY_LEVEL2            0x00004000
+#define IXP2400_RX_MODE_MPHY_LEVEL3            0x00000000
+#define IXP2400_RX_MODE_CBUS_8BIT              0x00002000
+#define IXP2400_RX_MODE_CBUS_4BIT              0x00000000
+#define IXP2400_RX_MODE_CSIX_SINGLE_FREELIST   0x00000200
+#define IXP2400_RX_MODE_CSIX_SPLIT_FREELISTS   0x00000000
+#define IXP2400_RX_MODE_RBUF_SIZE_MASK         0x0000000c
+#define IXP2400_RX_MODE_RBUF_SIZE_256          0x00000008
+#define IXP2400_RX_MODE_RBUF_SIZE_128          0x00000004
+#define IXP2400_RX_MODE_RBUF_SIZE_64           0x00000000
+
+#define IXP2400_PORT_RX_MODE_SLAVE             0x00000040
+#define IXP2400_PORT_RX_MODE_MASTER            0x00000000
+#define IXP2400_PORT_RX_MODE_POS_PHY_L3                0x00000020
+#define IXP2400_PORT_RX_MODE_POS_PHY_L2                0x00000000
+#define IXP2400_PORT_RX_MODE_POS_PHY           0x00000010
+#define IXP2400_PORT_RX_MODE_UTOPIA            0x00000000
+#define IXP2400_PORT_RX_MODE_EVEN_PARITY       0x0000000c
+#define IXP2400_PORT_RX_MODE_ODD_PARITY                0x00000008
+#define IXP2400_PORT_RX_MODE_NO_PARITY         0x00000000
+#define IXP2400_PORT_RX_MODE_UTOPIA_BIG_CELLS  0x00000002
+#define IXP2400_PORT_RX_MODE_UTOPIA_NORMAL_CELLS       0x00000000
+#define IXP2400_PORT_RX_MODE_2_CYCLE_DECODE    0x00000001
+#define IXP2400_PORT_RX_MODE_1_CYCLE_DECODE    0x00000000
+
+#define IXP2400_TX_MODE_CSIX                   0x00400000
+#define IXP2400_TX_MODE_UTOPIA_POS             0x00000000
+#define IXP2400_TX_MODE_WIDTH_MASK             0x00300000
+#define IXP2400_TX_MODE_1x16_2x8               0x00300000
+#define IXP2400_TX_MODE_4x8                    0x00200000
+#define IXP2400_TX_MODE_2x16                   0x00100000
+#define IXP2400_TX_MODE_1x32                   0x00000000
+#define IXP2400_TX_MODE_MPHY                   0x00080000
+#define IXP2400_TX_MODE_SPHY                   0x00000000
+#define IXP2400_TX_MODE_MPHY_32                        0x00040000
+#define IXP2400_TX_MODE_MPHY_4                 0x00000000
+#define IXP2400_TX_MODE_MPHY_POLLED_STATUS     0x00020000
+#define IXP2400_TX_MODE_MPHY_DIRECT_STATUS     0x00000000
+#define IXP2400_TX_MODE_CBUS_FULL_DUPLEX       0x00010000
+#define IXP2400_TX_MODE_CBUS_SIMPLEX           0x00000000
+#define IXP2400_TX_MODE_MPHY_LEVEL2            0x00004000
+#define IXP2400_TX_MODE_MPHY_LEVEL3            0x00000000
+#define IXP2400_TX_MODE_CBUS_8BIT              0x00002000
+#define IXP2400_TX_MODE_CBUS_4BIT              0x00000000
+#define IXP2400_TX_MODE_TBUF_SIZE_MASK         0x0000000c
+#define IXP2400_TX_MODE_TBUF_SIZE_256          0x00000008
+#define IXP2400_TX_MODE_TBUF_SIZE_128          0x00000004
+#define IXP2400_TX_MODE_TBUF_SIZE_64           0x00000000
+
+#define IXP2400_PORT_TX_MODE_SLAVE             0x00000040
+#define IXP2400_PORT_TX_MODE_MASTER            0x00000000
+#define IXP2400_PORT_TX_MODE_POS_PHY           0x00000010
+#define IXP2400_PORT_TX_MODE_UTOPIA            0x00000000
+#define IXP2400_PORT_TX_MODE_EVEN_PARITY       0x0000000c
+#define IXP2400_PORT_TX_MODE_ODD_PARITY                0x00000008
+#define IXP2400_PORT_TX_MODE_NO_PARITY         0x00000000
+#define IXP2400_PORT_TX_MODE_UTOPIA_BIG_CELLS  0x00000002
+#define IXP2400_PORT_TX_MODE_2_CYCLE_DECODE    0x00000001
+#define IXP2400_PORT_TX_MODE_1_CYCLE_DECODE    0x00000000
+
+
+#endif
diff --git a/drivers/net/ixp2000/ixp2400_rx.uc b/drivers/net/ixp2000/ixp2400_rx.uc
new file mode 100644 (file)
index 0000000..42a73e3
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * RX ucode for the Intel IXP2400 in POS-PHY mode.
+ * Copyright (C) 2004, 2005 Lennert Buytenhek
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Assumptions made in this code:
+ * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
+ *   only one full element list is used.  This includes, for example,
+ *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4.  (This
+ *   is not an exhaustive list.)
+ * - The RBUF uses 64-byte mpackets.
+ * - RX descriptors reside in SRAM, and have the following format:
+ *     struct rx_desc
+ *     {
+ *     // to uengine
+ *             u32     buf_phys_addr;
+ *             u32     buf_length;
+ *
+ *     // from uengine
+ *             u32     channel;
+ *             u32     pkt_length;
+ *     };
+ * - Packet data resides in DRAM.
+ * - Packet buffer addresses are 8-byte aligned.
+ * - Scratch ring 0 is rx_pending.
+ * - Scratch ring 1 is rx_done, and has status condition 'full'.
+ * - The host triggers rx_done flush and rx_pending refill on seeing INTA.
+ * - This code is run on all eight threads of the microengine it runs on.
+ *
+ * Local memory is used for per-channel RX state.
+ */
+
+#define RX_THREAD_FREELIST_0           0x0030
+#define RBUF_ELEMENT_DONE              0x0044
+
+#define CHANNEL_FLAGS                  *l$index0[0]
+#define CHANNEL_FLAG_RECEIVING         1
+#define PACKET_LENGTH                  *l$index0[1]
+#define PACKET_CHECKSUM                        *l$index0[2]
+#define BUFFER_HANDLE                  *l$index0[3]
+#define BUFFER_START                   *l$index0[4]
+#define BUFFER_LENGTH                  *l$index0[5]
+
+#define CHANNEL_STATE_SIZE             24      // in bytes
+#define CHANNEL_STATE_SHIFT            5       // ceil(log2(state size))
+
+
+       .sig volatile sig1
+       .sig volatile sig2
+       .sig volatile sig3
+
+       .sig mpacket_arrived
+       .reg add_to_rx_freelist
+       .reg read $rsw0, $rsw1
+       .xfer_order $rsw0 $rsw1
+
+       .reg zero
+
+       /*
+        * Initialise add_to_rx_freelist.
+        */
+       .begin
+               .reg temp
+               .reg temp2
+
+               immed[add_to_rx_freelist, RX_THREAD_FREELIST_0]
+               immed_w1[add_to_rx_freelist, (&$rsw0 | (&mpacket_arrived << 12))]
+
+               local_csr_rd[ACTIVE_CTX_STS]
+               immed[temp, 0]
+               alu[temp2, temp, and, 0x1f]
+               alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<20]
+               alu[temp2, temp, and, 0x80]
+               alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<18]
+       .end
+
+       immed[zero, 0]
+
+       /*
+        * Skip context 0 initialisation?
+        */
+       .begin
+               br!=ctx[0, mpacket_receive_loop#]
+       .end
+
+       /*
+        * Initialise local memory.
+        */
+       .begin
+               .reg addr
+               .reg temp
+
+               immed[temp, 0]
+       init_local_mem_loop#:
+               alu_shf[addr, --, b, temp, <<CHANNEL_STATE_SHIFT]
+               local_csr_wr[ACTIVE_LM_ADDR_0, addr]
+               nop
+               nop
+               nop
+
+               immed[CHANNEL_FLAGS, 0]
+
+               alu[temp, temp, +, 1]
+               alu[--, temp, and, 0x20]
+               beq[init_local_mem_loop#]
+       .end
+
+       /*
+        * Initialise signal pipeline.
+        */
+       .begin
+               local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
+               .set_sig sig1
+
+               local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
+               .set_sig sig2
+
+               local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
+               .set_sig sig3
+       .end
+
+mpacket_receive_loop#:
+       /*
+        * Synchronise and wait for mpacket.
+        */
+       .begin
+               ctx_arb[sig1]
+               local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
+
+               msf[fast_wr, --, add_to_rx_freelist, 0]
+               .set_sig mpacket_arrived
+               ctx_arb[mpacket_arrived]
+               .set $rsw0 $rsw1
+       .end
+
+       /*
+        * We halt if we see {inbparerr,parerr,null,soperror}.
+        */
+       .begin
+               alu_shf[--, 0x1b, and, $rsw0, >>8]
+               bne[abort_rswerr#]
+       .end
+
+       /*
+        * Point local memory pointer to this channel's state area.
+        */
+       .begin
+               .reg chanaddr
+
+               alu[chanaddr, $rsw0, and, 0x1f]
+               alu_shf[chanaddr, --, b, chanaddr, <<CHANNEL_STATE_SHIFT]
+               local_csr_wr[ACTIVE_LM_ADDR_0, chanaddr]
+               nop
+               nop
+               nop
+       .end
+
+       /*
+        * Check whether we received a SOP mpacket while we were already
+        * working on a packet, or a non-SOP mpacket while there was no
+        * packet pending.  (SOP == RECEIVING -> abort)  If everything's
+        * okay, update the RECEIVING flag to reflect our new state.
+        */
+       .begin
+               .reg temp
+               .reg eop
+
+               #if CHANNEL_FLAG_RECEIVING != 1
+               #error CHANNEL_FLAG_RECEIVING is not 1
+               #endif
+
+               alu_shf[temp, 1, and, $rsw0, >>15]
+               alu[temp, temp, xor, CHANNEL_FLAGS]
+               alu[--, temp, and, CHANNEL_FLAG_RECEIVING]
+               beq[abort_proterr#]
+
+               alu_shf[eop, 1, and, $rsw0, >>14]
+               alu[CHANNEL_FLAGS, temp, xor, eop]
+       .end
+
+       /*
+        * Copy the mpacket into the right spot, and in case of EOP,
+        * write back the descriptor and pass the packet on.
+        */
+       .begin
+               .reg buffer_offset
+               .reg _packet_length
+               .reg _packet_checksum
+               .reg _buffer_handle
+               .reg _buffer_start
+               .reg _buffer_length
+
+               /*
+                * Determine buffer_offset, _packet_length and
+                * _packet_checksum.
+                */
+               .begin
+                       .reg temp
+
+                       alu[--, 1, and, $rsw0, >>15]
+                       beq[not_sop#]
+
+                       immed[PACKET_LENGTH, 0]
+                       immed[PACKET_CHECKSUM, 0]
+
+               not_sop#:
+                       alu[buffer_offset, --, b, PACKET_LENGTH]
+                       alu_shf[temp, 0xff, and, $rsw0, >>16]
+                       alu[_packet_length, buffer_offset, +, temp]
+                       alu[PACKET_LENGTH, --, b, _packet_length]
+
+                       immed[temp, 0xffff]
+                       alu[temp, $rsw1, and, temp]
+                       alu[_packet_checksum, PACKET_CHECKSUM, +, temp]
+                       alu[PACKET_CHECKSUM, --, b, _packet_checksum]
+               .end
+
+               /*
+                * Allocate buffer in case of SOP.
+                */
+               .begin
+                       .reg temp
+
+                       alu[temp, 1, and, $rsw0, >>15]
+                       beq[skip_buffer_alloc#]
+
+                       .begin
+                               .sig zzz
+                               .reg read $stemp $stemp2
+                               .xfer_order $stemp $stemp2
+
+                       rx_nobufs#:
+                               scratch[get, $stemp, zero, 0, 1], ctx_swap[zzz]
+                               alu[_buffer_handle, --, b, $stemp]
+                               beq[rx_nobufs#]
+
+                               sram[read, $stemp, _buffer_handle, 0, 2],
+                                                               ctx_swap[zzz]
+                               alu[_buffer_start, --, b, $stemp]
+                               alu[_buffer_length, --, b, $stemp2]
+                       .end
+
+               skip_buffer_alloc#:
+               .end
+
+               /*
+                * Resynchronise.
+                */
+               .begin
+                       ctx_arb[sig2]
+                       local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
+               .end
+
+               /*
+                * Synchronise buffer state.
+                */
+               .begin
+                       .reg temp
+
+                       alu[temp, 1, and, $rsw0, >>15]
+                       beq[copy_from_local_mem#]
+
+                       alu[BUFFER_HANDLE, --, b, _buffer_handle]
+                       alu[BUFFER_START, --, b, _buffer_start]
+                       alu[BUFFER_LENGTH, --, b, _buffer_length]
+                       br[sync_state_done#]
+
+               copy_from_local_mem#:
+                       alu[_buffer_handle, --, b, BUFFER_HANDLE]
+                       alu[_buffer_start, --, b, BUFFER_START]
+                       alu[_buffer_length, --, b, BUFFER_LENGTH]
+
+               sync_state_done#:
+               .end
+
+#if 0
+               /*
+                * Debug buffer state management.
+                */
+               .begin
+                       .reg temp
+
+                       alu[temp, 1, and, $rsw0, >>14]
+                       beq[no_poison#]
+                       immed[BUFFER_HANDLE, 0xdead]
+                       immed[BUFFER_START, 0xdead]
+                       immed[BUFFER_LENGTH, 0xdead]
+               no_poison#:
+
+                       immed[temp, 0xdead]
+                       alu[--, _buffer_handle, -, temp]
+                       beq[state_corrupted#]
+                       alu[--, _buffer_start, -, temp]
+                       beq[state_corrupted#]
+                       alu[--, _buffer_length, -, temp]
+                       beq[state_corrupted#]
+               .end
+#endif
+
+               /*
+                * Check buffer length.
+                */
+               .begin
+                       alu[--, _buffer_length, -, _packet_length]
+                       blo[buffer_overflow#]
+               .end
+
+               /*
+                * Copy the mpacket and give back the RBUF element.
+                */
+               .begin
+                       .reg element
+                       .reg xfer_size
+                       .reg temp
+                       .sig copy_sig
+
+                       alu_shf[element, 0x7f, and, $rsw0, >>24]
+                       alu_shf[xfer_size, 0xff, and, $rsw0, >>16]
+
+                       alu[xfer_size, xfer_size, -, 1]
+                       alu_shf[xfer_size, 0x10, or, xfer_size, >>3]
+                       alu_shf[temp, 0x10, or, xfer_size, <<21]
+                       alu_shf[temp, temp, or, element, <<11]
+                       alu_shf[--, temp, or, 1, <<18]
+
+                       dram[rbuf_rd, --, _buffer_start, buffer_offset, max_8],
+                                               indirect_ref, sig_done[copy_sig]
+                       ctx_arb[copy_sig]
+
+                       alu[temp, RBUF_ELEMENT_DONE, or, element, <<16]
+                       msf[fast_wr, --, temp, 0]
+               .end
+
+               /*
+                * If EOP, write back the packet descriptor.
+                */
+               .begin
+                       .reg write $stemp $stemp2
+                       .xfer_order $stemp $stemp2
+                       .sig zzz
+
+                       alu_shf[--, 1, and, $rsw0, >>14]
+                       beq[no_writeback#]
+
+                       alu[$stemp, $rsw0, and, 0x1f]
+                       alu[$stemp2, --, b, _packet_length]
+                       sram[write, $stemp, _buffer_handle, 8, 2], ctx_swap[zzz]
+
+               no_writeback#:
+               .end
+
+               /*
+                * Resynchronise.
+                */
+               .begin
+                       ctx_arb[sig3]
+                       local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
+               .end
+
+               /*
+                * If EOP, put the buffer back onto the scratch ring.
+                */
+               .begin
+                       .reg write $stemp
+                       .sig zzz
+
+                       br_inp_state[SCR_Ring1_Status, rx_done_ring_overflow#]
+
+                       alu_shf[--, 1, and, $rsw0, >>14]
+                       beq[mpacket_receive_loop#]
+
+                       alu[--, 1, and, $rsw0, >>10]
+                       bne[rxerr#]
+
+                       alu[$stemp, --, b, _buffer_handle]
+                       scratch[put, $stemp, zero, 4, 1], ctx_swap[zzz]
+                       cap[fast_wr, 0, XSCALE_INT_A]
+                       br[mpacket_receive_loop#]
+
+               rxerr#:
+                       alu[$stemp, --, b, _buffer_handle]
+                       scratch[put, $stemp, zero, 0, 1], ctx_swap[zzz]
+                       br[mpacket_receive_loop#]
+               .end
+       .end
+
+
+abort_rswerr#:
+       halt
+
+abort_proterr#:
+       halt
+
+state_corrupted#:
+       halt
+
+buffer_overflow#:
+       halt
+
+rx_done_ring_overflow#:
+       halt
+
+
diff --git a/drivers/net/ixp2000/ixp2400_rx.ucode b/drivers/net/ixp2000/ixp2400_rx.ucode
new file mode 100644 (file)
index 0000000..e8aee2f
--- /dev/null
@@ -0,0 +1,130 @@
+static struct ixp2000_uengine_code ixp2400_rx =
+{
+       .cpu_model_bitmask      = 0x000003fe,
+       .cpu_min_revision       = 0,
+       .cpu_max_revision       = 255,
+
+       .uengine_parameters     = IXP2000_UENGINE_8_CONTEXTS |
+                                 IXP2000_UENGINE_PRN_UPDATE_EVERY |
+                                 IXP2000_UENGINE_NN_FROM_PREVIOUS |
+                                 IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
+                                 IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
+                                 IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
+
+       .initial_reg_values     = (struct ixp2000_reg_value []) {
+               { -1, -1 }
+       },
+
+       .num_insns              = 109,
+       .insns                  = (u8 []) {
+               0xf0, 0x00, 0x0c, 0xc0, 0x05,
+               0xf4, 0x44, 0x0c, 0x00, 0x05,
+               0xfc, 0x04, 0x4c, 0x00, 0x00,
+               0xf0, 0x00, 0x00, 0x3b, 0x00,
+               0xb4, 0x40, 0xf0, 0x3b, 0x1f,
+               0x8a, 0xc0, 0x50, 0x3e, 0x05,
+               0xb4, 0x40, 0xf0, 0x3b, 0x80,
+               0x9a, 0xe0, 0x00, 0x3e, 0x05,
+               0xf0, 0x00, 0x00, 0x07, 0x00,
+               0xd8, 0x05, 0xc0, 0x00, 0x11,
+               0xf0, 0x00, 0x00, 0x0f, 0x00,
+               0x91, 0xb0, 0x20, 0x0e, 0x00,
+               0xfc, 0x06, 0x60, 0x0b, 0x00,
+               0xf0, 0x00, 0x0c, 0x03, 0x00,
+               0xf0, 0x00, 0x0c, 0x03, 0x00,
+               0xf0, 0x00, 0x0c, 0x03, 0x00,
+               0xf0, 0x00, 0x0c, 0x02, 0x00,
+               0xb0, 0xc0, 0x30, 0x0f, 0x01,
+               0xa4, 0x70, 0x00, 0x0f, 0x20,
+               0xd8, 0x02, 0xc0, 0x01, 0x00,
+               0xfc, 0x10, 0xac, 0x23, 0x08,
+               0xfc, 0x10, 0xac, 0x43, 0x10,
+               0xfc, 0x10, 0xac, 0x63, 0x18,
+               0xe0, 0x00, 0x00, 0x00, 0x02,
+               0xfc, 0x10, 0xae, 0x23, 0x88,
+               0x3d, 0x00, 0x04, 0x03, 0x20,
+               0xe0, 0x00, 0x00, 0x00, 0x10,
+               0x84, 0x82, 0x02, 0x01, 0x3b,
+               0xd8, 0x1a, 0x00, 0x01, 0x01,
+               0xb4, 0x00, 0x8c, 0x7d, 0x80,
+               0x91, 0xb0, 0x80, 0x22, 0x00,
+               0xfc, 0x06, 0x60, 0x23, 0x00,
+               0xf0, 0x00, 0x0c, 0x03, 0x00,
+               0xf0, 0x00, 0x0c, 0x03, 0x00,
+               0xf0, 0x00, 0x0c, 0x03, 0x00,
+               0x94, 0xf0, 0x92, 0x01, 0x21,
+               0xac, 0x40, 0x60, 0x26, 0x00,
+               0xa4, 0x30, 0x0c, 0x04, 0x06,
+               0xd8, 0x1a, 0x40, 0x01, 0x00,
+               0x94, 0xe0, 0xa2, 0x01, 0x21,
+               0xac, 0x20, 0x00, 0x28, 0x06,
+               0x84, 0xf2, 0x02, 0x01, 0x21,
+               0xd8, 0x0b, 0x40, 0x01, 0x00,
+               0xf0, 0x00, 0x0c, 0x02, 0x01,
+               0xf0, 0x00, 0x0c, 0x02, 0x02,
+               0xa0, 0x00, 0x08, 0x04, 0x00,
+               0x95, 0x00, 0xc6, 0x01, 0xff,
+               0xa0, 0x80, 0x10, 0x30, 0x00,
+               0xa0, 0x60, 0x1c, 0x00, 0x01,
+               0xf0, 0x0f, 0xf0, 0x33, 0xff,
+               0xb4, 0x00, 0xc0, 0x31, 0x81,
+               0xb0, 0x80, 0xb0, 0x32, 0x02,
+               0xa0, 0x20, 0x20, 0x2c, 0x00,
+               0x94, 0xf0, 0xd2, 0x01, 0x21,
+               0xd8, 0x0f, 0x40, 0x01, 0x00,
+               0x19, 0x40, 0x10, 0x04, 0x20,
+               0xa0, 0x00, 0x26, 0x04, 0x00,
+               0xd8, 0x0d, 0xc0, 0x01, 0x00,
+               0x00, 0x42, 0x10, 0x80, 0x02,
+               0xb0, 0x00, 0x46, 0x04, 0x00,
+               0xb0, 0x00, 0x56, 0x08, 0x00,
+               0xe0, 0x00, 0x00, 0x00, 0x04,
+               0xfc, 0x10, 0xae, 0x43, 0x90,
+               0x84, 0xf0, 0x32, 0x01, 0x21,
+               0xd8, 0x11, 0x40, 0x01, 0x00,
+               0xa0, 0x60, 0x3c, 0x00, 0x02,
+               0xa0, 0x20, 0x40, 0x10, 0x00,
+               0xa0, 0x20, 0x50, 0x14, 0x00,
+               0xd8, 0x12, 0x00, 0x00, 0x18,
+               0xa0, 0x00, 0x28, 0x0c, 0x00,
+               0xb0, 0x00, 0x48, 0x10, 0x00,
+               0xb0, 0x00, 0x58, 0x14, 0x00,
+               0xaa, 0xf0, 0x00, 0x14, 0x01,
+               0xd8, 0x1a, 0xc0, 0x01, 0x05,
+               0x85, 0x80, 0x42, 0x01, 0xff,
+               0x95, 0x00, 0x66, 0x01, 0xff,
+               0xba, 0xc0, 0x60, 0x1b, 0x01,
+               0x9a, 0x30, 0x60, 0x19, 0x30,
+               0x9a, 0xb0, 0x70, 0x1a, 0x30,
+               0x9b, 0x50, 0x78, 0x1e, 0x04,
+               0x8a, 0xe2, 0x08, 0x1e, 0x21,
+               0x6a, 0x4e, 0x00, 0x13, 0x00,
+               0xe0, 0x00, 0x00, 0x00, 0x30,
+               0x9b, 0x00, 0x7a, 0x92, 0x04,
+               0x3d, 0x00, 0x04, 0x1f, 0x20,
+               0x84, 0xe2, 0x02, 0x01, 0x21,
+               0xd8, 0x16, 0x80, 0x01, 0x00,
+               0xa4, 0x18, 0x0c, 0x7d, 0x80,
+               0xa0, 0x58, 0x1c, 0x00, 0x01,
+               0x01, 0x42, 0x00, 0xa0, 0x02,
+               0xe0, 0x00, 0x00, 0x00, 0x08,
+               0xfc, 0x10, 0xae, 0x63, 0x98,
+               0xd8, 0x1b, 0x00, 0xc2, 0x14,
+               0x84, 0xe2, 0x02, 0x01, 0x21,
+               0xd8, 0x05, 0xc0, 0x01, 0x00,
+               0x84, 0xa2, 0x02, 0x01, 0x21,
+               0xd8, 0x19, 0x40, 0x01, 0x01,
+               0xa0, 0x58, 0x0c, 0x00, 0x02,
+               0x1a, 0x40, 0x00, 0x04, 0x24,
+               0x33, 0x00, 0x01, 0x2f, 0x20,
+               0xd8, 0x05, 0xc0, 0x00, 0x18,
+               0xa0, 0x58, 0x0c, 0x00, 0x02,
+               0x1a, 0x40, 0x00, 0x04, 0x20,
+               0xd8, 0x05, 0xc0, 0x00, 0x18,
+               0xe0, 0x00, 0x02, 0x00, 0x00,
+               0xe0, 0x00, 0x02, 0x00, 0x00,
+               0xe0, 0x00, 0x02, 0x00, 0x00,
+               0xe0, 0x00, 0x02, 0x00, 0x00,
+               0xe0, 0x00, 0x02, 0x00, 0x00,
+       }
+};
diff --git a/drivers/net/ixp2000/ixp2400_tx.uc b/drivers/net/ixp2000/ixp2400_tx.uc
new file mode 100644 (file)
index 0000000..d090d18
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * TX ucode for the Intel IXP2400 in POS-PHY mode.
+ * Copyright (C) 2004, 2005 Lennert Buytenhek
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Assumptions made in this code:
+ * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
+ *   only one TBUF partition is used.  This includes, for example,
+ *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4. (This
+ *   is not an exhaustive list.)
+ * - The TBUF uses 64-byte mpackets.
+ * - TX descriptors reside in SRAM, and have the following format:
+ *     struct tx_desc
+ *     {
+ *     // to uengine
+ *             u32     buf_phys_addr;
+ *             u32     pkt_length;
+ *             u32     channel;
+ *     };
+ * - Packet data resides in DRAM.
+ * - Packet buffer addresses are 8-byte aligned.
+ * - Scratch ring 2 is tx_pending.
+ * - Scratch ring 3 is tx_done, and has status condition 'full'.
+ * - This code is run on all eight threads of the microengine it runs on.
+ */
+
+#define TX_SEQUENCE_0          0x0060
+#define TBUF_CTRL              0x1800
+
+#define PARTITION_SIZE         128
+#define PARTITION_THRESH       96
+
+
+       .sig volatile sig1
+       .sig volatile sig2
+       .sig volatile sig3
+
+       .reg @old_tx_seq_0
+       .reg @mpkts_in_flight
+       .reg @next_tbuf_mpacket
+
+       .reg @buffer_handle
+       .reg @buffer_start
+       .reg @packet_length
+       .reg @channel
+       .reg @packet_offset
+
+       .reg zero
+
+       immed[zero, 0]
+
+       /*
+        * Skip context 0 initialisation?
+        */
+       .begin
+               br!=ctx[0, mpacket_tx_loop#]
+       .end
+
+       /*
+        * Wait until all pending TBUF elements have been transmitted.
+        */
+       .begin
+               .reg read $tx
+               .sig zzz
+
+       loop_empty#:
+               msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
+               alu_shf[--, --, b, $tx, >>31]
+               beq[loop_empty#]
+
+               alu[@old_tx_seq_0, --, b, $tx]
+       .end
+
+       immed[@mpkts_in_flight, 0]
+       alu[@next_tbuf_mpacket, @old_tx_seq_0, and, (PARTITION_SIZE - 1)]
+
+       immed[@buffer_handle, 0]
+
+       /*
+        * Initialise signal pipeline.
+        */
+       .begin
+               local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
+               .set_sig sig1
+
+               local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
+               .set_sig sig2
+
+               local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
+               .set_sig sig3
+       .end
+
+mpacket_tx_loop#:
+       .begin
+               .reg tbuf_element_index
+               .reg buffer_handle
+               .reg sop_eop
+               .reg packet_data
+               .reg channel
+               .reg mpacket_size
+
+               /*
+                * If there is no packet currently being transmitted,
+                * dequeue the next TX descriptor, and fetch the buffer
+                * address, packet length and destination channel number.
+                */
+               .begin
+                       .reg read $stemp $stemp2 $stemp3
+                       .xfer_order $stemp $stemp2 $stemp3
+                       .sig zzz
+
+                       ctx_arb[sig1]
+
+                       alu[--, --, b, @buffer_handle]
+                       bne[already_got_packet#]
+
+               tx_nobufs#:
+                       scratch[get, $stemp, zero, 8, 1], ctx_swap[zzz]
+                       alu[@buffer_handle, --, b, $stemp]
+                       beq[tx_nobufs#]
+
+                       sram[read, $stemp, $stemp, 0, 3], ctx_swap[zzz]
+                       alu[@buffer_start, --, b, $stemp]
+                       alu[@packet_length, --, b, $stemp2]
+                       beq[zero_byte_packet#]
+                       alu[@channel, --, b, $stemp3]
+                       immed[@packet_offset, 0]
+
+               already_got_packet#:
+                       local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
+               .end
+
+               /*
+                * Determine tbuf element index, SOP/EOP flags, mpacket
+                * offset and mpacket size and cache buffer_handle and
+                * channel number.
+                */
+               .begin
+                       alu[tbuf_element_index, --, b, @next_tbuf_mpacket]
+                       alu[@next_tbuf_mpacket, @next_tbuf_mpacket, +, 1]
+                       alu[@next_tbuf_mpacket, @next_tbuf_mpacket, and,
+                                                       (PARTITION_SIZE - 1)]
+
+                       alu[buffer_handle, --, b, @buffer_handle]
+                       immed[@buffer_handle, 0]
+
+                       immed[sop_eop, 1]
+
+                       alu[packet_data, --, b, @packet_offset]
+                       bne[no_sop#]
+                       alu[sop_eop, sop_eop, or, 2]
+               no_sop#:
+                       alu[packet_data, packet_data, +, @buffer_start]
+
+                       alu[channel, --, b, @channel]
+
+                       alu[mpacket_size, @packet_length, -, @packet_offset]
+                       alu[--, 64, -, mpacket_size]
+                       bhs[eop#]
+                       alu[@buffer_handle, --, b, buffer_handle]
+                       immed[mpacket_size, 64]
+                       alu[sop_eop, sop_eop, and, 2]
+               eop#:
+
+                       alu[@packet_offset, @packet_offset, +, mpacket_size]
+               .end
+
+               /*
+                * Wait until there's enough space in the TBUF.
+                */
+               .begin
+                       .reg read $tx
+                       .reg temp
+                       .sig zzz
+
+                       ctx_arb[sig2]
+
+                       br[test_space#]
+
+               loop_space#:
+                       msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
+
+                       alu[temp, $tx, -, @old_tx_seq_0]
+                       alu[temp, temp, and, 0xff]
+                       alu[@mpkts_in_flight, @mpkts_in_flight, -, temp]
+
+                       alu[@old_tx_seq_0, --, b, $tx]
+
+               test_space#:
+                       alu[--, PARTITION_THRESH, -, @mpkts_in_flight]
+                       blo[loop_space#]
+
+                       alu[@mpkts_in_flight, @mpkts_in_flight, +, 1]
+
+                       local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
+               .end
+
+               /*
+                * Copy the packet data to the TBUF.
+                */
+               .begin
+                       .reg temp
+                       .sig copy_sig
+
+                       alu[temp, mpacket_size, -, 1]
+                       alu_shf[temp, 0x10, or, temp, >>3]
+                       alu_shf[temp, 0x10, or, temp, <<21]
+                       alu_shf[temp, temp, or, tbuf_element_index, <<11]
+                       alu_shf[--, temp, or, 1, <<18]
+
+                       dram[tbuf_wr, --, packet_data, 0, max_8],
+                                       indirect_ref, sig_done[copy_sig]
+                       ctx_arb[copy_sig]
+               .end
+
+               /*
+                * Mark TBUF element as ready-to-be-transmitted.
+                */
+               .begin
+                       .reg write $tsw $tsw2
+                       .xfer_order $tsw $tsw2
+                       .reg temp
+                       .sig zzz
+
+                       alu_shf[temp, channel, or, mpacket_size, <<24]
+                       alu_shf[$tsw, temp, or, sop_eop, <<8]
+                       immed[$tsw2, 0]
+
+                       immed[temp, TBUF_CTRL]
+                       alu_shf[temp, temp, or, tbuf_element_index, <<3]
+                       msf[write, $tsw, temp, 0, 2], ctx_swap[zzz]
+               .end
+
+               /*
+                * Resynchronise.
+                */
+               .begin
+                       ctx_arb[sig3]
+                       local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
+               .end
+
+               /*
+                * If this was an EOP mpacket, recycle the TX buffer
+                * and signal the host.
+                */
+               .begin
+                       .reg write $stemp
+                       .sig zzz
+
+                       alu[--, sop_eop, and, 1]
+                       beq[mpacket_tx_loop#]
+
+               tx_done_ring_full#:
+                       br_inp_state[SCR_Ring3_Status, tx_done_ring_full#]
+
+                       alu[$stemp, --, b, buffer_handle]
+                       scratch[put, $stemp, zero, 12, 1], ctx_swap[zzz]
+                       cap[fast_wr, 0, XSCALE_INT_A]
+                       br[mpacket_tx_loop#]
+               .end
+       .end
+
+
+zero_byte_packet#:
+       halt
+
+
diff --git a/drivers/net/ixp2000/ixp2400_tx.ucode b/drivers/net/ixp2000/ixp2400_tx.ucode
new file mode 100644 (file)
index 0000000..a433e24
--- /dev/null
@@ -0,0 +1,98 @@
+static struct ixp2000_uengine_code ixp2400_tx =
+{
+       .cpu_model_bitmask      = 0x000003fe,
+       .cpu_min_revision       = 0,
+       .cpu_max_revision       = 255,
+
+       .uengine_parameters     = IXP2000_UENGINE_8_CONTEXTS |
+                                 IXP2000_UENGINE_PRN_UPDATE_EVERY |
+                                 IXP2000_UENGINE_NN_FROM_PREVIOUS |
+                                 IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
+                                 IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
+                                 IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
+
+       .initial_reg_values     = (struct ixp2000_reg_value []) {
+               { -1, -1 }
+       },
+
+       .num_insns              = 77,
+       .insns                  = (u8 []) {
+               0xf0, 0x00, 0x00, 0x07, 0x00,
+               0xd8, 0x03, 0x00, 0x00, 0x11,
+               0x3c, 0x40, 0x00, 0x04, 0xe0,
+               0x81, 0xf2, 0x02, 0x01, 0x00,
+               0xd8, 0x00, 0x80, 0x01, 0x00,
+               0xb0, 0x08, 0x06, 0x00, 0x00,
+               0xf0, 0x00, 0x0c, 0x00, 0x80,
+               0xb4, 0x49, 0x02, 0x03, 0x7f,
+               0xf0, 0x00, 0x02, 0x83, 0x00,
+               0xfc, 0x10, 0xac, 0x23, 0x08,
+               0xfc, 0x10, 0xac, 0x43, 0x10,
+               0xfc, 0x10, 0xac, 0x63, 0x18,
+               0xe0, 0x00, 0x00, 0x00, 0x02,
+               0xa0, 0x30, 0x02, 0x80, 0x00,
+               0xd8, 0x06, 0x00, 0x01, 0x01,
+               0x19, 0x40, 0x00, 0x04, 0x28,
+               0xb0, 0x0a, 0x06, 0x00, 0x00,
+               0xd8, 0x03, 0xc0, 0x01, 0x00,
+               0x00, 0x44, 0x00, 0x80, 0x80,
+               0xa0, 0x09, 0x06, 0x00, 0x00,
+               0xb0, 0x0b, 0x06, 0x04, 0x00,
+               0xd8, 0x13, 0x00, 0x01, 0x00,
+               0xb0, 0x0c, 0x06, 0x08, 0x00,
+               0xf0, 0x00, 0x0c, 0x00, 0xa0,
+               0xfc, 0x10, 0xae, 0x23, 0x88,
+               0xa0, 0x00, 0x12, 0x40, 0x00,
+               0xb0, 0xc9, 0x02, 0x43, 0x01,
+               0xb4, 0x49, 0x02, 0x43, 0x7f,
+               0xb0, 0x00, 0x22, 0x80, 0x00,
+               0xf0, 0x00, 0x02, 0x83, 0x00,
+               0xf0, 0x00, 0x0c, 0x04, 0x02,
+               0xb0, 0x40, 0x6c, 0x00, 0xa0,
+               0xd8, 0x08, 0x80, 0x01, 0x01,
+               0xaa, 0x00, 0x2c, 0x08, 0x02,
+               0xa0, 0xc0, 0x30, 0x18, 0x90,
+               0xa0, 0x00, 0x43, 0x00, 0x00,
+               0xba, 0xc0, 0x32, 0xc0, 0xa0,
+               0xaa, 0xb0, 0x00, 0x0f, 0x40,
+               0xd8, 0x0a, 0x80, 0x01, 0x04,
+               0xb0, 0x0a, 0x00, 0x08, 0x00,
+               0xf0, 0x00, 0x00, 0x0f, 0x40,
+               0xa4, 0x00, 0x2c, 0x08, 0x02,
+               0xa0, 0x8a, 0x00, 0x0c, 0xa0,
+               0xe0, 0x00, 0x00, 0x00, 0x04,
+               0xd8, 0x0c, 0x80, 0x00, 0x18,
+               0x3c, 0x40, 0x00, 0x04, 0xe0,
+               0xba, 0x80, 0x42, 0x01, 0x80,
+               0xb4, 0x40, 0x40, 0x13, 0xff,
+               0xaa, 0x88, 0x00, 0x10, 0x80,
+               0xb0, 0x08, 0x06, 0x00, 0x00,
+               0xaa, 0xf0, 0x0d, 0x80, 0x80,
+               0xd8, 0x0b, 0x40, 0x01, 0x05,
+               0xa0, 0x88, 0x0c, 0x04, 0x80,
+               0xfc, 0x10, 0xae, 0x43, 0x90,
+               0xba, 0xc0, 0x50, 0x0f, 0x01,
+               0x9a, 0x30, 0x50, 0x15, 0x30,
+               0x9a, 0xb0, 0x50, 0x16, 0x30,
+               0x9b, 0x50, 0x58, 0x16, 0x01,
+               0x8a, 0xe2, 0x08, 0x16, 0x21,
+               0x6b, 0x4e, 0x00, 0x83, 0x03,
+               0xe0, 0x00, 0x00, 0x00, 0x30,
+               0x9a, 0x80, 0x70, 0x0e, 0x04,
+               0x8b, 0x88, 0x08, 0x1e, 0x02,
+               0xf0, 0x00, 0x0c, 0x01, 0x81,
+               0xf0, 0x01, 0x80, 0x1f, 0x00,
+               0x9b, 0xd0, 0x78, 0x1e, 0x01,
+               0x3d, 0x42, 0x00, 0x1c, 0x20,
+               0xe0, 0x00, 0x00, 0x00, 0x08,
+               0xfc, 0x10, 0xae, 0x63, 0x98,
+               0xa4, 0x30, 0x0c, 0x04, 0x02,
+               0xd8, 0x03, 0x00, 0x01, 0x00,
+               0xd8, 0x11, 0xc1, 0x42, 0x14,
+               0xa0, 0x18, 0x00, 0x08, 0x00,
+               0x1a, 0x40, 0x00, 0x04, 0x2c,
+               0x33, 0x00, 0x01, 0x2f, 0x20,
+               0xd8, 0x03, 0x00, 0x00, 0x18,
+               0xe0, 0x00, 0x02, 0x00, 0x00,
+       }
+};
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
new file mode 100644 (file)
index 0000000..09f03f4
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <asm/arch/uengine.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include "ixp2400_rx.ucode"
+#include "ixp2400_tx.ucode"
+#include "ixpdev_priv.h"
+#include "ixpdev.h"
+
+#define DRV_MODULE_VERSION     "0.2"
+
+static int nds_count;
+static struct net_device **nds;
+static int nds_open;
+static void (*set_port_admin_status)(int port, int up);
+
+static struct ixpdev_rx_desc * const rx_desc =
+       (struct ixpdev_rx_desc *)(IXP2000_SRAM0_VIRT_BASE + RX_BUF_DESC_BASE);
+static struct ixpdev_tx_desc * const tx_desc =
+       (struct ixpdev_tx_desc *)(IXP2000_SRAM0_VIRT_BASE + TX_BUF_DESC_BASE);
+static int tx_pointer;
+
+
+static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct ixpdev_priv *ip = netdev_priv(dev);
+       struct ixpdev_tx_desc *desc;
+       int entry;
+
+       if (unlikely(skb->len > PAGE_SIZE)) {
+               /* @@@ Count drops.  */
+               dev_kfree_skb(skb);
+               return 0;
+       }
+
+       entry = tx_pointer;
+       tx_pointer = (tx_pointer + 1) % TX_BUF_COUNT;
+
+       desc = tx_desc + entry;
+       desc->pkt_length = skb->len;
+       desc->channel = ip->channel;
+
+       skb_copy_and_csum_dev(skb, phys_to_virt(desc->buf_addr));
+       dev_kfree_skb(skb);
+
+       ixp2000_reg_write(RING_TX_PENDING,
+               TX_BUF_DESC_BASE + (entry * sizeof(struct ixpdev_tx_desc)));
+
+       dev->trans_start = jiffies;
+
+       local_irq_disable();
+       ip->tx_queue_entries++;
+       if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
+               netif_stop_queue(dev);
+       local_irq_enable();
+
+       return 0;
+}
+
+
+static int ixpdev_rx(struct net_device *dev, int *budget)
+{
+       while (*budget > 0) {
+               struct ixpdev_rx_desc *desc;
+               struct sk_buff *skb;
+               void *buf;
+               u32 _desc;
+
+               _desc = ixp2000_reg_read(RING_RX_DONE);
+               if (_desc == 0)
+                       return 0;
+
+               desc = rx_desc +
+                       ((_desc - RX_BUF_DESC_BASE) / sizeof(struct ixpdev_rx_desc));
+               buf = phys_to_virt(desc->buf_addr);
+
+               if (desc->pkt_length < 4 || desc->pkt_length > PAGE_SIZE) {
+                       printk(KERN_ERR "ixp2000: rx err, length %d\n",
+                                       desc->pkt_length);
+                       goto err;
+               }
+
+               if (desc->channel < 0 || desc->channel >= nds_count) {
+                       printk(KERN_ERR "ixp2000: rx err, channel %d\n",
+                                       desc->channel);
+                       goto err;
+               }
+
+               /* @@@ Make FCS stripping configurable.  */
+               desc->pkt_length -= 4;
+
+               if (unlikely(!netif_running(nds[desc->channel])))
+                       goto err;
+
+               skb = dev_alloc_skb(desc->pkt_length + 2);
+               if (likely(skb != NULL)) {
+                       skb->dev = nds[desc->channel];
+                       skb_reserve(skb, 2);
+                       eth_copy_and_sum(skb, buf, desc->pkt_length, 0);
+                       skb_put(skb, desc->pkt_length);
+                       skb->protocol = eth_type_trans(skb, skb->dev);
+
+                       skb->dev->last_rx = jiffies;
+
+                       netif_receive_skb(skb);
+               }
+
+err:
+               ixp2000_reg_write(RING_RX_PENDING, _desc);
+               dev->quota--;
+               (*budget)--;
+       }
+
+       return 1;
+}
+
+/* dev always points to nds[0].  */
+static int ixpdev_poll(struct net_device *dev, int *budget)
+{
+       /* @@@ Have to stop polling when nds[0] is administratively
+        * downed while we are polling.  */
+       do {
+               ixp2000_reg_write(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0x00ff);
+
+               if (ixpdev_rx(dev, budget))
+                       return 1;
+       } while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
+
+       netif_rx_complete(dev);
+       ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
+
+       return 0;
+}
+
+static void ixpdev_tx_complete(void)
+{
+       int channel;
+       u32 wake;
+
+       wake = 0;
+       while (1) {
+               struct ixpdev_priv *ip;
+               u32 desc;
+               int entry;
+
+               desc = ixp2000_reg_read(RING_TX_DONE);
+               if (desc == 0)
+                       break;
+
+               /* @@@ Check whether entries come back in order.  */
+               entry = (desc - TX_BUF_DESC_BASE) / sizeof(struct ixpdev_tx_desc);
+               channel = tx_desc[entry].channel;
+
+               if (channel < 0 || channel >= nds_count) {
+                       printk(KERN_ERR "ixp2000: txcomp channel index "
+                                       "out of bounds (%d, %.8i, %d)\n",
+                                       channel, (unsigned int)desc, entry);
+                       continue;
+               }
+
+               ip = netdev_priv(nds[channel]);
+               if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
+                       wake |= 1 << channel;
+               ip->tx_queue_entries--;
+       }
+
+       for (channel = 0; wake != 0; channel++) {
+               if (wake & (1 << channel)) {
+                       netif_wake_queue(nds[channel]);
+                       wake &= ~(1 << channel);
+               }
+       }
+}
+
+static irqreturn_t ixpdev_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       u32 status;
+
+       status = ixp2000_reg_read(IXP2000_IRQ_THD_STATUS_A_0);
+       if (status == 0)
+               return IRQ_NONE;
+
+       /*
+        * Any of the eight receive units signaled RX?
+        */
+       if (status & 0x00ff) {
+               ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
+               if (likely(__netif_rx_schedule_prep(nds[0]))) {
+                       __netif_rx_schedule(nds[0]);
+               } else {
+                       printk(KERN_CRIT "ixp2000: irq while polling!!\n");
+               }
+       }
+
+       /*
+        * Any of the eight transmit units signaled TXdone?
+        */
+       if (status & 0xff00) {
+               ixp2000_reg_wrb(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0xff00);
+               ixpdev_tx_complete();
+       }
+
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ixpdev_poll_controller(struct net_device *dev)
+{
+       disable_irq(IRQ_IXP2000_THDA0);
+       ixpdev_interrupt(IRQ_IXP2000_THDA0, dev, NULL);
+       enable_irq(IRQ_IXP2000_THDA0);
+}
+#endif
+
+static int ixpdev_open(struct net_device *dev)
+{
+       struct ixpdev_priv *ip = netdev_priv(dev);
+       int err;
+
+       if (!nds_open++) {
+               err = request_irq(IRQ_IXP2000_THDA0, ixpdev_interrupt,
+                                       SA_SHIRQ, "ixp2000_eth", nds);
+               if (err) {
+                       nds_open--;
+                       return err;
+               }
+
+               ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0xffff);
+       }
+
+       set_port_admin_status(ip->channel, 1);
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+static int ixpdev_close(struct net_device *dev)
+{
+       struct ixpdev_priv *ip = netdev_priv(dev);
+
+       netif_stop_queue(dev);
+       set_port_admin_status(ip->channel, 0);
+
+       if (!--nds_open) {
+               ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0xffff);
+               free_irq(IRQ_IXP2000_THDA0, nds);
+       }
+
+       return 0;
+}
+
+struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
+{
+       struct net_device *dev;
+       struct ixpdev_priv *ip;
+
+       dev = alloc_etherdev(sizeof_priv);
+       if (dev == NULL)
+               return NULL;
+
+       dev->hard_start_xmit = ixpdev_xmit;
+       dev->poll = ixpdev_poll;
+       dev->open = ixpdev_open;
+       dev->stop = ixpdev_close;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = ixpdev_poll_controller;
+#endif
+
+       dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+       dev->weight = 64;
+
+       ip = netdev_priv(dev);
+       ip->channel = channel;
+       ip->tx_queue_entries = 0;
+
+       return dev;
+}
+
+int ixpdev_init(int __nds_count, struct net_device **__nds,
+               void (*__set_port_admin_status)(int port, int up))
+{
+       int i;
+       int err;
+
+       if (RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192) {
+               static void __too_many_rx_or_tx_buffers(void);
+               __too_many_rx_or_tx_buffers();
+       }
+
+       printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION);
+
+       nds_count = __nds_count;
+       nds = __nds;
+       set_port_admin_status = __set_port_admin_status;
+
+       for (i = 0; i < RX_BUF_COUNT; i++) {
+               void *buf;
+
+               buf = (void *)get_zeroed_page(GFP_KERNEL);
+               if (buf == NULL) {
+                       err = -ENOMEM;
+                       while (--i >= 0)
+                               free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+                       goto err_out;
+               }
+               rx_desc[i].buf_addr = virt_to_phys(buf);
+               rx_desc[i].buf_length = PAGE_SIZE;
+       }
+
+       /* @@@ Maybe we shouldn't be preallocating TX buffers.  */
+       for (i = 0; i < TX_BUF_COUNT; i++) {
+               void *buf;
+
+               buf = (void *)get_zeroed_page(GFP_KERNEL);
+               if (buf == NULL) {
+                       err = -ENOMEM;
+                       while (--i >= 0)
+                               free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+                       goto err_free_rx;
+               }
+               tx_desc[i].buf_addr = virt_to_phys(buf);
+       }
+
+       /* 256 entries, ring status set means 'empty', base address 0x0000.  */
+       ixp2000_reg_write(RING_RX_PENDING_BASE, 0x44000000);
+       ixp2000_reg_write(RING_RX_PENDING_HEAD, 0x00000000);
+       ixp2000_reg_write(RING_RX_PENDING_TAIL, 0x00000000);
+
+       /* 256 entries, ring status set means 'full', base address 0x0400.  */
+       ixp2000_reg_write(RING_RX_DONE_BASE, 0x40000400);
+       ixp2000_reg_write(RING_RX_DONE_HEAD, 0x00000000);
+       ixp2000_reg_write(RING_RX_DONE_TAIL, 0x00000000);
+
+       for (i = 0; i < RX_BUF_COUNT; i++) {
+               ixp2000_reg_write(RING_RX_PENDING,
+                       RX_BUF_DESC_BASE + (i * sizeof(struct ixpdev_rx_desc)));
+       }
+
+       ixp2000_uengine_load(0, &ixp2400_rx);
+       ixp2000_uengine_start_contexts(0, 0xff);
+
+       /* 256 entries, ring status set means 'empty', base address 0x0800.  */
+       ixp2000_reg_write(RING_TX_PENDING_BASE, 0x44000800);
+       ixp2000_reg_write(RING_TX_PENDING_HEAD, 0x00000000);
+       ixp2000_reg_write(RING_TX_PENDING_TAIL, 0x00000000);
+
+       /* 256 entries, ring status set means 'full', base address 0x0c00.  */
+       ixp2000_reg_write(RING_TX_DONE_BASE, 0x40000c00);
+       ixp2000_reg_write(RING_TX_DONE_HEAD, 0x00000000);
+       ixp2000_reg_write(RING_TX_DONE_TAIL, 0x00000000);
+
+       ixp2000_uengine_load(1, &ixp2400_tx);
+       ixp2000_uengine_start_contexts(1, 0xff);
+
+       for (i = 0; i < nds_count; i++) {
+               err = register_netdev(nds[i]);
+               if (err) {
+                       while (--i >= 0)
+                               unregister_netdev(nds[i]);
+                       goto err_free_tx;
+               }
+       }
+
+       for (i = 0; i < nds_count; i++) {
+               printk(KERN_INFO "%s: IXP2000 MSF ethernet (port %d), "
+                       "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", nds[i]->name, i,
+                       nds[i]->dev_addr[0], nds[i]->dev_addr[1],
+                       nds[i]->dev_addr[2], nds[i]->dev_addr[3],
+                       nds[i]->dev_addr[4], nds[i]->dev_addr[5]);
+       }
+
+       return 0;
+
+err_free_tx:
+       for (i = 0; i < TX_BUF_COUNT; i++)
+               free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+
+err_free_rx:
+       for (i = 0; i < RX_BUF_COUNT; i++)
+               free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+
+err_out:
+       return err;
+} 
+
+void ixpdev_deinit(void)
+{
+       int i;
+
+       /* @@@ Flush out pending packets.  */
+
+       for (i = 0; i < nds_count; i++)
+               unregister_netdev(nds[i]);
+
+       ixp2000_uengine_stop_contexts(1, 0xff);
+       ixp2000_uengine_stop_contexts(0, 0xff);
+       ixp2000_uengine_reset(0x3);
+
+       for (i = 0; i < TX_BUF_COUNT; i++)
+               free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+
+       for (i = 0; i < RX_BUF_COUNT; i++)
+               free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+}
diff --git a/drivers/net/ixp2000/ixpdev.h b/drivers/net/ixp2000/ixpdev.h
new file mode 100644 (file)
index 0000000..bd686cb
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __IXPDEV_H
+#define __IXPDEV_H
+
+struct ixpdev_priv
+{
+       int     channel;
+       int     tx_queue_entries;
+};
+
+struct net_device *ixpdev_alloc(int channel, int sizeof_priv);
+int ixpdev_init(int num_ports, struct net_device **nds,
+               void (*set_port_admin_status)(int port, int up));
+void ixpdev_deinit(void);
+
+
+#endif
diff --git a/drivers/net/ixp2000/ixpdev_priv.h b/drivers/net/ixp2000/ixpdev_priv.h
new file mode 100644 (file)
index 0000000..86aa08e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __IXPDEV_PRIV_H
+#define __IXPDEV_PRIV_H
+
+#define RX_BUF_DESC_BASE       0x00001000
+#define RX_BUF_COUNT           ((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_rx_desc)))
+#define TX_BUF_DESC_BASE       0x00002000
+#define TX_BUF_COUNT           ((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_tx_desc)))
+#define TX_BUF_COUNT_PER_CHAN  (TX_BUF_COUNT / 4)
+
+#define RING_RX_PENDING                ((u32 *)IXP2000_SCRATCH_RING_VIRT_BASE)
+#define RING_RX_DONE           ((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 4))
+#define RING_TX_PENDING                ((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 8))
+#define RING_TX_DONE           ((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 12))
+
+#define SCRATCH_REG(x)         ((u32 *)(IXP2000_GLOBAL_REG_VIRT_BASE | 0x0800 | (x)))
+#define RING_RX_PENDING_BASE   SCRATCH_REG(0x00)
+#define RING_RX_PENDING_HEAD   SCRATCH_REG(0x04)
+#define RING_RX_PENDING_TAIL   SCRATCH_REG(0x08)
+#define RING_RX_DONE_BASE      SCRATCH_REG(0x10)
+#define RING_RX_DONE_HEAD      SCRATCH_REG(0x14)
+#define RING_RX_DONE_TAIL      SCRATCH_REG(0x18)
+#define RING_TX_PENDING_BASE   SCRATCH_REG(0x20)
+#define RING_TX_PENDING_HEAD   SCRATCH_REG(0x24)
+#define RING_TX_PENDING_TAIL   SCRATCH_REG(0x28)
+#define RING_TX_DONE_BASE      SCRATCH_REG(0x30)
+#define RING_TX_DONE_HEAD      SCRATCH_REG(0x34)
+#define RING_TX_DONE_TAIL      SCRATCH_REG(0x38)
+
+struct ixpdev_rx_desc
+{
+       u32     buf_addr;
+       u32     buf_length;
+       u32     channel;
+       u32     pkt_length;
+};
+
+struct ixpdev_tx_desc
+{
+       u32     buf_addr;
+       u32     pkt_length;
+       u32     channel;
+       u32     unused;
+};
+
+
+#endif
diff --git a/drivers/net/ixp2000/pm3386.c b/drivers/net/ixp2000/pm3386.c
new file mode 100644 (file)
index 0000000..5c7ab75
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * Helper functions for the PM3386s on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/delay.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include "pm3386.h"
+
+/*
+ * Read from register 'reg' of PM3386 device 'pm'.
+ */
+static u16 pm3386_reg_read(int pm, int reg)
+{
+       void *_reg;
+       u16 value;
+
+       _reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
+       if (pm == 1)
+               _reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
+
+       value = *((volatile u16 *)(_reg + (reg << 1)));
+
+//     printk(KERN_INFO "pm3386_reg_read(%d, %.3x) = %.8x\n", pm, reg, value);
+
+       return value;
+}
+
+/*
+ * Write to register 'reg' of PM3386 device 'pm', and perform
+ * a readback from the identification register.
+ */
+static void pm3386_reg_write(int pm, int reg, u16 value)
+{
+       void *_reg;
+       u16 dummy;
+
+//     printk(KERN_INFO "pm3386_reg_write(%d, %.3x, %.8x)\n", pm, reg, value);
+
+       _reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
+       if (pm == 1)
+               _reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
+
+       *((volatile u16 *)(_reg + (reg << 1))) = value;
+
+       dummy = *((volatile u16 *)_reg);
+       __asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+}
+
+/*
+ * Read from port 'port' register 'reg', where the registers
+ * for the different ports are 'spacing' registers apart.
+ */
+static u16 pm3386_port_reg_read(int port, int _reg, int spacing)
+{
+       int reg;
+
+       reg = _reg;
+       if (port & 1)
+               reg += spacing;
+
+       return pm3386_reg_read(port >> 1, reg);
+}
+
+/*
+ * Write to port 'port' register 'reg', where the registers
+ * for the different ports are 'spacing' registers apart.
+ */
+static void pm3386_port_reg_write(int port, int _reg, int spacing, u16 value)
+{
+       int reg;
+
+       reg = _reg;
+       if (port & 1)
+               reg += spacing;
+
+       pm3386_reg_write(port >> 1, reg, value);
+}
+
+
+void pm3386_reset(void)
+{
+       u8 mac[3][6];
+
+       /* Save programmed MAC addresses.  */
+       pm3386_get_mac(0, mac[0]);
+       pm3386_get_mac(1, mac[1]);
+       pm3386_get_mac(2, mac[2]);
+
+       /* Assert analog and digital reset.  */
+       pm3386_reg_write(0, 0x002, 0x0060);
+       pm3386_reg_write(1, 0x002, 0x0060);
+       mdelay(1);
+
+       /* Deassert analog reset.  */
+       pm3386_reg_write(0, 0x002, 0x0062);
+       pm3386_reg_write(1, 0x002, 0x0062);
+       mdelay(10);
+
+       /* Deassert digital reset.  */
+       pm3386_reg_write(0, 0x002, 0x0063);
+       pm3386_reg_write(1, 0x002, 0x0063);
+       mdelay(10);
+
+       /* Restore programmed MAC addresses.  */
+       pm3386_set_mac(0, mac[0]);
+       pm3386_set_mac(1, mac[1]);
+       pm3386_set_mac(2, mac[2]);
+
+       /* Disable carrier on all ports.  */
+       pm3386_set_carrier(0, 0);
+       pm3386_set_carrier(1, 0);
+       pm3386_set_carrier(2, 0);
+}
+
+static u16 swaph(u16 x)
+{
+       return ((x << 8) | (x >> 8)) & 0xffff;
+}
+
+void pm3386_init_port(int port)
+{
+       int pm = port >> 1;
+
+       /*
+        * Work around ENP2611 bootloader programming MAC address
+        * in reverse.
+        */
+       if (pm3386_port_reg_read(port, 0x30a, 0x100) == 0x0000 &&
+           (pm3386_port_reg_read(port, 0x309, 0x100) & 0xff00) == 0x5000) {
+               u16 temp[3];
+
+               temp[0] = pm3386_port_reg_read(port, 0x308, 0x100);
+               temp[1] = pm3386_port_reg_read(port, 0x309, 0x100);
+               temp[2] = pm3386_port_reg_read(port, 0x30a, 0x100);
+               pm3386_port_reg_write(port, 0x308, 0x100, swaph(temp[2]));
+               pm3386_port_reg_write(port, 0x309, 0x100, swaph(temp[1]));
+               pm3386_port_reg_write(port, 0x30a, 0x100, swaph(temp[0]));
+       }
+
+       /*
+        * Initialise narrowbanding mode.  See application note 2010486
+        * for more information.  (@@@ We also need to issue a reset
+        * when ROOL or DOOL are detected.)
+        */
+       pm3386_port_reg_write(port, 0x708, 0x10, 0xd055);
+       udelay(500);
+       pm3386_port_reg_write(port, 0x708, 0x10, 0x5055);
+
+       /*
+        * SPI-3 ingress block.  Set 64 bytes SPI-3 burst size
+        * towards SPI-3 bridge.
+        */
+       pm3386_port_reg_write(port, 0x122, 0x20, 0x0002);
+
+       /*
+        * Enable ingress protocol checking, and soft reset the
+        * SPI-3 ingress block.
+        */
+       pm3386_reg_write(pm, 0x103, 0x0003);
+       while (!(pm3386_reg_read(pm, 0x103) & 0x80))
+               ;
+
+       /*
+        * SPI-3 egress block.  Gather 12288 bytes of the current
+        * packet in the TX fifo before initiating transmit on the
+        * SERDES interface.  (Prevents TX underflows.)
+        */
+       pm3386_port_reg_write(port, 0x221, 0x20, 0x0007);
+
+       /*
+        * Enforce odd parity from the SPI-3 bridge, and soft reset
+        * the SPI-3 egress block.
+        */
+       pm3386_reg_write(pm, 0x203, 0x000d & ~(4 << (port & 1)));
+       while ((pm3386_reg_read(pm, 0x203) & 0x000c) != 0x000c)
+               ;
+
+       /*
+        * EGMAC block.  Set this channels to reject long preambles,
+        * not send or transmit PAUSE frames, enable preamble checking,
+        * disable frame length checking, enable FCS appending, enable
+        * TX frame padding.
+        */
+       pm3386_port_reg_write(port, 0x302, 0x100, 0x0113);
+
+       /*
+        * Soft reset the EGMAC block.
+        */
+       pm3386_port_reg_write(port, 0x301, 0x100, 0x8000);
+       pm3386_port_reg_write(port, 0x301, 0x100, 0x0000);
+
+       /*
+        * Auto-sense autonegotiation status.
+        */
+       pm3386_port_reg_write(port, 0x306, 0x100, 0x0100);
+
+       /*
+        * Allow reception of jumbo frames.
+        */
+       pm3386_port_reg_write(port, 0x310, 0x100, 9018);
+
+       /*
+        * Allow transmission of jumbo frames.
+        */
+       pm3386_port_reg_write(port, 0x336, 0x100, 9018);
+
+       /* @@@ Should set 0x337/0x437 (RX forwarding threshold.)  */
+
+       /*
+        * Set autonegotiation parameters to 'no PAUSE, full duplex.'
+        */
+       pm3386_port_reg_write(port, 0x31c, 0x100, 0x0020);
+
+       /*
+        * Enable and restart autonegotiation.
+        */
+       pm3386_port_reg_write(port, 0x318, 0x100, 0x0003);
+       pm3386_port_reg_write(port, 0x318, 0x100, 0x0002);
+}
+
+void pm3386_get_mac(int port, u8 *mac)
+{
+       u16 temp;
+
+       temp = pm3386_port_reg_read(port, 0x308, 0x100);
+       mac[0] = temp & 0xff;
+       mac[1] = (temp >> 8) & 0xff;
+
+       temp = pm3386_port_reg_read(port, 0x309, 0x100);
+       mac[2] = temp & 0xff;
+       mac[3] = (temp >> 8) & 0xff;
+
+       temp = pm3386_port_reg_read(port, 0x30a, 0x100);
+       mac[4] = temp & 0xff;
+       mac[5] = (temp >> 8) & 0xff;
+}
+
+void pm3386_set_mac(int port, u8 *mac)
+{
+       pm3386_port_reg_write(port, 0x308, 0x100, (mac[1] << 8) | mac[0]);
+       pm3386_port_reg_write(port, 0x309, 0x100, (mac[3] << 8) | mac[2]);
+       pm3386_port_reg_write(port, 0x30a, 0x100, (mac[5] << 8) | mac[4]);
+}
+
+static u32 pm3386_get_stat(int port, u16 base)
+{
+       u32 value;
+
+       value = pm3386_port_reg_read(port, base, 0x100);
+       value |= pm3386_port_reg_read(port, base + 1, 0x100) << 16;
+
+       return value;
+}
+
+void pm3386_get_stats(int port, struct net_device_stats *stats)
+{
+       /*
+        * Snapshot statistics counters.
+        */
+       pm3386_port_reg_write(port, 0x500, 0x100, 0x0001);
+       while (pm3386_port_reg_read(port, 0x500, 0x100) & 0x0001)
+               ;
+
+       memset(stats, 0, sizeof(*stats));
+
+       stats->rx_packets = pm3386_get_stat(port, 0x510);
+       stats->tx_packets = pm3386_get_stat(port, 0x590);
+       stats->rx_bytes = pm3386_get_stat(port, 0x514);
+       stats->tx_bytes = pm3386_get_stat(port, 0x594);
+       /* @@@ Add other stats.  */
+}
+
+void pm3386_set_carrier(int port, int state)
+{
+       pm3386_port_reg_write(port, 0x703, 0x10, state ? 0x1001 : 0x0000);
+}
+
+int pm3386_is_link_up(int port)
+{
+       u16 temp;
+
+       temp = pm3386_port_reg_read(port, 0x31a, 0x100);
+       temp = pm3386_port_reg_read(port, 0x31a, 0x100);
+
+       return !!(temp & 0x0002);
+}
+
+void pm3386_enable_rx(int port)
+{
+       u16 temp;
+
+       temp = pm3386_port_reg_read(port, 0x303, 0x100);
+       temp |= 0x1000;
+       pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_disable_rx(int port)
+{
+       u16 temp;
+
+       temp = pm3386_port_reg_read(port, 0x303, 0x100);
+       temp &= 0xefff;
+       pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_enable_tx(int port)
+{
+       u16 temp;
+
+       temp = pm3386_port_reg_read(port, 0x303, 0x100);
+       temp |= 0x4000;
+       pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_disable_tx(int port)
+{
+       u16 temp;
+
+       temp = pm3386_port_reg_read(port, 0x303, 0x100);
+       temp &= 0xbfff;
+       pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ixp2000/pm3386.h b/drivers/net/ixp2000/pm3386.h
new file mode 100644 (file)
index 0000000..fe92bb0
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Helper functions for the PM3386s on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __PM3386_H
+#define __PM3386_H
+
+void pm3386_reset(void);
+void pm3386_init_port(int port);
+void pm3386_get_mac(int port, u8 *mac);
+void pm3386_set_mac(int port, u8 *mac);
+void pm3386_get_stats(int port, struct net_device_stats *stats);
+void pm3386_set_carrier(int port, int state);
+int pm3386_is_link_up(int port);
+void pm3386_enable_rx(int port);
+void pm3386_disable_rx(int port);
+void pm3386_enable_tx(int port);
+void pm3386_disable_tx(int port);
+
+
+#endif
index f857ae94d261ab505dd809499c372878c0d79e93..b0c3b6ab62634ea01d8be0e3ac5ee0d246ccb1f4 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 a842ecc60a34000d746c7d96aff16ca1f661f3e2..9369f811075d123f245dc54bfac2a86f56607225 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 0c1e114527fb3549feb59685ac57d41b77502529..9315046b3f5509eebea0b0207f9b36a4a4326c89 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 669dd52c412abe884dd7ad7176f3a850f5e182c6..89c46787676c9d9d3249597b38ce788a56fb5bc4 100644 (file)
@@ -66,7 +66,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "Version 2.0.9.3"
+#define DRV_VERSION "Version 2.0.9.4"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -412,7 +412,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                    config->tx_cfg[i].fifo_len - 1;
                mac_control->fifos[i].fifo_no = i;
                mac_control->fifos[i].nic = nic;
-               mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 1;
+               mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2;
 
                for (j = 0; j < page_num; j++) {
                        int k = 0;
@@ -459,6 +459,10 @@ static int init_shared_mem(struct s2io_nic *nic)
                }
        }
 
+       nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL);
+       if (!nic->ufo_in_band_v)
+               return -ENOMEM;
+
        /* Allocation and initialization of RXDs in Rings */
        size = 0;
        for (i = 0; i < config->rx_ring_num; i++) {
@@ -731,6 +735,8 @@ static void free_shared_mem(struct s2io_nic *nic)
                                    mac_control->stats_mem,
                                    mac_control->stats_mem_phy);
        }
+       if (nic->ufo_in_band_v)
+               kfree(nic->ufo_in_band_v);
 }
 
 /**
@@ -2003,6 +2009,49 @@ static int start_nic(struct s2io_nic *nic)
 
        return SUCCESS;
 }
+/**
+ * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb
+ */
+static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, int get_off)
+{
+       nic_t *nic = fifo_data->nic;
+       struct sk_buff *skb;
+       TxD_t *txds;
+       u16 j, frg_cnt;
+
+       txds = txdlp;
+       if (txds->Host_Control == (u64)(long)nic->ufo_in_band_v) {
+               pci_unmap_single(nic->pdev, (dma_addr_t)
+                       txds->Buffer_Pointer, sizeof(u64),
+                       PCI_DMA_TODEVICE);
+               txds++;
+       }
+
+       skb = (struct sk_buff *) ((unsigned long)
+                       txds->Host_Control);
+       if (!skb) {
+               memset(txdlp, 0, (sizeof(TxD_t) * fifo_data->max_txds));
+               return NULL;
+       }
+       pci_unmap_single(nic->pdev, (dma_addr_t)
+                        txds->Buffer_Pointer,
+                        skb->len - skb->data_len,
+                        PCI_DMA_TODEVICE);
+       frg_cnt = skb_shinfo(skb)->nr_frags;
+       if (frg_cnt) {
+               txds++;
+               for (j = 0; j < frg_cnt; j++, txds++) {
+                       skb_frag_t *frag = &skb_shinfo(skb)->frags[j];
+                       if (!txds->Buffer_Pointer)
+                               break;
+                       pci_unmap_page(nic->pdev, (dma_addr_t) 
+                                       txds->Buffer_Pointer,
+                                      frag->size, PCI_DMA_TODEVICE);
+               }
+       }
+       txdlp->Host_Control = 0;
+       return(skb);
+}
 
 /**
  *  free_tx_buffers - Free all queued Tx buffers
@@ -2020,7 +2069,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
        int i, j;
        mac_info_t *mac_control;
        struct config_param *config;
-       int cnt = 0, frg_cnt;
+       int cnt = 0;
 
        mac_control = &nic->mac_control;
        config = &nic->config;
@@ -2029,38 +2078,11 @@ static void free_tx_buffers(struct s2io_nic *nic)
                for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
                        txdp = (TxD_t *) mac_control->fifos[i].list_info[j].
                            list_virt_addr;
-                       skb =
-                           (struct sk_buff *) ((unsigned long) txdp->
-                                               Host_Control);
-                       if (skb == NULL) {
-                               memset(txdp, 0, sizeof(TxD_t) *
-                                      config->max_txds);
-                               continue;
-                       }
-                       frg_cnt = skb_shinfo(skb)->nr_frags;
-                       pci_unmap_single(nic->pdev, (dma_addr_t)
-                                        txdp->Buffer_Pointer,
-                                        skb->len - skb->data_len,
-                                        PCI_DMA_TODEVICE);
-                       if (frg_cnt) {
-                               TxD_t *temp;
-                               temp = txdp;
-                               txdp++;
-                               for (j = 0; j < frg_cnt; j++, txdp++) {
-                                       skb_frag_t *frag =
-                                           &skb_shinfo(skb)->frags[j];
-                                       pci_unmap_page(nic->pdev,
-                                                      (dma_addr_t)
-                                                      txdp->
-                                                      Buffer_Pointer,
-                                                      frag->size,
-                                                      PCI_DMA_TODEVICE);
-                               }
-                               txdp = temp;
+                       skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
+                       if (skb) {
+                               dev_kfree_skb(skb);
+                               cnt++;
                        }
-                       dev_kfree_skb(skb);
-                       memset(txdp, 0, sizeof(TxD_t) * config->max_txds);
-                       cnt++;
                }
                DBG_PRINT(INTR_DBG,
                          "%s:forcibly freeing %d skbs on FIFO%d\n",
@@ -2661,7 +2683,6 @@ static void tx_intr_handler(fifo_info_t *fifo_data)
        tx_curr_get_info_t get_info, put_info;
        struct sk_buff *skb;
        TxD_t *txdlp;
-       u16 j, frg_cnt;
 
        get_info = fifo_data->tx_curr_get_info;
        put_info = fifo_data->tx_curr_put_info;
@@ -2684,8 +2705,7 @@ to loss of link\n");
                        }
                }
 
-               skb = (struct sk_buff *) ((unsigned long)
-                               txdlp->Host_Control);
+               skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
                if (skb == NULL) {
                        DBG_PRINT(ERR_DBG, "%s: Null skb ",
                        __FUNCTION__);
@@ -2693,34 +2713,6 @@ to loss of link\n");
                        return;
                }
 
-               frg_cnt = skb_shinfo(skb)->nr_frags;
-               nic->tx_pkt_count++;
-
-               pci_unmap_single(nic->pdev, (dma_addr_t)
-                                txdlp->Buffer_Pointer,
-                                skb->len - skb->data_len,
-                                PCI_DMA_TODEVICE);
-               if (frg_cnt) {
-                       TxD_t *temp;
-                       temp = txdlp;
-                       txdlp++;
-                       for (j = 0; j < frg_cnt; j++, txdlp++) {
-                               skb_frag_t *frag =
-                                   &skb_shinfo(skb)->frags[j];
-                               if (!txdlp->Buffer_Pointer)
-                                       break;
-                               pci_unmap_page(nic->pdev,
-                                              (dma_addr_t)
-                                              txdlp->
-                                              Buffer_Pointer,
-                                              frag->size,
-                                              PCI_DMA_TODEVICE);
-                       }
-                       txdlp = temp;
-               }
-               memset(txdlp, 0,
-                      (sizeof(TxD_t) * fifo_data->max_txds));
-
                /* Updating the statistics block */
                nic->stats.tx_bytes += skb->len;
                dev_kfree_skb_irq(skb);
@@ -3331,7 +3323,7 @@ failed\n", dev->name);
                                          s2io_msix_fifo_handle, 0, sp->desc1,
                                          sp->s2io_entries[i].arg);
                                DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1, 
-                                                       sp->msix_info[i].addr);
+                                   (unsigned long long)sp->msix_info[i].addr);
                        } else {
                                sprintf(sp->desc2, "%s:MSI-X-%d-RX",
                                        dev->name, i);
@@ -3339,7 +3331,7 @@ failed\n", dev->name);
                                          s2io_msix_ring_handle, 0, sp->desc2,
                                          sp->s2io_entries[i].arg);
                                DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2, 
-                                                       sp->msix_info[i].addr);
+                                    (unsigned long long)sp->msix_info[i].addr);
                        }
                        if (err) {
                                DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \
@@ -3527,6 +3519,8 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                return 0;
        }
 
+       txdp->Control_1 = 0;
+       txdp->Control_2 = 0;
 #ifdef NETIF_F_TSO
        mss = skb_shinfo(skb)->tso_size;
        if (mss) {
@@ -3534,19 +3528,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
        }
 #endif
-
-       frg_cnt = skb_shinfo(skb)->nr_frags;
-       frg_len = skb->len - skb->data_len;
-
-       txdp->Buffer_Pointer = pci_map_single
-           (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
-       txdp->Host_Control = (unsigned long) skb;
        if (skb->ip_summed == CHECKSUM_HW) {
                txdp->Control_2 |=
                    (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN |
                     TXD_TX_CKO_UDP_EN);
        }
-
+       txdp->Control_1 |= TXD_GATHER_CODE_FIRST;
+       txdp->Control_1 |= TXD_LIST_OWN_XENA;
        txdp->Control_2 |= config->tx_intr_type;
 
        if (sp->vlgrp && vlan_tx_tag_present(skb)) {
@@ -3554,10 +3542,40 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
        }
 
-       txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
-                           TXD_GATHER_CODE_FIRST);
-       txdp->Control_1 |= TXD_LIST_OWN_XENA;
+       frg_len = skb->len - skb->data_len;
+       if (skb_shinfo(skb)->ufo_size) {
+               int ufo_size;
+
+               ufo_size = skb_shinfo(skb)->ufo_size;
+               ufo_size &= ~7;
+               txdp->Control_1 |= TXD_UFO_EN;
+               txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
+               txdp->Control_1 |= TXD_BUFFER0_SIZE(8);
+#ifdef __BIG_ENDIAN
+               sp->ufo_in_band_v[put_off] =
+                               (u64)skb_shinfo(skb)->ip6_frag_id;
+#else
+               sp->ufo_in_band_v[put_off] =
+                               (u64)skb_shinfo(skb)->ip6_frag_id << 32;
+#endif
+               txdp->Host_Control = (unsigned long)sp->ufo_in_band_v;
+               txdp->Buffer_Pointer = pci_map_single(sp->pdev,
+                                       sp->ufo_in_band_v,
+                                       sizeof(u64), PCI_DMA_TODEVICE);
+               txdp++;
+               txdp->Control_1 = 0;
+               txdp->Control_2 = 0;
+       }
+
+       txdp->Buffer_Pointer = pci_map_single
+           (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
+       txdp->Host_Control = (unsigned long) skb;
+       txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
 
+       if (skb_shinfo(skb)->ufo_size)
+               txdp->Control_1 |= TXD_UFO_EN;
+
+       frg_cnt = skb_shinfo(skb)->nr_frags;
        /* For fragmented SKB. */
        for (i = 0; i < frg_cnt; i++) {
                skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -3569,9 +3587,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                    (sp->pdev, frag->page, frag->page_offset,
                     frag->size, PCI_DMA_TODEVICE);
                txdp->Control_1 |= TXD_BUFFER0_SIZE(frag->size);
+               if (skb_shinfo(skb)->ufo_size)
+                       txdp->Control_1 |= TXD_UFO_EN;
        }
        txdp->Control_1 |= TXD_GATHER_CODE_LAST;
 
+       if (skb_shinfo(skb)->ufo_size)
+               frg_cnt++; /* as Txd0 was used for inband header */
+
        tx_fifo = mac_control->tx_FIFO_start[queue];
        val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr;
        writeq(val64, &tx_fifo->TxDL_Pointer);
@@ -3583,6 +3606,8 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        if (mss)
                val64 |= TX_FIFO_SPECIAL_FUNC;
 #endif
+       if (skb_shinfo(skb)->ufo_size)
+               val64 |= TX_FIFO_SPECIAL_FUNC;
        writeq(val64, &tx_fifo->List_Control);
 
        mmiowb();
@@ -4721,7 +4746,10 @@ static int s2io_eeprom_test(nic_t * sp, uint64_t * data)
                fail = 1;
 
        if (ret_data != 0x012345) {
-               DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+               DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. "
+                       "Data written %llx Data read %llx\n",
+                       dev->name, (unsigned long long)0x12345,
+                       (unsigned long long)ret_data);
                fail = 1;
        }
 
@@ -4740,7 +4768,10 @@ static int s2io_eeprom_test(nic_t * sp, uint64_t * data)
                fail = 1;
 
        if (ret_data != 0x012345) {
-               DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+               DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. "
+                       "Data written %llx Data read %llx\n",
+                       dev->name, (unsigned long long)0x12345,
+                       (unsigned long long)ret_data);
                fail = 1;
        }
 
@@ -5190,6 +5221,8 @@ static struct ethtool_ops netdev_ethtool_ops = {
        .get_tso = ethtool_op_get_tso,
        .set_tso = ethtool_op_set_tso,
 #endif
+       .get_ufo = ethtool_op_get_ufo,
+       .set_ufo = ethtool_op_set_ufo,
        .self_test_count = s2io_ethtool_self_test_count,
        .self_test = s2io_ethtool_test,
        .get_strings = s2io_ethtool_get_strings,
@@ -5941,7 +5974,8 @@ Defaulting to INTA\n");
                        break;
                }
        }
-       config->max_txds = MAX_SKB_FRAGS + 1;
+       /* + 2 because one Txd for skb->data and one Txd for UFO */
+       config->max_txds = MAX_SKB_FRAGS + 2;
 
        /* Rx side parameters. */
        if (rx_ring_sz[0] == 0)
@@ -6035,6 +6069,10 @@ Defaulting to INTA\n");
 #ifdef NETIF_F_TSO
        dev->features |= NETIF_F_TSO;
 #endif
+       if (sp->device_type & XFRAME_II_DEVICE) {
+               dev->features |= NETIF_F_UFO;
+               dev->features |= NETIF_F_HW_CSUM;
+       }
 
        dev->tx_timeout = &s2io_tx_watchdog;
        dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
index 419aad7f10e7c357c469904ca56cea95295daf3b..852a6a899d07cd5d1d9a79b7b724ce447daf5991 100644 (file)
@@ -393,7 +393,9 @@ typedef struct _TxD {
 #define TXD_GATHER_CODE_LAST    BIT(23)
 #define TXD_TCP_LSO_EN          BIT(30)
 #define TXD_UDP_COF_EN          BIT(31)
+#define TXD_UFO_EN             BIT(31) | BIT(30)
 #define TXD_TCP_LSO_MSS(val)    vBIT(val,34,14)
+#define TXD_UFO_MSS(val)       vBIT(val,34,14)
 #define TXD_BUFFER0_SIZE(val)   vBIT(val,48,16)
 
        u64 Control_2;
@@ -789,6 +791,7 @@ struct s2io_nic {
 
        spinlock_t      rx_lock;
        atomic_t        isr_cnt;
+       u64 *ufo_in_band_v;
 };
 
 #define RESET_ERROR 1;
index 1d4d88680db197cb1caa0660360db9001c140090..3d95fa20cd883e969cb3b138f8edb0a07a06c815 100644 (file)
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:   1.08.08 Jan. 22 2005
+   Revision:   1.08.09 Sep. 19 2005
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -17,6 +17,7 @@
    SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
    preliminary Rev. 1.0 Jan. 18, 1998
 
+   Rev 1.08.09 Sep. 19 2005 Daniele Venzano add Wake on LAN support
    Rev 1.08.08 Jan. 22 2005 Daniele Venzano use netif_msg for debugging messages
    Rev 1.08.07 Nov.  2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support
    Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support
@@ -76,7 +77,7 @@
 #include "sis900.h"
 
 #define SIS900_MODULE_NAME "sis900"
-#define SIS900_DRV_VERSION "v1.08.08 Jan. 22 2005"
+#define SIS900_DRV_VERSION "v1.08.09 Sep. 19 2005"
 
 static char version[] __devinitdata =
 KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
@@ -538,6 +539,11 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
                printk("%2.2x:", (u8)net_dev->dev_addr[i]);
        printk("%2.2x.\n", net_dev->dev_addr[i]);
 
+       /* Detect Wake on Lan support */
+       ret = inl(CFGPMC & PMESP);
+       if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0)
+               printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name);
+
        return 0;
 
  err_unmap_rx:
@@ -2015,6 +2021,67 @@ static int sis900_nway_reset(struct net_device *net_dev)
        return mii_nway_restart(&sis_priv->mii_info);
 }
 
+/**
+ *     sis900_set_wol - Set up Wake on Lan registers
+ *     @net_dev: the net device to probe
+ *     @wol: container for info passed to the driver
+ *
+ *     Process ethtool command "wol" to setup wake on lan features.
+ *     SiS900 supports sending WoL events if a correct packet is received,
+ *     but there is no simple way to filter them to only a subset (broadcast,
+ *     multicast, unicast or arp).
+ */
+static int sis900_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       long pmctrl_addr = net_dev->base_addr + pmctrl;
+       u32 cfgpmcsr = 0, pmctrl_bits = 0;
+
+       if (wol->wolopts == 0) {
+               pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
+               cfgpmcsr |= ~PME_EN;
+               pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
+               outl(pmctrl_bits, pmctrl_addr);
+               if (netif_msg_wol(sis_priv))
+                       printk(KERN_DEBUG "%s: Wake on LAN disabled\n", net_dev->name);
+               return 0;
+       }
+
+       if (wol->wolopts & (WAKE_MAGICSECURE | WAKE_UCAST | WAKE_MCAST
+                               | WAKE_BCAST | WAKE_ARP))
+               return -EINVAL;
+
+       if (wol->wolopts & WAKE_MAGIC)
+               pmctrl_bits |= MAGICPKT;
+       if (wol->wolopts & WAKE_PHY)
+               pmctrl_bits |= LINKON;
+       
+       outl(pmctrl_bits, pmctrl_addr);
+
+       pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
+       cfgpmcsr |= PME_EN;
+       pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
+       if (netif_msg_wol(sis_priv))
+               printk(KERN_DEBUG "%s: Wake on LAN enabled\n", net_dev->name);
+
+       return 0;
+}
+
+static void sis900_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
+{
+       long pmctrl_addr = net_dev->base_addr + pmctrl;
+       u32 pmctrl_bits;
+
+       pmctrl_bits = inl(pmctrl_addr);
+       if (pmctrl_bits & MAGICPKT)
+               wol->wolopts |= WAKE_MAGIC;
+       if (pmctrl_bits & LINKON)
+               wol->wolopts |= WAKE_PHY;
+
+       wol->supported = (WAKE_PHY | WAKE_MAGIC);
+}
+
 static struct ethtool_ops sis900_ethtool_ops = {
        .get_drvinfo    = sis900_get_drvinfo,
        .get_msglevel   = sis900_get_msglevel,
@@ -2023,6 +2090,8 @@ static struct ethtool_ops sis900_ethtool_ops = {
        .get_settings   = sis900_get_settings,
        .set_settings   = sis900_set_settings,
        .nway_reset     = sis900_nway_reset,
+       .get_wol        = sis900_get_wol,
+       .set_wol        = sis900_set_wol
 };
 
 /**
index de3c06735d15eab202779adcd714473b5e4844f7..4233ea55670f53e05f9bcc7fd4f2f1e6fba88e6f 100644 (file)
@@ -33,6 +33,7 @@ enum sis900_registers {
         rxcfg=0x34,             //Receive Configuration Register
         flctrl=0x38,            //Flow Control Register
         rxlen=0x3c,             //Receive Packet Length Register
+        cfgpmcsr=0x44,          //Configuration Power Management Control/Status Register
         rfcr=0x48,              //Receive Filter Control Register
         rfdr=0x4C,              //Receive Filter Data Register
         pmctrl=0xB0,            //Power Management Control Register
@@ -140,6 +141,50 @@ enum sis96x_eeprom_command {
        EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100
 };
 
+/* PCI Registers */
+enum sis900_pci_registers {
+       CFGPMC   = 0x40,
+       CFGPMCSR = 0x44
+};
+
+/* Power management capabilities bits */
+enum sis900_cfgpmc_register_bits {
+       PMVER   = 0x00070000, 
+       DSI     = 0x00100000,
+       PMESP   = 0xf8000000
+};
+
+enum sis900_pmesp_bits {
+       PME_D0 = 0x1,
+       PME_D1 = 0x2,
+       PME_D2 = 0x4,
+       PME_D3H = 0x8,
+       PME_D3C = 0x10
+};
+
+/* Power management control/status bits */
+enum sis900_cfgpmcsr_register_bits {
+       PMESTS = 0x00004000,
+       PME_EN = 0x00000100, // Power management enable
+       PWR_STA = 0x00000003 // Current power state
+};
+
+/* Wake-on-LAN support. */
+enum sis900_power_management_control_register_bits {
+       LINKLOSS  = 0x00000001,
+       LINKON    = 0x00000002,
+       MAGICPKT  = 0x00000400,
+       ALGORITHM = 0x00000800,
+       FRM1EN    = 0x00100000,
+       FRM2EN    = 0x00200000,
+       FRM3EN    = 0x00400000,
+       FRM1ACS   = 0x01000000,
+       FRM2ACS   = 0x02000000,
+       FRM3ACS   = 0x04000000,
+       WAKEALL   = 0x40000000,
+       GATECLK   = 0x80000000
+};
+
 /* Management Data I/O (mdio) frame */
 #define MIIread         0x6000
 #define MIIwrite        0x5002
index 7653d6e33aa28dc0b0e71f5c9b4cd321eda1c5cd..afd900d5d730e81d32353ecd5882415ab6047d48 100644 (file)
@@ -26,8 +26,7 @@ sk98lin-objs    :=    \
                skrlmt.o        \
                sktimer.o       \
                skvpd.o         \
-               skxmac2.o       \
-               skproc.o
+               skxmac2.o
 
 # DBGDEF =  \
 # -DDEBUG
index 2dc5728e3ef67ab2937387744ab627224c0e69f3..778d9e618ebd545b3349fffca86369b99c65a36d 100644 (file)
@@ -60,7 +60,6 @@ extern SK_U64         SkOsGetTime(SK_AC*);
 extern int             SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
 extern int             SkPciReadCfgWord(SK_AC*, int, SK_U16*);
 extern int             SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int             SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
 extern int             SkPciWriteCfgWord(SK_AC*, int, SK_U16);
 extern int             SkPciWriteCfgByte(SK_AC*, int, SK_U8);
 extern int             SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
@@ -268,8 +267,6 @@ typedef struct s_DevNet DEV_NET;
 struct s_DevNet {
        int             PortNr;
        int             NetNr;
-       int             Mtu;
-       int             Up;
        SK_AC   *pAC;
 };  
 
@@ -298,6 +295,7 @@ struct s_RxPort {
        RXD             *pRxdRingTail;  /* Tail of Rx rings */
        RXD             *pRxdRingPrev;  /* descriptor given to BMU previously */
        int             RxdRingFree;    /* # of free entrys */
+       int             RxCsum;         /* use receive checksum hardware */
        spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
        int             RxFillLimit;    /* limit for buffers in ring */
        SK_IOC          HwAddr;         /* bmu registers address */
@@ -390,12 +388,10 @@ struct s_AC  {
        
        SK_IOC          IoBase;         /* register set of adapter */
        int             BoardLevel;     /* level of active hw init (0-2) */
-       char            DeviceStr[80];  /* adapter string from vpd */
+
        SK_U32          AllocFlag;      /* flag allocation of resources */
        struct pci_dev  *PciDev;        /* for access to pci config space */
-       SK_U32          PciDevId;       /* pci device id */
        struct SK_NET_DEVICE    *dev[2];        /* pointer to device struct */
-       char            Name[30];       /* driver name */
 
        int             RxBufSize;      /* length of receive buffers */
         struct net_device_stats stats; /* linux 'netstat -i' statistics */
@@ -430,7 +426,6 @@ struct s_AC  {
        DIM_INFO        DynIrqModInfo;  /* all data related to DIM */
 
        /* Only for tests */
-       int             PortUp;
        int             PortDown;
        int             ChipsetType;    /*  Chipset family type 
                                         *  0 == Genesis family support
index bdc1a5eaaae9610533bcbffaffeecd83a01f425d..daa9a8d154fca28f3c23ae824a24c10415094093 100644 (file)
@@ -130,14 +130,12 @@ typedef   struct s_vpd_key {
 #ifndef VPD_DO_IO
 #define VPD_OUT8(pAC,IoC,Addr,Val)     (void)SkPciWriteCfgByte(pAC,Addr,Val)
 #define VPD_OUT16(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgWord(pAC,Addr,Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)    (void)SkPciWriteCfgDWord(pAC,Addr,Val)
 #define VPD_IN8(pAC,IoC,Addr,pVal)     (void)SkPciReadCfgByte(pAC,Addr,pVal)
 #define VPD_IN16(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgWord(pAC,Addr,pVal)
 #define VPD_IN32(pAC,IoC,Addr,pVal)    (void)SkPciReadCfgDWord(pAC,Addr,pVal)
 #else  /* VPD_DO_IO */
 #define VPD_OUT8(pAC,IoC,Addr,Val)     SK_OUT8(IoC,PCI_C(Addr),Val)
 #define VPD_OUT16(pAC,IoC,Addr,Val)    SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)    SK_OUT32(IoC,PCI_C(Addr),Val)
 #define VPD_IN8(pAC,IoC,Addr,pVal)     SK_IN8(IoC,PCI_C(Addr),pVal)
 #define VPD_IN16(pAC,IoC,Addr,pVal)    SK_IN16(IoC,PCI_C(Addr),pVal)
 #define VPD_IN32(pAC,IoC,Addr,pVal)    SK_IN32(IoC,PCI_C(Addr),pVal)
@@ -155,12 +153,6 @@ typedef    struct s_vpd_key {
                else                                            \
                        SK_OUT16(pAC,PCI_C(Addr),Val);          \
                }
-#define VPD_OUT32(pAC,Ioc,Addr,Val) {                  \
-               if ((pAC)->DgT.DgUseCfgCycle)                   \
-                       SkPciWriteCfgDWord(pAC,Addr,Val);       \
-               else                                            \
-                       SK_OUT32(pAC,PCI_C(Addr),Val);          \
-               }
 #define VPD_IN8(pAC,Ioc,Addr,pVal) {                   \
                if ((pAC)->DgT.DgUseCfgCycle)                   \
                        SkPciReadCfgByte(pAC,Addr,pVal);        \
index b71769ae4603ac3a0f89c07aefd626f63795438e..4265ed91a9c4800eee83f7ed2f53ae2a63f1459f 100644 (file)
@@ -539,6 +539,48 @@ static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *ep
         return ret ? -EIO : 0;
 }
 
+/* Only Yukon supports checksum offload. */
+static int setScatterGather(struct net_device *dev, u32 data)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+               return -EOPNOTSUPP;
+       return ethtool_op_set_sg(dev, data);
+}
+
+static int setTxCsum(struct net_device *dev, u32 data)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+               return -EOPNOTSUPP;
+
+       return ethtool_op_set_tx_csum(dev, data);
+}
+
+static u32 getRxCsum(struct net_device *dev)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       return pAC->RxPort[pNet->PortNr].RxCsum;
+}
+
+static int setRxCsum(struct net_device *dev, u32 data)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+               return -EOPNOTSUPP;
+
+       pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
+       return 0;
+}
+
 struct ethtool_ops SkGeEthtoolOps = {
        .get_settings           = getSettings,
        .set_settings           = setSettings,
@@ -551,4 +593,10 @@ struct ethtool_ops SkGeEthtoolOps = {
        .set_pauseparam         = setPauseParams,
        .get_link               = ethtool_op_get_link,
        .get_perm_addr          = ethtool_op_get_perm_addr,
+       .get_sg                 = ethtool_op_get_sg,
+       .set_sg                 = setScatterGather,
+       .get_tx_csum            = ethtool_op_get_tx_csum,
+       .set_tx_csum            = setTxCsum,
+       .get_rx_csum            = getRxCsum,
+       .set_rx_csum            = setRxCsum,
 };
index ae734393475876a6c0bd9ce521fb714967c15f21..9a76ac180b11519e69d09263a6bf1eafd8c1376a 100644 (file)
 
 #include       "h/skversion.h"
 
+#include       <linux/in.h>
 #include       <linux/module.h>
 #include       <linux/moduleparam.h>
 #include       <linux/init.h>
-#include       <linux/proc_fs.h>
 #include       <linux/dma-mapping.h>
 #include       <linux/ip.h>
 
@@ -206,7 +206,6 @@ static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);
 static struct  net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
 static int     SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
 static void    GetConfiguration(SK_AC*);
-static void    ProductStr(SK_AC*);
 static int     XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
 static void    FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
 static void    FillRxRing(SK_AC*, RX_PORT*);
@@ -235,28 +234,6 @@ static int      SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
  * Extern Function Prototypes
  *
  ******************************************************************************/
-static const char      SKRootName[] = "net/sk98lin";
-static struct          proc_dir_entry *pSkRootDir;
-extern struct  file_operations sk_proc_fops;
-
-static inline void SkGeProcCreate(struct net_device *dev)
-{
-       struct proc_dir_entry *pe;
-
-       if (pSkRootDir && 
-           (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
-               pe->proc_fops = &sk_proc_fops;
-               pe->data = dev;
-               pe->owner = THIS_MODULE;
-       }
-}
-static inline void SkGeProcRemove(struct net_device *dev)
-{
-       if (pSkRootDir)
-               remove_proc_entry(dev->name, pSkRootDir);
-}
-
 extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); 
 extern void SkDimDisplayModerationSettings(SK_AC *pAC);
 extern void SkDimStartModerationTimer(SK_AC *pAC);
@@ -277,6 +254,27 @@ extern  struct ethtool_ops SkGeEthtoolOps;
 static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
 static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
 
+/*****************************************************************************
+ *
+ *     SkPciWriteCfgDWord - write a 32 bit value to pci config space
+ *
+ * Description:
+ *     This routine writes a 32 bit value to the pci configuration
+ *     space.
+ *
+ * Returns:
+ *     0 - indicate everything worked ok.
+ *     != 0 - error indication
+ */
+static inline int SkPciWriteCfgDWord(
+SK_AC *pAC,    /* Adapter Control structure pointer */
+int PciAddr,           /* PCI register address */
+SK_U32 Val)            /* pointer to store the read value */
+{
+       pci_write_config_dword(pAC->PciDev, PciAddr, Val);
+       return(0);
+} /* SkPciWriteCfgDWord */
+
 /*****************************************************************************
  *
  *     SkGeInitPCI - Init the PCI resources
@@ -300,7 +298,7 @@ int SkGeInitPCI(SK_AC *pAC)
        dev->mem_start = pci_resource_start (pdev, 0);
        pci_set_master(pdev);
 
-       if (pci_request_regions(pdev, pAC->Name) != 0) {
+       if (pci_request_regions(pdev, "sk98lin") != 0) {
                retval = 2;
                goto out_disable;
        }
@@ -578,10 +576,10 @@ SK_BOOL   DualNet;
        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
        if (pAC->GIni.GIMacsFound == 2) {
-                Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+                Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
        } else if (pAC->GIni.GIMacsFound == 1) {
                Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
-                       pAC->Name, dev);
+                       "sk98lin", dev);
        } else {
                printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
                       pAC->GIni.GIMacsFound);
@@ -1265,7 +1263,6 @@ struct SK_NET_DEVICE      *dev)
        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
        pAC->MaxPorts++;
-       pNet->Up = 1;
 
 
        SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
@@ -1395,7 +1392,6 @@ struct SK_NET_DEVICE      *dev)
                        sizeof(SK_PNMI_STRUCT_DATA));
 
        pAC->MaxPorts--;
-       pNet->Up = 0;
 
        return (0);
 } /* SkGeClose */
@@ -2175,7 +2171,6 @@ rx_start:
                pMsg->ip_summed = CHECKSUM_NONE;
 #endif
 
-
                SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
                ForRlmt = SK_RLMT_RX_PROTOCOL;
 #if 0
@@ -2550,7 +2545,7 @@ unsigned long             Flags;
 static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
 {
 DEV_NET                *pNet;
-DEV_NET                *pOtherNet;
+struct net_device *pOtherDev;
 SK_AC          *pAC;
 unsigned long  Flags;
 int            i;
@@ -2580,11 +2575,11 @@ SK_EVPARA       EvPara;
        }
 #endif
 
-       pNet->Mtu = NewMtu;
-       pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
-       if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
-               return(0);
-       }
+       pOtherDev = pAC->dev[1 - pNet->NetNr];
+
+       if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
+            && (NewMtu <= 1500))
+               return 0;
 
        pAC->RxBufSize = NewMtu + 32;
        dev->mtu = NewMtu;
@@ -2746,7 +2741,8 @@ SK_EVPARA         EvPara;
                EvPara.Para32[1] = -1;
                SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
                        
-               if (pOtherNet->Up) {
+               if (netif_running(pOtherDev)) {
+                       DEV_NET *pOtherNet = netdev_priv(pOtherDev);
                        EvPara.Para32[0] = pOtherNet->PortNr;
                        SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
                }
@@ -2820,7 +2816,7 @@ unsigned long     Flags;                  /* for spin lock */
        pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
        pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
        
-        if (pNet->Mtu <= 1500) {
+        if (dev->mtu <= 1500) {
                 pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
         } else {
                 pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
@@ -3771,25 +3767,21 @@ int     Capabilities[3][3] =
  *
  * Returns: N/A
  */
-static void ProductStr(
-SK_AC  *pAC            /* pointer to adapter context */
+static inline int ProductStr(
+       SK_AC   *pAC,           /* pointer to adapter context */
+       char    *DeviceStr,     /* result string */
+       int      StrLen         /* length of the string */
 )
 {
-int    StrLen = 80;            /* length of the string, defined in SK_AC */
 char   Keyword[] = VPD_NAME;   /* vpd productname identifier */
 int    ReturnCode;             /* return code from vpd_read */
 unsigned long Flags;
 
        spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-       ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
-               &StrLen);
+       ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       if (ReturnCode != 0) {
-               /* there was an error reading the vpd data */
-               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
-                       ("Error reading VPD data: %d\n", ReturnCode));
-               pAC->DeviceStr[0] = '\0';
-       }
+
+       return ReturnCode;
 } /* ProductStr */
 
 /*****************************************************************************
@@ -3990,28 +3982,6 @@ SK_U8 *pVal)             /* pointer to store the read value */
 } /* SkPciReadCfgByte */
 
 
-/*****************************************************************************
- *
- *     SkPciWriteCfgDWord - write a 32 bit value to pci config space
- *
- * Description:
- *     This routine writes a 32 bit value to the pci configuration
- *     space.
- *
- * Returns:
- *     0 - indicate everything worked ok.
- *     != 0 - error indication
- */
-int SkPciWriteCfgDWord(
-SK_AC *pAC,    /* Adapter Control structure pointer */
-int PciAddr,           /* PCI register address */
-SK_U32 Val)            /* pointer to store the read value */
-{
-       pci_write_config_dword(pAC->PciDev, PciAddr, Val);
-       return(0);
-} /* SkPciWriteCfgDWord */
-
-
 /*****************************************************************************
  *
  *     SkPciWriteCfgWord - write a 16 bit value to pci config space
@@ -4150,6 +4120,7 @@ SK_BOOL           DualNet;
                        Flags);
                break;
        case SK_DRV_NET_UP:      /* SK_U32 PortIdx */
+       {       struct net_device *dev = pAC->dev[Param.Para32[0]];
                /* action list 5 */
                FromPort = Param.Para32[0];
                SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4233,22 +4204,12 @@ SK_BOOL         DualNet;
                        printk("    irq moderation:  disabled\n");
 
 
-#ifdef SK_ZEROCOPY
-               if (pAC->ChipsetType)
-#ifdef USE_SK_TX_CHECKSUM
-                       printk("    scatter-gather:  enabled\n");
-#else
-                       printk("    tx-checksum:     disabled\n");
-#endif
-               else
-                       printk("    scatter-gather:  disabled\n");
-#else
-                       printk("    scatter-gather:  disabled\n");
-#endif
-
-#ifndef USE_SK_RX_CHECKSUM
-                       printk("    rx-checksum:     disabled\n");
-#endif
+               printk("    scatter-gather:  %s\n",
+                      (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
+               printk("    tx-checksum:     %s\n",
+                      (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
+               printk("    rx-checksum:     %s\n",
+                      pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
 
                } else {
                         DoPrintInterfaceChange = SK_TRUE;
@@ -4263,9 +4224,9 @@ SK_BOOL           DualNet;
                }
 
                /* Inform the world that link protocol is up. */
-               netif_carrier_on(pAC->dev[Param.Para32[0]]);
-
+               netif_carrier_on(dev);
                break;
+       }
        case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
                /* action list 7 */
                SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4479,7 +4440,7 @@ SK_AC   *pAc)   /* pointer to adapter context */
 
        pAC->DiagModeActive = DIAG_ACTIVE;
        if (pAC->BoardLevel > SK_INIT_DATA) {
-               if (pNet->Up) {
+               if (netif_running(pAC->dev[0])) {
                        pAC->WasIfUp[0] = SK_TRUE;
                        pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
                        DoPrintInterfaceChange = SK_FALSE;
@@ -4489,7 +4450,7 @@ SK_AC   *pAc)   /* pointer to adapter context */
                }
                if (pNet != netdev_priv(pAC->dev[1])) {
                        pNet = netdev_priv(pAC->dev[1]);
-                       if (pNet->Up) {
+                       if (netif_running(pAC->dev[1])) {
                                pAC->WasIfUp[1] = SK_TRUE;
                                pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
                                DoPrintInterfaceChange = SK_FALSE;
@@ -4815,6 +4776,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
        struct net_device       *dev = NULL;
        static int boards_found = 0;
        int error = -ENODEV;
+       char DeviceStr[80];
 
        if (pci_enable_device(pdev))
                goto out;
@@ -4842,14 +4804,11 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
        memset(pNet->pAC, 0, sizeof(SK_AC));
        pAC = pNet->pAC;
        pAC->PciDev = pdev;
-       pAC->PciDevId = pdev->device;
+
        pAC->dev[0] = dev;
        pAC->dev[1] = dev;
-       sprintf(pAC->Name, "SysKonnect SK-98xx");
        pAC->CheckQueue = SK_FALSE;
 
-       pNet->Mtu = 1500;
-       pNet->Up = 0;
        dev->irq = pdev->irq;
        error = SkGeInitPCI(pAC);
        if (error) {
@@ -4872,21 +4831,30 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
        SET_NETDEV_DEV(dev, &pdev->dev);
        SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
+       /* Use only if yukon hardware */
        if (pAC->ChipsetType) {
-               /* Use only if yukon hardware */
-               /* SK and ZEROCOPY - fly baby... */
-               dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-       }
+#ifdef USE_SK_TX_CHECKSUM
+               dev->features |= NETIF_F_IP_CSUM;
+#endif
+#ifdef SK_ZEROCOPY
+               dev->features |= NETIF_F_SG;
 #endif
+#ifdef USE_SK_RX_CHECKSUM
+               pAC->RxPort[0].RxCsum = 1;
 #endif
+       }
 
        pAC->Index = boards_found++;
 
        if (SkGeBoardInit(dev, pAC))
                goto out_free_netdev;
 
+       /* Read Adapter name from VPD */
+       if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
+               printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
+               goto out_free_resources;
+       }
+
        /* Register net device */
        if (register_netdev(dev)) {
                printk(KERN_ERR "sk98lin: Could not register device.\n");
@@ -4894,8 +4862,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
        }
 
        /* Print adapter specific string from vpd */
-       ProductStr(pAC);
-       printk("%s: %s\n", dev->name, pAC->DeviceStr);
+       printk("%s: %s\n", dev->name, DeviceStr);
 
        /* Print configuration settings */
        printk("      PrefPort:%c  RlmtMode:%s\n",
@@ -4911,8 +4878,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
        memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-       SkGeProcCreate(dev);
-
        pNet->PortNr = 0;
        pNet->NetNr  = 0;
 
@@ -4931,8 +4896,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
                pNet->PortNr  = 1;
                pNet->NetNr   = 1;
                pNet->pAC     = pAC;
-               pNet->Mtu     = 1500;
-               pNet->Up      = 0;
 
                dev->open               = &SkGeOpen;
                dev->stop               = &SkGeClose;
@@ -4945,26 +4908,28 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
                SET_NETDEV_DEV(dev, &pdev->dev);
                SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
                if (pAC->ChipsetType) {
-                       /* SG and ZEROCOPY - fly baby... */
-                       dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-               }
+#ifdef USE_SK_TX_CHECKSUM
+                       dev->features |= NETIF_F_IP_CSUM;
+#endif
+#ifdef SK_ZEROCOPY
+                       dev->features |= NETIF_F_SG;
 #endif
+#ifdef USE_SK_RX_CHECKSUM
+                       pAC->RxPort[1].RxCsum = 1;
 #endif
+               }
 
                if (register_netdev(dev)) {
                        printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");
                        free_netdev(dev);
                        pAC->dev[1] = pAC->dev[0];
                } else {
-                       SkGeProcCreate(dev);
                        memcpy(&dev->dev_addr,
                                        &pAC->Addr.Net[1].CurrentMacAddress, 6);
                        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
        
-                       printk("%s: %s\n", dev->name, pAC->DeviceStr);
+                       printk("%s: %s\n", dev->name, DeviceStr);
                        printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
                }
        }
@@ -5000,10 +4965,7 @@ static void __devexit skge_remove_one(struct pci_dev *pdev)
        SK_AC *pAC = pNet->pAC;
        struct net_device *otherdev = pAC->dev[1];
 
-       SkGeProcRemove(dev);
        unregister_netdev(dev);
-       if (otherdev != dev)
-               SkGeProcRemove(otherdev);
 
        SkGeYellowLED(pAC, pAC->IoBase, 0);
 
@@ -5088,9 +5050,9 @@ static int skge_resume(struct pci_dev *pdev)
        pci_enable_device(pdev);
        pci_set_master(pdev);
        if (pAC->GIni.GIMacsFound == 2)
-               ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+               ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
        else
-               ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
+               ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, "sk98lin", dev);
        if (ret) {
                printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
                pAC->AllocFlag &= ~SK_ALLOC_IRQ;
@@ -5148,23 +5110,12 @@ static struct pci_driver skge_driver = {
 
 static int __init skge_init(void)
 {
-       int error;
-
-       pSkRootDir = proc_mkdir(SKRootName, NULL);
-       if (pSkRootDir) 
-               pSkRootDir->owner = THIS_MODULE;
-       
-       error = pci_register_driver(&skge_driver);
-       if (error)
-               remove_proc_entry(SKRootName, NULL);
-       return error;
+       return pci_module_init(&skge_driver);
 }
 
 static void __exit skge_exit(void)
 {
        pci_unregister_driver(&skge_driver);
-       remove_proc_entry(SKRootName, NULL);
-
 }
 
 module_init(skge_init);
diff --git a/drivers/net/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
deleted file mode 100644 (file)
index 5cece25..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/******************************************************************************
- *
- * Name:       skproc.c
- * Project:    GEnesis, PCI Gigabit Ethernet Adapter
- * Version:    $Revision: 1.11 $
- * Date:       $Date: 2003/12/11 16:03:57 $
- * Purpose:    Funktions to display statictic data
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *     (C)Copyright 1998-2002 SysKonnect GmbH.
- *     (C)Copyright 2002-2003 Marvell.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     Created 22-Nov-2000
- *     Author: Mirko Lindner (mlindner@syskonnect.de)
- *
- *     The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#include "h/skversion.h"
-
-static int sk_seq_show(struct seq_file *seq, void *v);
-static int sk_proc_open(struct inode *inode, struct file *file);
-
-struct file_operations sk_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = sk_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-
-/*****************************************************************************
- *
- *      sk_seq_show - show proc information of a particular adapter
- *
- * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device. It invokes the generic sk_gen_browse() to
- *  print out all items one per one.
- *  
- * Returns: 0
- *      
- */
-static int sk_seq_show(struct seq_file *seq, void *v)
-{
-       struct net_device *dev = seq->private;
-       DEV_NET                 *pNet = netdev_priv(dev);
-       SK_AC                   *pAC = pNet->pAC;
-       SK_PNMI_STRUCT_DATA     *pPnmiStruct = &pAC->PnmiStruct;
-       unsigned long           Flags;  
-       unsigned int            Size;
-       char                    sens_msg[50];
-       int                     t;
-       int                     i;
-
-       /* NetIndex in GetStruct is now required, zero is only dummy */
-       for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
-               if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
-                       t--;
-
-               spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-               Size = SK_PNMI_STRUCT_SIZE;
-#ifdef SK_DIAG_SUPPORT
-               if (pAC->BoardLevel == SK_INIT_DATA) {
-                       SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
-                       if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
-                               pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
-                       }
-               } else {
-                       SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
-               }
-#else
-               SkPnmiGetStruct(pAC, pAC->IoBase, 
-                               pPnmiStruct, &Size, t-1);
-#endif
-               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-       
-               if (pAC->dev[t-1] == dev) {
-                       SK_PNMI_STAT    *pPnmiStat = &pPnmiStruct->Stat[0];
-
-                       seq_printf(seq, "\nDetailed statistic for device %s\n",
-                                     pAC->dev[t-1]->name);
-                       seq_printf(seq, "=======================================\n");
-       
-                       /* Board statistics */
-                       seq_printf(seq, "\nBoard statistics\n\n");
-                       seq_printf(seq, "Active Port                    %c\n",
-                                     'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-                                                                   Net[t-1].PrefPort]->PortNumber);
-                       seq_printf(seq, "Preferred Port                 %c\n",
-                                     'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-                                                                   Net[t-1].PrefPort]->PortNumber);
-
-                       seq_printf(seq, "Bus speed (MHz)                %d\n",
-                                     pPnmiStruct->BusSpeed);
-
-                       seq_printf(seq, "Bus width (Bit)                %d\n",
-                                     pPnmiStruct->BusWidth);
-                       seq_printf(seq, "Driver version                 %s\n",
-                                     VER_STRING);
-                       seq_printf(seq, "Hardware revision              v%d.%d\n",
-                                     (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
-                                     pAC->GIni.GIPciHwRev & 0x0F);
-
-                       /* Print sensor informations */
-                       for (i=0; i < pAC->I2c.MaxSens; i ++) {
-                               /* Check type */
-                               switch (pAC->I2c.SenTable[i].SenType) {
-                               case 1:
-                                       strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                       strcat(sens_msg, " (C)");
-                                       seq_printf(seq, "%-25s      %d.%02d\n",
-                                                     sens_msg,
-                                                     pAC->I2c.SenTable[i].SenValue / 10,
-                                                     pAC->I2c.SenTable[i].SenValue % 10);
-
-                                       strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                       strcat(sens_msg, " (F)");
-                                       seq_printf(seq, "%-25s      %d.%02d\n",
-                                                     sens_msg,
-                                                     ((((pAC->I2c.SenTable[i].SenValue)
-                                                        *10)*9)/5 + 3200)/100,
-                                                     ((((pAC->I2c.SenTable[i].SenValue)
-                                                        *10)*9)/5 + 3200) % 10);
-                                       break;
-                               case 2:
-                                       strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                       strcat(sens_msg, " (V)");
-                                       seq_printf(seq, "%-25s      %d.%03d\n",
-                                                     sens_msg,
-                                                     pAC->I2c.SenTable[i].SenValue / 1000,
-                                                     pAC->I2c.SenTable[i].SenValue % 1000);
-                                       break;
-                               case 3:
-                                       strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-                                       strcat(sens_msg, " (rpm)");
-                                       seq_printf(seq, "%-25s      %d\n",
-                                                     sens_msg,
-                                                     pAC->I2c.SenTable[i].SenValue);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                               
-                       /*Receive statistics */
-                       seq_printf(seq, "\nReceive statistics\n\n");
-
-                       seq_printf(seq, "Received bytes                 %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
-                       seq_printf(seq, "Received packets               %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxOkCts);
-#if 0
-                       if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
-                           pAC->HWRevision < 12) {
-                               pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
-                                       pPnmiStat->StatRxShortsCts;
-                               pPnmiStat->StatRxShortsCts = 0;
-                       }
-#endif
-                       if (dev->mtu > 1500)
-                               pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
-                                       pPnmiStat->StatRxTooLongCts;
-
-                       seq_printf(seq, "Receive errors                 %Lu\n",
-                                     (unsigned long long) pPnmiStruct->InErrorsCts);
-                       seq_printf(seq, "Receive dropped                %Lu\n",
-                                     (unsigned long long) pPnmiStruct->RxNoBufCts);
-                       seq_printf(seq, "Received multicast             %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
-                       seq_printf(seq, "Receive error types\n");
-                       seq_printf(seq, "   length                      %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxRuntCts);
-                       seq_printf(seq, "   buffer overflow             %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
-                       seq_printf(seq, "   bad crc                     %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxFcsCts);
-                       seq_printf(seq, "   framing                     %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxFramingCts);
-                       seq_printf(seq, "   missed frames               %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxMissedCts);
-
-                       if (dev->mtu > 1500)
-                               pPnmiStat->StatRxTooLongCts = 0;
-
-                       seq_printf(seq, "   too long                    %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxTooLongCts);                                        
-                       seq_printf(seq, "   carrier extension           %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxCextCts);                           
-                       seq_printf(seq, "   too short                   %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxShortsCts);                         
-                       seq_printf(seq, "   symbol                      %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxSymbolCts);                         
-                       seq_printf(seq, "   LLC MAC size                %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxIRLengthCts);                               
-                       seq_printf(seq, "   carrier event               %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxCarrierCts);                                
-                       seq_printf(seq, "   jabber                      %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatRxJabberCts);                         
-
-
-                       /*Transmit statistics */
-                       seq_printf(seq, "\nTransmit statistics\n\n");
-                               
-                       seq_printf(seq, "Transmited bytes               %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
-                       seq_printf(seq, "Transmited packets             %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatTxOkCts);
-                       seq_printf(seq, "Transmit errors                %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-                       seq_printf(seq, "Transmit dropped               %Lu\n",
-                                     (unsigned long long) pPnmiStruct->TxNoBufCts);
-                       seq_printf(seq, "Transmit collisions            %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-                       seq_printf(seq, "Transmit error types\n");
-                       seq_printf(seq, "   excessive collision         %ld\n",
-                                     pAC->stats.tx_aborted_errors);
-                       seq_printf(seq, "   carrier                     %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatTxCarrierCts);
-                       seq_printf(seq, "   fifo underrun               %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
-                       seq_printf(seq, "   heartbeat                   %Lu\n",
-                                     (unsigned long long) pPnmiStat->StatTxCarrierCts);
-                       seq_printf(seq, "   window                      %ld\n",
-                                     pAC->stats.tx_window_errors);
-                               
-               }
-       }
-       return 0;
-}
-
-/*****************************************************************************
- *
- *      sk_proc_open - register the show function when proc is open'ed
- *  
- * Description:
- *  This function is called whenever a sk98lin proc file is queried.
- *  
- * Returns: the return value of single_open()
- *      
- */
-static int sk_proc_open(struct inode *inode, struct file *file)
-{
-    return single_open(file, sk_seq_show, PDE(inode)->data);
-}
-
-/*******************************************************************************
- *
- * End of file
- *
- ******************************************************************************/
index 00d683063c01639c0faf91446001015c84b597e5..b538e3038058a7afe022a83fbadf9876dac0ffbb 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>
@@ -43,7 +44,7 @@
 #include "skge.h"
 
 #define DRV_NAME               "skge"
-#define DRV_VERSION            "1.2"
+#define DRV_VERSION            "1.3"
 #define PFX                    DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE   128
@@ -88,15 +89,14 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
 
 static int skge_up(struct net_device *dev);
 static int skge_down(struct net_device *dev);
+static void skge_phy_reset(struct skge_port *skge);
 static void skge_tx_clean(struct skge_port *skge);
 static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static void genesis_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_init(struct skge_hw *hw, int port);
-static void yukon_reset(struct skge_hw *hw, int port);
 static void genesis_mac_init(struct skge_hw *hw, int port);
-static void genesis_reset(struct skge_hw *hw, int port);
 static void genesis_link_up(struct skge_port *skge);
 
 /* Avoid conditionals by using array */
@@ -276,10 +276,9 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        skge->autoneg = ecmd->autoneg;
        skge->advertising = ecmd->advertising;
 
-       if (netif_running(dev)) {
-               skge_down(dev);
-               skge_up(dev);
-       }
+       if (netif_running(dev))
+               skge_phy_reset(skge);
+
        return (0);
 }
 
@@ -399,6 +398,7 @@ static int skge_set_ring_param(struct net_device *dev,
                               struct ethtool_ringparam *p)
 {
        struct skge_port *skge = netdev_priv(dev);
+       int err;
 
        if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
            p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
@@ -409,7 +409,9 @@ static int skge_set_ring_param(struct net_device *dev,
 
        if (netif_running(dev)) {
                skge_down(dev);
-               skge_up(dev);
+               err = skge_up(dev);
+               if (err)
+                       dev_close(dev);
        }
 
        return 0;
@@ -430,21 +432,11 @@ static void skge_set_msglevel(struct net_device *netdev, u32 value)
 static int skge_nway_reset(struct net_device *dev)
 {
        struct skge_port *skge = netdev_priv(dev);
-       struct skge_hw *hw = skge->hw;
-       int port = skge->port;
 
        if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev))
                return -EINVAL;
 
-       spin_lock_bh(&hw->phy_lock);
-       if (hw->chip_id == CHIP_ID_GENESIS) {
-               genesis_reset(hw, port);
-               genesis_mac_init(hw, port);
-       } else {
-               yukon_reset(hw, port);
-               yukon_init(hw, port);
-       }
-       spin_unlock_bh(&hw->phy_lock);
+       skge_phy_reset(skge);
        return 0;
 }
 
@@ -516,10 +508,8 @@ static int skge_set_pauseparam(struct net_device *dev,
        else
                skge->flow_control = FLOW_MODE_NONE;
 
-       if (netif_running(dev)) {
-               skge_down(dev);
-               skge_up(dev);
-       }
+       if (netif_running(dev))
+               skge_phy_reset(skge);
        return 0;
 }
 
@@ -2019,6 +2009,25 @@ static void yukon_phy_intr(struct skge_port *skge)
        /* XXX restart autonegotiation? */
 }
 
+static void skge_phy_reset(struct skge_port *skge)
+{
+       struct skge_hw *hw = skge->hw;
+       int port = skge->port;
+
+       netif_stop_queue(skge->netdev);
+       netif_carrier_off(skge->netdev);
+
+       spin_lock_bh(&hw->phy_lock);
+       if (hw->chip_id == CHIP_ID_GENESIS) {
+               genesis_reset(hw, port);
+               genesis_mac_init(hw, port);
+       } else {
+               yukon_reset(hw, port);
+               yukon_init(hw, port);
+       }
+       spin_unlock_bh(&hw->phy_lock);
+}
+
 /* Basic MII support */
 static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -2187,6 +2196,7 @@ static int skge_up(struct net_device *dev)
        kfree(skge->rx_ring.start);
  free_pci_mem:
        pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+       skge->mem = NULL;
 
        return err;
 }
@@ -2197,6 +2207,9 @@ static int skge_down(struct net_device *dev)
        struct skge_hw *hw = skge->hw;
        int port = skge->port;
 
+       if (skge->mem == NULL)
+               return 0;
+
        if (netif_msg_ifdown(skge))
                printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
@@ -2253,6 +2266,7 @@ static int skge_down(struct net_device *dev)
        kfree(skge->rx_ring.start);
        kfree(skge->tx_ring.start);
        pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+       skge->mem = NULL;
        return 0;
 }
 
@@ -2413,18 +2427,23 @@ static void skge_tx_timeout(struct net_device *dev)
 
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
 {
-       int err = 0;
-       int running = netif_running(dev);
+       int err;
 
        if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
                return -EINVAL;
 
+       if (!netif_running(dev)) {
+               dev->mtu = new_mtu;
+               return 0;
+       }
+
+       skge_down(dev);
 
-       if (running)
-               skge_down(dev);
        dev->mtu = new_mtu;
-       if (running)
-               skge_up(dev);
+
+       err = skge_up(dev);
+       if (err)
+               dev_close(dev);
 
        return err;
 }
@@ -3398,8 +3417,8 @@ static int skge_resume(struct pci_dev *pdev)
                struct net_device *dev = hw->dev[i];
                if (dev) {
                        netif_device_attach(dev);
-                       if (netif_running(dev))
-                               skge_up(dev);
+                       if (netif_running(dev) && skge_up(dev))
+                               dev_close(dev);
                }
        }
        return 0;
index ee123c15f5450947f874bcd3b5963ba61f1dc98f..2efdacc290e58962cb8917953e78cb7afd6ca17d 100644 (file)
@@ -475,18 +475,6 @@ enum {
        Q_T2    = 0x40, /* 32 bit       Test Register 2 */
        Q_T3    = 0x44, /* 32 bit       Test Register 3 */
 
-/* Yukon-2 */
-       Q_DONE  = 0x24, /* 16 bit       Done Index              (Yukon-2 only) */
-       Q_WM    = 0x40, /* 16 bit       FIFO Watermark */
-       Q_AL    = 0x42, /*  8 bit       FIFO Alignment */
-       Q_RSP   = 0x44, /* 16 bit       FIFO Read Shadow Pointer */
-       Q_RSL   = 0x46, /*  8 bit       FIFO Read Shadow Level */
-       Q_RP    = 0x48, /*  8 bit       FIFO Read Pointer */
-       Q_RL    = 0x4a, /*  8 bit       FIFO Read Level */
-       Q_WP    = 0x4c, /*  8 bit       FIFO Write Pointer */
-       Q_WSP   = 0x4d, /*  8 bit       FIFO Write Shadow Pointer */
-       Q_WL    = 0x4e, /*  8 bit       FIFO Write Level */
-       Q_WSL   = 0x4f, /*  8 bit       FIFO Write Shadow Level */
 };
 #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
 
@@ -675,22 +663,16 @@ enum {
        LED_OFF = 1<<0, /* switch LED off */
 };
 
-/* Receive GMAC FIFO (YUKON and Yukon-2) */
+/* Receive GMAC FIFO (YUKON) */
 enum {
        RX_GMF_EA       = 0x0c40,/* 32 bit      Rx GMAC FIFO End Address */
        RX_GMF_AF_THR   = 0x0c44,/* 32 bit      Rx GMAC FIFO Almost Full Thresh. */
        RX_GMF_CTRL_T   = 0x0c48,/* 32 bit      Rx GMAC FIFO Control/Test */
        RX_GMF_FL_MSK   = 0x0c4c,/* 32 bit      Rx GMAC FIFO Flush Mask */
        RX_GMF_FL_THR   = 0x0c50,/* 32 bit      Rx GMAC FIFO Flush Threshold */
-       RX_GMF_TR_THR   = 0x0c54,/* 32 bit      Rx Truncation Threshold (Yukon-2) */
-
-       RX_GMF_VLAN     = 0x0c5c,/* 32 bit      Rx VLAN Type Register (Yukon-2) */
        RX_GMF_WP       = 0x0c60,/* 32 bit      Rx GMAC FIFO Write Pointer */
-
        RX_GMF_WLEV     = 0x0c68,/* 32 bit      Rx GMAC FIFO Write Level */
-
        RX_GMF_RP       = 0x0c70,/* 32 bit      Rx GMAC FIFO Read Pointer */
-
        RX_GMF_RLEV     = 0x0c78,/* 32 bit      Rx GMAC FIFO Read Level */
 };
 
@@ -855,48 +837,6 @@ enum {
        GMAC_TI_ST_TST  = 0x0e1a,/*  8 bit      Time Stamp Timer Test Reg */
 };
 
-/* Status BMU Registers (Yukon-2 only)*/
-enum {
-       STAT_CTRL       = 0x0e80,/* 32 bit      Status BMU Control Reg */
-       STAT_LAST_IDX   = 0x0e84,/* 16 bit      Status BMU Last Index */
-       /* 0x0e85 - 0x0e86:     reserved */
-       STAT_LIST_ADDR_LO       = 0x0e88,/* 32 bit      Status List Start Addr (low) */
-       STAT_LIST_ADDR_HI       = 0x0e8c,/* 32 bit      Status List Start Addr (high) */
-       STAT_TXA1_RIDX  = 0x0e90,/* 16 bit      Status TxA1 Report Index Reg */
-       STAT_TXS1_RIDX  = 0x0e92,/* 16 bit      Status TxS1 Report Index Reg */
-       STAT_TXA2_RIDX  = 0x0e94,/* 16 bit      Status TxA2 Report Index Reg */
-       STAT_TXS2_RIDX  = 0x0e96,/* 16 bit      Status TxS2 Report Index Reg */
-       STAT_TX_IDX_TH  = 0x0e98,/* 16 bit      Status Tx Index Threshold Reg */
-       STAT_PUT_IDX    = 0x0e9c,/* 16 bit      Status Put Index Reg */
-
-/* FIFO Control/Status Registers (Yukon-2 only)*/
-       STAT_FIFO_WP    = 0x0ea0,/*  8 bit      Status FIFO Write Pointer Reg */
-       STAT_FIFO_RP    = 0x0ea4,/*  8 bit      Status FIFO Read Pointer Reg */
-       STAT_FIFO_RSP   = 0x0ea6,/*  8 bit      Status FIFO Read Shadow Ptr */
-       STAT_FIFO_LEVEL = 0x0ea8,/*  8 bit      Status FIFO Level Reg */
-       STAT_FIFO_SHLVL = 0x0eaa,/*  8 bit      Status FIFO Shadow Level Reg */
-       STAT_FIFO_WM    = 0x0eac,/*  8 bit      Status FIFO Watermark Reg */
-       STAT_FIFO_ISR_WM        = 0x0ead,/*  8 bit      Status FIFO ISR Watermark Reg */
-
-/* Level and ISR Timer Registers (Yukon-2 only)*/
-       STAT_LEV_TIMER_INI      = 0x0eb0,/* 32 bit      Level Timer Init. Value Reg */
-       STAT_LEV_TIMER_CNT      = 0x0eb4,/* 32 bit      Level Timer Counter Reg */
-       STAT_LEV_TIMER_CTRL     = 0x0eb8,/*  8 bit      Level Timer Control Reg */
-       STAT_LEV_TIMER_TEST     = 0x0eb9,/*  8 bit      Level Timer Test Reg */
-       STAT_TX_TIMER_INI       = 0x0ec0,/* 32 bit      Tx Timer Init. Value Reg */
-       STAT_TX_TIMER_CNT       = 0x0ec4,/* 32 bit      Tx Timer Counter Reg */
-       STAT_TX_TIMER_CTRL      = 0x0ec8,/*  8 bit      Tx Timer Control Reg */
-       STAT_TX_TIMER_TEST      = 0x0ec9,/*  8 bit      Tx Timer Test Reg */
-       STAT_ISR_TIMER_INI      = 0x0ed0,/* 32 bit      ISR Timer Init. Value Reg */
-       STAT_ISR_TIMER_CNT      = 0x0ed4,/* 32 bit      ISR Timer Counter Reg */
-       STAT_ISR_TIMER_CTRL     = 0x0ed8,/*  8 bit      ISR Timer Control Reg */
-       STAT_ISR_TIMER_TEST     = 0x0ed9,/*  8 bit      ISR Timer Test Reg */
-
-       ST_LAST_IDX_MASK        = 0x007f,/* Last Index Mask */
-       ST_TXRP_IDX_MASK        = 0x0fff,/* Tx Report Index Mask */
-       ST_TXTH_IDX_MASK        = 0x0fff,/* Tx Threshold Index Mask */
-       ST_WM_IDX_MASK  = 0x3f,/* FIFO Watermark Index Mask */
-};
 
 enum {
        LINKLED_OFF          = 0x01,
@@ -923,8 +863,6 @@ enum {
        WOL_MATCH_CTL   = 0x0f22,/*  8 bit      WOL Match Control Reg */
        WOL_MATCH_RES   = 0x0f23,/*  8 bit      WOL Match Result Reg */
        WOL_MAC_ADDR    = 0x0f24,/* 32 bit      WOL MAC Address */
-       WOL_PATT_PME    = 0x0f2a,/*  8 bit      WOL PME Match Enable (Yukon-2) */
-       WOL_PATT_ASFM   = 0x0f2b,/*  8 bit      WOL ASF Match Enable (Yukon-2) */
        WOL_PATT_RPTR   = 0x0f2c,/*  8 bit      WOL Pattern Read Pointer */
 
 /* WOL Pattern Length Registers (YUKON only) */
@@ -1641,15 +1579,6 @@ enum {
        PHY_M_FESC_SEL_CL_A     = 1<<0, /* Select Class A driver (100B-TX) */
 };
 
-/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
-/*****  PHY_MARV_PHY_CTRL (page 2)             16 bit r/w      MAC Specific Ctrl *****/
-enum {
-       PHY_M_MAC_MD_MSK        = 7<<7, /* Bit  9.. 7: Mode Select Mask */
-       PHY_M_MAC_MD_AUTO       = 3,/* Auto Copper/1000Base-X */
-       PHY_M_MAC_MD_COPPER     = 5,/* Copper only */
-       PHY_M_MAC_MD_1000BX     = 7,/* 1000Base-X only */
-};
-#define PHY_M_MAC_MODE_SEL(x)  (((x)<<7) & PHY_M_MAC_MD_MSK)
 
 /*****  PHY_MARV_PHY_CTRL (page 3)             16 bit r/w      LED Control Reg. *****/
 enum {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
new file mode 100644 (file)
index 0000000..f5d697c
--- /dev/null
@@ -0,0 +1,3262 @@
+/*
+ * New driver for Marvell Yukon 2 chipset.
+ * Based on earlier sk98lin, and skge driver.
+ *
+ * This driver intentionally does not support all the features
+ * of the original driver such as link fail-over and link management because
+ * those should be done at higher levels.
+ *
+ * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * TOTEST
+ *     - speed setting
+ *     - suspend/resume
+ */
+
+#include <linux/config.h>
+#include <linux/crc32.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/if_vlan.h>
+#include <linux/prefetch.h>
+#include <linux/mii.h>
+
+#include <asm/irq.h>
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define SKY2_VLAN_TAG_USED 1
+#endif
+
+#include "sky2.h"
+
+#define DRV_NAME               "sky2"
+#define DRV_VERSION            "0.11"
+#define PFX                    DRV_NAME " "
+
+/*
+ * The Yukon II chipset takes 64 bit command blocks (called list elements)
+ * that are organized into three (receive, transmit, status) different rings
+ * similar to Tigon3. A transmit can require several elements;
+ * a receive requires one (or two if using 64 bit dma).
+ */
+
+#define is_ec_a1(hw) \
+       unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \
+                (hw)->chip_rev == CHIP_REV_YU_EC_A1)
+
+#define RX_LE_SIZE             512
+#define RX_LE_BYTES            (RX_LE_SIZE*sizeof(struct sky2_rx_le))
+#define RX_MAX_PENDING         (RX_LE_SIZE/2 - 2)
+#define RX_DEF_PENDING         RX_MAX_PENDING
+
+#define TX_RING_SIZE           512
+#define TX_DEF_PENDING         (TX_RING_SIZE - 1)
+#define TX_MIN_PENDING         64
+#define MAX_SKB_TX_LE          (4 + 2*MAX_SKB_FRAGS)
+
+#define STATUS_RING_SIZE       2048    /* 2 ports * (TX + 2*RX) */
+#define STATUS_LE_BYTES                (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
+#define ETH_JUMBO_MTU          9000
+#define TX_WATCHDOG            (5 * HZ)
+#define NAPI_WEIGHT            64
+#define PHY_RETRIES            1000
+
+static const u32 default_msg =
+    NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
+    | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
+    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_INTR;
+
+static int debug = -1;         /* defaults above */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+static int copybreak __read_mostly = 256;
+module_param(copybreak, int, 0);
+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+
+static const struct pci_device_id sky2_id_table[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
+       { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, sky2_id_table);
+
+/* Avoid conditionals by using array */
+static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
+static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
+
+/* This driver supports yukon2 chipset only */
+static const char *yukon2_name[] = {
+       "XL",           /* 0xb3 */
+       "EC Ultra",     /* 0xb4 */
+       "UNKNOWN",      /* 0xb5 */
+       "EC",           /* 0xb6 */
+       "FE",           /* 0xb7 */
+};
+
+/* Access to external PHY */
+static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
+{
+       int i;
+
+       gma_write16(hw, port, GM_SMI_DATA, val);
+       gma_write16(hw, port, GM_SMI_CTRL,
+                   GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
+
+       for (i = 0; i < PHY_RETRIES; i++) {
+               if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+                       return 0;
+               udelay(1);
+       }
+
+       printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name);
+       return -ETIMEDOUT;
+}
+
+static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
+{
+       int i;
+
+       gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
+                   | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
+
+       for (i = 0; i < PHY_RETRIES; i++) {
+               if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) {
+                       *val = gma_read16(hw, port, GM_SMI_DATA);
+                       return 0;
+               }
+
+               udelay(1);
+       }
+
+       return -ETIMEDOUT;
+}
+
+static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
+{
+       u16 v;
+
+       if (__gm_phy_read(hw, port, reg, &v) != 0)
+               printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
+       return v;
+}
+
+static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
+{
+       u16 power_control;
+       u32 reg1;
+       int vaux;
+       int ret = 0;
+
+       pr_debug("sky2_set_power_state %d\n", state);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+       pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control);
+       vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+               (power_control & PCI_PM_CAP_PME_D3cold);
+
+       pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control);
+
+       power_control |= PCI_PM_CTRL_PME_STATUS;
+       power_control &= ~(PCI_PM_CTRL_STATE_MASK);
+
+       switch (state) {
+       case PCI_D0:
+               /* switch power to VCC (WA for VAUX problem) */
+               sky2_write8(hw, B0_POWER_CTRL,
+                           PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
+
+               /* disable Core Clock Division, */
+               sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
+
+               if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+                       /* enable bits are inverted */
+                       sky2_write8(hw, B2_Y2_CLK_GATE,
+                                   Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+                                   Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+                                   Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+               else
+                       sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+
+               /* Turn off phy power saving */
+               pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
+               reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+
+               /* looks like this XL is back asswards .. */
+               if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) {
+                       reg1 |= PCI_Y2_PHY1_COMA;
+                       if (hw->ports > 1)
+                               reg1 |= PCI_Y2_PHY2_COMA;
+               }
+               pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
+               break;
+
+       case PCI_D3hot:
+       case PCI_D3cold:
+               /* Turn on phy power saving */
+               pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
+               if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+                       reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+               else
+                       reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+               pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
+
+               if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+                       sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+               else
+                       /* enable bits are inverted */
+                       sky2_write8(hw, B2_Y2_CLK_GATE,
+                                   Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+                                   Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+                                   Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+
+               /* switch power to VAUX */
+               if (vaux && state != PCI_D3cold)
+                       sky2_write8(hw, B0_POWER_CTRL,
+                                   (PC_VAUX_ENA | PC_VCC_ENA |
+                                    PC_VAUX_ON | PC_VCC_OFF));
+               break;
+       default:
+               printk(KERN_ERR PFX "Unknown power state %d\n", state);
+               ret = -1;
+       }
+
+       pci_write_config_byte(hw->pdev, hw->pm_cap + PCI_PM_CTRL, power_control);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+       return ret;
+}
+
+static void sky2_phy_reset(struct sky2_hw *hw, unsigned port)
+{
+       u16 reg;
+
+       /* disable all GMAC IRQ's */
+       sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+       /* disable PHY IRQs */
+       gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+
+       gma_write16(hw, port, GM_MC_ADDR_H1, 0);        /* clear MC hash */
+       gma_write16(hw, port, GM_MC_ADDR_H2, 0);
+       gma_write16(hw, port, GM_MC_ADDR_H3, 0);
+       gma_write16(hw, port, GM_MC_ADDR_H4, 0);
+
+       reg = gma_read16(hw, port, GM_RX_CTRL);
+       reg |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
+       gma_write16(hw, port, GM_RX_CTRL, reg);
+}
+
+static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
+{
+       struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+       u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
+
+       if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) {
+               u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+
+               ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+                          PHY_M_EC_MAC_S_MSK);
+               ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
+
+               if (hw->chip_id == CHIP_ID_YUKON_EC)
+                       ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
+               else
+                       ectrl |= PHY_M_EC_M_DSC(2) | PHY_M_EC_S_DSC(3);
+
+               gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
+       }
+
+       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+       if (hw->copper) {
+               if (hw->chip_id == CHIP_ID_YUKON_FE) {
+                       /* enable automatic crossover */
+                       ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
+               } else {
+                       /* disable energy detect */
+                       ctrl &= ~PHY_M_PC_EN_DET_MSK;
+
+                       /* enable automatic crossover */
+                       ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
+
+                       if (sky2->autoneg == AUTONEG_ENABLE &&
+                           hw->chip_id == CHIP_ID_YUKON_XL) {
+                               ctrl &= ~PHY_M_PC_DSC_MSK;
+                               ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
+                       }
+               }
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+       } else {
+               /* workaround for deviation #4.88 (CRC errors) */
+               /* disable Automatic Crossover */
+
+               ctrl &= ~PHY_M_PC_MDIX_MSK;
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+               if (hw->chip_id == CHIP_ID_YUKON_XL) {
+                       /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
+                       gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+                       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+                       ctrl &= ~PHY_M_MAC_MD_MSK;
+                       ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+                       /* select page 1 to access Fiber registers */
+                       gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
+               }
+       }
+
+       ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+       if (sky2->autoneg == AUTONEG_DISABLE)
+               ctrl &= ~PHY_CT_ANE;
+       else
+               ctrl |= PHY_CT_ANE;
+
+       ctrl |= PHY_CT_RESET;
+       gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+       ctrl = 0;
+       ct1000 = 0;
+       adv = PHY_AN_CSMA;
+
+       if (sky2->autoneg == AUTONEG_ENABLE) {
+               if (hw->copper) {
+                       if (sky2->advertising & ADVERTISED_1000baseT_Full)
+                               ct1000 |= PHY_M_1000C_AFD;
+                       if (sky2->advertising & ADVERTISED_1000baseT_Half)
+                               ct1000 |= PHY_M_1000C_AHD;
+                       if (sky2->advertising & ADVERTISED_100baseT_Full)
+                               adv |= PHY_M_AN_100_FD;
+                       if (sky2->advertising & ADVERTISED_100baseT_Half)
+                               adv |= PHY_M_AN_100_HD;
+                       if (sky2->advertising & ADVERTISED_10baseT_Full)
+                               adv |= PHY_M_AN_10_FD;
+                       if (sky2->advertising & ADVERTISED_10baseT_Half)
+                               adv |= PHY_M_AN_10_HD;
+               } else          /* special defines for FIBER (88E1011S only) */
+                       adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
+
+               /* Set Flow-control capabilities */
+               if (sky2->tx_pause && sky2->rx_pause)
+                       adv |= PHY_AN_PAUSE_CAP;        /* symmetric */
+               else if (sky2->rx_pause && !sky2->tx_pause)
+                       adv |= PHY_AN_PAUSE_ASYM | PHY_AN_PAUSE_CAP;
+               else if (!sky2->rx_pause && sky2->tx_pause)
+                       adv |= PHY_AN_PAUSE_ASYM;       /* local */
+
+               /* Restart Auto-negotiation */
+               ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+       } else {
+               /* forced speed/duplex settings */
+               ct1000 = PHY_M_1000C_MSE;
+
+               if (sky2->duplex == DUPLEX_FULL)
+                       ctrl |= PHY_CT_DUP_MD;
+
+               switch (sky2->speed) {
+               case SPEED_1000:
+                       ctrl |= PHY_CT_SP1000;
+                       break;
+               case SPEED_100:
+                       ctrl |= PHY_CT_SP100;
+                       break;
+               }
+
+               ctrl |= PHY_CT_RESET;
+       }
+
+       if (hw->chip_id != CHIP_ID_YUKON_FE)
+               gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+
+       gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
+       gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+       /* Setup Phy LED's */
+       ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
+       ledover = 0;
+
+       switch (hw->chip_id) {
+       case CHIP_ID_YUKON_FE:
+               /* on 88E3082 these bits are at 11..9 (shifted left) */
+               ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
+
+               ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);
+
+               /* delete ACT LED control bits */
+               ctrl &= ~PHY_M_FELP_LED1_MSK;
+               /* change ACT LED control to blink mode */
+               ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
+               gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
+               break;
+
+       case CHIP_ID_YUKON_XL:
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+               /* select page 3 to access LED control register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+
+               /* set LED Function Control register */
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) |     /* LINK/ACT */
+                                                          PHY_M_LEDC_INIT_CTRL(7) |    /* 10 Mbps */
+                                                          PHY_M_LEDC_STA1_CTRL(7) |    /* 100 Mbps */
+                                                          PHY_M_LEDC_STA0_CTRL(7)));   /* 1000 Mbps */
+
+               /* set Polarity Control register */
+               gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
+                            (PHY_M_POLC_LS1_P_MIX(4) |
+                             PHY_M_POLC_IS0_P_MIX(4) |
+                             PHY_M_POLC_LOS_CTRL(2) |
+                             PHY_M_POLC_INIT_CTRL(2) |
+                             PHY_M_POLC_STA1_CTRL(2) |
+                             PHY_M_POLC_STA0_CTRL(2)));
+
+               /* restore page register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+               break;
+
+       default:
+               /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
+               ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+               /* turn off the Rx LED (LED_RX) */
+               ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
+       }
+
+       gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+
+       if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
+               /* turn on 100 Mbps LED (LED_LINK100) */
+               ledover |= PHY_M_LED_MO_100(MO_LED_ON);
+       }
+
+       if (ledover)
+               gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+
+       /* Enable phy interrupt on auto-negotiation complete (or link up) */
+       if (sky2->autoneg == AUTONEG_ENABLE)
+               gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
+       else
+               gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+}
+
+/* Force a renegotiation */
+static void sky2_phy_reinit(struct sky2_port *sky2)
+{
+       down(&sky2->phy_sema);
+       sky2_phy_init(sky2->hw, sky2->port);
+       up(&sky2->phy_sema);
+}
+
+static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
+{
+       struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+       u16 reg;
+       int i;
+       const u8 *addr = hw->dev[port]->dev_addr;
+
+       sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+       sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
+
+       sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+
+       if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && port == 1) {
+               /* WA DEV_472 -- looks like crossed wires on port 2 */
+               /* clear GMAC 1 Control reset */
+               sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
+               do {
+                       sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
+                       sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
+               } while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
+                        gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
+                        gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
+       }
+
+       if (sky2->autoneg == AUTONEG_DISABLE) {
+               reg = gma_read16(hw, port, GM_GP_CTRL);
+               reg |= GM_GPCR_AU_ALL_DIS;
+               gma_write16(hw, port, GM_GP_CTRL, reg);
+               gma_read16(hw, port, GM_GP_CTRL);
+
+               switch (sky2->speed) {
+               case SPEED_1000:
+                       reg |= GM_GPCR_SPEED_1000;
+                       /* fallthru */
+               case SPEED_100:
+                       reg |= GM_GPCR_SPEED_100;
+               }
+
+               if (sky2->duplex == DUPLEX_FULL)
+                       reg |= GM_GPCR_DUP_FULL;
+       } else
+               reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
+
+       if (!sky2->tx_pause && !sky2->rx_pause) {
+               sky2_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+               reg |=
+                   GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+       } else if (sky2->tx_pause && !sky2->rx_pause) {
+               /* disable Rx flow-control */
+               reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+       }
+
+       gma_write16(hw, port, GM_GP_CTRL, reg);
+
+       sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
+
+       down(&sky2->phy_sema);
+       sky2_phy_init(hw, port);
+       up(&sky2->phy_sema);
+
+       /* MIB clear */
+       reg = gma_read16(hw, port, GM_PHY_ADDR);
+       gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+
+       for (i = 0; i < GM_MIB_CNT_SIZE; i++)
+               gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i);
+       gma_write16(hw, port, GM_PHY_ADDR, reg);
+
+       /* transmit control */
+       gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
+
+       /* receive control reg: unicast + multicast + no FCS  */
+       gma_write16(hw, port, GM_RX_CTRL,
+                   GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
+
+       /* transmit flow control */
+       gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
+
+       /* transmit parameter */
+       gma_write16(hw, port, GM_TX_PARAM,
+                   TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
+                   TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
+                   TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
+                   TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));
+
+       /* serial mode register */
+       reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
+               GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+
+       if (hw->dev[port]->mtu > ETH_DATA_LEN)
+               reg |= GM_SMOD_JUMBO_ENA;
+
+       gma_write16(hw, port, GM_SERIAL_MODE, reg);
+
+       /* virtual address for data */
+       gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
+
+       /* physical address: used for pause frames */
+       gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
+
+       /* ignore counter overflows */
+       gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
+       gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
+       gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
+
+       /* Configure Rx MAC FIFO */
+       sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
+       sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T),
+                    GMF_RX_CTRL_DEF);
+
+       /* Flush Rx MAC FIFO on any flow control or error */
+       sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
+
+       /* Set threshold to 0xa (64 bytes)
+        *  ASF disabled so no need to do WA dev #4.30
+        */
+       sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+
+       /* Configure Tx MAC FIFO */
+       sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
+       sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+               sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
+               sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
+               if (hw->dev[port]->mtu > ETH_DATA_LEN) {
+                       /* set Tx GMAC FIFO Almost Empty Threshold */
+                       sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), 0x180);
+                       /* Disable Store & Forward mode for TX */
+                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
+               }
+       }
+
+}
+
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len)
+{
+       u32 end;
+
+       start /= 8;
+       len /= 8;
+       end = start + len - 1;
+
+       sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
+       sky2_write32(hw, RB_ADDR(q, RB_START), start);
+       sky2_write32(hw, RB_ADDR(q, RB_END), end);
+       sky2_write32(hw, RB_ADDR(q, RB_WP), start);
+       sky2_write32(hw, RB_ADDR(q, RB_RP), start);
+
+       if (q == Q_R1 || q == Q_R2) {
+               u32 rxup, rxlo;
+
+               rxlo = len/2;
+               rxup = rxlo + len/4;
+
+               /* Set thresholds on receive queue's */
+               sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup);
+               sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), rxlo);
+       } else {
+               /* Enable store & forward on Tx queue's because
+                * Tx FIFO is only 1K on Yukon
+                */
+               sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
+       }
+
+       sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
+       sky2_read8(hw, RB_ADDR(q, RB_CTRL));
+}
+
+/* Setup Bus Memory Interface */
+static void sky2_qset(struct sky2_hw *hw, u16 q)
+{
+       sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
+       sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
+       sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
+       sky2_write32(hw, Q_ADDR(q, Q_WM),  BMU_WM_DEFAULT);
+}
+
+/* Setup prefetch unit registers. This is the interface between
+ * hardware and driver list elements
+ */
+static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
+                                     u64 addr, u32 last)
+{
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), addr >> 32);
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32) addr);
+       sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
+
+       sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
+}
+
+static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
+{
+       struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
+
+       sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE;
+       return le;
+}
+
+/*
+ * This is a workaround code taken from SysKonnect sk98lin driver
+ * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
+ */
+static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q,
+                               u16 idx, u16 *last, u16 size)
+{
+       if (is_ec_a1(hw) && idx < *last) {
+               u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
+
+               if (hwget == 0) {
+                       /* Start prefetching again */
+                       sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0);
+                       goto setnew;
+               }
+
+               if (hwget == size - 1) {
+                       /* set watermark to one list element */
+                       sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8);
+
+                       /* set put index to first list element */
+                       sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0);
+               } else          /* have hardware go to end of list */
+                       sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX),
+                                    size - 1);
+       } else {
+setnew:
+               sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
+       }
+       *last = idx;
+}
+
+
+static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
+{
+       struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
+       sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE;
+       return le;
+}
+
+/* Return high part of DMA address (could be 32 or 64 bit) */
+static inline u32 high32(dma_addr_t a)
+{
+       return (a >> 16) >> 16;
+}
+
+/* Build description to hardware about buffer */
+static inline void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+{
+       struct sky2_rx_le *le;
+       u32 hi = high32(map);
+       u16 len = sky2->rx_bufsize;
+
+       if (sky2->rx_addr64 != hi) {
+               le = sky2_next_rx(sky2);
+               le->addr = cpu_to_le32(hi);
+               le->ctrl = 0;
+               le->opcode = OP_ADDR64 | HW_OWNER;
+               sky2->rx_addr64 = high32(map + len);
+       }
+
+       le = sky2_next_rx(sky2);
+       le->addr = cpu_to_le32((u32) map);
+       le->length = cpu_to_le16(len);
+       le->ctrl = 0;
+       le->opcode = OP_PACKET | HW_OWNER;
+}
+
+
+/* Tell chip where to start receive checksum.
+ * Actually has two checksums, but set both same to avoid possible byte
+ * order problems.
+ */
+static void rx_set_checksum(struct sky2_port *sky2)
+{
+       struct sky2_rx_le *le;
+
+       le = sky2_next_rx(sky2);
+       le->addr = (ETH_HLEN << 16) | ETH_HLEN;
+       le->ctrl = 0;
+       le->opcode = OP_TCPSTART | HW_OWNER;
+
+       sky2_write32(sky2->hw,
+                    Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                    sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+
+}
+
+/*
+ * The RX Stop command will not work for Yukon-2 if the BMU does not
+ * reach the end of packet and since we can't make sure that we have
+ * incoming data, we must reset the BMU while it is not doing a DMA
+ * transfer. Since it is possible that the RX path is still active,
+ * the RX RAM buffer will be stopped first, so any possible incoming
+ * data will not trigger a DMA. After the RAM buffer is stopped, the
+ * BMU is polled until any DMA in progress is ended and only then it
+ * will be reset.
+ */
+static void sky2_rx_stop(struct sky2_port *sky2)
+{
+       struct sky2_hw *hw = sky2->hw;
+       unsigned rxq = rxqaddr[sky2->port];
+       int i;
+
+       /* disable the RAM Buffer receive queue */
+       sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);
+
+       for (i = 0; i < 0xffff; i++)
+               if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
+                   == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
+                       goto stopped;
+
+       printk(KERN_WARNING PFX "%s: receiver stop failed\n",
+              sky2->netdev->name);
+stopped:
+       sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
+
+       /* reset the Rx prefetch unit */
+       sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+}
+
+/* Clean out receive buffer area, assumes receiver hardware stopped */
+static void sky2_rx_clean(struct sky2_port *sky2)
+{
+       unsigned i;
+
+       memset(sky2->rx_le, 0, RX_LE_BYTES);
+       for (i = 0; i < sky2->rx_pending; i++) {
+               struct ring_info *re = sky2->rx_ring + i;
+
+               if (re->skb) {
+                       pci_unmap_single(sky2->hw->pdev,
+                                        re->mapaddr, sky2->rx_bufsize,
+                                        PCI_DMA_FROMDEVICE);
+                       kfree_skb(re->skb);
+                       re->skb = NULL;
+               }
+       }
+}
+
+/* Basic MII support */
+static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+       struct mii_ioctl_data *data = if_mii(ifr);
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       int err = -EOPNOTSUPP;
+
+       if (!netif_running(dev))
+               return -ENODEV; /* Phy still in reset */
+
+       switch(cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = PHY_ADDR_MARV;
+
+               /* fallthru */
+       case SIOCGMIIREG: {
+               u16 val = 0;
+
+               down(&sky2->phy_sema);
+               err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
+               up(&sky2->phy_sema);
+
+               data->val_out = val;
+               break;
+       }
+
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+
+               down(&sky2->phy_sema);
+               err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
+                                  data->val_in);
+               up(&sky2->phy_sema);
+               break;
+       }
+       return err;
+}
+
+#ifdef SKY2_VLAN_TAG_USED
+static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       u16 port = sky2->port;
+
+       spin_lock(&sky2->tx_lock);
+
+       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
+       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
+       sky2->vlgrp = grp;
+
+       spin_unlock(&sky2->tx_lock);
+}
+
+static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       u16 port = sky2->port;
+
+       spin_lock(&sky2->tx_lock);
+
+       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
+       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
+       if (sky2->vlgrp)
+               sky2->vlgrp->vlan_devices[vid] = NULL;
+
+       spin_unlock(&sky2->tx_lock);
+}
+#endif
+
+/*
+ * Allocate and setup receiver buffer pool.
+ * In case of 64 bit dma, there are 2X as many list elements
+ * available as ring entries
+ * and need to reserve one list element so we don't wrap around.
+ *
+ * It appears the hardware has a bug in the FIFO logic that
+ * cause it to hang if the FIFO gets overrun and the receive buffer
+ * is not aligned.  This means we can't use skb_reserve to align
+ * the IP header.
+ */
+static int sky2_rx_start(struct sky2_port *sky2)
+{
+       struct sky2_hw *hw = sky2->hw;
+       unsigned rxq = rxqaddr[sky2->port];
+       int i;
+
+       sky2->rx_put = sky2->rx_next = 0;
+       sky2_qset(hw, rxq);
+       sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
+
+       rx_set_checksum(sky2);
+       for (i = 0; i < sky2->rx_pending; i++) {
+               struct ring_info *re = sky2->rx_ring + i;
+
+               re->skb = dev_alloc_skb(sky2->rx_bufsize);
+               if (!re->skb)
+                       goto nomem;
+
+               re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
+                                            sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+               sky2_rx_add(sky2, re->mapaddr);
+       }
+
+       /* Tell chip about available buffers */
+       sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
+       sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
+       return 0;
+nomem:
+       sky2_rx_clean(sky2);
+       return -ENOMEM;
+}
+
+/* Bring up network interface. */
+static int sky2_up(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u32 ramsize, rxspace;
+       int err = -ENOMEM;
+
+       if (netif_msg_ifup(sky2))
+               printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+
+       /* must be power of 2 */
+       sky2->tx_le = pci_alloc_consistent(hw->pdev,
+                                          TX_RING_SIZE *
+                                          sizeof(struct sky2_tx_le),
+                                          &sky2->tx_le_map);
+       if (!sky2->tx_le)
+               goto err_out;
+
+       sky2->tx_ring = kcalloc(TX_RING_SIZE, sizeof(struct tx_ring_info),
+                               GFP_KERNEL);
+       if (!sky2->tx_ring)
+               goto err_out;
+       sky2->tx_prod = sky2->tx_cons = 0;
+
+       sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+                                          &sky2->rx_le_map);
+       if (!sky2->rx_le)
+               goto err_out;
+       memset(sky2->rx_le, 0, RX_LE_BYTES);
+
+       sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
+                               GFP_KERNEL);
+       if (!sky2->rx_ring)
+               goto err_out;
+
+       sky2_mac_init(hw, port);
+
+       /* Configure RAM buffers */
+       if (hw->chip_id == CHIP_ID_YUKON_FE ||
+           (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == 2))
+               ramsize = 4096;
+       else {
+               u8 e0 = sky2_read8(hw, B2_E_0);
+               ramsize = (e0 == 0) ? (128 * 1024) : (e0 * 4096);
+       }
+
+       /* 2/3 for Rx */
+       rxspace = (2 * ramsize) / 3;
+       sky2_ramset(hw, rxqaddr[port], 0, rxspace);
+       sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
+
+       /* Make sure SyncQ is disabled */
+       sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
+                   RB_RST_SET);
+
+       sky2_qset(hw, txqaddr[port]);
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U)
+               sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
+
+
+       sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
+                          TX_RING_SIZE - 1);
+
+       err = sky2_rx_start(sky2);
+       if (err)
+               goto err_out;
+
+       /* Enable interrupts from phy/mac for port */
+       hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
+       sky2_write32(hw, B0_IMSK, hw->intr_mask);
+       return 0;
+
+err_out:
+       if (sky2->rx_le) {
+               pci_free_consistent(hw->pdev, RX_LE_BYTES,
+                                   sky2->rx_le, sky2->rx_le_map);
+               sky2->rx_le = NULL;
+       }
+       if (sky2->tx_le) {
+               pci_free_consistent(hw->pdev,
+                                   TX_RING_SIZE * sizeof(struct sky2_tx_le),
+                                   sky2->tx_le, sky2->tx_le_map);
+               sky2->tx_le = NULL;
+       }
+       kfree(sky2->tx_ring);
+       kfree(sky2->rx_ring);
+
+       sky2->tx_ring = NULL;
+       sky2->rx_ring = NULL;
+       return err;
+}
+
+/* Modular subtraction in ring */
+static inline int tx_dist(unsigned tail, unsigned head)
+{
+       return (head - tail) % TX_RING_SIZE;
+}
+
+/* Number of list elements available for next tx */
+static inline int tx_avail(const struct sky2_port *sky2)
+{
+       return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod);
+}
+
+/* Estimate of number of transmit list elements required */
+static inline unsigned tx_le_req(const struct sk_buff *skb)
+{
+       unsigned count;
+
+       count = sizeof(dma_addr_t) / sizeof(u32);
+       count += skb_shinfo(skb)->nr_frags * count;
+
+       if (skb_shinfo(skb)->tso_size)
+               ++count;
+
+       if (skb->ip_summed == CHECKSUM_HW)
+               ++count;
+
+       return count;
+}
+
+/*
+ * Put one packet in ring for transmit.
+ * A single packet can generate multiple list elements, and
+ * the number of ring elements will probably be less than the number
+ * of list elements used.
+ *
+ * No BH disabling for tx_lock here (like tg3)
+ */
+static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       struct sky2_tx_le *le = NULL;
+       struct tx_ring_info *re;
+       unsigned i, len;
+       dma_addr_t mapping;
+       u32 addr64;
+       u16 mss;
+       u8 ctrl;
+
+       if (!spin_trylock(&sky2->tx_lock))
+               return NETDEV_TX_LOCKED;
+
+       if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
+               /* There is a known but harmless race with lockless tx
+                * and netif_stop_queue.
+                */
+               if (!netif_queue_stopped(dev)) {
+                       netif_stop_queue(dev);
+                       printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+                              dev->name);
+               }
+               spin_unlock(&sky2->tx_lock);
+
+               return NETDEV_TX_BUSY;
+       }
+
+       if (unlikely(netif_msg_tx_queued(sky2)))
+               printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
+                      dev->name, sky2->tx_prod, skb->len);
+
+       len = skb_headlen(skb);
+       mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+       addr64 = high32(mapping);
+
+       re = sky2->tx_ring + sky2->tx_prod;
+
+       /* Send high bits if changed or crosses boundary */
+       if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
+               le = get_tx_le(sky2);
+               le->tx.addr = cpu_to_le32(addr64);
+               le->ctrl = 0;
+               le->opcode = OP_ADDR64 | HW_OWNER;
+               sky2->tx_addr64 = high32(mapping + len);
+       }
+
+       /* Check for TCP Segmentation Offload */
+       mss = skb_shinfo(skb)->tso_size;
+       if (mss != 0) {
+               /* just drop the packet if non-linear expansion fails */
+               if (skb_header_cloned(skb) &&
+                   pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
+                       dev_kfree_skb_any(skb);
+                       goto out_unlock;
+               }
+
+               mss += ((skb->h.th->doff - 5) * 4);     /* TCP options */
+               mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr);
+               mss += ETH_HLEN;
+       }
+
+       if (mss != sky2->tx_last_mss) {
+               le = get_tx_le(sky2);
+               le->tx.tso.size = cpu_to_le16(mss);
+               le->tx.tso.rsvd = 0;
+               le->opcode = OP_LRGLEN | HW_OWNER;
+               le->ctrl = 0;
+               sky2->tx_last_mss = mss;
+       }
+
+       ctrl = 0;
+#ifdef SKY2_VLAN_TAG_USED
+       /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
+       if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
+               if (!le) {
+                       le = get_tx_le(sky2);
+                       le->tx.addr = 0;
+                       le->opcode = OP_VLAN|HW_OWNER;
+                       le->ctrl = 0;
+               } else
+                       le->opcode |= OP_VLAN;
+               le->length = cpu_to_be16(vlan_tx_tag_get(skb));
+               ctrl |= INS_VLAN;
+       }
+#endif
+
+       /* Handle TCP checksum offload */
+       if (skb->ip_summed == CHECKSUM_HW) {
+               u16 hdr = skb->h.raw - skb->data;
+               u16 offset = hdr + skb->csum;
+
+               ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+               if (skb->nh.iph->protocol == IPPROTO_UDP)
+                       ctrl |= UDPTCP;
+
+               le = get_tx_le(sky2);
+               le->tx.csum.start = cpu_to_le16(hdr);
+               le->tx.csum.offset = cpu_to_le16(offset);
+               le->length = 0; /* initial checksum value */
+               le->ctrl = 1;   /* one packet */
+               le->opcode = OP_TCPLISW | HW_OWNER;
+       }
+
+       le = get_tx_le(sky2);
+       le->tx.addr = cpu_to_le32((u32) mapping);
+       le->length = cpu_to_le16(len);
+       le->ctrl = ctrl;
+       le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
+
+       /* Record the transmit mapping info */
+       re->skb = skb;
+       pci_unmap_addr_set(re, mapaddr, mapping);
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               struct tx_ring_info *fre;
+
+               mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
+                                      frag->size, PCI_DMA_TODEVICE);
+               addr64 = (mapping >> 16) >> 16;
+               if (addr64 != sky2->tx_addr64) {
+                       le = get_tx_le(sky2);
+                       le->tx.addr = cpu_to_le32(addr64);
+                       le->ctrl = 0;
+                       le->opcode = OP_ADDR64 | HW_OWNER;
+                       sky2->tx_addr64 = addr64;
+               }
+
+               le = get_tx_le(sky2);
+               le->tx.addr = cpu_to_le32((u32) mapping);
+               le->length = cpu_to_le16(frag->size);
+               le->ctrl = ctrl;
+               le->opcode = OP_BUFFER | HW_OWNER;
+
+               fre = sky2->tx_ring
+                   + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE;
+               pci_unmap_addr_set(fre, mapaddr, mapping);
+       }
+
+       re->idx = sky2->tx_prod;
+       le->ctrl |= EOP;
+
+       sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
+                    &sky2->tx_last_put, TX_RING_SIZE);
+
+       if (tx_avail(sky2) <= MAX_SKB_TX_LE)
+               netif_stop_queue(dev);
+
+out_unlock:
+       mmiowb();
+       spin_unlock(&sky2->tx_lock);
+
+       dev->trans_start = jiffies;
+       return NETDEV_TX_OK;
+}
+
+/*
+ * Free ring elements from starting at tx_cons until "done"
+ *
+ * NB: the hardware will tell us about partial completion of multi-part
+ *     buffers; these are deferred until completion.
+ */
+static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+{
+       struct net_device *dev = sky2->netdev;
+       struct pci_dev *pdev = sky2->hw->pdev;
+       u16 nxt, put;
+       unsigned i;
+
+       BUG_ON(done >= TX_RING_SIZE);
+
+       if (unlikely(netif_msg_tx_done(sky2)))
+               printk(KERN_DEBUG "%s: tx done, up to %u\n",
+                      dev->name, done);
+
+       for (put = sky2->tx_cons; put != done; put = nxt) {
+               struct tx_ring_info *re = sky2->tx_ring + put;
+               struct sk_buff *skb = re->skb;
+
+               nxt = re->idx;
+               BUG_ON(nxt >= TX_RING_SIZE);
+               prefetch(sky2->tx_ring + nxt);
+
+               /* Check for partial status */
+               if (tx_dist(put, done) < tx_dist(put, nxt))
+                       break;
+
+               skb = re->skb;
+               pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
+                                skb_headlen(skb), PCI_DMA_TODEVICE);
+
+               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+                       struct tx_ring_info *fre;
+                       fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE;
+                       pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
+                                      skb_shinfo(skb)->frags[i].size,
+                                      PCI_DMA_TODEVICE);
+               }
+
+               dev_kfree_skb_any(skb);
+       }
+
+       spin_lock(&sky2->tx_lock);
+       sky2->tx_cons = put;
+       if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE)
+               netif_wake_queue(dev);
+       spin_unlock(&sky2->tx_lock);
+}
+
+/* Cleanup all untransmitted buffers, assume transmitter not running */
+static void sky2_tx_clean(struct sky2_port *sky2)
+{
+       sky2_tx_complete(sky2, sky2->tx_prod);
+}
+
+/* Network shutdown */
+static int sky2_down(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 ctrl;
+
+       /* Never really got started! */
+       if (!sky2->tx_le)
+               return 0;
+
+       if (netif_msg_ifdown(sky2))
+               printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
+
+       /* Stop more packets from being queued */
+       netif_stop_queue(dev);
+
+       /* Disable port IRQ */
+       local_irq_disable();
+       hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
+       sky2_write32(hw, B0_IMSK, hw->intr_mask);
+       local_irq_enable();
+
+       flush_scheduled_work();
+
+       sky2_phy_reset(hw, port);
+
+       /* Stop transmitter */
+       sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
+       sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));
+
+       sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
+                    RB_RST_SET | RB_DIS_OP_MD);
+
+       ctrl = gma_read16(hw, port, GM_GP_CTRL);
+       ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
+       gma_write16(hw, port, GM_GP_CTRL, ctrl);
+
+       sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+
+       /* Workaround shared GMAC reset */
+       if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
+             && port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
+               sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+
+       /* Disable Force Sync bit and Enable Alloc bit */
+       sky2_write8(hw, SK_REG(port, TXA_CTRL),
+                   TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+
+       /* Stop Interval Timer and Limit Counter of Tx Arbiter */
+       sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
+       sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
+
+       /* Reset the PCI FIFO of the async Tx queue */
+       sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
+                    BMU_RST_SET | BMU_FIFO_RST);
+
+       /* Reset the Tx prefetch units */
+       sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
+                    PREF_UNIT_RST_SET);
+
+       sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
+
+       sky2_rx_stop(sky2);
+
+       sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+       sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+
+       /* turn off LED's */
+       sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+
+       synchronize_irq(hw->pdev->irq);
+
+       sky2_tx_clean(sky2);
+       sky2_rx_clean(sky2);
+
+       pci_free_consistent(hw->pdev, RX_LE_BYTES,
+                           sky2->rx_le, sky2->rx_le_map);
+       kfree(sky2->rx_ring);
+
+       pci_free_consistent(hw->pdev,
+                           TX_RING_SIZE * sizeof(struct sky2_tx_le),
+                           sky2->tx_le, sky2->tx_le_map);
+       kfree(sky2->tx_ring);
+
+       sky2->tx_le = NULL;
+       sky2->rx_le = NULL;
+
+       sky2->rx_ring = NULL;
+       sky2->tx_ring = NULL;
+
+       return 0;
+}
+
+static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
+{
+       if (!hw->copper)
+               return SPEED_1000;
+
+       if (hw->chip_id == CHIP_ID_YUKON_FE)
+               return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10;
+
+       switch (aux & PHY_M_PS_SPEED_MSK) {
+       case PHY_M_PS_SPEED_1000:
+               return SPEED_1000;
+       case PHY_M_PS_SPEED_100:
+               return SPEED_100;
+       default:
+               return SPEED_10;
+       }
+}
+
+static void sky2_link_up(struct sky2_port *sky2)
+{
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 reg;
+
+       /* Enable Transmit FIFO Underrun */
+       sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
+
+       reg = gma_read16(hw, port, GM_GP_CTRL);
+       if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE)
+               reg |= GM_GPCR_DUP_FULL;
+
+       /* enable Rx/Tx */
+       reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+       gma_write16(hw, port, GM_GP_CTRL, reg);
+       gma_read16(hw, port, GM_GP_CTRL);
+
+       gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+
+       netif_carrier_on(sky2->netdev);
+       netif_wake_queue(sky2->netdev);
+
+       /* Turn on link LED */
+       sky2_write8(hw, SK_REG(port, LNK_LED_REG),
+                   LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
+
+       if (hw->chip_id == CHIP_ID_YUKON_XL) {
+               u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) |      /* LINK/ACT */
+                            PHY_M_LEDC_INIT_CTRL(sky2->speed ==
+                                                 SPEED_10 ? 7 : 0) |
+                            PHY_M_LEDC_STA1_CTRL(sky2->speed ==
+                                                 SPEED_100 ? 7 : 0) |
+                            PHY_M_LEDC_STA0_CTRL(sky2->speed ==
+                                                 SPEED_1000 ? 7 : 0));
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+       }
+
+       if (netif_msg_link(sky2))
+               printk(KERN_INFO PFX
+                      "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
+                      sky2->netdev->name, sky2->speed,
+                      sky2->duplex == DUPLEX_FULL ? "full" : "half",
+                      (sky2->tx_pause && sky2->rx_pause) ? "both" :
+                      sky2->tx_pause ? "tx" : sky2->rx_pause ? "rx" : "none");
+}
+
+static void sky2_link_down(struct sky2_port *sky2)
+{
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 reg;
+
+       gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+
+       reg = gma_read16(hw, port, GM_GP_CTRL);
+       reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+       gma_write16(hw, port, GM_GP_CTRL, reg);
+       gma_read16(hw, port, GM_GP_CTRL);       /* PCI post */
+
+       if (sky2->rx_pause && !sky2->tx_pause) {
+               /* restore Asymmetric Pause bit */
+               gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+                            gm_phy_read(hw, port, PHY_MARV_AUNE_ADV)
+                            | PHY_M_AN_ASP);
+       }
+
+       netif_carrier_off(sky2->netdev);
+       netif_stop_queue(sky2->netdev);
+
+       /* Turn on link LED */
+       sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
+
+       if (netif_msg_link(sky2))
+               printk(KERN_INFO PFX "%s: Link is down.\n", sky2->netdev->name);
+       sky2_phy_init(hw, port);
+}
+
+static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
+{
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 lpa;
+
+       lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
+
+       if (lpa & PHY_M_AN_RF) {
+               printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
+               return -1;
+       }
+
+       if (hw->chip_id != CHIP_ID_YUKON_FE &&
+           gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
+               printk(KERN_ERR PFX "%s: master/slave fault",
+                      sky2->netdev->name);
+               return -1;
+       }
+
+       if (!(aux & PHY_M_PS_SPDUP_RES)) {
+               printk(KERN_ERR PFX "%s: speed/duplex mismatch",
+                      sky2->netdev->name);
+               return -1;
+       }
+
+       sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+
+       sky2->speed = sky2_phy_speed(hw, aux);
+
+       /* Pause bits are offset (9..8) */
+       if (hw->chip_id == CHIP_ID_YUKON_XL)
+               aux >>= 6;
+
+       sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
+       sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0;
+
+       if ((sky2->tx_pause || sky2->rx_pause)
+           && !(sky2->speed < SPEED_1000 && sky2->duplex == DUPLEX_HALF))
+               sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+       else
+               sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+
+       return 0;
+}
+
+/*
+ * Interrupt from PHY are handled outside of interrupt context
+ * because accessing phy registers requires spin wait which might
+ * cause excess interrupt latency.
+ */
+static void sky2_phy_task(void *arg)
+{
+       struct sky2_port *sky2 = arg;
+       struct sky2_hw *hw = sky2->hw;
+       u16 istatus, phystat;
+
+       down(&sky2->phy_sema);
+       istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT);
+       phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT);
+
+       if (netif_msg_intr(sky2))
+               printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
+                      sky2->netdev->name, istatus, phystat);
+
+       if (istatus & PHY_M_IS_AN_COMPL) {
+               if (sky2_autoneg_done(sky2, phystat) == 0)
+                       sky2_link_up(sky2);
+               goto out;
+       }
+
+       if (istatus & PHY_M_IS_LSP_CHANGE)
+               sky2->speed = sky2_phy_speed(hw, phystat);
+
+       if (istatus & PHY_M_IS_DUP_CHANGE)
+               sky2->duplex =
+                   (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+
+       if (istatus & PHY_M_IS_LST_CHANGE) {
+               if (phystat & PHY_M_PS_LINK_UP)
+                       sky2_link_up(sky2);
+               else
+                       sky2_link_down(sky2);
+       }
+out:
+       up(&sky2->phy_sema);
+
+       local_irq_disable();
+       hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2;
+       sky2_write32(hw, B0_IMSK, hw->intr_mask);
+       local_irq_enable();
+}
+
+static void sky2_tx_timeout(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned txq = txqaddr[sky2->port];
+
+       if (netif_msg_timer(sky2))
+               printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
+
+       netif_stop_queue(dev);
+
+       sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
+       sky2_read32(hw, Q_ADDR(txq, Q_CSR));
+
+       sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+
+       sky2_tx_clean(sky2);
+
+       sky2_qset(hw, txq);
+       sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
+
+       netif_wake_queue(dev);
+}
+
+
+#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */
+static inline unsigned sky2_buf_size(int mtu)
+{
+       return roundup(mtu + ETH_HLEN + 4, 8);
+}
+
+static int sky2_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       int err;
+       u16 ctl, mode;
+
+       if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
+               return -EINVAL;
+
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U && new_mtu > ETH_DATA_LEN)
+               return -EINVAL;
+
+       if (!netif_running(dev)) {
+               dev->mtu = new_mtu;
+               return 0;
+       }
+
+       sky2_write32(hw, B0_IMSK, 0);
+
+       dev->trans_start = jiffies;     /* prevent tx timeout */
+       netif_stop_queue(dev);
+       netif_poll_disable(hw->dev[0]);
+
+       ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
+       gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
+       sky2_rx_stop(sky2);
+       sky2_rx_clean(sky2);
+
+       dev->mtu = new_mtu;
+       sky2->rx_bufsize = sky2_buf_size(new_mtu);
+       mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
+               GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+
+       if (dev->mtu > ETH_DATA_LEN)
+               mode |= GM_SMOD_JUMBO_ENA;
+
+       gma_write16(hw, sky2->port, GM_SERIAL_MODE, mode);
+
+       sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
+
+       err = sky2_rx_start(sky2);
+       sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+       if (err)
+               dev_close(dev);
+       else {
+               gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
+
+               netif_poll_enable(hw->dev[0]);
+               netif_wake_queue(dev);
+       }
+
+       return err;
+}
+
+/*
+ * Receive one packet.
+ * For small packets or errors, just reuse existing skb.
+ * For larger packets, get new buffer.
+ */
+static struct sk_buff *sky2_receive(struct sky2_port *sky2,
+                                   u16 length, u32 status)
+{
+       struct ring_info *re = sky2->rx_ring + sky2->rx_next;
+       struct sk_buff *skb = NULL;
+
+       if (unlikely(netif_msg_rx_status(sky2)))
+               printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
+                      sky2->netdev->name, sky2->rx_next, status, length);
+
+       sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
+       prefetch(sky2->rx_ring + sky2->rx_next);
+
+       if (status & GMR_FS_ANY_ERR)
+               goto error;
+
+       if (!(status & GMR_FS_RX_OK))
+               goto resubmit;
+
+       if ((status >> 16) != length || length > sky2->rx_bufsize)
+               goto oversize;
+
+       if (length < copybreak) {
+               skb = alloc_skb(length + 2, GFP_ATOMIC);
+               if (!skb)
+                       goto resubmit;
+
+               skb_reserve(skb, 2);
+               pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
+                                           length, PCI_DMA_FROMDEVICE);
+               memcpy(skb->data, re->skb->data, length);
+               skb->ip_summed = re->skb->ip_summed;
+               skb->csum = re->skb->csum;
+               pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
+                                              length, PCI_DMA_FROMDEVICE);
+       } else {
+               struct sk_buff *nskb;
+
+               nskb = dev_alloc_skb(sky2->rx_bufsize);
+               if (!nskb)
+                       goto resubmit;
+
+               skb = re->skb;
+               re->skb = nskb;
+               pci_unmap_single(sky2->hw->pdev, re->mapaddr,
+                                sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+               prefetch(skb->data);
+
+               re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
+                                            sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+       }
+
+       skb_put(skb, length);
+resubmit:
+       re->skb->ip_summed = CHECKSUM_NONE;
+       sky2_rx_add(sky2, re->mapaddr);
+
+       /* Tell receiver about new buffers. */
+       sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put,
+                    &sky2->rx_last_put, RX_LE_SIZE);
+
+       return skb;
+
+oversize:
+       ++sky2->net_stats.rx_over_errors;
+       goto resubmit;
+
+error:
+       ++sky2->net_stats.rx_errors;
+
+       if (netif_msg_rx_err(sky2))
+               printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
+                      sky2->netdev->name, status, length);
+
+       if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
+               sky2->net_stats.rx_length_errors++;
+       if (status & GMR_FS_FRAGMENT)
+               sky2->net_stats.rx_frame_errors++;
+       if (status & GMR_FS_CRC_ERR)
+               sky2->net_stats.rx_crc_errors++;
+       if (status & GMR_FS_RX_FF_OV)
+               sky2->net_stats.rx_fifo_errors++;
+
+       goto resubmit;
+}
+
+/*
+ * Check for transmit complete
+ */
+#define TX_NO_STATUS   0xffff
+
+static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
+{
+       if (last != TX_NO_STATUS) {
+               struct net_device *dev = hw->dev[port];
+               if (dev && netif_running(dev)) {
+                       struct sky2_port *sky2 = netdev_priv(dev);
+                       sky2_tx_complete(sky2, last);
+               }
+       }
+}
+
+/*
+ * Both ports share the same status interrupt, therefore there is only
+ * one poll routine.
+ */
+static int sky2_poll(struct net_device *dev0, int *budget)
+{
+       struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
+       unsigned int to_do = min(dev0->quota, *budget);
+       unsigned int work_done = 0;
+       u16 hwidx;
+       u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
+
+       hwidx = sky2_read16(hw, STAT_PUT_IDX);
+       BUG_ON(hwidx >= STATUS_RING_SIZE);
+       rmb();
+
+       while (hwidx != hw->st_idx) {
+               struct sky2_status_le *le  = hw->st_le + hw->st_idx;
+               struct net_device *dev;
+               struct sky2_port *sky2;
+               struct sk_buff *skb;
+               u32 status;
+               u16 length;
+               u8 op;
+
+               le = hw->st_le + hw->st_idx;
+               hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
+               prefetch(hw->st_le + hw->st_idx);
+
+               BUG_ON(le->link >= 2);
+               dev = hw->dev[le->link];
+               if (dev == NULL || !netif_running(dev))
+                       continue;
+
+               sky2 = netdev_priv(dev);
+               status = le32_to_cpu(le->status);
+               length = le16_to_cpu(le->length);
+               op = le->opcode & ~HW_OWNER;
+               le->opcode = 0;
+
+               switch (op) {
+               case OP_RXSTAT:
+                       skb = sky2_receive(sky2, length, status);
+                       if (!skb)
+                               break;
+
+                       skb->dev = dev;
+                       skb->protocol = eth_type_trans(skb, dev);
+                       dev->last_rx = jiffies;
+
+#ifdef SKY2_VLAN_TAG_USED
+                       if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
+                               vlan_hwaccel_receive_skb(skb,
+                                                        sky2->vlgrp,
+                                                        be16_to_cpu(sky2->rx_tag));
+                       } else
+#endif
+                               netif_receive_skb(skb);
+
+                       if (++work_done >= to_do)
+                               goto exit_loop;
+                       break;
+
+#ifdef SKY2_VLAN_TAG_USED
+               case OP_RXVLAN:
+                       sky2->rx_tag = length;
+                       break;
+
+               case OP_RXCHKSVLAN:
+                       sky2->rx_tag = length;
+                       /* fall through */
+#endif
+               case OP_RXCHKS:
+                       skb = sky2->rx_ring[sky2->rx_next].skb;
+                       skb->ip_summed = CHECKSUM_HW;
+                       skb->csum = le16_to_cpu(status);
+                       break;
+
+               case OP_TXINDEXLE:
+                       /* TX index reports status for both ports */
+                       tx_done[0] = status & 0xffff;
+                       tx_done[1] = ((status >> 24) & 0xff)
+                               | (u16)(length & 0xf) << 8;
+                       break;
+
+               default:
+                       if (net_ratelimit())
+                               printk(KERN_WARNING PFX
+                                      "unknown status opcode 0x%x\n", op);
+                       break;
+               }
+       }
+
+exit_loop:
+       sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+       mmiowb();
+
+       sky2_tx_check(hw, 0, tx_done[0]);
+       sky2_tx_check(hw, 1, tx_done[1]);
+
+       if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) {
+               /* need to restart TX timer */
+               if (is_ec_a1(hw)) {
+                       sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+                       sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+               }
+
+               netif_rx_complete(dev0);
+               hw->intr_mask |= Y2_IS_STAT_BMU;
+               sky2_write32(hw, B0_IMSK, hw->intr_mask);
+               mmiowb();
+               return 0;
+       } else {
+               *budget -= work_done;
+               dev0->quota -= work_done;
+               return 1;
+       }
+}
+
+static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
+{
+       struct net_device *dev = hw->dev[port];
+
+       printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
+              dev->name, status);
+
+       if (status & Y2_IS_PAR_RD1) {
+               printk(KERN_ERR PFX "%s: ram data read parity error\n",
+                      dev->name);
+               /* Clear IRQ */
+               sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
+       }
+
+       if (status & Y2_IS_PAR_WR1) {
+               printk(KERN_ERR PFX "%s: ram data write parity error\n",
+                      dev->name);
+
+               sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
+       }
+
+       if (status & Y2_IS_PAR_MAC1) {
+               printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
+               sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
+       }
+
+       if (status & Y2_IS_PAR_RX1) {
+               printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
+               sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
+       }
+
+       if (status & Y2_IS_TCP_TXA1) {
+               printk(KERN_ERR PFX "%s: TCP segmentation error\n", dev->name);
+               sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
+       }
+}
+
+static void sky2_hw_intr(struct sky2_hw *hw)
+{
+       u32 status = sky2_read32(hw, B0_HWE_ISRC);
+
+       if (status & Y2_IS_TIST_OV)
+               sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+
+       if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
+               u16 pci_err;
+
+               pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err);
+               printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
+                      pci_name(hw->pdev), pci_err);
+
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+               pci_write_config_word(hw->pdev, PCI_STATUS,
+                                     pci_err | PCI_STATUS_ERROR_BITS);
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+       }
+
+       if (status & Y2_IS_PCI_EXP) {
+               /* PCI-Express uncorrectable Error occurred */
+               u32 pex_err;
+
+               pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err);
+
+               printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
+                      pci_name(hw->pdev), pex_err);
+
+               /* clear the interrupt */
+               sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+               pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+                                      0xffffffffUL);
+               sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+               if (pex_err & PEX_FATAL_ERRORS) {
+                       u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
+                       hwmsk &= ~Y2_IS_PCI_EXP;
+                       sky2_write32(hw, B0_HWE_IMSK, hwmsk);
+               }
+       }
+
+       if (status & Y2_HWE_L1_MASK)
+               sky2_hw_error(hw, 0, status);
+       status >>= 8;
+       if (status & Y2_HWE_L1_MASK)
+               sky2_hw_error(hw, 1, status);
+}
+
+static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
+{
+       struct net_device *dev = hw->dev[port];
+       struct sky2_port *sky2 = netdev_priv(dev);
+       u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
+
+       if (netif_msg_intr(sky2))
+               printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n",
+                      dev->name, status);
+
+       if (status & GM_IS_RX_FF_OR) {
+               ++sky2->net_stats.rx_fifo_errors;
+               sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
+       }
+
+       if (status & GM_IS_TX_FF_UR) {
+               ++sky2->net_stats.tx_fifo_errors;
+               sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
+       }
+}
+
+static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
+{
+       struct net_device *dev = hw->dev[port];
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
+       sky2_write32(hw, B0_IMSK, hw->intr_mask);
+       schedule_work(&sky2->phy_task);
+}
+
+static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct sky2_hw *hw = dev_id;
+       struct net_device *dev0 = hw->dev[0];
+       u32 status;
+
+       status = sky2_read32(hw, B0_Y2_SP_ISRC2);
+       if (status == 0 || status == ~0)
+               return IRQ_NONE;
+
+       if (status & Y2_IS_HW_ERR)
+               sky2_hw_intr(hw);
+
+       /* Do NAPI for Rx and Tx status */
+       if (status & Y2_IS_STAT_BMU) {
+               hw->intr_mask &= ~Y2_IS_STAT_BMU;
+               sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+               if (likely(__netif_rx_schedule_prep(dev0))) {
+                       prefetch(&hw->st_le[hw->st_idx]);
+                       __netif_rx_schedule(dev0);
+               }
+       }
+
+       if (status & Y2_IS_IRQ_PHY1)
+               sky2_phy_intr(hw, 0);
+
+       if (status & Y2_IS_IRQ_PHY2)
+               sky2_phy_intr(hw, 1);
+
+       if (status & Y2_IS_IRQ_MAC1)
+               sky2_mac_intr(hw, 0);
+
+       if (status & Y2_IS_IRQ_MAC2)
+               sky2_mac_intr(hw, 1);
+
+       sky2_write32(hw, B0_Y2_SP_ICR, 2);
+
+       sky2_read32(hw, B0_IMSK);
+
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void sky2_netpoll(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       sky2_intr(sky2->hw->pdev->irq, sky2->hw, NULL);
+}
+#endif
+
+/* Chip internal frequency for clock calculations */
+static inline u32 sky2_mhz(const struct sky2_hw *hw)
+{
+       switch (hw->chip_id) {
+       case CHIP_ID_YUKON_EC:
+       case CHIP_ID_YUKON_EC_U:
+               return 125;     /* 125 Mhz */
+       case CHIP_ID_YUKON_FE:
+               return 100;     /* 100 Mhz */
+       default:                /* YUKON_XL */
+               return 156;     /* 156 Mhz */
+       }
+}
+
+static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
+{
+       return sky2_mhz(hw) * us;
+}
+
+static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
+{
+       return clk / sky2_mhz(hw);
+}
+
+
+static int sky2_reset(struct sky2_hw *hw)
+{
+       u32 ctst;
+       u16 status;
+       u8 t8, pmd_type;
+       int i;
+
+       ctst = sky2_read32(hw, B0_CTST);
+
+       sky2_write8(hw, B0_CTST, CS_RST_CLR);
+       hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
+       if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
+               printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
+                      pci_name(hw->pdev), hw->chip_id);
+               return -EOPNOTSUPP;
+       }
+
+       /* ring for status responses */
+       hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
+                                        &hw->st_dma);
+       if (!hw->st_le)
+               return -ENOMEM;
+
+       /* disable ASF */
+       if (hw->chip_id <= CHIP_ID_YUKON_EC) {
+               sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+               sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
+       }
+
+       /* do a SW reset */
+       sky2_write8(hw, B0_CTST, CS_RST_SET);
+       sky2_write8(hw, B0_CTST, CS_RST_CLR);
+
+       /* clear PCI errors, if any */
+       pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+       pci_write_config_word(hw->pdev, PCI_STATUS,
+                             status | PCI_STATUS_ERROR_BITS);
+
+       sky2_write8(hw, B0_CTST, CS_MRST_CLR);
+
+       /* clear any PEX errors */
+       if (is_pciex(hw)) {
+               u16 lstat;
+               pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+                                      0xffffffffUL);
+               pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat);
+       }
+
+       pmd_type = sky2_read8(hw, B2_PMD_TYP);
+       hw->copper = !(pmd_type == 'L' || pmd_type == 'S');
+
+       hw->ports = 1;
+       t8 = sky2_read8(hw, B2_Y2_HW_RES);
+       if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
+               if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
+                       ++hw->ports;
+       }
+       hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
+
+       sky2_set_power_state(hw, PCI_D0);
+
+       for (i = 0; i < hw->ports; i++) {
+               sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+               sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+       }
+
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+       /* Clear I2C IRQ noise */
+       sky2_write32(hw, B2_I2C_IRQ, 1);
+
+       /* turn off hardware timer (unused) */
+       sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
+       sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
+
+       sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
+
+       /* Turn off descriptor polling */
+       sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
+
+       /* Turn off receive timestamp */
+       sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
+       sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+
+       /* enable the Tx Arbiters */
+       for (i = 0; i < hw->ports; i++)
+               sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
+
+       /* Initialize ram interface */
+       for (i = 0; i < hw->ports; i++) {
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
+
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
+       }
+
+       sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+
+       for (i = 0; i < hw->ports; i++)
+               sky2_phy_reset(hw, i);
+
+       memset(hw->st_le, 0, STATUS_LE_BYTES);
+       hw->st_idx = 0;
+
+       sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
+       sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);
+
+       sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
+       sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
+
+       /* Set the list last index */
+       sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
+
+       /* These status setup values are copied from SysKonnect's driver */
+       if (is_ec_a1(hw)) {
+               /* WA for dev. #4.3 */
+               sky2_write16(hw, STAT_TX_IDX_TH, 0xfff);        /* Tx Threshold */
+
+               /* set Status-FIFO watermark */
+               sky2_write8(hw, STAT_FIFO_WM, 0x21);    /* WA for dev. #4.18 */
+
+               /* set Status-FIFO ISR watermark */
+               sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07);        /* WA for dev. #4.18 */
+               sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000));
+       } else {
+               sky2_write16(hw, STAT_TX_IDX_TH, 10);
+               sky2_write8(hw, STAT_FIFO_WM, 16);
+
+               /* set Status-FIFO ISR watermark */
+               if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
+                       sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
+               else
+                       sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
+
+               sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
+               sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
+               sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
+       }
+
+       /* enable status unit */
+       sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
+
+       sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+       sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+       sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+
+       return 0;
+}
+
+static inline u32 sky2_supported_modes(const struct sky2_hw *hw)
+{
+       u32 modes;
+       if (hw->copper) {
+               modes = SUPPORTED_10baseT_Half
+                   | SUPPORTED_10baseT_Full
+                   | SUPPORTED_100baseT_Half
+                   | SUPPORTED_100baseT_Full
+                   | SUPPORTED_Autoneg | SUPPORTED_TP;
+
+               if (hw->chip_id != CHIP_ID_YUKON_FE)
+                       modes |= SUPPORTED_1000baseT_Half
+                           | SUPPORTED_1000baseT_Full;
+       } else
+               modes = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
+                   | SUPPORTED_Autoneg;
+       return modes;
+}
+
+static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+
+       ecmd->transceiver = XCVR_INTERNAL;
+       ecmd->supported = sky2_supported_modes(hw);
+       ecmd->phy_address = PHY_ADDR_MARV;
+       if (hw->copper) {
+               ecmd->supported = SUPPORTED_10baseT_Half
+                   | SUPPORTED_10baseT_Full
+                   | SUPPORTED_100baseT_Half
+                   | SUPPORTED_100baseT_Full
+                   | SUPPORTED_1000baseT_Half
+                   | SUPPORTED_1000baseT_Full
+                   | SUPPORTED_Autoneg | SUPPORTED_TP;
+               ecmd->port = PORT_TP;
+       } else
+               ecmd->port = PORT_FIBRE;
+
+       ecmd->advertising = sky2->advertising;
+       ecmd->autoneg = sky2->autoneg;
+       ecmd->speed = sky2->speed;
+       ecmd->duplex = sky2->duplex;
+       return 0;
+}
+
+static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       const struct sky2_hw *hw = sky2->hw;
+       u32 supported = sky2_supported_modes(hw);
+
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               ecmd->advertising = supported;
+               sky2->duplex = -1;
+               sky2->speed = -1;
+       } else {
+               u32 setting;
+
+               switch (ecmd->speed) {
+               case SPEED_1000:
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               setting = SUPPORTED_1000baseT_Full;
+                       else if (ecmd->duplex == DUPLEX_HALF)
+                               setting = SUPPORTED_1000baseT_Half;
+                       else
+                               return -EINVAL;
+                       break;
+               case SPEED_100:
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               setting = SUPPORTED_100baseT_Full;
+                       else if (ecmd->duplex == DUPLEX_HALF)
+                               setting = SUPPORTED_100baseT_Half;
+                       else
+                               return -EINVAL;
+                       break;
+
+               case SPEED_10:
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               setting = SUPPORTED_10baseT_Full;
+                       else if (ecmd->duplex == DUPLEX_HALF)
+                               setting = SUPPORTED_10baseT_Half;
+                       else
+                               return -EINVAL;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               if ((setting & supported) == 0)
+                       return -EINVAL;
+
+               sky2->speed = ecmd->speed;
+               sky2->duplex = ecmd->duplex;
+       }
+
+       sky2->autoneg = ecmd->autoneg;
+       sky2->advertising = ecmd->advertising;
+
+       if (netif_running(dev))
+               sky2_phy_reinit(sky2);
+
+       return 0;
+}
+
+static void sky2_get_drvinfo(struct net_device *dev,
+                            struct ethtool_drvinfo *info)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->fw_version, "N/A");
+       strcpy(info->bus_info, pci_name(sky2->hw->pdev));
+}
+
+static const struct sky2_stat {
+       char name[ETH_GSTRING_LEN];
+       u16 offset;
+} sky2_stats[] = {
+       { "tx_bytes",      GM_TXO_OK_HI },
+       { "rx_bytes",      GM_RXO_OK_HI },
+       { "tx_broadcast",  GM_TXF_BC_OK },
+       { "rx_broadcast",  GM_RXF_BC_OK },
+       { "tx_multicast",  GM_TXF_MC_OK },
+       { "rx_multicast",  GM_RXF_MC_OK },
+       { "tx_unicast",    GM_TXF_UC_OK },
+       { "rx_unicast",    GM_RXF_UC_OK },
+       { "tx_mac_pause",  GM_TXF_MPAUSE },
+       { "rx_mac_pause",  GM_RXF_MPAUSE },
+       { "collisions",    GM_TXF_SNG_COL },
+       { "late_collision",GM_TXF_LAT_COL },
+       { "aborted",       GM_TXF_ABO_COL },
+       { "multi_collisions", GM_TXF_MUL_COL },
+       { "fifo_underrun", GM_TXE_FIFO_UR },
+       { "fifo_overflow", GM_RXE_FIFO_OV },
+       { "rx_toolong",    GM_RXF_LNG_ERR },
+       { "rx_jabber",     GM_RXF_JAB_PKT },
+       { "rx_runt",       GM_RXE_FRAG },
+       { "rx_too_long",   GM_RXF_LNG_ERR },
+       { "rx_fcs_error",   GM_RXF_FCS_ERR },
+};
+
+static u32 sky2_get_rx_csum(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       return sky2->rx_csum;
+}
+
+static int sky2_set_rx_csum(struct net_device *dev, u32 data)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       sky2->rx_csum = data;
+
+       sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                    data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+
+       return 0;
+}
+
+static u32 sky2_get_msglevel(struct net_device *netdev)
+{
+       struct sky2_port *sky2 = netdev_priv(netdev);
+       return sky2->msg_enable;
+}
+
+static int sky2_nway_reset(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       if (sky2->autoneg != AUTONEG_ENABLE)
+               return -EINVAL;
+
+       sky2_phy_reinit(sky2);
+
+       return 0;
+}
+
+static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
+{
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       int i;
+
+       data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
+           | (u64) gma_read32(hw, port, GM_TXO_OK_LO);
+       data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
+           | (u64) gma_read32(hw, port, GM_RXO_OK_LO);
+
+       for (i = 2; i < count; i++)
+               data[i] = (u64) gma_read32(hw, port, sky2_stats[i].offset);
+}
+
+static void sky2_set_msglevel(struct net_device *netdev, u32 value)
+{
+       struct sky2_port *sky2 = netdev_priv(netdev);
+       sky2->msg_enable = value;
+}
+
+static int sky2_get_stats_count(struct net_device *dev)
+{
+       return ARRAY_SIZE(sky2_stats);
+}
+
+static void sky2_get_ethtool_stats(struct net_device *dev,
+                                  struct ethtool_stats *stats, u64 * data)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       sky2_phy_stats(sky2, data, ARRAY_SIZE(sky2_stats));
+}
+
+static void sky2_get_strings(struct net_device *dev, u32 stringset, u8 * data)
+{
+       int i;
+
+       switch (stringset) {
+       case ETH_SS_STATS:
+               for (i = 0; i < ARRAY_SIZE(sky2_stats); i++)
+                       memcpy(data + i * ETH_GSTRING_LEN,
+                              sky2_stats[i].name, ETH_GSTRING_LEN);
+               break;
+       }
+}
+
+/* Use hardware MIB variables for critical path statistics and
+ * transmit feedback not reported at interrupt.
+ * Other errors are accounted for in interrupt handler.
+ */
+static struct net_device_stats *sky2_get_stats(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       u64 data[13];
+
+       sky2_phy_stats(sky2, data, ARRAY_SIZE(data));
+
+       sky2->net_stats.tx_bytes = data[0];
+       sky2->net_stats.rx_bytes = data[1];
+       sky2->net_stats.tx_packets = data[2] + data[4] + data[6];
+       sky2->net_stats.rx_packets = data[3] + data[5] + data[7];
+       sky2->net_stats.multicast = data[5] + data[7];
+       sky2->net_stats.collisions = data[10];
+       sky2->net_stats.tx_aborted_errors = data[12];
+
+       return &sky2->net_stats;
+}
+
+static int sky2_set_mac_address(struct net_device *dev, void *p)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+       memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8,
+                   dev->dev_addr, ETH_ALEN);
+       memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8,
+                   dev->dev_addr, ETH_ALEN);
+
+       if (netif_running(dev))
+               sky2_phy_reinit(sky2);
+
+       return 0;
+}
+
+static void sky2_set_multicast(struct net_device *dev)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       struct dev_mc_list *list = dev->mc_list;
+       u16 reg;
+       u8 filter[8];
+
+       memset(filter, 0, sizeof(filter));
+
+       reg = gma_read16(hw, port, GM_RX_CTRL);
+       reg |= GM_RXCR_UCF_ENA;
+
+       if (dev->flags & IFF_PROMISC)   /* promiscuous */
+               reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+       else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16)     /* all multicast */
+               memset(filter, 0xff, sizeof(filter));
+       else if (dev->mc_count == 0)    /* no multicast */
+               reg &= ~GM_RXCR_MCF_ENA;
+       else {
+               int i;
+               reg |= GM_RXCR_MCF_ENA;
+
+               for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
+                       u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
+                       filter[bit / 8] |= 1 << (bit % 8);
+               }
+       }
+
+       gma_write16(hw, port, GM_MC_ADDR_H1,
+                   (u16) filter[0] | ((u16) filter[1] << 8));
+       gma_write16(hw, port, GM_MC_ADDR_H2,
+                   (u16) filter[2] | ((u16) filter[3] << 8));
+       gma_write16(hw, port, GM_MC_ADDR_H3,
+                   (u16) filter[4] | ((u16) filter[5] << 8));
+       gma_write16(hw, port, GM_MC_ADDR_H4,
+                   (u16) filter[6] | ((u16) filter[7] << 8));
+
+       gma_write16(hw, port, GM_RX_CTRL, reg);
+}
+
+/* Can have one global because blinking is controlled by
+ * ethtool and that is always under RTNL mutex
+ */
+static void sky2_led(struct sky2_hw *hw, unsigned port, int on)
+{
+       u16 pg;
+
+       switch (hw->chip_id) {
+       case CHIP_ID_YUKON_XL:
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                            on ? (PHY_M_LEDC_LOS_CTRL(1) |
+                                  PHY_M_LEDC_INIT_CTRL(7) |
+                                  PHY_M_LEDC_STA1_CTRL(7) |
+                                  PHY_M_LEDC_STA0_CTRL(7))
+                            : 0);
+
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+               break;
+
+       default:
+               gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+               gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+                            on ? PHY_M_LED_MO_DUP(MO_LED_ON) |
+                            PHY_M_LED_MO_10(MO_LED_ON) |
+                            PHY_M_LED_MO_100(MO_LED_ON) |
+                            PHY_M_LED_MO_1000(MO_LED_ON) |
+                            PHY_M_LED_MO_RX(MO_LED_ON)
+                            : PHY_M_LED_MO_DUP(MO_LED_OFF) |
+                            PHY_M_LED_MO_10(MO_LED_OFF) |
+                            PHY_M_LED_MO_100(MO_LED_OFF) |
+                            PHY_M_LED_MO_1000(MO_LED_OFF) |
+                            PHY_M_LED_MO_RX(MO_LED_OFF));
+
+       }
+}
+
+/* blink LED's for finding board */
+static int sky2_phys_id(struct net_device *dev, u32 data)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 ledctrl, ledover = 0;
+       long ms;
+       int interrupted;
+       int onoff = 1;
+
+       if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))
+               ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT);
+       else
+               ms = data * 1000;
+
+       /* save initial values */
+       down(&sky2->phy_sema);
+       if (hw->chip_id == CHIP_ID_YUKON_XL) {
+               u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+               ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+       } else {
+               ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL);
+               ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER);
+       }
+
+       interrupted = 0;
+       while (!interrupted && ms > 0) {
+               sky2_led(hw, port, onoff);
+               onoff = !onoff;
+
+               up(&sky2->phy_sema);
+               interrupted = msleep_interruptible(250);
+               down(&sky2->phy_sema);
+
+               ms -= 250;
+       }
+
+       /* resume regularly scheduled programming */
+       if (hw->chip_id == CHIP_ID_YUKON_XL) {
+               u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+       } else {
+               gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+               gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+       }
+       up(&sky2->phy_sema);
+
+       return 0;
+}
+
+static void sky2_get_pauseparam(struct net_device *dev,
+                               struct ethtool_pauseparam *ecmd)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       ecmd->tx_pause = sky2->tx_pause;
+       ecmd->rx_pause = sky2->rx_pause;
+       ecmd->autoneg = sky2->autoneg;
+}
+
+static int sky2_set_pauseparam(struct net_device *dev,
+                              struct ethtool_pauseparam *ecmd)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       int err = 0;
+
+       sky2->autoneg = ecmd->autoneg;
+       sky2->tx_pause = ecmd->tx_pause != 0;
+       sky2->rx_pause = ecmd->rx_pause != 0;
+
+       sky2_phy_reinit(sky2);
+
+       return err;
+}
+
+#ifdef CONFIG_PM
+static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       wol->supported = WAKE_MAGIC;
+       wol->wolopts = sky2->wol ? WAKE_MAGIC : 0;
+}
+
+static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+
+       if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
+               return -EOPNOTSUPP;
+
+       sky2->wol = wol->wolopts == WAKE_MAGIC;
+
+       if (sky2->wol) {
+               memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN);
+
+               sky2_write16(hw, WOL_CTRL_STAT,
+                            WOL_CTL_ENA_PME_ON_MAGIC_PKT |
+                            WOL_CTL_ENA_MAGIC_PKT_UNIT);
+       } else
+               sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT);
+
+       return 0;
+}
+#endif
+
+static int sky2_get_coalesce(struct net_device *dev,
+                            struct ethtool_coalesce *ecmd)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+
+       if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_STOP)
+               ecmd->tx_coalesce_usecs = 0;
+       else {
+               u32 clks = sky2_read32(hw, STAT_TX_TIMER_INI);
+               ecmd->tx_coalesce_usecs = sky2_clk2us(hw, clks);
+       }
+       ecmd->tx_max_coalesced_frames = sky2_read16(hw, STAT_TX_IDX_TH);
+
+       if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_STOP)
+               ecmd->rx_coalesce_usecs = 0;
+       else {
+               u32 clks = sky2_read32(hw, STAT_LEV_TIMER_INI);
+               ecmd->rx_coalesce_usecs = sky2_clk2us(hw, clks);
+       }
+       ecmd->rx_max_coalesced_frames = sky2_read8(hw, STAT_FIFO_WM);
+
+       if (sky2_read8(hw, STAT_ISR_TIMER_CTRL) == TIM_STOP)
+               ecmd->rx_coalesce_usecs_irq = 0;
+       else {
+               u32 clks = sky2_read32(hw, STAT_ISR_TIMER_INI);
+               ecmd->rx_coalesce_usecs_irq = sky2_clk2us(hw, clks);
+       }
+
+       ecmd->rx_max_coalesced_frames_irq = sky2_read8(hw, STAT_FIFO_ISR_WM);
+
+       return 0;
+}
+
+/* Note: this affect both ports */
+static int sky2_set_coalesce(struct net_device *dev,
+                            struct ethtool_coalesce *ecmd)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       const u32 tmin = sky2_clk2us(hw, 1);
+       const u32 tmax = 5000;
+
+       if (ecmd->tx_coalesce_usecs != 0 &&
+           (ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax))
+               return -EINVAL;
+
+       if (ecmd->rx_coalesce_usecs != 0 &&
+           (ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax))
+               return -EINVAL;
+
+       if (ecmd->rx_coalesce_usecs_irq != 0 &&
+           (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax))
+               return -EINVAL;
+
+       if (ecmd->tx_max_coalesced_frames > 0xffff)
+               return -EINVAL;
+       if (ecmd->rx_max_coalesced_frames > 0xff)
+               return -EINVAL;
+       if (ecmd->rx_max_coalesced_frames_irq > 0xff)
+               return -EINVAL;
+
+       if (ecmd->tx_coalesce_usecs == 0)
+               sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+       else {
+               sky2_write32(hw, STAT_TX_TIMER_INI,
+                            sky2_us2clk(hw, ecmd->tx_coalesce_usecs));
+               sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+       }
+       sky2_write16(hw, STAT_TX_IDX_TH, ecmd->tx_max_coalesced_frames);
+
+       if (ecmd->rx_coalesce_usecs == 0)
+               sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
+       else {
+               sky2_write32(hw, STAT_LEV_TIMER_INI,
+                            sky2_us2clk(hw, ecmd->rx_coalesce_usecs));
+               sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+       }
+       sky2_write8(hw, STAT_FIFO_WM, ecmd->rx_max_coalesced_frames);
+
+       if (ecmd->rx_coalesce_usecs_irq == 0)
+               sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
+       else {
+               sky2_write32(hw, STAT_TX_TIMER_INI,
+                            sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
+               sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+       }
+       sky2_write8(hw, STAT_FIFO_ISR_WM, ecmd->rx_max_coalesced_frames_irq);
+       return 0;
+}
+
+static void sky2_get_ringparam(struct net_device *dev,
+                              struct ethtool_ringparam *ering)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+
+       ering->rx_max_pending = RX_MAX_PENDING;
+       ering->rx_mini_max_pending = 0;
+       ering->rx_jumbo_max_pending = 0;
+       ering->tx_max_pending = TX_RING_SIZE - 1;
+
+       ering->rx_pending = sky2->rx_pending;
+       ering->rx_mini_pending = 0;
+       ering->rx_jumbo_pending = 0;
+       ering->tx_pending = sky2->tx_pending;
+}
+
+static int sky2_set_ringparam(struct net_device *dev,
+                             struct ethtool_ringparam *ering)
+{
+       struct sky2_port *sky2 = netdev_priv(dev);
+       int err = 0;
+
+       if (ering->rx_pending > RX_MAX_PENDING ||
+           ering->rx_pending < 8 ||
+           ering->tx_pending < MAX_SKB_TX_LE ||
+           ering->tx_pending > TX_RING_SIZE - 1)
+               return -EINVAL;
+
+       if (netif_running(dev))
+               sky2_down(dev);
+
+       sky2->rx_pending = ering->rx_pending;
+       sky2->tx_pending = ering->tx_pending;
+
+       if (netif_running(dev)) {
+               err = sky2_up(dev);
+               if (err)
+                       dev_close(dev);
+               else
+                       sky2_set_multicast(dev);
+       }
+
+       return err;
+}
+
+static int sky2_get_regs_len(struct net_device *dev)
+{
+       return 0x4000;
+}
+
+/*
+ * Returns copy of control register region
+ * Note: access to the RAM address register set will cause timeouts.
+ */
+static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+                         void *p)
+{
+       const struct sky2_port *sky2 = netdev_priv(dev);
+       const void __iomem *io = sky2->hw->regs;
+
+       BUG_ON(regs->len < B3_RI_WTO_R1);
+       regs->version = 1;
+       memset(p, 0, regs->len);
+
+       memcpy_fromio(p, io, B3_RAM_ADDR);
+
+       memcpy_fromio(p + B3_RI_WTO_R1,
+                     io + B3_RI_WTO_R1,
+                     regs->len - B3_RI_WTO_R1);
+}
+
+static struct ethtool_ops sky2_ethtool_ops = {
+       .get_settings = sky2_get_settings,
+       .set_settings = sky2_set_settings,
+       .get_drvinfo = sky2_get_drvinfo,
+       .get_msglevel = sky2_get_msglevel,
+       .set_msglevel = sky2_set_msglevel,
+       .nway_reset   = sky2_nway_reset,
+       .get_regs_len = sky2_get_regs_len,
+       .get_regs = sky2_get_regs,
+       .get_link = ethtool_op_get_link,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = ethtool_op_set_sg,
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = ethtool_op_set_tx_csum,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = ethtool_op_set_tso,
+       .get_rx_csum = sky2_get_rx_csum,
+       .set_rx_csum = sky2_set_rx_csum,
+       .get_strings = sky2_get_strings,
+       .get_coalesce = sky2_get_coalesce,
+       .set_coalesce = sky2_set_coalesce,
+       .get_ringparam = sky2_get_ringparam,
+       .set_ringparam = sky2_set_ringparam,
+       .get_pauseparam = sky2_get_pauseparam,
+       .set_pauseparam = sky2_set_pauseparam,
+#ifdef CONFIG_PM
+       .get_wol = sky2_get_wol,
+       .set_wol = sky2_set_wol,
+#endif
+       .phys_id = sky2_phys_id,
+       .get_stats_count = sky2_get_stats_count,
+       .get_ethtool_stats = sky2_get_ethtool_stats,
+       .get_perm_addr  = ethtool_op_get_perm_addr,
+};
+
+/* Initialize network device */
+static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
+                                                    unsigned port, int highmem)
+{
+       struct sky2_port *sky2;
+       struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+
+       if (!dev) {
+               printk(KERN_ERR "sky2 etherdev alloc failed");
+               return NULL;
+       }
+
+       SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &hw->pdev->dev);
+       dev->irq = hw->pdev->irq;
+       dev->open = sky2_up;
+       dev->stop = sky2_down;
+       dev->do_ioctl = sky2_ioctl;
+       dev->hard_start_xmit = sky2_xmit_frame;
+       dev->get_stats = sky2_get_stats;
+       dev->set_multicast_list = sky2_set_multicast;
+       dev->set_mac_address = sky2_set_mac_address;
+       dev->change_mtu = sky2_change_mtu;
+       SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
+       dev->tx_timeout = sky2_tx_timeout;
+       dev->watchdog_timeo = TX_WATCHDOG;
+       if (port == 0)
+               dev->poll = sky2_poll;
+       dev->weight = NAPI_WEIGHT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = sky2_netpoll;
+#endif
+
+       sky2 = netdev_priv(dev);
+       sky2->netdev = dev;
+       sky2->hw = hw;
+       sky2->msg_enable = netif_msg_init(debug, default_msg);
+
+       spin_lock_init(&sky2->tx_lock);
+       /* Auto speed and flow control */
+       sky2->autoneg = AUTONEG_ENABLE;
+       sky2->tx_pause = 1;
+       sky2->rx_pause = 1;
+       sky2->duplex = -1;
+       sky2->speed = -1;
+       sky2->advertising = sky2_supported_modes(hw);
+
+       /* Receive checksum disabled for Yukon XL
+        * because of observed problems with incorrect
+        * values when multiple packets are received in one interrupt
+        */
+       sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
+
+       INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2);
+       init_MUTEX(&sky2->phy_sema);
+       sky2->tx_pending = TX_DEF_PENDING;
+       sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING;
+       sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
+
+       hw->dev[port] = dev;
+
+       sky2->port = port;
+
+       dev->features |= NETIF_F_LLTX;
+       if (hw->chip_id != CHIP_ID_YUKON_EC_U)
+               dev->features |= NETIF_F_TSO;
+       if (highmem)
+               dev->features |= NETIF_F_HIGHDMA;
+       dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+
+#ifdef SKY2_VLAN_TAG_USED
+       dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+       dev->vlan_rx_register = sky2_vlan_rx_register;
+       dev->vlan_rx_kill_vid = sky2_vlan_rx_kill_vid;
+#endif
+
+       /* read the mac address */
+       memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+
+       /* device is off until link detection */
+       netif_carrier_off(dev);
+       netif_stop_queue(dev);
+
+       return dev;
+}
+
+static inline void sky2_show_addr(struct net_device *dev)
+{
+       const struct sky2_port *sky2 = netdev_priv(dev);
+
+       if (netif_msg_probe(sky2))
+               printk(KERN_INFO PFX "%s: addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+                      dev->name,
+                      dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+                      dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+}
+
+static int __devinit sky2_probe(struct pci_dev *pdev,
+                               const struct pci_device_id *ent)
+{
+       struct net_device *dev, *dev1 = NULL;
+       struct sky2_hw *hw;
+       int err, pm_cap, using_dac = 0;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR PFX "%s cannot enable PCI device\n",
+                      pci_name(pdev));
+               goto err_out;
+       }
+
+       err = pci_request_regions(pdev, DRV_NAME);
+       if (err) {
+               printk(KERN_ERR PFX "%s cannot obtain PCI resources\n",
+                      pci_name(pdev));
+               goto err_out;
+       }
+
+       pci_set_master(pdev);
+
+       /* Find power-management capability. */
+       pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+       if (pm_cap == 0) {
+               printk(KERN_ERR PFX "Cannot find PowerManagement capability, "
+                      "aborting.\n");
+               err = -EIO;
+               goto err_out_free_regions;
+       }
+
+       if (sizeof(dma_addr_t) > sizeof(u32)) {
+               err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+               if (!err)
+                       using_dac = 1;
+       }
+
+       if (!using_dac) {
+               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               if (err) {
+                       printk(KERN_ERR PFX "%s no usable DMA configuration\n",
+                              pci_name(pdev));
+                       goto err_out_free_regions;
+               }
+       }
+#ifdef __BIG_ENDIAN
+       /* byte swap descriptors in hardware */
+       {
+               u32 reg;
+
+               pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+               reg |= PCI_REV_DESC;
+               pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
+       }
+#endif
+
+       err = -ENOMEM;
+       hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+       if (!hw) {
+               printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
+                      pci_name(pdev));
+               goto err_out_free_regions;
+       }
+
+       memset(hw, 0, sizeof(*hw));
+       hw->pdev = pdev;
+
+       hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
+       if (!hw->regs) {
+               printk(KERN_ERR PFX "%s: cannot map device registers\n",
+                      pci_name(pdev));
+               goto err_out_free_hw;
+       }
+       hw->pm_cap = pm_cap;
+
+       err = sky2_reset(hw);
+       if (err)
+               goto err_out_iounmap;
+
+       printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n",
+              DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq,
+              yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
+              hw->chip_id, hw->chip_rev);
+
+       dev = sky2_init_netdev(hw, 0, using_dac);
+       if (!dev)
+               goto err_out_free_pci;
+
+       err = register_netdev(dev);
+       if (err) {
+               printk(KERN_ERR PFX "%s: cannot register net device\n",
+                      pci_name(pdev));
+               goto err_out_free_netdev;
+       }
+
+       sky2_show_addr(dev);
+
+       if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
+               if (register_netdev(dev1) == 0)
+                       sky2_show_addr(dev1);
+               else {
+                       /* Failure to register second port need not be fatal */
+                       printk(KERN_WARNING PFX
+                              "register of second port failed\n");
+                       hw->dev[1] = NULL;
+                       free_netdev(dev1);
+               }
+       }
+
+       err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
+       if (err) {
+               printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+                      pci_name(pdev), pdev->irq);
+               goto err_out_unregister;
+       }
+
+       hw->intr_mask = Y2_IS_BASE;
+       sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+       pci_set_drvdata(pdev, hw);
+
+       return 0;
+
+err_out_unregister:
+       if (dev1) {
+               unregister_netdev(dev1);
+               free_netdev(dev1);
+       }
+       unregister_netdev(dev);
+err_out_free_netdev:
+       free_netdev(dev);
+err_out_free_pci:
+       sky2_write8(hw, B0_CTST, CS_RST_SET);
+       pci_free_consistent(hw->pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
+err_out_iounmap:
+       iounmap(hw->regs);
+err_out_free_hw:
+       kfree(hw);
+err_out_free_regions:
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+err_out:
+       return err;
+}
+
+static void __devexit sky2_remove(struct pci_dev *pdev)
+{
+       struct sky2_hw *hw = pci_get_drvdata(pdev);
+       struct net_device *dev0, *dev1;
+
+       if (!hw)
+               return;
+
+       dev0 = hw->dev[0];
+       dev1 = hw->dev[1];
+       if (dev1)
+               unregister_netdev(dev1);
+       unregister_netdev(dev0);
+
+       sky2_write32(hw, B0_IMSK, 0);
+       sky2_set_power_state(hw, PCI_D3hot);
+       sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+       sky2_write8(hw, B0_CTST, CS_RST_SET);
+       sky2_read8(hw, B0_CTST);
+
+       free_irq(pdev->irq, hw);
+       pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+
+       if (dev1)
+               free_netdev(dev1);
+       free_netdev(dev0);
+       iounmap(hw->regs);
+       kfree(hw);
+
+       pci_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct sky2_hw *hw = pci_get_drvdata(pdev);
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               struct net_device *dev = hw->dev[i];
+
+               if (dev) {
+                       if (!netif_running(dev))
+                               continue;
+
+                       sky2_down(dev);
+                       netif_device_detach(dev);
+               }
+       }
+
+       return sky2_set_power_state(hw, pci_choose_state(pdev, state));
+}
+
+static int sky2_resume(struct pci_dev *pdev)
+{
+       struct sky2_hw *hw = pci_get_drvdata(pdev);
+       int i;
+
+       pci_restore_state(pdev);
+       pci_enable_wake(pdev, PCI_D0, 0);
+       sky2_set_power_state(hw, PCI_D0);
+
+       sky2_reset(hw);
+
+       for (i = 0; i < 2; i++) {
+               struct net_device *dev = hw->dev[i];
+               if (dev) {
+                       if (netif_running(dev)) {
+                               netif_device_attach(dev);
+                               if (sky2_up(dev))
+                                       dev_close(dev);
+                       }
+               }
+       }
+       return 0;
+}
+#endif
+
+static struct pci_driver sky2_driver = {
+       .name = DRV_NAME,
+       .id_table = sky2_id_table,
+       .probe = sky2_probe,
+       .remove = __devexit_p(sky2_remove),
+#ifdef CONFIG_PM
+       .suspend = sky2_suspend,
+       .resume = sky2_resume,
+#endif
+};
+
+static int __init sky2_init_module(void)
+{
+       return pci_register_driver(&sky2_driver);
+}
+
+static void __exit sky2_cleanup_module(void)
+{
+       pci_unregister_driver(&sky2_driver);
+}
+
+module_init(sky2_init_module);
+module_exit(sky2_cleanup_module);
+
+MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver");
+MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
new file mode 100644 (file)
index 0000000..9551892
--- /dev/null
@@ -0,0 +1,1922 @@
+/*
+ * Definitions for the new Marvell Yukon 2 driver.
+ */
+#ifndef _SKY2_H
+#define _SKY2_H
+
+/* PCI config registers */
+#define PCI_DEV_REG1   0x40
+#define PCI_DEV_REG2   0x44
+#define PCI_DEV_STATUS  0x7c
+#define PCI_OS_PCI_X    (1<<26)
+
+#define PEX_LNK_STAT   0xf2
+#define PEX_UNC_ERR_STAT 0x104
+#define PEX_DEV_CTRL   0xe8
+
+/* Yukon-2 */
+enum pci_dev_reg_1 {
+       PCI_Y2_PIG_ENA   = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
+       PCI_Y2_DLL_DIS   = 1<<30, /* Disable PCI DLL (YUKON-2) */
+       PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */
+       PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */
+       PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */
+       PCI_Y2_PHY1_POWD = 1<<26, /* Set PHY 1 to Power Down (YUKON-2) */
+};
+
+enum pci_dev_reg_2 {
+       PCI_VPD_WR_THR  = 0xffL<<24,    /* Bit 31..24:  VPD Write Threshold */
+       PCI_DEV_SEL     = 0x7fL<<17,    /* Bit 23..17:  EEPROM Device Select */
+       PCI_VPD_ROM_SZ  = 7L<<14,       /* Bit 16..14:  VPD ROM Size    */
+
+       PCI_PATCH_DIR   = 0xfL<<8,      /* Bit 11.. 8:  Ext Patches dir 3..0 */
+       PCI_EXT_PATCHS  = 0xfL<<4,      /* Bit  7.. 4:  Extended Patches 3..0 */
+       PCI_EN_DUMMY_RD = 1<<3,         /* Enable Dummy Read */
+       PCI_REV_DESC    = 1<<2,         /* Reverse Desc. Bytes */
+
+       PCI_USEDATA64   = 1<<0,         /* Use 64Bit Data bus ext */
+};
+
+
+#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
+                              PCI_STATUS_SIG_SYSTEM_ERROR | \
+                              PCI_STATUS_REC_MASTER_ABORT | \
+                              PCI_STATUS_REC_TARGET_ABORT | \
+                              PCI_STATUS_PARITY)
+
+enum pex_dev_ctrl {
+       PEX_DC_MAX_RRS_MSK      = 7<<12, /* Bit 14..12: Max. Read Request Size */
+       PEX_DC_EN_NO_SNOOP      = 1<<11,/* Enable No Snoop */
+       PEX_DC_EN_AUX_POW       = 1<<10,/* Enable AUX Power */
+       PEX_DC_EN_PHANTOM       = 1<<9, /* Enable Phantom Functions */
+       PEX_DC_EN_EXT_TAG       = 1<<8, /* Enable Extended Tag Field */
+       PEX_DC_MAX_PLS_MSK      = 7<<5, /* Bit  7.. 5:  Max. Payload Size Mask */
+       PEX_DC_EN_REL_ORD       = 1<<4, /* Enable Relaxed Ordering */
+       PEX_DC_EN_UNS_RQ_RP     = 1<<3, /* Enable Unsupported Request Reporting */
+       PEX_DC_EN_FAT_ER_RP     = 1<<2, /* Enable Fatal Error Reporting */
+       PEX_DC_EN_NFA_ER_RP     = 1<<1, /* Enable Non-Fatal Error Reporting */
+       PEX_DC_EN_COR_ER_RP     = 1<<0, /* Enable Correctable Error Reporting */
+};
+#define  PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
+
+/* PEX_UNC_ERR_STAT     PEX Uncorrectable Errors Status Register (Yukon-2) */
+enum pex_err {
+       PEX_UNSUP_REQ   = 1<<20, /* Unsupported Request Error */
+
+       PEX_MALFOR_TLP  = 1<<18, /* Malformed TLP */
+
+       PEX_UNEXP_COMP  = 1<<16, /* Unexpected Completion */
+
+       PEX_COMP_TO     = 1<<14, /* Completion Timeout */
+       PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */
+       PEX_POIS_TLP    = 1<<12, /* Poisoned TLP */
+
+       PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */
+       PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
+};
+
+
+enum csr_regs {
+       B0_RAP          = 0x0000,
+       B0_CTST         = 0x0004,
+       B0_Y2LED        = 0x0005,
+       B0_POWER_CTRL   = 0x0007,
+       B0_ISRC         = 0x0008,
+       B0_IMSK         = 0x000c,
+       B0_HWE_ISRC     = 0x0010,
+       B0_HWE_IMSK     = 0x0014,
+
+       /* Special ISR registers (Yukon-2 only) */
+       B0_Y2_SP_ISRC2  = 0x001c,
+       B0_Y2_SP_ISRC3  = 0x0020,
+       B0_Y2_SP_EISR   = 0x0024,
+       B0_Y2_SP_LISR   = 0x0028,
+       B0_Y2_SP_ICR    = 0x002c,
+
+       B2_MAC_1        = 0x0100,
+       B2_MAC_2        = 0x0108,
+       B2_MAC_3        = 0x0110,
+       B2_CONN_TYP     = 0x0118,
+       B2_PMD_TYP      = 0x0119,
+       B2_MAC_CFG      = 0x011a,
+       B2_CHIP_ID      = 0x011b,
+       B2_E_0          = 0x011c,
+
+       B2_Y2_CLK_GATE  = 0x011d,
+       B2_Y2_HW_RES    = 0x011e,
+       B2_E_3          = 0x011f,
+       B2_Y2_CLK_CTRL  = 0x0120,
+
+       B2_TI_INI       = 0x0130,
+       B2_TI_VAL       = 0x0134,
+       B2_TI_CTRL      = 0x0138,
+       B2_TI_TEST      = 0x0139,
+
+       B2_TST_CTRL1    = 0x0158,
+       B2_TST_CTRL2    = 0x0159,
+       B2_GP_IO        = 0x015c,
+
+       B2_I2C_CTRL     = 0x0160,
+       B2_I2C_DATA     = 0x0164,
+       B2_I2C_IRQ      = 0x0168,
+       B2_I2C_SW       = 0x016c,
+
+       B3_RAM_ADDR     = 0x0180,
+       B3_RAM_DATA_LO  = 0x0184,
+       B3_RAM_DATA_HI  = 0x0188,
+
+/* RAM Interface Registers */
+/* Yukon-2: use RAM_BUFFER() to access the RAM buffer */
+/*
+ * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
+ * not usable in SW. Please notice these are NOT real timeouts, these are
+ * the number of qWords transferred continuously.
+ */
+#define RAM_BUFFER(port, reg)  (reg | (port <<6))
+
+       B3_RI_WTO_R1    = 0x0190,
+       B3_RI_WTO_XA1   = 0x0191,
+       B3_RI_WTO_XS1   = 0x0192,
+       B3_RI_RTO_R1    = 0x0193,
+       B3_RI_RTO_XA1   = 0x0194,
+       B3_RI_RTO_XS1   = 0x0195,
+       B3_RI_WTO_R2    = 0x0196,
+       B3_RI_WTO_XA2   = 0x0197,
+       B3_RI_WTO_XS2   = 0x0198,
+       B3_RI_RTO_R2    = 0x0199,
+       B3_RI_RTO_XA2   = 0x019a,
+       B3_RI_RTO_XS2   = 0x019b,
+       B3_RI_TO_VAL    = 0x019c,
+       B3_RI_CTRL      = 0x01a0,
+       B3_RI_TEST      = 0x01a2,
+       B3_MA_TOINI_RX1 = 0x01b0,
+       B3_MA_TOINI_RX2 = 0x01b1,
+       B3_MA_TOINI_TX1 = 0x01b2,
+       B3_MA_TOINI_TX2 = 0x01b3,
+       B3_MA_TOVAL_RX1 = 0x01b4,
+       B3_MA_TOVAL_RX2 = 0x01b5,
+       B3_MA_TOVAL_TX1 = 0x01b6,
+       B3_MA_TOVAL_TX2 = 0x01b7,
+       B3_MA_TO_CTRL   = 0x01b8,
+       B3_MA_TO_TEST   = 0x01ba,
+       B3_MA_RCINI_RX1 = 0x01c0,
+       B3_MA_RCINI_RX2 = 0x01c1,
+       B3_MA_RCINI_TX1 = 0x01c2,
+       B3_MA_RCINI_TX2 = 0x01c3,
+       B3_MA_RCVAL_RX1 = 0x01c4,
+       B3_MA_RCVAL_RX2 = 0x01c5,
+       B3_MA_RCVAL_TX1 = 0x01c6,
+       B3_MA_RCVAL_TX2 = 0x01c7,
+       B3_MA_RC_CTRL   = 0x01c8,
+       B3_MA_RC_TEST   = 0x01ca,
+       B3_PA_TOINI_RX1 = 0x01d0,
+       B3_PA_TOINI_RX2 = 0x01d4,
+       B3_PA_TOINI_TX1 = 0x01d8,
+       B3_PA_TOINI_TX2 = 0x01dc,
+       B3_PA_TOVAL_RX1 = 0x01e0,
+       B3_PA_TOVAL_RX2 = 0x01e4,
+       B3_PA_TOVAL_TX1 = 0x01e8,
+       B3_PA_TOVAL_TX2 = 0x01ec,
+       B3_PA_CTRL      = 0x01f0,
+       B3_PA_TEST      = 0x01f2,
+
+       Y2_CFG_SPC      = 0x1c00,
+};
+
+/*     B0_CTST                 16 bit  Control/Status register */
+enum {
+       Y2_VMAIN_AVAIL  = 1<<17,/* VMAIN available (YUKON-2 only) */
+       Y2_VAUX_AVAIL   = 1<<16,/* VAUX available (YUKON-2 only) */
+       Y2_ASF_ENABLE   = 1<<13,/* ASF Unit Enable (YUKON-2 only) */
+       Y2_ASF_DISABLE  = 1<<12,/* ASF Unit Disable (YUKON-2 only) */
+       Y2_CLK_RUN_ENA  = 1<<11,/* CLK_RUN Enable  (YUKON-2 only) */
+       Y2_CLK_RUN_DIS  = 1<<10,/* CLK_RUN Disable (YUKON-2 only) */
+       Y2_LED_STAT_ON  = 1<<9, /* Status LED On  (YUKON-2 only) */
+       Y2_LED_STAT_OFF = 1<<8, /* Status LED Off (YUKON-2 only) */
+
+       CS_ST_SW_IRQ    = 1<<7, /* Set IRQ SW Request */
+       CS_CL_SW_IRQ    = 1<<6, /* Clear IRQ SW Request */
+       CS_STOP_DONE    = 1<<5, /* Stop Master is finished */
+       CS_STOP_MAST    = 1<<4, /* Command Bit to stop the master */
+       CS_MRST_CLR     = 1<<3, /* Clear Master reset   */
+       CS_MRST_SET     = 1<<2, /* Set Master reset     */
+       CS_RST_CLR      = 1<<1, /* Clear Software reset */
+       CS_RST_SET      = 1,    /* Set   Software reset */
+};
+
+/*     B0_LED                   8 Bit  LED register */
+enum {
+/* Bit  7.. 2: reserved */
+       LED_STAT_ON     = 1<<1, /* Status LED on        */
+       LED_STAT_OFF    = 1,    /* Status LED off       */
+};
+
+/*     B0_POWER_CTRL    8 Bit  Power Control reg (YUKON only) */
+enum {
+       PC_VAUX_ENA     = 1<<7, /* Switch VAUX Enable  */
+       PC_VAUX_DIS     = 1<<6, /* Switch VAUX Disable */
+       PC_VCC_ENA      = 1<<5, /* Switch VCC Enable  */
+       PC_VCC_DIS      = 1<<4, /* Switch VCC Disable */
+       PC_VAUX_ON      = 1<<3, /* Switch VAUX On  */
+       PC_VAUX_OFF     = 1<<2, /* Switch VAUX Off */
+       PC_VCC_ON       = 1<<1, /* Switch VCC On  */
+       PC_VCC_OFF      = 1<<0, /* Switch VCC Off */
+};
+
+/*     B2_IRQM_MSK     32 bit  IRQ Moderation Mask */
+
+/*     B0_Y2_SP_ISRC2  32 bit  Special Interrupt Source Reg 2 */
+/*     B0_Y2_SP_ISRC3  32 bit  Special Interrupt Source Reg 3 */
+/*     B0_Y2_SP_EISR   32 bit  Enter ISR Reg */
+/*     B0_Y2_SP_LISR   32 bit  Leave ISR Reg */
+enum {
+       Y2_IS_HW_ERR    = 1<<31,        /* Interrupt HW Error */
+       Y2_IS_STAT_BMU  = 1<<30,        /* Status BMU Interrupt */
+       Y2_IS_ASF       = 1<<29,        /* ASF subsystem Interrupt */
+
+       Y2_IS_POLL_CHK  = 1<<27,        /* Check IRQ from polling unit */
+       Y2_IS_TWSI_RDY  = 1<<26,        /* IRQ on end of TWSI Tx */
+       Y2_IS_IRQ_SW    = 1<<25,        /* SW forced IRQ        */
+       Y2_IS_TIMINT    = 1<<24,        /* IRQ from Timer       */
+
+       Y2_IS_IRQ_PHY2  = 1<<12,        /* Interrupt from PHY 2 */
+       Y2_IS_IRQ_MAC2  = 1<<11,        /* Interrupt from MAC 2 */
+       Y2_IS_CHK_RX2   = 1<<10,        /* Descriptor error Rx 2 */
+       Y2_IS_CHK_TXS2  = 1<<9,         /* Descriptor error TXS 2 */
+       Y2_IS_CHK_TXA2  = 1<<8,         /* Descriptor error TXA 2 */
+
+       Y2_IS_IRQ_PHY1  = 1<<4,         /* Interrupt from PHY 1 */
+       Y2_IS_IRQ_MAC1  = 1<<3,         /* Interrupt from MAC 1 */
+       Y2_IS_CHK_RX1   = 1<<2,         /* Descriptor error Rx 1 */
+       Y2_IS_CHK_TXS1  = 1<<1,         /* Descriptor error TXS 1 */
+       Y2_IS_CHK_TXA1  = 1<<0,         /* Descriptor error TXA 1 */
+
+       Y2_IS_BASE      = Y2_IS_HW_ERR | Y2_IS_STAT_BMU |
+                         Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY |
+                         Y2_IS_IRQ_SW | Y2_IS_TIMINT,
+       Y2_IS_PORT_1    = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 |
+                         Y2_IS_CHK_RX1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXS1,
+       Y2_IS_PORT_2    = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 |
+                         Y2_IS_CHK_RX2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_TXS2,
+};
+
+/*     B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
+enum {
+       IS_ERR_MSK      = 0x00003fff,/*                 All Error bits */
+
+       IS_IRQ_TIST_OV  = 1<<13, /* Time Stamp Timer Overflow (YUKON only) */
+       IS_IRQ_SENSOR   = 1<<12, /* IRQ from Sensor (YUKON only) */
+       IS_IRQ_MST_ERR  = 1<<11, /* IRQ master error detected */
+       IS_IRQ_STAT     = 1<<10, /* IRQ status exception */
+       IS_NO_STAT_M1   = 1<<9, /* No Rx Status from MAC 1 */
+       IS_NO_STAT_M2   = 1<<8, /* No Rx Status from MAC 2 */
+       IS_NO_TIST_M1   = 1<<7, /* No Time Stamp from MAC 1 */
+       IS_NO_TIST_M2   = 1<<6, /* No Time Stamp from MAC 2 */
+       IS_RAM_RD_PAR   = 1<<5, /* RAM Read  Parity Error */
+       IS_RAM_WR_PAR   = 1<<4, /* RAM Write Parity Error */
+       IS_M1_PAR_ERR   = 1<<3, /* MAC 1 Parity Error */
+       IS_M2_PAR_ERR   = 1<<2, /* MAC 2 Parity Error */
+       IS_R1_PAR_ERR   = 1<<1, /* Queue R1 Parity Error */
+       IS_R2_PAR_ERR   = 1<<0, /* Queue R2 Parity Error */
+};
+
+/* Hardware error interrupt mask for Yukon 2 */
+enum {
+       Y2_IS_TIST_OV   = 1<<29,/* Time Stamp Timer overflow interrupt */
+       Y2_IS_SENSOR    = 1<<28, /* Sensor interrupt */
+       Y2_IS_MST_ERR   = 1<<27, /* Master error interrupt */
+       Y2_IS_IRQ_STAT  = 1<<26, /* Status exception interrupt */
+       Y2_IS_PCI_EXP   = 1<<25, /* PCI-Express interrupt */
+       Y2_IS_PCI_NEXP  = 1<<24, /* PCI-Express error similar to PCI error */
+                                               /* Link 2 */
+       Y2_IS_PAR_RD2   = 1<<13, /* Read RAM parity error interrupt */
+       Y2_IS_PAR_WR2   = 1<<12, /* Write RAM parity error interrupt */
+       Y2_IS_PAR_MAC2  = 1<<11, /* MAC hardware fault interrupt */
+       Y2_IS_PAR_RX2   = 1<<10, /* Parity Error Rx Queue 2 */
+       Y2_IS_TCP_TXS2  = 1<<9, /* TCP length mismatch sync Tx queue IRQ */
+       Y2_IS_TCP_TXA2  = 1<<8, /* TCP length mismatch async Tx queue IRQ */
+                                               /* Link 1 */
+       Y2_IS_PAR_RD1   = 1<<5, /* Read RAM parity error interrupt */
+       Y2_IS_PAR_WR1   = 1<<4, /* Write RAM parity error interrupt */
+       Y2_IS_PAR_MAC1  = 1<<3, /* MAC hardware fault interrupt */
+       Y2_IS_PAR_RX1   = 1<<2, /* Parity Error Rx Queue 1 */
+       Y2_IS_TCP_TXS1  = 1<<1, /* TCP length mismatch sync Tx queue IRQ */
+       Y2_IS_TCP_TXA1  = 1<<0, /* TCP length mismatch async Tx queue IRQ */
+
+       Y2_HWE_L1_MASK  = Y2_IS_PAR_RD1 | Y2_IS_PAR_WR1 | Y2_IS_PAR_MAC1 |
+                         Y2_IS_PAR_RX1 | Y2_IS_TCP_TXS1| Y2_IS_TCP_TXA1,
+       Y2_HWE_L2_MASK  = Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |
+                         Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2,
+
+       Y2_HWE_ALL_MASK = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT |
+                         Y2_IS_PCI_EXP |
+                         Y2_HWE_L1_MASK | Y2_HWE_L2_MASK,
+};
+
+/*     B28_DPT_CTRL     8 bit  Descriptor Poll Timer Ctrl Reg */
+enum {
+       DPT_START       = 1<<1,
+       DPT_STOP        = 1<<0,
+};
+
+/*     B2_TST_CTRL1     8 bit  Test Control Register 1 */
+enum {
+       TST_FRC_DPERR_MR = 1<<7, /* force DATAPERR on MST RD */
+       TST_FRC_DPERR_MW = 1<<6, /* force DATAPERR on MST WR */
+       TST_FRC_DPERR_TR = 1<<5, /* force DATAPERR on TRG RD */
+       TST_FRC_DPERR_TW = 1<<4, /* force DATAPERR on TRG WR */
+       TST_FRC_APERR_M  = 1<<3, /* force ADDRPERR on MST */
+       TST_FRC_APERR_T  = 1<<2, /* force ADDRPERR on TRG */
+       TST_CFG_WRITE_ON = 1<<1, /* Enable  Config Reg WR */
+       TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */
+};
+
+/*     B2_MAC_CFG               8 bit  MAC Configuration / Chip Revision */
+enum {
+       CFG_CHIP_R_MSK    = 0xf<<4,     /* Bit 7.. 4: Chip Revision */
+                                       /* Bit 3.. 2:   reserved */
+       CFG_DIS_M2_CLK    = 1<<1,       /* Disable Clock for 2nd MAC */
+       CFG_SNG_MAC       = 1<<0,       /* MAC Config: 0=2 MACs / 1=1 MAC*/
+};
+
+/*     B2_CHIP_ID               8 bit  Chip Identification Number */
+enum {
+       CHIP_ID_GENESIS    = 0x0a, /* Chip ID for GENESIS */
+       CHIP_ID_YUKON      = 0xb0, /* Chip ID for YUKON */
+       CHIP_ID_YUKON_LITE = 0xb1, /* Chip ID for YUKON-Lite (Rev. A1-A3) */
+       CHIP_ID_YUKON_LP   = 0xb2, /* Chip ID for YUKON-LP */
+       CHIP_ID_YUKON_XL   = 0xb3, /* Chip ID for YUKON-2 XL */
+       CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */
+       CHIP_ID_YUKON_EC   = 0xb6, /* Chip ID for YUKON-2 EC */
+       CHIP_ID_YUKON_FE   = 0xb7, /* Chip ID for YUKON-2 FE */
+
+       CHIP_REV_YU_EC_A1    = 0,  /* Chip Rev. for Yukon-EC A1/A0 */
+       CHIP_REV_YU_EC_A2    = 1,  /* Chip Rev. for Yukon-EC A2 */
+       CHIP_REV_YU_EC_A3    = 2,  /* Chip Rev. for Yukon-EC A3 */
+};
+
+/*     B2_Y2_CLK_GATE   8 bit  Clock Gating (Yukon-2 only) */
+enum {
+       Y2_STATUS_LNK2_INAC     = 1<<7, /* Status Link 2 inactive (0 = active) */
+       Y2_CLK_GAT_LNK2_DIS     = 1<<6, /* Disable clock gating Link 2 */
+       Y2_COR_CLK_LNK2_DIS     = 1<<5, /* Disable Core clock Link 2 */
+       Y2_PCI_CLK_LNK2_DIS     = 1<<4, /* Disable PCI clock Link 2 */
+       Y2_STATUS_LNK1_INAC     = 1<<3, /* Status Link 1 inactive (0 = active) */
+       Y2_CLK_GAT_LNK1_DIS     = 1<<2, /* Disable clock gating Link 1 */
+       Y2_COR_CLK_LNK1_DIS     = 1<<1, /* Disable Core clock Link 1 */
+       Y2_PCI_CLK_LNK1_DIS     = 1<<0, /* Disable PCI clock Link 1 */
+};
+
+/*     B2_Y2_HW_RES    8 bit   HW Resources (Yukon-2 only) */
+enum {
+       CFG_LED_MODE_MSK        = 7<<2, /* Bit  4.. 2:  LED Mode Mask */
+       CFG_LINK_2_AVAIL        = 1<<1, /* Link 2 available */
+       CFG_LINK_1_AVAIL        = 1<<0, /* Link 1 available */
+};
+#define CFG_LED_MODE(x)                (((x) & CFG_LED_MODE_MSK) >> 2)
+#define CFG_DUAL_MAC_MSK       (CFG_LINK_2_AVAIL | CFG_LINK_1_AVAIL)
+
+
+/* B2_Y2_CLK_CTRL      32 bit  Clock Frequency Control Register (Yukon-2/EC) */
+enum {
+       Y2_CLK_DIV_VAL_MSK      = 0xff<<16,/* Bit 23..16: Clock Divisor Value */
+#define        Y2_CLK_DIV_VAL(x)       (((x)<<16) & Y2_CLK_DIV_VAL_MSK)
+       Y2_CLK_DIV_VAL2_MSK     = 7<<21,   /* Bit 23..21: Clock Divisor Value */
+       Y2_CLK_SELECT2_MSK      = 0x1f<<16,/* Bit 20..16: Clock Select */
+#define Y2_CLK_DIV_VAL_2(x)    (((x)<<21) & Y2_CLK_DIV_VAL2_MSK)
+#define Y2_CLK_SEL_VAL_2(x)    (((x)<<16) & Y2_CLK_SELECT2_MSK)
+       Y2_CLK_DIV_ENA          = 1<<1, /* Enable  Core Clock Division */
+       Y2_CLK_DIV_DIS          = 1<<0, /* Disable Core Clock Division */
+};
+
+/*     B2_TI_CTRL               8 bit  Timer control */
+/*     B2_IRQM_CTRL     8 bit  IRQ Moderation Timer Control */
+enum {
+       TIM_START       = 1<<2, /* Start Timer */
+       TIM_STOP        = 1<<1, /* Stop  Timer */
+       TIM_CLR_IRQ     = 1<<0, /* Clear Timer IRQ (!IRQM) */
+};
+
+/*     B2_TI_TEST               8 Bit  Timer Test */
+/*     B2_IRQM_TEST     8 bit  IRQ Moderation Timer Test */
+/*     B28_DPT_TST              8 bit  Descriptor Poll Timer Test Reg */
+enum {
+       TIM_T_ON        = 1<<2, /* Test mode on */
+       TIM_T_OFF       = 1<<1, /* Test mode off */
+       TIM_T_STEP      = 1<<0, /* Test step */
+};
+
+/*     B3_RAM_ADDR             32 bit  RAM Address, to read or write */
+                                       /* Bit 31..19:  reserved */
+#define RAM_ADR_RAN    0x0007ffffL     /* Bit 18.. 0:  RAM Address Range */
+/* RAM Interface Registers */
+
+/*     B3_RI_CTRL              16 bit  RAM Interface Control Register */
+enum {
+       RI_CLR_RD_PERR  = 1<<9, /* Clear IRQ RAM Read Parity Err */
+       RI_CLR_WR_PERR  = 1<<8, /* Clear IRQ RAM Write Parity Err*/
+
+       RI_RST_CLR      = 1<<1, /* Clear RAM Interface Reset */
+       RI_RST_SET      = 1<<0, /* Set   RAM Interface Reset */
+};
+
+#define SK_RI_TO_53    36              /* RAM interface timeout */
+
+
+/* Port related registers FIFO, and Arbiter */
+#define SK_REG(port,reg)       (((port)<<7)+(reg))
+
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+/*     TXA_ITI_INI             32 bit  Tx Arb Interval Timer Init Val */
+/*     TXA_ITI_VAL             32 bit  Tx Arb Interval Timer Value */
+/*     TXA_LIM_INI             32 bit  Tx Arb Limit Counter Init Val */
+/*     TXA_LIM_VAL             32 bit  Tx Arb Limit Counter Value */
+
+#define TXA_MAX_VAL    0x00ffffffUL    /* Bit 23.. 0:  Max TXA Timer/Cnt Val */
+
+/*     TXA_CTRL                 8 bit  Tx Arbiter Control Register */
+enum {
+       TXA_ENA_FSYNC   = 1<<7, /* Enable  force of sync Tx queue */
+       TXA_DIS_FSYNC   = 1<<6, /* Disable force of sync Tx queue */
+       TXA_ENA_ALLOC   = 1<<5, /* Enable  alloc of free bandwidth */
+       TXA_DIS_ALLOC   = 1<<4, /* Disable alloc of free bandwidth */
+       TXA_START_RC    = 1<<3, /* Start sync Rate Control */
+       TXA_STOP_RC     = 1<<2, /* Stop  sync Rate Control */
+       TXA_ENA_ARB     = 1<<1, /* Enable  Tx Arbiter */
+       TXA_DIS_ARB     = 1<<0, /* Disable Tx Arbiter */
+};
+
+/*
+ *     Bank 4 - 5
+ */
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+enum {
+       TXA_ITI_INI     = 0x0200,/* 32 bit      Tx Arb Interval Timer Init Val*/
+       TXA_ITI_VAL     = 0x0204,/* 32 bit      Tx Arb Interval Timer Value */
+       TXA_LIM_INI     = 0x0208,/* 32 bit      Tx Arb Limit Counter Init Val */
+       TXA_LIM_VAL     = 0x020c,/* 32 bit      Tx Arb Limit Counter Value */
+       TXA_CTRL        = 0x0210,/*  8 bit      Tx Arbiter Control Register */
+       TXA_TEST        = 0x0211,/*  8 bit      Tx Arbiter Test Register */
+       TXA_STAT        = 0x0212,/*  8 bit      Tx Arbiter Status Register */
+};
+
+
+enum {
+       B6_EXT_REG      = 0x0300,/* External registers (GENESIS only) */
+       B7_CFG_SPC      = 0x0380,/* copy of the Configuration register */
+       B8_RQ1_REGS     = 0x0400,/* Receive Queue 1 */
+       B8_RQ2_REGS     = 0x0480,/* Receive Queue 2 */
+       B8_TS1_REGS     = 0x0600,/* Transmit sync queue 1 */
+       B8_TA1_REGS     = 0x0680,/* Transmit async queue 1 */
+       B8_TS2_REGS     = 0x0700,/* Transmit sync queue 2 */
+       B8_TA2_REGS     = 0x0780,/* Transmit sync queue 2 */
+       B16_RAM_REGS    = 0x0800,/* RAM Buffer Registers */
+};
+
+/* Queue Register Offsets, use Q_ADDR() to access */
+enum {
+       B8_Q_REGS = 0x0400, /* base of Queue registers */
+       Q_D     = 0x00, /* 8*32 bit     Current Descriptor */
+       Q_DA_L  = 0x20, /* 32 bit       Current Descriptor Address Low dWord */
+       Q_DA_H  = 0x24, /* 32 bit       Current Descriptor Address High dWord */
+       Q_AC_L  = 0x28, /* 32 bit       Current Address Counter Low dWord */
+       Q_AC_H  = 0x2c, /* 32 bit       Current Address Counter High dWord */
+       Q_BC    = 0x30, /* 32 bit       Current Byte Counter */
+       Q_CSR   = 0x34, /* 32 bit       BMU Control/Status Register */
+       Q_F     = 0x38, /* 32 bit       Flag Register */
+       Q_T1    = 0x3c, /* 32 bit       Test Register 1 */
+       Q_T1_TR = 0x3c, /*  8 bit       Test Register 1 Transfer SM */
+       Q_T1_WR = 0x3d, /*  8 bit       Test Register 1 Write Descriptor SM */
+       Q_T1_RD = 0x3e, /*  8 bit       Test Register 1 Read Descriptor SM */
+       Q_T1_SV = 0x3f, /*  8 bit       Test Register 1 Supervisor SM */
+       Q_T2    = 0x40, /* 32 bit       Test Register 2 */
+       Q_T3    = 0x44, /* 32 bit       Test Register 3 */
+
+/* Yukon-2 */
+       Q_DONE  = 0x24, /* 16 bit       Done Index              (Yukon-2 only) */
+       Q_WM    = 0x40, /* 16 bit       FIFO Watermark */
+       Q_AL    = 0x42, /*  8 bit       FIFO Alignment */
+       Q_RSP   = 0x44, /* 16 bit       FIFO Read Shadow Pointer */
+       Q_RSL   = 0x46, /*  8 bit       FIFO Read Shadow Level */
+       Q_RP    = 0x48, /*  8 bit       FIFO Read Pointer */
+       Q_RL    = 0x4a, /*  8 bit       FIFO Read Level */
+       Q_WP    = 0x4c, /*  8 bit       FIFO Write Pointer */
+       Q_WSP   = 0x4d, /*  8 bit       FIFO Write Shadow Pointer */
+       Q_WL    = 0x4e, /*  8 bit       FIFO Write Level */
+       Q_WSL   = 0x4f, /*  8 bit       FIFO Write Shadow Level */
+};
+#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
+
+
+/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
+enum {
+       Y2_B8_PREF_REGS         = 0x0450,
+
+       PREF_UNIT_CTRL          = 0x00, /* 32 bit       Control register */
+       PREF_UNIT_LAST_IDX      = 0x04, /* 16 bit       Last Index */
+       PREF_UNIT_ADDR_LO       = 0x08, /* 32 bit       List start addr, low part */
+       PREF_UNIT_ADDR_HI       = 0x0c, /* 32 bit       List start addr, high part*/
+       PREF_UNIT_GET_IDX       = 0x10, /* 16 bit       Get Index */
+       PREF_UNIT_PUT_IDX       = 0x14, /* 16 bit       Put Index */
+       PREF_UNIT_FIFO_WP       = 0x20, /*  8 bit       FIFO write pointer */
+       PREF_UNIT_FIFO_RP       = 0x24, /*  8 bit       FIFO read pointer */
+       PREF_UNIT_FIFO_WM       = 0x28, /*  8 bit       FIFO watermark */
+       PREF_UNIT_FIFO_LEV      = 0x2c, /*  8 bit       FIFO level */
+
+       PREF_UNIT_MASK_IDX      = 0x0fff,
+};
+#define Y2_QADDR(q,reg)                (Y2_B8_PREF_REGS + (q) + (reg))
+
+/* RAM Buffer Register Offsets */
+enum {
+
+       RB_START        = 0x00,/* 32 bit        RAM Buffer Start Address */
+       RB_END  = 0x04,/* 32 bit        RAM Buffer End Address */
+       RB_WP   = 0x08,/* 32 bit        RAM Buffer Write Pointer */
+       RB_RP   = 0x0c,/* 32 bit        RAM Buffer Read Pointer */
+       RB_RX_UTPP      = 0x10,/* 32 bit        Rx Upper Threshold, Pause Packet */
+       RB_RX_LTPP      = 0x14,/* 32 bit        Rx Lower Threshold, Pause Packet */
+       RB_RX_UTHP      = 0x18,/* 32 bit        Rx Upper Threshold, High Prio */
+       RB_RX_LTHP      = 0x1c,/* 32 bit        Rx Lower Threshold, High Prio */
+       /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
+       RB_PC   = 0x20,/* 32 bit        RAM Buffer Packet Counter */
+       RB_LEV  = 0x24,/* 32 bit        RAM Buffer Level Register */
+       RB_CTRL = 0x28,/* 32 bit        RAM Buffer Control Register */
+       RB_TST1 = 0x29,/*  8 bit        RAM Buffer Test Register 1 */
+       RB_TST2 = 0x2a,/*  8 bit        RAM Buffer Test Register 2 */
+};
+
+/* Receive and Transmit Queues */
+enum {
+       Q_R1    = 0x0000,       /* Receive Queue 1 */
+       Q_R2    = 0x0080,       /* Receive Queue 2 */
+       Q_XS1   = 0x0200,       /* Synchronous Transmit Queue 1 */
+       Q_XA1   = 0x0280,       /* Asynchronous Transmit Queue 1 */
+       Q_XS2   = 0x0300,       /* Synchronous Transmit Queue 2 */
+       Q_XA2   = 0x0380,       /* Asynchronous Transmit Queue 2 */
+};
+
+/* Different PHY Types */
+enum {
+       PHY_ADDR_MARV   = 0,
+};
+
+#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs))
+
+
+enum {
+       LNK_SYNC_INI    = 0x0c30,/* 32 bit      Link Sync Cnt Init Value */
+       LNK_SYNC_VAL    = 0x0c34,/* 32 bit      Link Sync Cnt Current Value */
+       LNK_SYNC_CTRL   = 0x0c38,/*  8 bit      Link Sync Cnt Control Register */
+       LNK_SYNC_TST    = 0x0c39,/*  8 bit      Link Sync Cnt Test Register */
+
+       LNK_LED_REG     = 0x0c3c,/*  8 bit      Link LED Register */
+
+/* Receive GMAC FIFO (YUKON and Yukon-2) */
+
+       RX_GMF_EA       = 0x0c40,/* 32 bit      Rx GMAC FIFO End Address */
+       RX_GMF_AF_THR   = 0x0c44,/* 32 bit      Rx GMAC FIFO Almost Full Thresh. */
+       RX_GMF_CTRL_T   = 0x0c48,/* 32 bit      Rx GMAC FIFO Control/Test */
+       RX_GMF_FL_MSK   = 0x0c4c,/* 32 bit      Rx GMAC FIFO Flush Mask */
+       RX_GMF_FL_THR   = 0x0c50,/* 32 bit      Rx GMAC FIFO Flush Threshold */
+       RX_GMF_TR_THR   = 0x0c54,/* 32 bit      Rx Truncation Threshold (Yukon-2) */
+       RX_GMF_UP_THR   = 0x0c58,/*  8 bit      Rx Upper Pause Thr (Yukon-EC_U) */
+       RX_GMF_LP_THR   = 0x0c5a,/*  8 bit      Rx Lower Pause Thr (Yukon-EC_U) */
+       RX_GMF_VLAN     = 0x0c5c,/* 32 bit      Rx VLAN Type Register (Yukon-2) */
+       RX_GMF_WP       = 0x0c60,/* 32 bit      Rx GMAC FIFO Write Pointer */
+
+       RX_GMF_WLEV     = 0x0c68,/* 32 bit      Rx GMAC FIFO Write Level */
+
+       RX_GMF_RP       = 0x0c70,/* 32 bit      Rx GMAC FIFO Read Pointer */
+
+       RX_GMF_RLEV     = 0x0c78,/* 32 bit      Rx GMAC FIFO Read Level */
+};
+
+
+/*     Q_BC                    32 bit  Current Byte Counter */
+
+/* BMU Control Status Registers */
+/*     B0_R1_CSR               32 bit  BMU Ctrl/Stat Rx Queue 1 */
+/*     B0_R2_CSR               32 bit  BMU Ctrl/Stat Rx Queue 2 */
+/*     B0_XA1_CSR              32 bit  BMU Ctrl/Stat Sync Tx Queue 1 */
+/*     B0_XS1_CSR              32 bit  BMU Ctrl/Stat Async Tx Queue 1 */
+/*     B0_XA2_CSR              32 bit  BMU Ctrl/Stat Sync Tx Queue 2 */
+/*     B0_XS2_CSR              32 bit  BMU Ctrl/Stat Async Tx Queue 2 */
+/*     Q_CSR                   32 bit  BMU Control/Status Register */
+
+/* Rx BMU Control / Status Registers (Yukon-2) */
+enum {
+       BMU_IDLE        = 1<<31, /* BMU Idle State */
+       BMU_RX_TCP_PKT  = 1<<30, /* Rx TCP Packet (when RSS Hash enabled) */
+       BMU_RX_IP_PKT   = 1<<29, /* Rx IP  Packet (when RSS Hash enabled) */
+
+       BMU_ENA_RX_RSS_HASH = 1<<15, /* Enable  Rx RSS Hash */
+       BMU_DIS_RX_RSS_HASH = 1<<14, /* Disable Rx RSS Hash */
+       BMU_ENA_RX_CHKSUM = 1<<13, /* Enable  Rx TCP/IP Checksum Check */
+       BMU_DIS_RX_CHKSUM = 1<<12, /* Disable Rx TCP/IP Checksum Check */
+       BMU_CLR_IRQ_PAR = 1<<11, /* Clear IRQ on Parity errors (Rx) */
+       BMU_CLR_IRQ_TCP = 1<<11, /* Clear IRQ on TCP segment. error (Tx) */
+       BMU_CLR_IRQ_CHK = 1<<10, /* Clear IRQ Check */
+       BMU_STOP        = 1<<9, /* Stop  Rx/Tx Queue */
+       BMU_START       = 1<<8, /* Start Rx/Tx Queue */
+       BMU_FIFO_OP_ON  = 1<<7, /* FIFO Operational On */
+       BMU_FIFO_OP_OFF = 1<<6, /* FIFO Operational Off */
+       BMU_FIFO_ENA    = 1<<5, /* Enable FIFO */
+       BMU_FIFO_RST    = 1<<4, /* Reset  FIFO */
+       BMU_OP_ON       = 1<<3, /* BMU Operational On */
+       BMU_OP_OFF      = 1<<2, /* BMU Operational Off */
+       BMU_RST_CLR     = 1<<1, /* Clear BMU Reset (Enable) */
+       BMU_RST_SET     = 1<<0, /* Set   BMU Reset */
+
+       BMU_CLR_RESET   = BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR,
+       BMU_OPER_INIT   = BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START |
+                         BMU_FIFO_ENA | BMU_OP_ON,
+
+       BMU_WM_DEFAULT = 0x600,
+};
+
+/* Tx BMU Control / Status Registers (Yukon-2) */
+                                                               /* Bit 31: same as for Rx */
+enum {
+       BMU_TX_IPIDINCR_ON      = 1<<13, /* Enable  IP ID Increment */
+       BMU_TX_IPIDINCR_OFF     = 1<<12, /* Disable IP ID Increment */
+       BMU_TX_CLR_IRQ_TCP      = 1<<11, /* Clear IRQ on TCP segment length mismatch */
+};
+
+/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
+/* PREF_UNIT_CTRL      32 bit  Prefetch Control register */
+enum {
+       PREF_UNIT_OP_ON         = 1<<3, /* prefetch unit operational */
+       PREF_UNIT_OP_OFF        = 1<<2, /* prefetch unit not operational */
+       PREF_UNIT_RST_CLR       = 1<<1, /* Clear Prefetch Unit Reset */
+       PREF_UNIT_RST_SET       = 1<<0, /* Set   Prefetch Unit Reset */
+};
+
+/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+/*     RB_START                32 bit  RAM Buffer Start Address */
+/*     RB_END                  32 bit  RAM Buffer End Address */
+/*     RB_WP                   32 bit  RAM Buffer Write Pointer */
+/*     RB_RP                   32 bit  RAM Buffer Read Pointer */
+/*     RB_RX_UTPP              32 bit  Rx Upper Threshold, Pause Pack */
+/*     RB_RX_LTPP              32 bit  Rx Lower Threshold, Pause Pack */
+/*     RB_RX_UTHP              32 bit  Rx Upper Threshold, High Prio */
+/*     RB_RX_LTHP              32 bit  Rx Lower Threshold, High Prio */
+/*     RB_PC                   32 bit  RAM Buffer Packet Counter */
+/*     RB_LEV                  32 bit  RAM Buffer Level Register */
+
+#define RB_MSK 0x0007ffff      /* Bit 18.. 0:  RAM Buffer Pointer Bits */
+/*     RB_TST2                  8 bit  RAM Buffer Test Register 2 */
+/*     RB_TST1                  8 bit  RAM Buffer Test Register 1 */
+
+/*     RB_CTRL                  8 bit  RAM Buffer Control Register */
+enum {
+       RB_ENA_STFWD    = 1<<5, /* Enable  Store & Forward */
+       RB_DIS_STFWD    = 1<<4, /* Disable Store & Forward */
+       RB_ENA_OP_MD    = 1<<3, /* Enable  Operation Mode */
+       RB_DIS_OP_MD    = 1<<2, /* Disable Operation Mode */
+       RB_RST_CLR      = 1<<1, /* Clear RAM Buf STM Reset */
+       RB_RST_SET      = 1<<0, /* Set   RAM Buf STM Reset */
+};
+
+
+/* Transmit GMAC FIFO (YUKON only) */
+enum {
+       TX_GMF_EA       = 0x0d40,/* 32 bit      Tx GMAC FIFO End Address */
+       TX_GMF_AE_THR   = 0x0d44,/* 32 bit      Tx GMAC FIFO Almost Empty Thresh.*/
+       TX_GMF_CTRL_T   = 0x0d48,/* 32 bit      Tx GMAC FIFO Control/Test */
+
+       TX_GMF_WP       = 0x0d60,/* 32 bit      Tx GMAC FIFO Write Pointer */
+       TX_GMF_WSP      = 0x0d64,/* 32 bit      Tx GMAC FIFO Write Shadow Ptr. */
+       TX_GMF_WLEV     = 0x0d68,/* 32 bit      Tx GMAC FIFO Write Level */
+
+       TX_GMF_RP       = 0x0d70,/* 32 bit      Tx GMAC FIFO Read Pointer */
+       TX_GMF_RSTP     = 0x0d74,/* 32 bit      Tx GMAC FIFO Restart Pointer */
+       TX_GMF_RLEV     = 0x0d78,/* 32 bit      Tx GMAC FIFO Read Level */
+};
+
+/* Descriptor Poll Timer Registers */
+enum {
+       B28_DPT_INI     = 0x0e00,/* 24 bit      Descriptor Poll Timer Init Val */
+       B28_DPT_VAL     = 0x0e04,/* 24 bit      Descriptor Poll Timer Curr Val */
+       B28_DPT_CTRL    = 0x0e08,/*  8 bit      Descriptor Poll Timer Ctrl Reg */
+
+       B28_DPT_TST     = 0x0e0a,/*  8 bit      Descriptor Poll Timer Test Reg */
+};
+
+/* Time Stamp Timer Registers (YUKON only) */
+enum {
+       GMAC_TI_ST_VAL  = 0x0e14,/* 32 bit      Time Stamp Timer Curr Val */
+       GMAC_TI_ST_CTRL = 0x0e18,/*  8 bit      Time Stamp Timer Ctrl Reg */
+       GMAC_TI_ST_TST  = 0x0e1a,/*  8 bit      Time Stamp Timer Test Reg */
+};
+
+/* Polling Unit Registers (Yukon-2 only) */
+enum {
+       POLL_CTRL       = 0x0e20, /* 32 bit     Polling Unit Control Reg */
+       POLL_LAST_IDX   = 0x0e24,/* 16 bit      Polling Unit List Last Index */
+
+       POLL_LIST_ADDR_LO= 0x0e28,/* 32 bit     Poll. List Start Addr (low) */
+       POLL_LIST_ADDR_HI= 0x0e2c,/* 32 bit     Poll. List Start Addr (high) */
+};
+
+/* ASF Subsystem Registers (Yukon-2 only) */
+enum {
+       B28_Y2_SMB_CONFIG  = 0x0e40,/* 32 bit   ASF SMBus Config Register */
+       B28_Y2_SMB_CSD_REG = 0x0e44,/* 32 bit   ASF SMB Control/Status/Data */
+       B28_Y2_ASF_IRQ_V_BASE=0x0e60,/* 32 bit  ASF IRQ Vector Base */
+
+       B28_Y2_ASF_STAT_CMD= 0x0e68,/* 32 bit   ASF Status and Command Reg */
+       B28_Y2_ASF_HOST_COM= 0x0e6c,/* 32 bit   ASF Host Communication Reg */
+       B28_Y2_DATA_REG_1  = 0x0e70,/* 32 bit   ASF/Host Data Register 1 */
+       B28_Y2_DATA_REG_2  = 0x0e74,/* 32 bit   ASF/Host Data Register 2 */
+       B28_Y2_DATA_REG_3  = 0x0e78,/* 32 bit   ASF/Host Data Register 3 */
+       B28_Y2_DATA_REG_4  = 0x0e7c,/* 32 bit   ASF/Host Data Register 4 */
+};
+
+/* Status BMU Registers (Yukon-2 only)*/
+enum {
+       STAT_CTRL       = 0x0e80,/* 32 bit      Status BMU Control Reg */
+       STAT_LAST_IDX   = 0x0e84,/* 16 bit      Status BMU Last Index */
+
+       STAT_LIST_ADDR_LO= 0x0e88,/* 32 bit     Status List Start Addr (low) */
+       STAT_LIST_ADDR_HI= 0x0e8c,/* 32 bit     Status List Start Addr (high) */
+       STAT_TXA1_RIDX  = 0x0e90,/* 16 bit      Status TxA1 Report Index Reg */
+       STAT_TXS1_RIDX  = 0x0e92,/* 16 bit      Status TxS1 Report Index Reg */
+       STAT_TXA2_RIDX  = 0x0e94,/* 16 bit      Status TxA2 Report Index Reg */
+       STAT_TXS2_RIDX  = 0x0e96,/* 16 bit      Status TxS2 Report Index Reg */
+       STAT_TX_IDX_TH  = 0x0e98,/* 16 bit      Status Tx Index Threshold Reg */
+       STAT_PUT_IDX    = 0x0e9c,/* 16 bit      Status Put Index Reg */
+
+/* FIFO Control/Status Registers (Yukon-2 only)*/
+       STAT_FIFO_WP    = 0x0ea0,/*  8 bit      Status FIFO Write Pointer Reg */
+       STAT_FIFO_RP    = 0x0ea4,/*  8 bit      Status FIFO Read Pointer Reg */
+       STAT_FIFO_RSP   = 0x0ea6,/*  8 bit      Status FIFO Read Shadow Ptr */
+       STAT_FIFO_LEVEL = 0x0ea8,/*  8 bit      Status FIFO Level Reg */
+       STAT_FIFO_SHLVL = 0x0eaa,/*  8 bit      Status FIFO Shadow Level Reg */
+       STAT_FIFO_WM    = 0x0eac,/*  8 bit      Status FIFO Watermark Reg */
+       STAT_FIFO_ISR_WM= 0x0ead,/*  8 bit      Status FIFO ISR Watermark Reg */
+
+/* Level and ISR Timer Registers (Yukon-2 only)*/
+       STAT_LEV_TIMER_INI= 0x0eb0,/* 32 bit    Level Timer Init. Value Reg */
+       STAT_LEV_TIMER_CNT= 0x0eb4,/* 32 bit    Level Timer Counter Reg */
+       STAT_LEV_TIMER_CTRL= 0x0eb8,/*  8 bit   Level Timer Control Reg */
+       STAT_LEV_TIMER_TEST= 0x0eb9,/*  8 bit   Level Timer Test Reg */
+       STAT_TX_TIMER_INI  = 0x0ec0,/* 32 bit   Tx Timer Init. Value Reg */
+       STAT_TX_TIMER_CNT  = 0x0ec4,/* 32 bit   Tx Timer Counter Reg */
+       STAT_TX_TIMER_CTRL = 0x0ec8,/*  8 bit   Tx Timer Control Reg */
+       STAT_TX_TIMER_TEST = 0x0ec9,/*  8 bit   Tx Timer Test Reg */
+       STAT_ISR_TIMER_INI = 0x0ed0,/* 32 bit   ISR Timer Init. Value Reg */
+       STAT_ISR_TIMER_CNT = 0x0ed4,/* 32 bit   ISR Timer Counter Reg */
+       STAT_ISR_TIMER_CTRL= 0x0ed8,/*  8 bit   ISR Timer Control Reg */
+       STAT_ISR_TIMER_TEST= 0x0ed9,/*  8 bit   ISR Timer Test Reg */
+};
+
+enum {
+       LINKLED_OFF          = 0x01,
+       LINKLED_ON           = 0x02,
+       LINKLED_LINKSYNC_OFF = 0x04,
+       LINKLED_LINKSYNC_ON  = 0x08,
+       LINKLED_BLINK_OFF    = 0x10,
+       LINKLED_BLINK_ON     = 0x20,
+};
+
+/* GMAC and GPHY Control Registers (YUKON only) */
+enum {
+       GMAC_CTRL       = 0x0f00,/* 32 bit      GMAC Control Reg */
+       GPHY_CTRL       = 0x0f04,/* 32 bit      GPHY Control Reg */
+       GMAC_IRQ_SRC    = 0x0f08,/*  8 bit      GMAC Interrupt Source Reg */
+       GMAC_IRQ_MSK    = 0x0f0c,/*  8 bit      GMAC Interrupt Mask Reg */
+       GMAC_LINK_CTRL  = 0x0f10,/* 16 bit      Link Control Reg */
+
+/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
+
+       WOL_REG_OFFS    = 0x20,/* HW-Bug: Address is + 0x20 against spec. */
+
+       WOL_CTRL_STAT   = 0x0f20,/* 16 bit      WOL Control/Status Reg */
+       WOL_MATCH_CTL   = 0x0f22,/*  8 bit      WOL Match Control Reg */
+       WOL_MATCH_RES   = 0x0f23,/*  8 bit      WOL Match Result Reg */
+       WOL_MAC_ADDR    = 0x0f24,/* 32 bit      WOL MAC Address */
+       WOL_PATT_PME    = 0x0f2a,/*  8 bit      WOL PME Match Enable (Yukon-2) */
+       WOL_PATT_ASFM   = 0x0f2b,/*  8 bit      WOL ASF Match Enable (Yukon-2) */
+       WOL_PATT_RPTR   = 0x0f2c,/*  8 bit      WOL Pattern Read Pointer */
+
+/* WOL Pattern Length Registers (YUKON only) */
+
+       WOL_PATT_LEN_LO = 0x0f30,/* 32 bit      WOL Pattern Length 3..0 */
+       WOL_PATT_LEN_HI = 0x0f34,/* 24 bit      WOL Pattern Length 6..4 */
+
+/* WOL Pattern Counter Registers (YUKON only) */
+
+
+       WOL_PATT_CNT_0  = 0x0f38,/* 32 bit      WOL Pattern Counter 3..0 */
+       WOL_PATT_CNT_4  = 0x0f3c,/* 24 bit      WOL Pattern Counter 6..4 */
+};
+
+enum {
+       WOL_PATT_RAM_1  = 0x1000,/*  WOL Pattern RAM Link 1 */
+       WOL_PATT_RAM_2  = 0x1400,/*  WOL Pattern RAM Link 2 */
+};
+
+enum {
+       BASE_GMAC_1     = 0x2800,/* GMAC 1 registers */
+       BASE_GMAC_2     = 0x3800,/* GMAC 2 registers */
+};
+
+/*
+ * Marvel-PHY Registers, indirect addressed over GMAC
+ */
+enum {
+       PHY_MARV_CTRL           = 0x00,/* 16 bit r/w    PHY Control Register */
+       PHY_MARV_STAT           = 0x01,/* 16 bit r/o    PHY Status Register */
+       PHY_MARV_ID0            = 0x02,/* 16 bit r/o    PHY ID0 Register */
+       PHY_MARV_ID1            = 0x03,/* 16 bit r/o    PHY ID1 Register */
+       PHY_MARV_AUNE_ADV       = 0x04,/* 16 bit r/w    Auto-Neg. Advertisement */
+       PHY_MARV_AUNE_LP        = 0x05,/* 16 bit r/o    Link Part Ability Reg */
+       PHY_MARV_AUNE_EXP       = 0x06,/* 16 bit r/o    Auto-Neg. Expansion Reg */
+       PHY_MARV_NEPG           = 0x07,/* 16 bit r/w    Next Page Register */
+       PHY_MARV_NEPG_LP        = 0x08,/* 16 bit r/o    Next Page Link Partner */
+       /* Marvel-specific registers */
+       PHY_MARV_1000T_CTRL     = 0x09,/* 16 bit r/w    1000Base-T Control Reg */
+       PHY_MARV_1000T_STAT     = 0x0a,/* 16 bit r/o    1000Base-T Status Reg */
+       PHY_MARV_EXT_STAT       = 0x0f,/* 16 bit r/o    Extended Status Reg */
+       PHY_MARV_PHY_CTRL       = 0x10,/* 16 bit r/w    PHY Specific Ctrl Reg */
+       PHY_MARV_PHY_STAT       = 0x11,/* 16 bit r/o    PHY Specific Stat Reg */
+       PHY_MARV_INT_MASK       = 0x12,/* 16 bit r/w    Interrupt Mask Reg */
+       PHY_MARV_INT_STAT       = 0x13,/* 16 bit r/o    Interrupt Status Reg */
+       PHY_MARV_EXT_CTRL       = 0x14,/* 16 bit r/w    Ext. PHY Specific Ctrl */
+       PHY_MARV_RXE_CNT        = 0x15,/* 16 bit r/w    Receive Error Counter */
+       PHY_MARV_EXT_ADR        = 0x16,/* 16 bit r/w    Ext. Ad. for Cable Diag. */
+       PHY_MARV_PORT_IRQ       = 0x17,/* 16 bit r/o    Port 0 IRQ (88E1111 only) */
+       PHY_MARV_LED_CTRL       = 0x18,/* 16 bit r/w    LED Control Reg */
+       PHY_MARV_LED_OVER       = 0x19,/* 16 bit r/w    Manual LED Override Reg */
+       PHY_MARV_EXT_CTRL_2     = 0x1a,/* 16 bit r/w    Ext. PHY Specific Ctrl 2 */
+       PHY_MARV_EXT_P_STAT     = 0x1b,/* 16 bit r/w    Ext. PHY Spec. Stat Reg */
+       PHY_MARV_CABLE_DIAG     = 0x1c,/* 16 bit r/o    Cable Diagnostic Reg */
+       PHY_MARV_PAGE_ADDR      = 0x1d,/* 16 bit r/w    Extended Page Address Reg */
+       PHY_MARV_PAGE_DATA      = 0x1e,/* 16 bit r/w    Extended Page Data Reg */
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+       PHY_MARV_FE_LED_PAR     = 0x16,/* 16 bit r/w    LED Parallel Select Reg. */
+       PHY_MARV_FE_LED_SER     = 0x17,/* 16 bit r/w    LED Stream Select S. LED */
+       PHY_MARV_FE_VCT_TX      = 0x1a,/* 16 bit r/w    VCT Reg. for TXP/N Pins */
+       PHY_MARV_FE_VCT_RX      = 0x1b,/* 16 bit r/o    VCT Reg. for RXP/N Pins */
+       PHY_MARV_FE_SPEC_2      = 0x1c,/* 16 bit r/w    Specific Control Reg. 2 */
+};
+
+enum {
+       PHY_CT_RESET    = 1<<15, /* Bit 15: (sc)        clear all PHY related regs */
+       PHY_CT_LOOP     = 1<<14, /* Bit 14:     enable Loopback over PHY */
+       PHY_CT_SPS_LSB  = 1<<13, /* Bit 13:     Speed select, lower bit */
+       PHY_CT_ANE      = 1<<12, /* Bit 12:     Auto-Negotiation Enabled */
+       PHY_CT_PDOWN    = 1<<11, /* Bit 11:     Power Down Mode */
+       PHY_CT_ISOL     = 1<<10, /* Bit 10:     Isolate Mode */
+       PHY_CT_RE_CFG   = 1<<9, /* Bit  9:      (sc) Restart Auto-Negotiation */
+       PHY_CT_DUP_MD   = 1<<8, /* Bit  8:      Duplex Mode */
+       PHY_CT_COL_TST  = 1<<7, /* Bit  7:      Collision Test enabled */
+       PHY_CT_SPS_MSB  = 1<<6, /* Bit  6:      Speed select, upper bit */
+};
+
+enum {
+       PHY_CT_SP1000   = PHY_CT_SPS_MSB, /* enable speed of 1000 Mbps */
+       PHY_CT_SP100    = PHY_CT_SPS_LSB, /* enable speed of  100 Mbps */
+       PHY_CT_SP10     = 0,              /* enable speed of   10 Mbps */
+};
+
+enum {
+       PHY_ST_EXT_ST   = 1<<8, /* Bit  8:      Extended Status Present */
+
+       PHY_ST_PRE_SUP  = 1<<6, /* Bit  6:      Preamble Suppression */
+       PHY_ST_AN_OVER  = 1<<5, /* Bit  5:      Auto-Negotiation Over */
+       PHY_ST_REM_FLT  = 1<<4, /* Bit  4:      Remote Fault Condition Occured */
+       PHY_ST_AN_CAP   = 1<<3, /* Bit  3:      Auto-Negotiation Capability */
+       PHY_ST_LSYNC    = 1<<2, /* Bit  2:      Link Synchronized */
+       PHY_ST_JAB_DET  = 1<<1, /* Bit  1:      Jabber Detected */
+       PHY_ST_EXT_REG  = 1<<0, /* Bit  0:      Extended Register available */
+};
+
+enum {
+       PHY_I1_OUI_MSK  = 0x3f<<10, /* Bit 15..10:      Organization Unique ID */
+       PHY_I1_MOD_NUM  = 0x3f<<4, /* Bit  9.. 4:       Model Number */
+       PHY_I1_REV_MSK  = 0xf, /* Bit  3.. 0:   Revision Number */
+};
+
+/* different Marvell PHY Ids */
+enum {
+       PHY_MARV_ID0_VAL= 0x0141, /* Marvell Unique Identifier */
+
+       PHY_BCOM_ID1_A1 = 0x6041,
+       PHY_BCOM_ID1_B2 = 0x6043,
+       PHY_BCOM_ID1_C0 = 0x6044,
+       PHY_BCOM_ID1_C5 = 0x6047,
+
+       PHY_MARV_ID1_B0 = 0x0C23, /* Yukon (PHY 88E1011) */
+       PHY_MARV_ID1_B2 = 0x0C25, /* Yukon-Plus (PHY 88E1011) */
+       PHY_MARV_ID1_C2 = 0x0CC2, /* Yukon-EC (PHY 88E1111) */
+       PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
+};
+
+/* Advertisement register bits */
+enum {
+       PHY_AN_NXT_PG   = 1<<15, /* Bit 15:     Request Next Page */
+       PHY_AN_ACK      = 1<<14, /* Bit 14:     (ro) Acknowledge Received */
+       PHY_AN_RF       = 1<<13, /* Bit 13:     Remote Fault Bits */
+
+       PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11:    Try for asymmetric */
+       PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10:    Try for pause */
+       PHY_AN_100BASE4 = 1<<9, /* Bit 9:       Try for 100mbps 4k packets */
+       PHY_AN_100FULL  = 1<<8, /* Bit 8:       Try for 100mbps full-duplex */
+       PHY_AN_100HALF  = 1<<7, /* Bit 7:       Try for 100mbps half-duplex */
+       PHY_AN_10FULL   = 1<<6, /* Bit 6:       Try for 10mbps full-duplex */
+       PHY_AN_10HALF   = 1<<5, /* Bit 5:       Try for 10mbps half-duplex */
+       PHY_AN_CSMA     = 1<<0, /* Bit 0:       Only selector supported */
+       PHY_AN_SEL      = 0x1f, /* Bit 4..0:    Selector Field, 00001=Ethernet*/
+       PHY_AN_FULL     = PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA,
+       PHY_AN_ALL      = PHY_AN_10HALF | PHY_AN_10FULL |
+                         PHY_AN_100HALF | PHY_AN_100FULL,
+};
+
+/*****  PHY_BCOM_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
+/*****  PHY_MARV_1000T_STAT    16 bit r/o      1000Base-T Status Reg *****/
+enum {
+       PHY_B_1000S_MSF = 1<<15, /* Bit 15:     Master/Slave Fault */
+       PHY_B_1000S_MSR = 1<<14, /* Bit 14:     Master/Slave Result */
+       PHY_B_1000S_LRS = 1<<13, /* Bit 13:     Local Receiver Status */
+       PHY_B_1000S_RRS = 1<<12, /* Bit 12:     Remote Receiver Status */
+       PHY_B_1000S_LP_FD       = 1<<11, /* Bit 11:     Link Partner can FD */
+       PHY_B_1000S_LP_HD       = 1<<10, /* Bit 10:     Link Partner can HD */
+                                                                       /* Bit  9..8:   reserved */
+       PHY_B_1000S_IEC = 0xff, /* Bit  7..0:   Idle Error Count */
+};
+
+/** Marvell-Specific */
+enum {
+       PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */
+       PHY_M_AN_ACK    = 1<<14, /* (ro)        Acknowledge Received */
+       PHY_M_AN_RF     = 1<<13, /* Remote Fault */
+
+       PHY_M_AN_ASP    = 1<<11, /* Asymmetric Pause */
+       PHY_M_AN_PC     = 1<<10, /* MAC Pause implemented */
+       PHY_M_AN_100_T4 = 1<<9, /* Not cap. 100Base-T4 (always 0) */
+       PHY_M_AN_100_FD = 1<<8, /* Advertise 100Base-TX Full Duplex */
+       PHY_M_AN_100_HD = 1<<7, /* Advertise 100Base-TX Half Duplex */
+       PHY_M_AN_10_FD  = 1<<6, /* Advertise 10Base-TX Full Duplex */
+       PHY_M_AN_10_HD  = 1<<5, /* Advertise 10Base-TX Half Duplex */
+       PHY_M_AN_SEL_MSK =0x1f<<4,      /* Bit  4.. 0: Selector Field Mask */
+};
+
+/* special defines for FIBER (88E1011S only) */
+enum {
+       PHY_M_AN_ASP_X  = 1<<8, /* Asymmetric Pause */
+       PHY_M_AN_PC_X   = 1<<7, /* MAC Pause implemented */
+       PHY_M_AN_1000X_AHD      = 1<<6, /* Advertise 10000Base-X Half Duplex */
+       PHY_M_AN_1000X_AFD      = 1<<5, /* Advertise 10000Base-X Full Duplex */
+};
+
+/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
+enum {
+       PHY_M_P_NO_PAUSE_X      = 0<<7,/* Bit  8.. 7:   no Pause Mode */
+       PHY_M_P_SYM_MD_X        = 1<<7, /* Bit  8.. 7:  symmetric Pause Mode */
+       PHY_M_P_ASYM_MD_X       = 2<<7,/* Bit  8.. 7:   asymmetric Pause Mode */
+       PHY_M_P_BOTH_MD_X       = 3<<7,/* Bit  8.. 7:   both Pause Mode */
+};
+
+/*****  PHY_MARV_1000T_CTRL    16 bit r/w      1000Base-T Control Reg *****/
+enum {
+       PHY_M_1000C_TEST        = 7<<13,/* Bit 15..13:  Test Modes */
+       PHY_M_1000C_MSE = 1<<12, /* Manual Master/Slave Enable */
+       PHY_M_1000C_MSC = 1<<11, /* M/S Configuration (1=Master) */
+       PHY_M_1000C_MPD = 1<<10, /* Multi-Port Device */
+       PHY_M_1000C_AFD = 1<<9, /* Advertise Full Duplex */
+       PHY_M_1000C_AHD = 1<<8, /* Advertise Half Duplex */
+};
+
+/*****  PHY_MARV_PHY_CTRL      16 bit r/w      PHY Specific Ctrl Reg *****/
+enum {
+       PHY_M_PC_TX_FFD_MSK     = 3<<14,/* Bit 15..14: Tx FIFO Depth Mask */
+       PHY_M_PC_RX_FFD_MSK     = 3<<12,/* Bit 13..12: Rx FIFO Depth Mask */
+       PHY_M_PC_ASS_CRS_TX     = 1<<11, /* Assert CRS on Transmit */
+       PHY_M_PC_FL_GOOD        = 1<<10, /* Force Link Good */
+       PHY_M_PC_EN_DET_MSK     = 3<<8,/* Bit  9.. 8: Energy Detect Mask */
+       PHY_M_PC_ENA_EXT_D      = 1<<7, /* Enable Ext. Distance (10BT) */
+       PHY_M_PC_MDIX_MSK       = 3<<5,/* Bit  6.. 5: MDI/MDIX Config. Mask */
+       PHY_M_PC_DIS_125CLK     = 1<<4, /* Disable 125 CLK */
+       PHY_M_PC_MAC_POW_UP     = 1<<3, /* MAC Power up */
+       PHY_M_PC_SQE_T_ENA      = 1<<2, /* SQE Test Enabled */
+       PHY_M_PC_POL_R_DIS      = 1<<1, /* Polarity Reversal Disabled */
+       PHY_M_PC_DIS_JABBER     = 1<<0, /* Disable Jabber */
+};
+
+enum {
+       PHY_M_PC_EN_DET         = 2<<8, /* Energy Detect (Mode 1) */
+       PHY_M_PC_EN_DET_PLUS    = 3<<8, /* Energy Detect Plus (Mode 2) */
+};
+
+#define PHY_M_PC_MDI_XMODE(x)  (((x)<<5) & PHY_M_PC_MDIX_MSK)
+
+enum {
+       PHY_M_PC_MAN_MDI        = 0, /* 00 = Manual MDI configuration */
+       PHY_M_PC_MAN_MDIX       = 1, /* 01 = Manual MDIX configuration */
+       PHY_M_PC_ENA_AUTO       = 3, /* 11 = Enable Automatic Crossover */
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+       PHY_M_PC_ENA_DTE_DT     = 1<<15, /* Enable Data Terminal Equ. (DTE) Detect */
+       PHY_M_PC_ENA_ENE_DT     = 1<<14, /* Enable Energy Detect (sense & pulse) */
+       PHY_M_PC_DIS_NLP_CK     = 1<<13, /* Disable Normal Link Puls (NLP) Check */
+       PHY_M_PC_ENA_LIP_NP     = 1<<12, /* Enable Link Partner Next Page Reg. */
+       PHY_M_PC_DIS_NLP_GN     = 1<<11, /* Disable Normal Link Puls Generation */
+
+       PHY_M_PC_DIS_SCRAMB     = 1<<9, /* Disable Scrambler */
+       PHY_M_PC_DIS_FEFI       = 1<<8, /* Disable Far End Fault Indic. (FEFI) */
+
+       PHY_M_PC_SH_TP_SEL      = 1<<6, /* Shielded Twisted Pair Select */
+       PHY_M_PC_RX_FD_MSK      = 3<<2,/* Bit  3.. 2: Rx FIFO Depth Mask */
+};
+
+/*****  PHY_MARV_PHY_STAT      16 bit r/o      PHY Specific Status Reg *****/
+enum {
+       PHY_M_PS_SPEED_MSK      = 3<<14, /* Bit 15..14: Speed Mask */
+       PHY_M_PS_SPEED_1000     = 1<<15, /*             10 = 1000 Mbps */
+       PHY_M_PS_SPEED_100      = 1<<14, /*             01 =  100 Mbps */
+       PHY_M_PS_SPEED_10       = 0,     /*             00 =   10 Mbps */
+       PHY_M_PS_FULL_DUP       = 1<<13, /* Full Duplex */
+       PHY_M_PS_PAGE_REC       = 1<<12, /* Page Received */
+       PHY_M_PS_SPDUP_RES      = 1<<11, /* Speed & Duplex Resolved */
+       PHY_M_PS_LINK_UP        = 1<<10, /* Link Up */
+       PHY_M_PS_CABLE_MSK      = 7<<7,  /* Bit  9.. 7: Cable Length Mask */
+       PHY_M_PS_MDI_X_STAT     = 1<<6,  /* MDI Crossover Stat (1=MDIX) */
+       PHY_M_PS_DOWNS_STAT     = 1<<5,  /* Downshift Status (1=downsh.) */
+       PHY_M_PS_ENDET_STAT     = 1<<4,  /* Energy Detect Status (1=act) */
+       PHY_M_PS_TX_P_EN        = 1<<3,  /* Tx Pause Enabled */
+       PHY_M_PS_RX_P_EN        = 1<<2,  /* Rx Pause Enabled */
+       PHY_M_PS_POL_REV        = 1<<1,  /* Polarity Reversed */
+       PHY_M_PS_JABBER         = 1<<0,  /* Jabber */
+};
+
+#define PHY_M_PS_PAUSE_MSK     (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+       PHY_M_PS_DTE_DETECT     = 1<<15, /* Data Terminal Equipment (DTE) Detected */
+       PHY_M_PS_RES_SPEED      = 1<<14, /* Resolved Speed (1=100 Mbps, 0=10 Mbps */
+};
+
+enum {
+       PHY_M_IS_AN_ERROR       = 1<<15, /* Auto-Negotiation Error */
+       PHY_M_IS_LSP_CHANGE     = 1<<14, /* Link Speed Changed */
+       PHY_M_IS_DUP_CHANGE     = 1<<13, /* Duplex Mode Changed */
+       PHY_M_IS_AN_PR          = 1<<12, /* Page Received */
+       PHY_M_IS_AN_COMPL       = 1<<11, /* Auto-Negotiation Completed */
+       PHY_M_IS_LST_CHANGE     = 1<<10, /* Link Status Changed */
+       PHY_M_IS_SYMB_ERROR     = 1<<9, /* Symbol Error */
+       PHY_M_IS_FALSE_CARR     = 1<<8, /* False Carrier */
+       PHY_M_IS_FIFO_ERROR     = 1<<7, /* FIFO Overflow/Underrun Error */
+       PHY_M_IS_MDI_CHANGE     = 1<<6, /* MDI Crossover Changed */
+       PHY_M_IS_DOWNSH_DET     = 1<<5, /* Downshift Detected */
+       PHY_M_IS_END_CHANGE     = 1<<4, /* Energy Detect Changed */
+
+       PHY_M_IS_DTE_CHANGE     = 1<<2, /* DTE Power Det. Status Changed */
+       PHY_M_IS_POL_CHANGE     = 1<<1, /* Polarity Changed */
+       PHY_M_IS_JABBER         = 1<<0, /* Jabber */
+
+       PHY_M_DEF_MSK           = PHY_M_IS_LSP_CHANGE | PHY_M_IS_LST_CHANGE
+                                | PHY_M_IS_FIFO_ERROR,
+       PHY_M_AN_MSK           = PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL,
+};
+
+
+/*****  PHY_MARV_EXT_CTRL      16 bit r/w      Ext. PHY Specific Ctrl *****/
+enum {
+       PHY_M_EC_ENA_BC_EXT = 1<<15, /* Enable Block Carr. Ext. (88E1111 only) */
+       PHY_M_EC_ENA_LIN_LB = 1<<14, /* Enable Line Loopback (88E1111 only) */
+
+       PHY_M_EC_DIS_LINK_P = 1<<12, /* Disable Link Pulses (88E1111 only) */
+       PHY_M_EC_M_DSC_MSK  = 3<<10, /* Bit 11..10:     Master Downshift Counter */
+                                       /* (88E1011 only) */
+       PHY_M_EC_S_DSC_MSK  = 3<<8,/* Bit  9.. 8:       Slave  Downshift Counter */
+                                      /* (88E1011 only) */
+       PHY_M_EC_M_DSC_MSK2 = 7<<9,/* Bit 11.. 9:       Master Downshift Counter */
+                                       /* (88E1111 only) */
+       PHY_M_EC_DOWN_S_ENA = 1<<8, /* Downshift Enable (88E1111 only) */
+                                       /* !!! Errata in spec. (1 = disable) */
+       PHY_M_EC_RX_TIM_CT  = 1<<7, /* RGMII Rx Timing Control*/
+       PHY_M_EC_MAC_S_MSK  = 7<<4,/* Bit  6.. 4:       Def. MAC interface speed */
+       PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
+       PHY_M_EC_DTE_D_ENA  = 1<<2, /* DTE Detect Enable (88E1111 only) */
+       PHY_M_EC_TX_TIM_CT  = 1<<1, /* RGMII Tx Timing Control */
+       PHY_M_EC_TRANS_DIS  = 1<<0, /* Transmitter Disable (88E1111 only) */};
+
+#define PHY_M_EC_M_DSC(x)      ((x)<<10 & PHY_M_EC_M_DSC_MSK)
+                                       /* 00=1x; 01=2x; 10=3x; 11=4x */
+#define PHY_M_EC_S_DSC(x)      ((x)<<8 & PHY_M_EC_S_DSC_MSK)
+                                       /* 00=dis; 01=1x; 10=2x; 11=3x */
+#define PHY_M_EC_DSC_2(x)      ((x)<<9 & PHY_M_EC_M_DSC_MSK2)
+                                       /* 000=1x; 001=2x; 010=3x; 011=4x */
+#define PHY_M_EC_MAC_S(x)      ((x)<<4 & PHY_M_EC_MAC_S_MSK)
+                                       /* 01X=0; 110=2.5; 111=25 (MHz) */
+
+/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+enum {
+       PHY_M_PC_DIS_LINK_Pa    = 1<<15,/* Disable Link Pulses */
+       PHY_M_PC_DSC_MSK        = 7<<12,/* Bit 14..12:  Downshift Counter */
+       PHY_M_PC_DOWN_S_ENA     = 1<<11,/* Downshift Enable */
+};
+/* !!! Errata in spec. (1 = disable) */
+
+#define PHY_M_PC_DSC(x)                        (((x)<<12) & PHY_M_PC_DSC_MSK)
+                                                                                       /* 100=5x; 101=6x; 110=7x; 111=8x */
+enum {
+       MAC_TX_CLK_0_MHZ        = 2,
+       MAC_TX_CLK_2_5_MHZ      = 6,
+       MAC_TX_CLK_25_MHZ       = 7,
+};
+
+/*****  PHY_MARV_LED_CTRL      16 bit r/w      LED Control Reg *****/
+enum {
+       PHY_M_LEDC_DIS_LED      = 1<<15, /* Disable LED */
+       PHY_M_LEDC_PULS_MSK     = 7<<12,/* Bit 14..12: Pulse Stretch Mask */
+       PHY_M_LEDC_F_INT        = 1<<11, /* Force Interrupt */
+       PHY_M_LEDC_BL_R_MSK     = 7<<8,/* Bit 10.. 8: Blink Rate Mask */
+       PHY_M_LEDC_DP_C_LSB     = 1<<7, /* Duplex Control (LSB, 88E1111 only) */
+       PHY_M_LEDC_TX_C_LSB     = 1<<6, /* Tx Control (LSB, 88E1111 only) */
+       PHY_M_LEDC_LK_C_MSK     = 7<<3,/* Bit  5.. 3: Link Control Mask */
+                                       /* (88E1111 only) */
+};
+
+enum {
+       PHY_M_LEDC_LINK_MSK     = 3<<3,/* Bit  4.. 3: Link Control Mask */
+                                                                       /* (88E1011 only) */
+       PHY_M_LEDC_DP_CTRL      = 1<<2, /* Duplex Control */
+       PHY_M_LEDC_DP_C_MSB     = 1<<2, /* Duplex Control (MSB, 88E1111 only) */
+       PHY_M_LEDC_RX_CTRL      = 1<<1, /* Rx Activity / Link */
+       PHY_M_LEDC_TX_CTRL      = 1<<0, /* Tx Activity / Link */
+       PHY_M_LEDC_TX_C_MSB     = 1<<0, /* Tx Control (MSB, 88E1111 only) */
+};
+
+#define PHY_M_LED_PULS_DUR(x)  (((x)<<12) & PHY_M_LEDC_PULS_MSK)
+
+/*****  PHY_MARV_PHY_STAT (page 3)16 bit r/w   Polarity Control Reg. *****/
+enum {
+       PHY_M_POLC_LS1M_MSK     = 0xf<<12, /* Bit 15..12: LOS,STAT1 Mix % Mask */
+       PHY_M_POLC_IS0M_MSK     = 0xf<<8,  /* Bit 11.. 8: INIT,STAT0 Mix % Mask */
+       PHY_M_POLC_LOS_MSK      = 0x3<<6,  /* Bit  7.. 6: LOS Pol. Ctrl. Mask */
+       PHY_M_POLC_INIT_MSK     = 0x3<<4,  /* Bit  5.. 4: INIT Pol. Ctrl. Mask */
+       PHY_M_POLC_STA1_MSK     = 0x3<<2,  /* Bit  3.. 2: STAT1 Pol. Ctrl. Mask */
+       PHY_M_POLC_STA0_MSK     = 0x3,     /* Bit  1.. 0: STAT0 Pol. Ctrl. Mask */
+};
+
+#define PHY_M_POLC_LS1_P_MIX(x)        (((x)<<12) & PHY_M_POLC_LS1M_MSK)
+#define PHY_M_POLC_IS0_P_MIX(x)        (((x)<<8) & PHY_M_POLC_IS0M_MSK)
+#define PHY_M_POLC_LOS_CTRL(x) (((x)<<6) & PHY_M_POLC_LOS_MSK)
+#define PHY_M_POLC_INIT_CTRL(x)        (((x)<<4) & PHY_M_POLC_INIT_MSK)
+#define PHY_M_POLC_STA1_CTRL(x)        (((x)<<2) & PHY_M_POLC_STA1_MSK)
+#define PHY_M_POLC_STA0_CTRL(x)        (((x)<<0) & PHY_M_POLC_STA0_MSK)
+
+enum {
+       PULS_NO_STR     = 0,/* no pulse stretching */
+       PULS_21MS       = 1,/* 21 ms to 42 ms */
+       PULS_42MS       = 2,/* 42 ms to 84 ms */
+       PULS_84MS       = 3,/* 84 ms to 170 ms */
+       PULS_170MS      = 4,/* 170 ms to 340 ms */
+       PULS_340MS      = 5,/* 340 ms to 670 ms */
+       PULS_670MS      = 6,/* 670 ms to 1.3 s */
+       PULS_1300MS     = 7,/* 1.3 s to 2.7 s */
+};
+
+#define PHY_M_LED_BLINK_RT(x)  (((x)<<8) & PHY_M_LEDC_BL_R_MSK)
+
+enum {
+       BLINK_42MS      = 0,/* 42 ms */
+       BLINK_84MS      = 1,/* 84 ms */
+       BLINK_170MS     = 2,/* 170 ms */
+       BLINK_340MS     = 3,/* 340 ms */
+       BLINK_670MS     = 4,/* 670 ms */
+};
+
+/*****  PHY_MARV_LED_OVER      16 bit r/w      Manual LED Override Reg *****/
+#define PHY_M_LED_MO_SGMII(x)  ((x)<<14) /* Bit 15..14:  SGMII AN Timer */
+                                                                               /* Bit 13..12:  reserved */
+#define PHY_M_LED_MO_DUP(x)    ((x)<<10) /* Bit 11..10:  Duplex */
+#define PHY_M_LED_MO_10(x)     ((x)<<8) /* Bit  9.. 8:  Link 10 */
+#define PHY_M_LED_MO_100(x)    ((x)<<6) /* Bit  7.. 6:  Link 100 */
+#define PHY_M_LED_MO_1000(x)   ((x)<<4) /* Bit  5.. 4:  Link 1000 */
+#define PHY_M_LED_MO_RX(x)     ((x)<<2) /* Bit  3.. 2:  Rx */
+#define PHY_M_LED_MO_TX(x)     ((x)<<0) /* Bit  1.. 0:  Tx */
+
+enum {
+       MO_LED_NORM     = 0,
+       MO_LED_BLINK    = 1,
+       MO_LED_OFF      = 2,
+       MO_LED_ON       = 3,
+};
+
+/*****  PHY_MARV_EXT_CTRL_2    16 bit r/w      Ext. PHY Specific Ctrl 2 *****/
+enum {
+       PHY_M_EC2_FI_IMPED      = 1<<6, /* Fiber Input  Impedance */
+       PHY_M_EC2_FO_IMPED      = 1<<5, /* Fiber Output Impedance */
+       PHY_M_EC2_FO_M_CLK      = 1<<4, /* Fiber Mode Clock Enable */
+       PHY_M_EC2_FO_BOOST      = 1<<3, /* Fiber Output Boost */
+       PHY_M_EC2_FO_AM_MSK     = 7,/* Bit  2.. 0:      Fiber Output Amplitude */
+};
+
+/*****  PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/
+enum {
+       PHY_M_FC_AUTO_SEL       = 1<<15, /* Fiber/Copper Auto Sel. Dis. */
+       PHY_M_FC_AN_REG_ACC     = 1<<14, /* Fiber/Copper AN Reg. Access */
+       PHY_M_FC_RESOLUTION     = 1<<13, /* Fiber/Copper Resolution */
+       PHY_M_SER_IF_AN_BP      = 1<<12, /* Ser. IF AN Bypass Enable */
+       PHY_M_SER_IF_BP_ST      = 1<<11, /* Ser. IF AN Bypass Status */
+       PHY_M_IRQ_POLARITY      = 1<<10, /* IRQ polarity */
+       PHY_M_DIS_AUT_MED       = 1<<9, /* Disable Aut. Medium Reg. Selection */
+       /* (88E1111 only) */
+
+       PHY_M_UNDOC1            = 1<<7, /* undocumented bit !! */
+       PHY_M_DTE_POW_STAT      = 1<<4, /* DTE Power Status (88E1111 only) */
+       PHY_M_MODE_MASK = 0xf, /* Bit  3.. 0: copy of HWCFG MODE[3:0] */
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+/*****  PHY_MARV_FE_LED_PAR            16 bit r/w      LED Parallel Select Reg. *****/
+                                                                       /* Bit 15..12: reserved (used internally) */
+enum {
+       PHY_M_FELP_LED2_MSK = 0xf<<8,   /* Bit 11.. 8: LED2 Mask (LINK) */
+       PHY_M_FELP_LED1_MSK = 0xf<<4,   /* Bit  7.. 4: LED1 Mask (ACT) */
+       PHY_M_FELP_LED0_MSK = 0xf, /* Bit  3.. 0: LED0 Mask (SPEED) */
+};
+
+#define PHY_M_FELP_LED2_CTRL(x)        (((x)<<8) & PHY_M_FELP_LED2_MSK)
+#define PHY_M_FELP_LED1_CTRL(x)        (((x)<<4) & PHY_M_FELP_LED1_MSK)
+#define PHY_M_FELP_LED0_CTRL(x)        (((x)<<0) & PHY_M_FELP_LED0_MSK)
+
+enum {
+       LED_PAR_CTRL_COLX       = 0x00,
+       LED_PAR_CTRL_ERROR      = 0x01,
+       LED_PAR_CTRL_DUPLEX     = 0x02,
+       LED_PAR_CTRL_DP_COL     = 0x03,
+       LED_PAR_CTRL_SPEED      = 0x04,
+       LED_PAR_CTRL_LINK       = 0x05,
+       LED_PAR_CTRL_TX         = 0x06,
+       LED_PAR_CTRL_RX         = 0x07,
+       LED_PAR_CTRL_ACT        = 0x08,
+       LED_PAR_CTRL_LNK_RX     = 0x09,
+       LED_PAR_CTRL_LNK_AC     = 0x0a,
+       LED_PAR_CTRL_ACT_BL     = 0x0b,
+       LED_PAR_CTRL_TX_BL      = 0x0c,
+       LED_PAR_CTRL_RX_BL      = 0x0d,
+       LED_PAR_CTRL_COL_BL     = 0x0e,
+       LED_PAR_CTRL_INACT      = 0x0f
+};
+
+/*****,PHY_MARV_FE_SPEC_2              16 bit r/w      Specific Control Reg. 2 *****/
+enum {
+       PHY_M_FESC_DIS_WAIT     = 1<<2, /* Disable TDR Waiting Period */
+       PHY_M_FESC_ENA_MCLK     = 1<<1, /* Enable MAC Rx Clock in sleep mode */
+       PHY_M_FESC_SEL_CL_A     = 1<<0, /* Select Class A driver (100B-TX) */
+};
+
+/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+/*****  PHY_MARV_PHY_CTRL (page 2)             16 bit r/w      MAC Specific Ctrl *****/
+enum {
+       PHY_M_MAC_MD_MSK        = 7<<7, /* Bit  9.. 7: Mode Select Mask */
+       PHY_M_MAC_MD_AUTO       = 3,/* Auto Copper/1000Base-X */
+       PHY_M_MAC_MD_COPPER     = 5,/* Copper only */
+       PHY_M_MAC_MD_1000BX     = 7,/* 1000Base-X only */
+};
+#define PHY_M_MAC_MODE_SEL(x)  (((x)<<7) & PHY_M_MAC_MD_MSK)
+
+/*****  PHY_MARV_PHY_CTRL (page 3)             16 bit r/w      LED Control Reg. *****/
+enum {
+       PHY_M_LEDC_LOS_MSK      = 0xf<<12,/* Bit 15..12: LOS LED Ctrl. Mask */
+       PHY_M_LEDC_INIT_MSK     = 0xf<<8, /* Bit 11.. 8: INIT LED Ctrl. Mask */
+       PHY_M_LEDC_STA1_MSK     = 0xf<<4,/* Bit  7.. 4: STAT1 LED Ctrl. Mask */
+       PHY_M_LEDC_STA0_MSK     = 0xf, /* Bit  3.. 0: STAT0 LED Ctrl. Mask */
+};
+
+#define PHY_M_LEDC_LOS_CTRL(x) (((x)<<12) & PHY_M_LEDC_LOS_MSK)
+#define PHY_M_LEDC_INIT_CTRL(x)        (((x)<<8) & PHY_M_LEDC_INIT_MSK)
+#define PHY_M_LEDC_STA1_CTRL(x)        (((x)<<4) & PHY_M_LEDC_STA1_MSK)
+#define PHY_M_LEDC_STA0_CTRL(x)        (((x)<<0) & PHY_M_LEDC_STA0_MSK)
+
+/* GMAC registers  */
+/* Port Registers */
+enum {
+       GM_GP_STAT      = 0x0000,       /* 16 bit r/o   General Purpose Status */
+       GM_GP_CTRL      = 0x0004,       /* 16 bit r/w   General Purpose Control */
+       GM_TX_CTRL      = 0x0008,       /* 16 bit r/w   Transmit Control Reg. */
+       GM_RX_CTRL      = 0x000c,       /* 16 bit r/w   Receive Control Reg. */
+       GM_TX_FLOW_CTRL = 0x0010,       /* 16 bit r/w   Transmit Flow-Control */
+       GM_TX_PARAM     = 0x0014,       /* 16 bit r/w   Transmit Parameter Reg. */
+       GM_SERIAL_MODE  = 0x0018,       /* 16 bit r/w   Serial Mode Register */
+/* Source Address Registers */
+       GM_SRC_ADDR_1L  = 0x001c,       /* 16 bit r/w   Source Address 1 (low) */
+       GM_SRC_ADDR_1M  = 0x0020,       /* 16 bit r/w   Source Address 1 (middle) */
+       GM_SRC_ADDR_1H  = 0x0024,       /* 16 bit r/w   Source Address 1 (high) */
+       GM_SRC_ADDR_2L  = 0x0028,       /* 16 bit r/w   Source Address 2 (low) */
+       GM_SRC_ADDR_2M  = 0x002c,       /* 16 bit r/w   Source Address 2 (middle) */
+       GM_SRC_ADDR_2H  = 0x0030,       /* 16 bit r/w   Source Address 2 (high) */
+
+/* Multicast Address Hash Registers */
+       GM_MC_ADDR_H1   = 0x0034,       /* 16 bit r/w   Multicast Address Hash 1 */
+       GM_MC_ADDR_H2   = 0x0038,       /* 16 bit r/w   Multicast Address Hash 2 */
+       GM_MC_ADDR_H3   = 0x003c,       /* 16 bit r/w   Multicast Address Hash 3 */
+       GM_MC_ADDR_H4   = 0x0040,       /* 16 bit r/w   Multicast Address Hash 4 */
+
+/* Interrupt Source Registers */
+       GM_TX_IRQ_SRC   = 0x0044,       /* 16 bit r/o   Tx Overflow IRQ Source */
+       GM_RX_IRQ_SRC   = 0x0048,       /* 16 bit r/o   Rx Overflow IRQ Source */
+       GM_TR_IRQ_SRC   = 0x004c,       /* 16 bit r/o   Tx/Rx Over. IRQ Source */
+
+/* Interrupt Mask Registers */
+       GM_TX_IRQ_MSK   = 0x0050,       /* 16 bit r/w   Tx Overflow IRQ Mask */
+       GM_RX_IRQ_MSK   = 0x0054,       /* 16 bit r/w   Rx Overflow IRQ Mask */
+       GM_TR_IRQ_MSK   = 0x0058,       /* 16 bit r/w   Tx/Rx Over. IRQ Mask */
+
+/* Serial Management Interface (SMI) Registers */
+       GM_SMI_CTRL     = 0x0080,       /* 16 bit r/w   SMI Control Register */
+       GM_SMI_DATA     = 0x0084,       /* 16 bit r/w   SMI Data Register */
+       GM_PHY_ADDR     = 0x0088,       /* 16 bit r/w   GPHY Address Register */
+};
+
+/* MIB Counters */
+#define GM_MIB_CNT_BASE        0x0100          /* Base Address of MIB Counters */
+#define GM_MIB_CNT_SIZE        44              /* Number of MIB Counters */
+
+/*
+ * MIB Counters base address definitions (low word) -
+ * use offset 4 for access to high word        (32 bit r/o)
+ */
+enum {
+       GM_RXF_UC_OK  = GM_MIB_CNT_BASE + 0,    /* Unicast Frames Received OK */
+       GM_RXF_BC_OK    = GM_MIB_CNT_BASE + 8,  /* Broadcast Frames Received OK */
+       GM_RXF_MPAUSE   = GM_MIB_CNT_BASE + 16, /* Pause MAC Ctrl Frames Received */
+       GM_RXF_MC_OK    = GM_MIB_CNT_BASE + 24, /* Multicast Frames Received OK */
+       GM_RXF_FCS_ERR  = GM_MIB_CNT_BASE + 32, /* Rx Frame Check Seq. Error */
+       /* GM_MIB_CNT_BASE + 40:        reserved */
+       GM_RXO_OK_LO    = GM_MIB_CNT_BASE + 48, /* Octets Received OK Low */
+       GM_RXO_OK_HI    = GM_MIB_CNT_BASE + 56, /* Octets Received OK High */
+       GM_RXO_ERR_LO   = GM_MIB_CNT_BASE + 64, /* Octets Received Invalid Low */
+       GM_RXO_ERR_HI   = GM_MIB_CNT_BASE + 72, /* Octets Received Invalid High */
+       GM_RXF_SHT      = GM_MIB_CNT_BASE + 80, /* Frames <64 Byte Received OK */
+       GM_RXE_FRAG     = GM_MIB_CNT_BASE + 88, /* Frames <64 Byte Received with FCS Err */
+       GM_RXF_64B      = GM_MIB_CNT_BASE + 96, /* 64 Byte Rx Frame */
+       GM_RXF_127B     = GM_MIB_CNT_BASE + 104,        /* 65-127 Byte Rx Frame */
+       GM_RXF_255B     = GM_MIB_CNT_BASE + 112,        /* 128-255 Byte Rx Frame */
+       GM_RXF_511B     = GM_MIB_CNT_BASE + 120,        /* 256-511 Byte Rx Frame */
+       GM_RXF_1023B    = GM_MIB_CNT_BASE + 128,        /* 512-1023 Byte Rx Frame */
+       GM_RXF_1518B    = GM_MIB_CNT_BASE + 136,        /* 1024-1518 Byte Rx Frame */
+       GM_RXF_MAX_SZ   = GM_MIB_CNT_BASE + 144,        /* 1519-MaxSize Byte Rx Frame */
+       GM_RXF_LNG_ERR  = GM_MIB_CNT_BASE + 152,        /* Rx Frame too Long Error */
+       GM_RXF_JAB_PKT  = GM_MIB_CNT_BASE + 160,        /* Rx Jabber Packet Frame */
+       /* GM_MIB_CNT_BASE + 168:       reserved */
+       GM_RXE_FIFO_OV  = GM_MIB_CNT_BASE + 176,        /* Rx FIFO overflow Event */
+       /* GM_MIB_CNT_BASE + 184:       reserved */
+       GM_TXF_UC_OK    = GM_MIB_CNT_BASE + 192,        /* Unicast Frames Xmitted OK */
+       GM_TXF_BC_OK    = GM_MIB_CNT_BASE + 200,        /* Broadcast Frames Xmitted OK */
+       GM_TXF_MPAUSE   = GM_MIB_CNT_BASE + 208,        /* Pause MAC Ctrl Frames Xmitted */
+       GM_TXF_MC_OK    = GM_MIB_CNT_BASE + 216,        /* Multicast Frames Xmitted OK */
+       GM_TXO_OK_LO    = GM_MIB_CNT_BASE + 224,        /* Octets Transmitted OK Low */
+       GM_TXO_OK_HI    = GM_MIB_CNT_BASE + 232,        /* Octets Transmitted OK High */
+       GM_TXF_64B      = GM_MIB_CNT_BASE + 240,        /* 64 Byte Tx Frame */
+       GM_TXF_127B     = GM_MIB_CNT_BASE + 248,        /* 65-127 Byte Tx Frame */
+       GM_TXF_255B     = GM_MIB_CNT_BASE + 256,        /* 128-255 Byte Tx Frame */
+       GM_TXF_511B     = GM_MIB_CNT_BASE + 264,        /* 256-511 Byte Tx Frame */
+       GM_TXF_1023B    = GM_MIB_CNT_BASE + 272,        /* 512-1023 Byte Tx Frame */
+       GM_TXF_1518B    = GM_MIB_CNT_BASE + 280,        /* 1024-1518 Byte Tx Frame */
+       GM_TXF_MAX_SZ   = GM_MIB_CNT_BASE + 288,        /* 1519-MaxSize Byte Tx Frame */
+
+       GM_TXF_COL      = GM_MIB_CNT_BASE + 304,        /* Tx Collision */
+       GM_TXF_LAT_COL  = GM_MIB_CNT_BASE + 312,        /* Tx Late Collision */
+       GM_TXF_ABO_COL  = GM_MIB_CNT_BASE + 320,        /* Tx aborted due to Exces. Col. */
+       GM_TXF_MUL_COL  = GM_MIB_CNT_BASE + 328,        /* Tx Multiple Collision */
+       GM_TXF_SNG_COL  = GM_MIB_CNT_BASE + 336,        /* Tx Single Collision */
+       GM_TXE_FIFO_UR  = GM_MIB_CNT_BASE + 344,        /* Tx FIFO Underrun Event */
+};
+
+/* GMAC Bit Definitions */
+/*     GM_GP_STAT      16 bit r/o      General Purpose Status Register */
+enum {
+       GM_GPSR_SPEED           = 1<<15, /* Bit 15:     Port Speed (1 = 100 Mbps) */
+       GM_GPSR_DUPLEX          = 1<<14, /* Bit 14:     Duplex Mode (1 = Full) */
+       GM_GPSR_FC_TX_DIS       = 1<<13, /* Bit 13:     Tx Flow-Control Mode Disabled */
+       GM_GPSR_LINK_UP         = 1<<12, /* Bit 12:     Link Up Status */
+       GM_GPSR_PAUSE           = 1<<11, /* Bit 11:     Pause State */
+       GM_GPSR_TX_ACTIVE       = 1<<10, /* Bit 10:     Tx in Progress */
+       GM_GPSR_EXC_COL         = 1<<9, /* Bit  9:      Excessive Collisions Occured */
+       GM_GPSR_LAT_COL         = 1<<8, /* Bit  8:      Late Collisions Occured */
+
+       GM_GPSR_PHY_ST_CH       = 1<<5, /* Bit  5:      PHY Status Change */
+       GM_GPSR_GIG_SPEED       = 1<<4, /* Bit  4:      Gigabit Speed (1 = 1000 Mbps) */
+       GM_GPSR_PART_MODE       = 1<<3, /* Bit  3:      Partition mode */
+       GM_GPSR_FC_RX_DIS       = 1<<2, /* Bit  2:      Rx Flow-Control Mode Disabled */
+       GM_GPSR_PROM_EN         = 1<<1, /* Bit  1:      Promiscuous Mode Enabled */
+};
+
+/*     GM_GP_CTRL      16 bit r/w      General Purpose Control Register */
+enum {
+       GM_GPCR_PROM_ENA        = 1<<14,        /* Bit 14:      Enable Promiscuous Mode */
+       GM_GPCR_FC_TX_DIS       = 1<<13, /* Bit 13:     Disable Tx Flow-Control Mode */
+       GM_GPCR_TX_ENA          = 1<<12, /* Bit 12:     Enable Transmit */
+       GM_GPCR_RX_ENA          = 1<<11, /* Bit 11:     Enable Receive */
+       GM_GPCR_BURST_ENA       = 1<<10, /* Bit 10:     Enable Burst Mode */
+       GM_GPCR_LOOP_ENA        = 1<<9, /* Bit  9:      Enable MAC Loopback Mode */
+       GM_GPCR_PART_ENA        = 1<<8, /* Bit  8:      Enable Partition Mode */
+       GM_GPCR_GIGS_ENA        = 1<<7, /* Bit  7:      Gigabit Speed (1000 Mbps) */
+       GM_GPCR_FL_PASS         = 1<<6, /* Bit  6:      Force Link Pass */
+       GM_GPCR_DUP_FULL        = 1<<5, /* Bit  5:      Full Duplex Mode */
+       GM_GPCR_FC_RX_DIS       = 1<<4, /* Bit  4:      Disable Rx Flow-Control Mode */
+       GM_GPCR_SPEED_100       = 1<<3,   /* Bit  3:    Port Speed 100 Mbps */
+       GM_GPCR_AU_DUP_DIS      = 1<<2, /* Bit  2:      Disable Auto-Update Duplex */
+       GM_GPCR_AU_FCT_DIS      = 1<<1, /* Bit  1:      Disable Auto-Update Flow-C. */
+       GM_GPCR_AU_SPD_DIS      = 1<<0, /* Bit  0:      Disable Auto-Update Speed */
+};
+
+#define GM_GPCR_SPEED_1000     (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
+#define GM_GPCR_AU_ALL_DIS     (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
+
+/*     GM_TX_CTRL                      16 bit r/w      Transmit Control Register */
+enum {
+       GM_TXCR_FORCE_JAM       = 1<<15, /* Bit 15:     Force Jam / Flow-Control */
+       GM_TXCR_CRC_DIS         = 1<<14, /* Bit 14:     Disable insertion of CRC */
+       GM_TXCR_PAD_DIS         = 1<<13, /* Bit 13:     Disable padding of packets */
+       GM_TXCR_COL_THR_MSK     = 1<<10, /* Bit 12..10: Collision Threshold */
+};
+
+#define TX_COL_THR(x)          (((x)<<10) & GM_TXCR_COL_THR_MSK)
+#define TX_COL_DEF             0x04
+
+/*     GM_RX_CTRL                      16 bit r/w      Receive Control Register */
+enum {
+       GM_RXCR_UCF_ENA = 1<<15, /* Bit 15:     Enable Unicast filtering */
+       GM_RXCR_MCF_ENA = 1<<14, /* Bit 14:     Enable Multicast filtering */
+       GM_RXCR_CRC_DIS = 1<<13, /* Bit 13:     Remove 4-byte CRC */
+       GM_RXCR_PASS_FC = 1<<12, /* Bit 12:     Pass FC packets to FIFO */
+};
+
+/*     GM_TX_PARAM             16 bit r/w      Transmit Parameter Register */
+enum {
+       GM_TXPA_JAMLEN_MSK      = 0x03<<14,     /* Bit 15..14:  Jam Length */
+       GM_TXPA_JAMIPG_MSK      = 0x1f<<9,      /* Bit 13..9:   Jam IPG */
+       GM_TXPA_JAMDAT_MSK      = 0x1f<<4,      /* Bit  8..4:   IPG Jam to Data */
+       GM_TXPA_BO_LIM_MSK      = 0x0f,         /* Bit  3.. 0: Backoff Limit Mask */
+
+       TX_JAM_LEN_DEF          = 0x03,
+       TX_JAM_IPG_DEF          = 0x0b,
+       TX_IPG_JAM_DEF          = 0x1c,
+       TX_BOF_LIM_DEF          = 0x04,
+};
+
+#define TX_JAM_LEN_VAL(x)      (((x)<<14) & GM_TXPA_JAMLEN_MSK)
+#define TX_JAM_IPG_VAL(x)      (((x)<<9)  & GM_TXPA_JAMIPG_MSK)
+#define TX_IPG_JAM_DATA(x)     (((x)<<4)  & GM_TXPA_JAMDAT_MSK)
+#define TX_BACK_OFF_LIM(x)     ((x) & GM_TXPA_BO_LIM_MSK)
+
+
+/*     GM_SERIAL_MODE                  16 bit r/w      Serial Mode Register */
+enum {
+       GM_SMOD_DATABL_MSK      = 0x1f<<11, /* Bit 15..11:      Data Blinder (r/o) */
+       GM_SMOD_LIMIT_4         = 1<<10, /* Bit 10:     4 consecutive Tx trials */
+       GM_SMOD_VLAN_ENA        = 1<<9, /* Bit  9:      Enable VLAN  (Max. Frame Len) */
+       GM_SMOD_JUMBO_ENA       = 1<<8, /* Bit  8:      Enable Jumbo (Max. Frame Len) */
+        GM_SMOD_IPG_MSK        = 0x1f  /* Bit 4..0:    Inter-Packet Gap (IPG) */
+};
+
+#define DATA_BLIND_VAL(x)      (((x)<<11) & GM_SMOD_DATABL_MSK)
+#define DATA_BLIND_DEF         0x04
+
+#define IPG_DATA_VAL(x)                (x & GM_SMOD_IPG_MSK)
+#define IPG_DATA_DEF           0x1e
+
+/*     GM_SMI_CTRL                     16 bit r/w      SMI Control Register */
+enum {
+       GM_SMI_CT_PHY_A_MSK     = 0x1f<<11,/* Bit 15..11:       PHY Device Address */
+       GM_SMI_CT_REG_A_MSK     = 0x1f<<6,/* Bit 10.. 6:        PHY Register Address */
+       GM_SMI_CT_OP_RD         = 1<<5, /* Bit  5:      OpCode Read (0=Write)*/
+       GM_SMI_CT_RD_VAL        = 1<<4, /* Bit  4:      Read Valid (Read completed) */
+       GM_SMI_CT_BUSY          = 1<<3, /* Bit  3:      Busy (Operation in progress) */
+};
+
+#define GM_SMI_CT_PHY_AD(x)    (((x)<<11) & GM_SMI_CT_PHY_A_MSK)
+#define GM_SMI_CT_REG_AD(x)    (((x)<<6) & GM_SMI_CT_REG_A_MSK)
+
+/*     GM_PHY_ADDR                             16 bit r/w      GPHY Address Register */
+enum {
+       GM_PAR_MIB_CLR  = 1<<5, /* Bit  5:      Set MIB Clear Counter Mode */
+       GM_PAR_MIB_TST  = 1<<4, /* Bit  4:      MIB Load Counter (Test Mode) */
+};
+
+/* Receive Frame Status Encoding */
+enum {
+       GMR_FS_LEN      = 0xffff<<16, /* Bit 31..16:    Rx Frame Length */
+       GMR_FS_VLAN     = 1<<13, /* VLAN Packet */
+       GMR_FS_JABBER   = 1<<12, /* Jabber Packet */
+       GMR_FS_UN_SIZE  = 1<<11, /* Undersize Packet */
+       GMR_FS_MC       = 1<<10, /* Multicast Packet */
+       GMR_FS_BC       = 1<<9,  /* Broadcast Packet */
+       GMR_FS_RX_OK    = 1<<8,  /* Receive OK (Good Packet) */
+       GMR_FS_GOOD_FC  = 1<<7,  /* Good Flow-Control Packet */
+       GMR_FS_BAD_FC   = 1<<6,  /* Bad  Flow-Control Packet */
+       GMR_FS_MII_ERR  = 1<<5,  /* MII Error */
+       GMR_FS_LONG_ERR = 1<<4,  /* Too Long Packet */
+       GMR_FS_FRAGMENT = 1<<3,  /* Fragment */
+
+       GMR_FS_CRC_ERR  = 1<<1,  /* CRC Error */
+       GMR_FS_RX_FF_OV = 1<<0,  /* Rx FIFO Overflow */
+
+       GMR_FS_ANY_ERR  = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
+                         GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
+                         GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
+                         GMR_FS_UN_SIZE | GMR_FS_JABBER,
+};
+
+/*     RX_GMF_CTRL_T   32 bit  Rx GMAC FIFO Control/Test */
+enum {
+       RX_TRUNC_ON     = 1<<27,        /* enable  packet truncation */
+       RX_TRUNC_OFF    = 1<<26,        /* disable packet truncation */
+       RX_VLAN_STRIP_ON = 1<<25,       /* enable  VLAN stripping */
+       RX_VLAN_STRIP_OFF = 1<<24,      /* disable VLAN stripping */
+
+       GMF_WP_TST_ON   = 1<<14,        /* Write Pointer Test On */
+       GMF_WP_TST_OFF  = 1<<13,        /* Write Pointer Test Off */
+       GMF_WP_STEP     = 1<<12,        /* Write Pointer Step/Increment */
+
+       GMF_RP_TST_ON   = 1<<10,        /* Read Pointer Test On */
+       GMF_RP_TST_OFF  = 1<<9,         /* Read Pointer Test Off */
+       GMF_RP_STEP     = 1<<8,         /* Read Pointer Step/Increment */
+       GMF_RX_F_FL_ON  = 1<<7,         /* Rx FIFO Flush Mode On */
+       GMF_RX_F_FL_OFF = 1<<6,         /* Rx FIFO Flush Mode Off */
+       GMF_CLI_RX_FO   = 1<<5,         /* Clear IRQ Rx FIFO Overrun */
+       GMF_CLI_RX_C    = 1<<4,         /* Clear IRQ Rx Frame Complete */
+
+       GMF_OPER_ON     = 1<<3,         /* Operational Mode On */
+       GMF_OPER_OFF    = 1<<2,         /* Operational Mode Off */
+       GMF_RST_CLR     = 1<<1,         /* Clear GMAC FIFO Reset */
+       GMF_RST_SET     = 1<<0,         /* Set   GMAC FIFO Reset */
+
+       RX_GMF_FL_THR_DEF = 0xa,        /* flush threshold (default) */
+
+       GMF_RX_CTRL_DEF = GMF_OPER_ON | GMF_RX_F_FL_ON,
+};
+
+
+/*     TX_GMF_CTRL_T   32 bit  Tx GMAC FIFO Control/Test */
+enum {
+       TX_STFW_DIS     = 1<<31,/* Disable Store & Forward (Yukon-EC Ultra) */
+       TX_STFW_ENA     = 1<<30,/* Enable  Store & Forward (Yukon-EC Ultra) */
+
+       TX_VLAN_TAG_ON  = 1<<25,/* enable  VLAN tagging */
+       TX_VLAN_TAG_OFF = 1<<24,/* disable VLAN tagging */
+
+       GMF_WSP_TST_ON  = 1<<18,/* Write Shadow Pointer Test On */
+       GMF_WSP_TST_OFF = 1<<17,/* Write Shadow Pointer Test Off */
+       GMF_WSP_STEP    = 1<<16,/* Write Shadow Pointer Step/Increment */
+
+       GMF_CLI_TX_FU   = 1<<6, /* Clear IRQ Tx FIFO Underrun */
+       GMF_CLI_TX_FC   = 1<<5, /* Clear IRQ Tx Frame Complete */
+       GMF_CLI_TX_PE   = 1<<4, /* Clear IRQ Tx Parity Error */
+};
+
+/*     GMAC_TI_ST_CTRL  8 bit  Time Stamp Timer Ctrl Reg (YUKON only) */
+enum {
+       GMT_ST_START    = 1<<2, /* Start Time Stamp Timer */
+       GMT_ST_STOP     = 1<<1, /* Stop  Time Stamp Timer */
+       GMT_ST_CLR_IRQ  = 1<<0, /* Clear Time Stamp Timer IRQ */
+};
+
+/* B28_Y2_ASF_STAT_CMD         32 bit  ASF Status and Command Reg */
+enum {
+       Y2_ASF_OS_PRES  = 1<<4, /* ASF operation system present */
+       Y2_ASF_RESET    = 1<<3, /* ASF system in reset state */
+       Y2_ASF_RUNNING  = 1<<2, /* ASF system operational */
+       Y2_ASF_CLR_HSTI = 1<<1, /* Clear ASF IRQ */
+       Y2_ASF_IRQ      = 1<<0, /* Issue an IRQ to ASF system */
+
+       Y2_ASF_UC_STATE = 3<<2, /* ASF uC State */
+       Y2_ASF_CLK_HALT = 0,    /* ASF system clock stopped */
+};
+
+/* B28_Y2_ASF_HOST_COM 32 bit  ASF Host Communication Reg */
+enum {
+       Y2_ASF_CLR_ASFI = 1<<1, /* Clear host IRQ */
+       Y2_ASF_HOST_IRQ = 1<<0, /* Issue an IRQ to HOST system */
+};
+
+/*     STAT_CTRL               32 bit  Status BMU control register (Yukon-2 only) */
+enum {
+       SC_STAT_CLR_IRQ = 1<<4, /* Status Burst IRQ clear */
+       SC_STAT_OP_ON   = 1<<3, /* Operational Mode On */
+       SC_STAT_OP_OFF  = 1<<2, /* Operational Mode Off */
+       SC_STAT_RST_CLR = 1<<1, /* Clear Status Unit Reset (Enable) */
+       SC_STAT_RST_SET = 1<<0, /* Set   Status Unit Reset */
+};
+
+/*     GMAC_CTRL               32 bit  GMAC Control Reg (YUKON only) */
+enum {
+       GMC_H_BURST_ON  = 1<<7, /* Half Duplex Burst Mode On */
+       GMC_H_BURST_OFF = 1<<6, /* Half Duplex Burst Mode Off */
+       GMC_F_LOOPB_ON  = 1<<5, /* FIFO Loopback On */
+       GMC_F_LOOPB_OFF = 1<<4, /* FIFO Loopback Off */
+       GMC_PAUSE_ON    = 1<<3, /* Pause On */
+       GMC_PAUSE_OFF   = 1<<2, /* Pause Off */
+       GMC_RST_CLR     = 1<<1, /* Clear GMAC Reset */
+       GMC_RST_SET     = 1<<0, /* Set   GMAC Reset */
+};
+
+/*     GPHY_CTRL               32 bit  GPHY Control Reg (YUKON only) */
+enum {
+       GPC_SEL_BDT     = 1<<28, /* Select Bi-Dir. Transfer for MDC/MDIO */
+       GPC_INT_POL_HI  = 1<<27, /* IRQ Polarity is Active HIGH */
+       GPC_75_OHM      = 1<<26, /* Use 75 Ohm Termination instead of 50 */
+       GPC_DIS_FC      = 1<<25, /* Disable Automatic Fiber/Copper Detection */
+       GPC_DIS_SLEEP   = 1<<24, /* Disable Energy Detect */
+       GPC_HWCFG_M_3   = 1<<23, /* HWCFG_MODE[3] */
+       GPC_HWCFG_M_2   = 1<<22, /* HWCFG_MODE[2] */
+       GPC_HWCFG_M_1   = 1<<21, /* HWCFG_MODE[1] */
+       GPC_HWCFG_M_0   = 1<<20, /* HWCFG_MODE[0] */
+       GPC_ANEG_0      = 1<<19, /* ANEG[0] */
+       GPC_ENA_XC      = 1<<18, /* Enable MDI crossover */
+       GPC_DIS_125     = 1<<17, /* Disable 125 MHz clock */
+       GPC_ANEG_3      = 1<<16, /* ANEG[3] */
+       GPC_ANEG_2      = 1<<15, /* ANEG[2] */
+       GPC_ANEG_1      = 1<<14, /* ANEG[1] */
+       GPC_ENA_PAUSE   = 1<<13, /* Enable Pause (SYM_OR_REM) */
+       GPC_PHYADDR_4   = 1<<12, /* Bit 4 of Phy Addr */
+       GPC_PHYADDR_3   = 1<<11, /* Bit 3 of Phy Addr */
+       GPC_PHYADDR_2   = 1<<10, /* Bit 2 of Phy Addr */
+       GPC_PHYADDR_1   = 1<<9,  /* Bit 1 of Phy Addr */
+       GPC_PHYADDR_0   = 1<<8,  /* Bit 0 of Phy Addr */
+                                               /* Bits  7..2:  reserved */
+       GPC_RST_CLR     = 1<<1, /* Clear GPHY Reset */
+       GPC_RST_SET     = 1<<0, /* Set   GPHY Reset */
+};
+
+/*     GMAC_IRQ_SRC     8 bit  GMAC Interrupt Source Reg (YUKON only) */
+/*     GMAC_IRQ_MSK     8 bit  GMAC Interrupt Mask   Reg (YUKON only) */
+enum {
+       GM_IS_TX_CO_OV  = 1<<5, /* Transmit Counter Overflow IRQ */
+       GM_IS_RX_CO_OV  = 1<<4, /* Receive Counter Overflow IRQ */
+       GM_IS_TX_FF_UR  = 1<<3, /* Transmit FIFO Underrun */
+       GM_IS_TX_COMPL  = 1<<2, /* Frame Transmission Complete */
+       GM_IS_RX_FF_OR  = 1<<1, /* Receive FIFO Overrun */
+       GM_IS_RX_COMPL  = 1<<0, /* Frame Reception Complete */
+
+#define GMAC_DEF_MSK     GM_IS_TX_FF_UR
+
+/*     GMAC_LINK_CTRL  16 bit  GMAC Link Control Reg (YUKON only) */
+                                               /* Bits 15.. 2: reserved */
+       GMLC_RST_CLR    = 1<<1, /* Clear GMAC Link Reset */
+       GMLC_RST_SET    = 1<<0, /* Set   GMAC Link Reset */
+
+
+/*     WOL_CTRL_STAT   16 bit  WOL Control/Status Reg */
+       WOL_CTL_LINK_CHG_OCC            = 1<<15,
+       WOL_CTL_MAGIC_PKT_OCC           = 1<<14,
+       WOL_CTL_PATTERN_OCC             = 1<<13,
+       WOL_CTL_CLEAR_RESULT            = 1<<12,
+       WOL_CTL_ENA_PME_ON_LINK_CHG     = 1<<11,
+       WOL_CTL_DIS_PME_ON_LINK_CHG     = 1<<10,
+       WOL_CTL_ENA_PME_ON_MAGIC_PKT    = 1<<9,
+       WOL_CTL_DIS_PME_ON_MAGIC_PKT    = 1<<8,
+       WOL_CTL_ENA_PME_ON_PATTERN      = 1<<7,
+       WOL_CTL_DIS_PME_ON_PATTERN      = 1<<6,
+       WOL_CTL_ENA_LINK_CHG_UNIT       = 1<<5,
+       WOL_CTL_DIS_LINK_CHG_UNIT       = 1<<4,
+       WOL_CTL_ENA_MAGIC_PKT_UNIT      = 1<<3,
+       WOL_CTL_DIS_MAGIC_PKT_UNIT      = 1<<2,
+       WOL_CTL_ENA_PATTERN_UNIT        = 1<<1,
+       WOL_CTL_DIS_PATTERN_UNIT        = 1<<0,
+};
+
+#define WOL_CTL_DEFAULT                                \
+       (WOL_CTL_DIS_PME_ON_LINK_CHG |  \
+       WOL_CTL_DIS_PME_ON_PATTERN |    \
+       WOL_CTL_DIS_PME_ON_MAGIC_PKT |  \
+       WOL_CTL_DIS_LINK_CHG_UNIT |             \
+       WOL_CTL_DIS_PATTERN_UNIT |              \
+       WOL_CTL_DIS_MAGIC_PKT_UNIT)
+
+/*     WOL_MATCH_CTL    8 bit  WOL Match Control Reg */
+#define WOL_CTL_PATT_ENA(x)    (1 << (x))
+
+
+/* Control flags */
+enum {
+       UDPTCP  = 1<<0,
+       CALSUM  = 1<<1,
+       WR_SUM  = 1<<2,
+       INIT_SUM= 1<<3,
+       LOCK_SUM= 1<<4,
+       INS_VLAN= 1<<5,
+       FRC_STAT= 1<<6,
+       EOP     = 1<<7,
+};
+
+enum {
+       HW_OWNER        = 1<<7,
+       OP_TCPWRITE     = 0x11,
+       OP_TCPSTART     = 0x12,
+       OP_TCPINIT      = 0x14,
+       OP_TCPLCK       = 0x18,
+       OP_TCPCHKSUM    = OP_TCPSTART,
+       OP_TCPIS        = OP_TCPINIT | OP_TCPSTART,
+       OP_TCPLW        = OP_TCPLCK | OP_TCPWRITE,
+       OP_TCPLSW       = OP_TCPLCK | OP_TCPSTART | OP_TCPWRITE,
+       OP_TCPLISW      = OP_TCPLCK | OP_TCPINIT | OP_TCPSTART | OP_TCPWRITE,
+
+       OP_ADDR64       = 0x21,
+       OP_VLAN         = 0x22,
+       OP_ADDR64VLAN   = OP_ADDR64 | OP_VLAN,
+       OP_LRGLEN       = 0x24,
+       OP_LRGLENVLAN   = OP_LRGLEN | OP_VLAN,
+       OP_BUFFER       = 0x40,
+       OP_PACKET       = 0x41,
+       OP_LARGESEND    = 0x43,
+
+/* YUKON-2 STATUS opcodes defines */
+       OP_RXSTAT       = 0x60,
+       OP_RXTIMESTAMP  = 0x61,
+       OP_RXVLAN       = 0x62,
+       OP_RXCHKS       = 0x64,
+       OP_RXCHKSVLAN   = OP_RXCHKS | OP_RXVLAN,
+       OP_RXTIMEVLAN   = OP_RXTIMESTAMP | OP_RXVLAN,
+       OP_RSS_HASH     = 0x65,
+       OP_TXINDEXLE    = 0x68,
+};
+
+/* Yukon 2 hardware interface
+ * Not tested on big endian
+ */
+struct sky2_tx_le {
+       union {
+               __le32  addr;
+               struct {
+                       __le16  offset;
+                       __le16  start;
+               } csum  __attribute((packed));
+               struct {
+                       __le16  size;
+                       __le16  rsvd;
+               } tso  __attribute((packed));
+       } tx;
+       __le16  length; /* also vlan tag or checksum start */
+       u8      ctrl;
+       u8      opcode;
+} __attribute((packed));
+
+struct sky2_rx_le {
+       __le32  addr;
+       __le16  length;
+       u8      ctrl;
+       u8      opcode;
+} __attribute((packed));;
+
+struct sky2_status_le {
+       __le32  status; /* also checksum */
+       __le16  length; /* also vlan tag */
+       u8      link;
+       u8      opcode;
+} __attribute((packed));
+
+struct tx_ring_info {
+       struct sk_buff  *skb;
+       DECLARE_PCI_UNMAP_ADDR(mapaddr);
+       u16             idx;
+};
+
+struct ring_info {
+       struct sk_buff  *skb;
+       dma_addr_t      mapaddr;
+};
+
+struct sky2_port {
+       struct sky2_hw       *hw;
+       struct net_device    *netdev;
+       unsigned             port;
+       u32                  msg_enable;
+
+       spinlock_t           tx_lock  ____cacheline_aligned_in_smp;
+       struct tx_ring_info  *tx_ring;
+       struct sky2_tx_le    *tx_le;
+       u16                  tx_cons;           /* next le to check */
+       u16                  tx_prod;           /* next le to use */
+       u32                  tx_addr64;
+       u16                  tx_pending;
+       u16                  tx_last_put;
+       u16                  tx_last_mss;
+
+       struct ring_info     *rx_ring ____cacheline_aligned_in_smp;
+       struct sky2_rx_le    *rx_le;
+       u32                  rx_addr64;
+       u16                  rx_next;           /* next re to check */
+       u16                  rx_put;            /* next le index to use */
+       u16                  rx_pending;
+       u16                  rx_last_put;
+       u16                  rx_bufsize;
+#ifdef SKY2_VLAN_TAG_USED
+       u16                  rx_tag;
+       struct vlan_group    *vlgrp;
+#endif
+
+       dma_addr_t           rx_le_map;
+       dma_addr_t           tx_le_map;
+       u32                  advertising;       /* ADVERTISED_ bits */
+       u16                  speed;     /* SPEED_1000, SPEED_100, ... */
+       u8                   autoneg;   /* AUTONEG_ENABLE, AUTONEG_DISABLE */
+       u8                   duplex;    /* DUPLEX_HALF, DUPLEX_FULL */
+       u8                   rx_pause;
+       u8                   tx_pause;
+       u8                   rx_csum;
+       u8                   wol;
+
+       struct net_device_stats net_stats;
+
+       struct work_struct   phy_task;
+       struct semaphore     phy_sema;
+};
+
+struct sky2_hw {
+       void __iomem         *regs;
+       struct pci_dev       *pdev;
+       u32                  intr_mask;
+       struct net_device    *dev[2];
+
+       int                  pm_cap;
+       u8                   chip_id;
+       u8                   chip_rev;
+       u8                   copper;
+       u8                   ports;
+
+       struct sky2_status_le *st_le;
+       u32                  st_idx;
+       dma_addr_t           st_dma;
+};
+
+/* Register accessor for memory mapped device */
+static inline u32 sky2_read32(const struct sky2_hw *hw, unsigned reg)
+{
+       return readl(hw->regs + reg);
+}
+
+static inline u16 sky2_read16(const struct sky2_hw *hw, unsigned reg)
+{
+       return readw(hw->regs + reg);
+}
+
+static inline u8 sky2_read8(const struct sky2_hw *hw, unsigned reg)
+{
+       return readb(hw->regs + reg);
+}
+
+/* This should probably go away, bus based tweeks suck */
+static inline int is_pciex(const struct sky2_hw *hw)
+{
+       u32 status;
+       pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status);
+       return (status & PCI_OS_PCI_X) == 0;
+}
+
+static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val)
+{
+       writel(val, hw->regs + reg);
+}
+
+static inline void sky2_write16(const struct sky2_hw *hw, unsigned reg, u16 val)
+{
+       writew(val, hw->regs + reg);
+}
+
+static inline void sky2_write8(const struct sky2_hw *hw, unsigned reg, u8 val)
+{
+       writeb(val, hw->regs + reg);
+}
+
+/* Yukon PHY related registers */
+#define SK_GMAC_REG(port,reg) \
+       (BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
+#define GM_PHY_RETRIES 100
+
+static inline u16 gma_read16(const struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+       return sky2_read16(hw, SK_GMAC_REG(port,reg));
+}
+
+static inline u32 gma_read32(struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+       unsigned base = SK_GMAC_REG(port, reg);
+       return (u32) sky2_read16(hw, base)
+               | (u32) sky2_read16(hw, base+4) << 16;
+}
+
+static inline void gma_write16(const struct sky2_hw *hw, unsigned port, int r, u16 v)
+{
+       sky2_write16(hw, SK_GMAC_REG(port,r), v);
+}
+
+static inline void gma_set_addr(struct sky2_hw *hw, unsigned port, unsigned reg,
+                                   const u8 *addr)
+{
+       gma_write16(hw, port, reg,  (u16) addr[0] | ((u16) addr[1] << 8));
+       gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
+       gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
+}
+#endif
index 2fc9893d69e10532bfe50c707c0f0ee816e586b9..eb86b059809b6ac4242bbf91d16d258e7e9a7ab5 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 942fae0f2130227794dfcd17d7ccfdeaee63d655..c2506b56a18691f0eb4f4bfa9830fc8f877657a6 100644 (file)
@@ -2865,11 +2865,11 @@ void TLan_PhyMonitor( struct net_device *dev )
         *                              for this device.
         *              phy             The address of the PHY to be queried.
         *              reg             The register whose contents are to be
-        *                              retreived.
+        *                              retrieved.
         *              val             A pointer to a variable to store the
         *                              retrieved value.
         *
-        *      This function uses the TLAN's MII bus to retreive the contents
+        *      This function uses the TLAN's MII bus to retrieve the contents
         *      of a given register on a PHY.  It sends the appropriate info
         *      and then reads the 16-bit register value from the MII bus via
         *      the TLAN SIO register.
diff --git a/drivers/net/wan/.gitignore b/drivers/net/wan/.gitignore
new file mode 100644 (file)
index 0000000..dae3ea6
--- /dev/null
@@ -0,0 +1 @@
+wanxlfw.inc
diff --git a/drivers/net/wan/lmc/lmc_prot.h b/drivers/net/wan/lmc/lmc_prot.h
deleted file mode 100644 (file)
index f3b1df9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _LMC_PROTO_H_
-#define _LMC_PROTO_H_
-
-void lmc_proto_init(lmc_softc_t * const)
-void lmc_proto_attach(lmc_softc_t *sc const)
-void lmc_proto_detach(lmc_softc *sc const)
-void lmc_proto_reopen(lmc_softc_t *sc const)
-int lmc_proto_ioctl(lmc_softc_t *sc const, struct ifreq *ifr, int cmd)
-void lmc_proto_open(lmc_softc_t *sc const)
-void lmc_proto_close(lmc_softc_t *sc const)
-unsigned short lmc_proto_type(lmc_softc_t *sc const, struct skbuff *skb)
-
-
-#endif
-
index 00e55165b760506fe7e1f21c3aaf4197e3e3a3b8..24f7967aab67218f8f68fd1cdeae19a47183b3e1 100644 (file)
@@ -173,7 +173,7 @@ config IPW2100_MONITOR
          promiscuous mode via the Wireless Tool's Monitor mode.  While in this
          mode, no packets can be sent.
 
-config IPW_DEBUG
+config IPW2100_DEBUG
        bool "Enable full debugging output in IPW2100 module."
        depends on IPW2100
        ---help---
@@ -192,7 +192,7 @@ config IPW_DEBUG
 
 config IPW2200
        tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
-       depends on IEEE80211 && PCI
+       depends on NET_RADIO && IEEE80211 && PCI
        select FW_LOADER
        ---help---
           A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
@@ -217,7 +217,7 @@ config IPW2200
           say M here and read <file:Documentation/modules.txt>.  The module
           will be called ipw2200.ko.
 
-config IPW_DEBUG
+config IPW2200_DEBUG
        bool "Enable full debugging output in IPW2200 module."
        depends on IPW2200
        ---help---
index 7a92b1cbd6aadf80f8aaef65df9e930df82da984..ee866fd6957de2cf9ed0f3b75a9ca37971c4534b 100644 (file)
@@ -4037,7 +4037,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
                Cmd cmd;
                Resp rsp;
 
-               if (test_bit(FLAG_ENABLED, &ai->flags))
+               if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
                        printk(KERN_ERR
                                "%s: MAC should be disabled (rid=%04x)\n",
                                __FUNCTION__, rid);
@@ -5093,9 +5093,9 @@ static int set_wep_key(struct airo_info *ai, u16 index,
                printk(KERN_INFO "Setting key %d\n", index);
        }
 
-       disable_MAC(ai, lock);
+       if (perm) disable_MAC(ai, lock);
        writeWepKeyRid(ai, &wkr, perm, lock);
-       enable_MAC(ai, &rsp, lock);
+       if (perm) enable_MAC(ai, &rsp, lock);
        return 0;
 }
 
@@ -6170,6 +6170,8 @@ static int airo_set_encode(struct net_device *dev,
 {
        struct airo_info *local = dev->priv;
        CapabilityRid cap_rid;          /* Card capability info */
+       int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
+       u16 currentAuthType = local->config.authType;
 
        /* Is WEP supported ? */
        readCapabilityRid(local, &cap_rid, 1);
@@ -6212,7 +6214,7 @@ static int airo_set_encode(struct net_device *dev,
                        /* Copy the key in the driver */
                        memcpy(key.key, extra, dwrq->length);
                        /* Send the key to the card */
-                       set_wep_key(local, index, key.key, key.len, 1, 1);
+                       set_wep_key(local, index, key.key, key.len, perm, 1);
                }
                /* WE specify that if a valid key is set, encryption
                 * should be enabled (user may turn it off later)
@@ -6220,13 +6222,12 @@ static int airo_set_encode(struct net_device *dev,
                if((index == current_index) && (key.len > 0) &&
                   (local->config.authType == AUTH_OPEN)) {
                        local->config.authType = AUTH_ENCRYPT;
-                       set_bit (FLAG_COMMIT, &local->flags);
                }
        } else {
                /* Do we want to just set the transmit key index ? */
                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
                if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) {
-                       set_wep_key(local, index, NULL, 0, 1, 1);
+                       set_wep_key(local, index, NULL, 0, perm, 1);
                } else
                        /* Don't complain if only change the mode */
                        if(!dwrq->flags & IW_ENCODE_MODE) {
@@ -6241,7 +6242,7 @@ static int airo_set_encode(struct net_device *dev,
        if(dwrq->flags & IW_ENCODE_OPEN)
                local->config.authType = AUTH_ENCRYPT;  // Only Wep
        /* Commit the changes to flags if needed */
-       if(dwrq->flags & IW_ENCODE_MODE)
+       if (local->config.authType != currentAuthType)
                set_bit (FLAG_COMMIT, &local->flags);
        return -EINPROGRESS;            /* Call commit handler */
 }
index 5e53c5258a33e82933f92e2fe8e04a6698eb2465..e4729ddf29fd652b023601d1f523affd6aa88e53 100644 (file)
@@ -5,9 +5,9 @@
         Copyright 2000-2001 ATMEL Corporation.
         Copyright 2003-2004 Simon Kelley.
 
-    This code was developed from version 2.1.1 of the Atmel drivers, 
-    released by Atmel corp. under the GPL in December 2002. It also 
-    includes code from the Linux aironet drivers (C) Benjamin Reed, 
+    This code was developed from version 2.1.1 of the Atmel drivers,
+    released by Atmel corp. under the GPL in December 2002. It also
+    includes code from the Linux aironet drivers (C) Benjamin Reed,
     and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
     extensions, (C) Jean Tourrilhes.
 
@@ -31,7 +31,7 @@
     along with Atmel wireless lan drivers; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-    For all queries about this code, please contact the current author, 
+    For all queries about this code, please contact the current author,
     Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
 
     Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
@@ -79,13 +79,13 @@ MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.")
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
 
-/* The name of the firmware file to be loaded 
+/* The name of the firmware file to be loaded
    over-rides any automatic selection */
 static char *firmware = NULL;
 module_param(firmware, charp, 0);
 
 /* table of firmware file names */
-static struct { 
+static struct {
        AtmelFWType fw_type;
        const char *fw_file;
        const char *fw_file_ext;
@@ -104,17 +104,17 @@ static struct {
 #define MAX_SSID_LENGTH 32
 #define MGMT_JIFFIES (256 * HZ / 100)
 
-#define MAX_BSS_ENTRIES        64      
+#define MAX_BSS_ENTRIES        64
 
 /* registers */
-#define GCR  0x00    //      (SIR0)  General Configuration Register        
-#define BSR  0x02    //      (SIR1)  Bank Switching Select Register 
+#define GCR  0x00    //      (SIR0)  General Configuration Register
+#define BSR  0x02    //      (SIR1)  Bank Switching Select Register
 #define AR   0x04
 #define DR   0x08
-#define MR1  0x12    //      Mirror Register 1                  
-#define MR2  0x14    //      Mirror Register 2  
-#define MR3  0x16    //      Mirror Register 3  
-#define MR4  0x18    //      Mirror Register 4   
+#define MR1  0x12    //      Mirror Register 1
+#define MR2  0x14    //      Mirror Register 2
+#define MR3  0x16    //      Mirror Register 3
+#define MR4  0x18    //      Mirror Register 4
 
 #define GPR1                            0x0c
 #define GPR2                            0x0e
@@ -123,9 +123,9 @@ static struct {
 // Constants for the GCR register.
 //
 #define GCR_REMAP     0x0400          // Remap internal SRAM to 0
-#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset) 
+#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset)
 #define GCR_CORES     0x0060          // Core Reset (ARM and PAI are reset)
-#define GCR_ENINT     0x0002          // Enable Interrupts    
+#define GCR_ENINT     0x0002          // Enable Interrupts
 #define GCR_ACKINT    0x0008          // Acknowledge Interrupts
 
 #define BSS_SRAM      0x0200          // AMBA module selection --> SRAM
@@ -190,7 +190,7 @@ struct rx_desc {
         u32          Next;
         u16          MsduPos;
         u16          MsduSize;
-       
+
         u8           State;
         u8           Status;
         u8           Rate;
@@ -199,7 +199,6 @@ struct rx_desc {
         u8           PreambleType;
         u16          Duration;
         u32          RxTime;
-
 };
 
 #define RX_DESC_FLAG_VALID       0x80
@@ -218,16 +217,15 @@ struct rx_desc {
 #define RX_DESC_DURATION_OFFSET      14
 #define RX_DESC_RX_TIME_OFFSET       16
 
-
 struct tx_desc {
        u32       NextDescriptor;
        u16       TxStartOfFrame;
        u16       TxLength;
-       
+
        u8        TxState;
        u8        TxStatus;
        u8        RetryCount;
-       
+
        u8        TxRate;
 
        u8        KeyIndex;
@@ -238,10 +236,8 @@ struct tx_desc {
        u8        Reserved;
        u8        PacketType;
        u16       HostTxLength;
-       
 };
 
-
 #define TX_DESC_NEXT_OFFSET          0
 #define TX_DESC_POS_OFFSET           4
 #define TX_DESC_SIZE_OFFSET          6
@@ -255,8 +251,6 @@ struct tx_desc {
 #define TX_DESC_PACKET_TYPE_OFFSET   17
 #define TX_DESC_HOST_LENGTH_OFFSET   18
 
-
-
 ///////////////////////////////////////////////////////
 // Host-MAC interface
 ///////////////////////////////////////////////////////
@@ -266,7 +260,6 @@ struct tx_desc {
 #define TX_FIRM_OWN             0x80
 #define TX_DONE                 0x40
 
-
 #define TX_ERROR                0x01
 
 #define TX_PACKET_TYPE_DATA     0x01
@@ -280,8 +273,7 @@ struct tx_desc {
 #define ISR_COMMAND_COMPLETE    0x10        // command completed
 #define ISR_OUT_OF_RANGE        0x20        // command completed
 #define ISR_IBSS_MERGE          0x40        // (4.1.2.30): IBSS merge
-#define ISR_GENERIC_IRQ         0x80                
-
+#define ISR_GENERIC_IRQ         0x80
 
 #define Local_Mib_Type          0x01
 #define Mac_Address_Mib_Type    0x02
@@ -317,7 +309,6 @@ struct tx_desc {
 #define LOCAL_MIB_PREAMBLE_TYPE               9
 #define MAC_ADDR_MIB_MAC_ADDR_POS             0
 
-
 #define         CMD_Set_MIB_Vars              0x01
 #define         CMD_Get_MIB_Vars              0x02
 #define         CMD_Scan                      0x03
@@ -338,7 +329,6 @@ struct tx_desc {
 #define         CMD_STATUS_HOST_ERROR             0xFF
 #define         CMD_STATUS_BUSY                   0xFE
 
-
 #define CMD_BLOCK_COMMAND_OFFSET        0
 #define CMD_BLOCK_STATUS_OFFSET         1
 #define CMD_BLOCK_PARAMETERS_OFFSET     4
@@ -347,15 +337,15 @@ struct tx_desc {
 
 #define MGMT_FRAME_BODY_OFFSET         24
 #define MAX_AUTHENTICATION_RETRIES     3
-#define MAX_ASSOCIATION_RETRIES        3
+#define MAX_ASSOCIATION_RETRIES                3
 
 #define AUTHENTICATION_RESPONSE_TIME_OUT  1000
 
 #define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
 #define LOOP_RETRY_LIMIT   500000
 
-#define ACTIVE_MODE    1
-#define PS_MODE        2
+#define ACTIVE_MODE    1
+#define PS_MODE                2
 
 #define MAX_ENCRYPTION_KEYS 4
 #define MAX_ENCRYPTION_KEY_SIZE 40
@@ -377,7 +367,7 @@ struct tx_desc {
 #define REG_DOMAIN_MKK1                0x41    //Channel       1-14    Japan(MKK1)
 #define REG_DOMAIN_ISRAEL      0x50    //Channel       3-9     ISRAEL
 
-#define BSS_TYPE_AD_HOC        1
+#define BSS_TYPE_AD_HOC                1
 #define BSS_TYPE_INFRASTRUCTURE 2
 
 #define SCAN_TYPE_ACTIVE       0
@@ -389,7 +379,7 @@ struct tx_desc {
 
 #define DATA_FRAME_WS_HEADER_SIZE   30
 
-/* promiscuous mode control */ 
+/* promiscuous mode control */
 #define PROM_MODE_OFF                  0x0
 #define PROM_MODE_UNKNOWN              0x1
 #define PROM_MODE_CRC_FAILED           0x2
@@ -398,8 +388,7 @@ struct tx_desc {
 #define PROM_MODE_CTRL                 0x10
 #define PROM_MODE_BAD_PROTOCOL         0x20
 
-
-#define IFACE_INT_STATUS_OFFSET        0
+#define IFACE_INT_STATUS_OFFSET                0
 #define IFACE_INT_MASK_OFFSET          1
 #define IFACE_LOCKOUT_HOST_OFFSET      2
 #define IFACE_LOCKOUT_MAC_OFFSET       3
@@ -407,7 +396,7 @@ struct tx_desc {
 #define IFACE_MAC_STAT_OFFSET          30
 #define IFACE_GENERIC_INT_TYPE_OFFSET  32
 
-#define CIPHER_SUITE_NONE     0 
+#define CIPHER_SUITE_NONE     0
 #define CIPHER_SUITE_WEP_64   1
 #define CIPHER_SUITE_TKIP     2
 #define CIPHER_SUITE_AES      3
@@ -419,11 +408,11 @@ struct tx_desc {
 //
 //
 
-// FuncCtrl field: 
+// FuncCtrl field:
 //
 #define FUNC_CTRL_TxENABLE             0x10
 #define FUNC_CTRL_RxENABLE             0x20
-#define FUNC_CTRL_INIT_COMPLETE        0x01
+#define FUNC_CTRL_INIT_COMPLETE                0x01
 
 /* A stub firmware image which reads the MAC address from NVRAM on the card.
    For copyright information and source see the end of this file. */
@@ -486,10 +475,10 @@ struct atmel_private {
        struct net_device_stats stats;  // device stats
        spinlock_t irqlock, timerlock;  // spinlocks
        enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
-       enum { 
-               CARD_TYPE_PARALLEL_FLASH, 
+       enum {
+               CARD_TYPE_PARALLEL_FLASH,
                CARD_TYPE_SPI_FLASH,
-               CARD_TYPE_EEPROM 
+               CARD_TYPE_EEPROM
        } card_type;
        int do_rx_crc; /* If we need to CRC incoming packets */
        int probe_crc; /* set if we don't yet know */
@@ -497,18 +486,18 @@ struct atmel_private {
        u16 rx_desc_head;
        u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
        u16 tx_free_mem, tx_buff_head, tx_buff_tail;
-       
+
        u16 frag_seq, frag_len, frag_no;
-       u8 frag_source[6]; 
-       
+       u8 frag_source[6];
+
        u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
        u8 group_cipher_suite, pairwise_cipher_suite;
        u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
-       int wep_key_len[MAX_ENCRYPTION_KEYS]; 
+       int wep_key_len[MAX_ENCRYPTION_KEYS];
        int use_wpa, radio_on_broken; /* firmware dependent stuff. */
 
        u16 host_info_base;
-       struct host_info_struct { 
+       struct host_info_struct {
                /* NB this is matched to the hardware, don't change. */
                u8 volatile int_status;
                u8 volatile int_mask;
@@ -524,20 +513,20 @@ struct atmel_private {
                u16 rx_buff_size;
                u16 rx_desc_pos;
                u16 rx_desc_count;
-               
+
                u16 build_version;
-               u16 command_pos;        
-               
+               u16 command_pos;
+
                u16 major_version;
                u16 minor_version;
-               
+
                u16 func_ctrl;
                u16 mac_status;
                u16 generic_IRQ_type;
                u8  reserved[2];
        } host_info;
 
-       enum { 
+       enum {
                STATION_STATE_SCANNING,
                STATION_STATE_JOINNING,
                STATION_STATE_AUTHENTICATING,
@@ -547,7 +536,7 @@ struct atmel_private {
                STATION_STATE_DOWN,
                STATION_STATE_MGMT_ERROR
        } station_state;
-       
+
        int operating_mode, power_mode;
        time_t last_qual;
        int beacons_this_sec;
@@ -560,18 +549,18 @@ struct atmel_private {
        int long_retry, short_retry;
        int preamble;
        int default_beacon_period, beacon_period, listen_interval;
-       int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;  
+       int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
        int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
        enum {
                SITE_SURVEY_IDLE,
                SITE_SURVEY_IN_PROGRESS,
-               SITE_SURVEY_COMPLETED 
+               SITE_SURVEY_COMPLETED
        } site_survey_state;
        time_t last_survey;
 
        int station_was_associated, station_is_associated;
        int fast_scan;
-                               
+
        struct bss_info {
                int channel;
                int SSIDsize;
@@ -584,13 +573,12 @@ struct atmel_private {
                u8 SSID[MAX_SSID_LENGTH];
        } BSSinfo[MAX_BSS_ENTRIES];
        int BSS_list_entries, current_BSS;
-       int connect_to_any_BSS; 
+       int connect_to_any_BSS;
        int SSID_size, new_SSID_size;
        u8 CurrentBSSID[6], BSSID[6];
        u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
        u64 last_beacon_timestamp;
        u8 rx_buf[MAX_WIRELESS_BODY];
-       
 };
 
 static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
@@ -598,39 +586,49 @@ static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
 static const struct {
        int reg_domain;
        int min, max;
-       char *name; 
+       char *name;
 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
                      { REG_DOMAIN_DOC, 1, 11, "Canada" },
                      { REG_DOMAIN_ETSI, 1, 13, "Europe" },
                      { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
-                     { REG_DOMAIN_FRANCE, 10, 13, "France" }, 
+                     { REG_DOMAIN_FRANCE, 10, 13, "France" },
                      { REG_DOMAIN_MKK, 14, 14, "MKK" },
                      { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
                      { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
 
 static void build_wpa_mib(struct atmel_private *priv);
 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len);
-static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len);
+static void atmel_copy_to_card(struct net_device *dev, u16 dest,
+                              unsigned char *src, u16 len);
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
+                              u16 src, u16 len);
 static void atmel_set_gcr(struct net_device *dev, u16 mask);
 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
 static int atmel_lock_mac(struct atmel_private *priv);
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
 static void atmel_command_irq(struct atmel_private *priv);
 static int atmel_validate_channel(struct atmel_private *priv, int channel);
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+static void atmel_management_frame(struct atmel_private *priv,
+                                  struct ieee80211_hdr_4addr *header,
                                   u16 frame_len, u8 rssi);
 static void atmel_management_timer(u_long a);
-static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
+static void atmel_send_command(struct atmel_private *priv, int command,
+                              void *cmd, int cmd_size);
+static int atmel_send_command_wait(struct atmel_private *priv, int command,
+                                  void *cmd, int cmd_size);
+static void atmel_transmit_management_frame(struct atmel_private *priv,
+                                           struct ieee80211_hdr_4addr *header,
                                            u8 *body, int body_len);
 
 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
-static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data);
-static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data);
-static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
-static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
+static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
+                          u8 data);
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
+                           u16 data);
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
+                         u8 *data, int data_len);
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
+                         u8 *data, int data_len);
 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
 static void atmel_smooth_qual(struct atmel_private *priv);
@@ -650,12 +648,12 @@ static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
        return priv->host_info.command_pos + offset;
 }
 
-static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16  desc)
+static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
 {
        return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
 }
 
-static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16  desc)
+static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
 {
        return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
 }
@@ -682,25 +680,25 @@ static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
 
 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
 {
-       atmel_writeAR(priv->dev, pos);  
+       atmel_writeAR(priv->dev, pos);
        return atmel_read8(priv->dev, DR);
 }
 
 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
 {
-       atmel_writeAR(priv->dev, pos);  
+       atmel_writeAR(priv->dev, pos);
        atmel_write8(priv->dev, DR, data);
 }
 
 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
 {
-               atmel_writeAR(priv->dev, pos);  
+       atmel_writeAR(priv->dev, pos);
        return atmel_read16(priv->dev, DR);
 }
 
 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
 {
-               atmel_writeAR(priv->dev, pos);  
+       atmel_writeAR(priv->dev, pos);
        atmel_write16(priv->dev, DR, data);
 }
 
@@ -710,11 +708,10 @@ static void tx_done_irq(struct atmel_private *priv)
 {
        int i;
 
-       for (i = 0; 
+       for (i = 0;
             atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
                     i < priv->host_info.tx_desc_count;
             i++) {
-               
                u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
                u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
                u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
@@ -728,16 +725,16 @@ static void tx_done_irq(struct atmel_private *priv)
                        priv->tx_buff_head = 0;
                else
                        priv->tx_buff_head += msdu_size;
-                       
+
                if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
-                       priv->tx_desc_head++ ;                                  
+                       priv->tx_desc_head++ ;
                else
                        priv->tx_desc_head = 0;
-               
+
                if (type == TX_PACKET_TYPE_DATA) {
                        if (status == TX_STATUS_SUCCESS)
                                priv->stats.tx_packets++;
-                       else 
+                       else
                                priv->stats.tx_errors++;
                        netif_wake_queue(priv->dev);
                }
@@ -748,21 +745,22 @@ static u16 find_tx_buff(struct atmel_private *priv, u16 len)
 {
        u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
 
-       if (priv->tx_desc_free == 3 || priv->tx_free_mem < len) 
+       if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
                return 0;
-       
+
        if (bottom_free >= len)
                return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
-       
+
        if (priv->tx_free_mem - bottom_free >= len) {
                priv->tx_buff_tail = 0;
                return priv->host_info.tx_buff_pos;
        }
-       
+
        return 0;
 }
 
-static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 len, u16 buff, u8 type)
+static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
+                                u16 len, u16 buff, u8 type)
 {
        atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
        atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
@@ -775,8 +773,8 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
                int cipher_type, cipher_length;
                if (is_bcast) {
                        cipher_type = priv->group_cipher_suite;
-                       if (cipher_type == CIPHER_SUITE_WEP_64 || 
-                           cipher_type == CIPHER_SUITE_WEP_128 )
+                       if (cipher_type == CIPHER_SUITE_WEP_64 ||
+                           cipher_type == CIPHER_SUITE_WEP_128)
                                cipher_length = 8;
                        else if (cipher_type == CIPHER_SUITE_TKIP)
                                cipher_length = 12;
@@ -790,8 +788,8 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
                        }
                } else {
                        cipher_type = priv->pairwise_cipher_suite;
-                       if (cipher_type == CIPHER_SUITE_WEP_64 || 
-                           cipher_type == CIPHER_SUITE_WEP_128 )
+                       if (cipher_type == CIPHER_SUITE_WEP_64 ||
+                           cipher_type == CIPHER_SUITE_WEP_128)
                                cipher_length = 8;
                        else if (cipher_type == CIPHER_SUITE_TKIP)
                                cipher_length = 12;
@@ -804,9 +802,9 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
                                cipher_length = 0;
                        }
                }
-               
+
                atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
-                           cipher_type);       
+                           cipher_type);
                atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
                            cipher_length);
        }
@@ -815,46 +813,46 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
        if (priv->tx_desc_previous != priv->tx_desc_tail)
                atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
        priv->tx_desc_previous = priv->tx_desc_tail;
-       if (priv->tx_desc_tail < (priv->host_info.tx_desc_count -))
+       if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
                priv->tx_desc_tail++;
        else
                priv->tx_desc_tail = 0;
        priv->tx_desc_free--;
        priv->tx_free_mem -= len;
-
 }
 
-static int start_tx (struct sk_buff *skb, struct net_device *dev)
+static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct atmel_private *priv = netdev_priv(dev);
        struct ieee80211_hdr_4addr header;
        unsigned long flags;
        u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
        u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-       if (priv->card && priv->present_callback && 
+
+       if (priv->card && priv->present_callback &&
            !(*priv->present_callback)(priv->card)) {
                priv->stats.tx_errors++;
                dev_kfree_skb(skb);
                return 0;
        }
-       
+
        if (priv->station_state != STATION_STATE_READY) {
                priv->stats.tx_errors++;
                dev_kfree_skb(skb);
                return 0;
        }
-       
+
        /* first ensure the timer func cannot run */
-       spin_lock_bh(&priv->timerlock); 
+       spin_lock_bh(&priv->timerlock);
        /* then stop the hardware ISR */
-       spin_lock_irqsave(&priv->irqlock, flags); 
+       spin_lock_irqsave(&priv->irqlock, flags);
        /* nb doing the above in the opposite order will deadlock */
-       
+
        /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
-          12 first bytes (containing DA/SA) and put them in the appropriate fields of
-          the Wireless Header. Thus the packet length is then the initial + 18 (+30-12) */
-       
+          12 first bytes (containing DA/SA) and put them in the appropriate
+          fields of the Wireless Header. Thus the packet length is then the
+          initial + 18 (+30-12) */
+
        if (!(buff = find_tx_buff(priv, len + 18))) {
                priv->stats.tx_dropped++;
                spin_unlock_irqrestore(&priv->irqlock, flags);
@@ -862,7 +860,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
                return 1;
        }
-       
+
        frame_ctl = IEEE80211_FTYPE_DATA;
        header.duration_id = 0;
        header.seq_ctl = 0;
@@ -878,7 +876,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
                memcpy(&header.addr2, dev->dev_addr, 6);
                memcpy(&header.addr3, skb->data, 6);
        }
-       
+
        if (priv->use_wpa)
                memcpy(&header.addr4, SNAP_RFC1024, 6);
 
@@ -888,27 +886,27 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
        /* Copy the packet sans its 802.3 header addresses which have been replaced */
        atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
        priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
-       
+
        /* low bit of first byte of destination tells us if broadcast */
        tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
        dev->trans_start = jiffies;
        priv->stats.tx_bytes += len;
-       
+
        spin_unlock_irqrestore(&priv->irqlock, flags);
        spin_unlock_bh(&priv->timerlock);
        dev_kfree_skb(skb);
-       
-       return 0;       
+
+       return 0;
 }
 
-static void atmel_transmit_management_frame(struct atmel_private *priv, 
+static void atmel_transmit_management_frame(struct atmel_private *priv,
                                            struct ieee80211_hdr_4addr *header,
                                            u8 *body, int body_len)
 {
        u16 buff;
-       int len =  MGMT_FRAME_BODY_OFFSET + body_len;
-       
-       if (!(buff = find_tx_buff(priv, len))) 
+       int len = MGMT_FRAME_BODY_OFFSET + body_len;
+
+       if (!(buff = find_tx_buff(priv, len)))
                return;
 
        atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
@@ -916,24 +914,25 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
        priv->tx_buff_tail += len;
        tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
 }
-       
-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+
+static void fast_rx_path(struct atmel_private *priv,
+                        struct ieee80211_hdr_4addr *header,
                         u16 msdu_size, u16 rx_packet_loc, u32 crc)
 {
        /* fast path: unfragmented packet copy directly into skbuf */
-       u8 mac4[6]; 
-       struct sk_buff  *skb;
+       u8 mac4[6];
+       struct sk_buff  *skb;
        unsigned char *skbp;
-       
+
        /* get the final, mac 4 header field, this tells us encapsulation */
        atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
        msdu_size -= 6;
-       
+
        if (priv->do_rx_crc) {
                crc = crc32_le(crc, mac4, 6);
                msdu_size -= 4;
        }
-       
+
        if (!(skb = dev_alloc_skb(msdu_size + 14))) {
                priv->stats.rx_dropped++;
                return;
@@ -942,7 +941,7 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
        skb_reserve(skb, 2);
        skbp = skb_put(skb, msdu_size + 12);
        atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
-       
+
        if (priv->do_rx_crc) {
                u32 netcrc;
                crc = crc32_le(crc, skbp + 12, msdu_size);
@@ -953,24 +952,25 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
                        return;
                }
        }
-       
+
        memcpy(skbp, header->addr1, 6); /* destination address */
-       if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS) 
+       if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
                memcpy(&skbp[6], header->addr3, 6);
        else
                memcpy(&skbp[6], header->addr2, 6); /* source address */
-       
-       priv->dev->last_rx=jiffies;
+
+       priv->dev->last_rx = jiffies;
        skb->dev = priv->dev;
        skb->protocol = eth_type_trans(skb, priv->dev);
-       skb->ip_summed = CHECKSUM_NONE; 
+       skb->ip_summed = CHECKSUM_NONE;
        netif_rx(skb);
        priv->stats.rx_bytes += 12 + msdu_size;
        priv->stats.rx_packets++;
 }
 
 /* Test to see if the packet in card memory at packet_loc has a valid CRC
-   It doesn't matter that this is slow: it is only used to proble the first few packets. */
+   It doesn't matter that this is slow: it is only used to proble the first few
+   packets. */
 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
 {
        int i = msdu_size - 4;
@@ -980,7 +980,7 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
                return 0;
 
        atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
-       
+
        atmel_writeAR(priv->dev, packet_loc);
        while (i--) {
                u8 octet = atmel_read8(priv->dev, DR);
@@ -990,20 +990,22 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
        return (crc ^ 0xffffffff) == netcrc;
 }
 
-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
-                        u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
+static void frag_rx_path(struct atmel_private *priv,
+                        struct ieee80211_hdr_4addr *header,
+                        u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
+                        u8 frag_no, int more_frags)
 {
-       u8 mac4[6]; 
+       u8 mac4[6];
        u8 source[6];
        struct sk_buff *skb;
 
-       if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS) 
+       if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
                memcpy(source, header->addr3, 6);
        else
-               memcpy(source, header->addr2, 6); 
-       
+               memcpy(source, header->addr2, 6);
+
        rx_packet_loc += 24; /* skip header */
-       
+
        if (priv->do_rx_crc)
                msdu_size -= 4;
 
@@ -1012,16 +1014,16 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
                msdu_size -= 6;
                rx_packet_loc += 6;
 
-               if (priv->do_rx_crc) 
+               if (priv->do_rx_crc)
                        crc = crc32_le(crc, mac4, 6);
-              
+
                priv->frag_seq = seq_no;
                priv->frag_no = 1;
                priv->frag_len = msdu_size;
-               memcpy(priv->frag_source, source, 6); 
+               memcpy(priv->frag_source, source, 6);
                memcpy(&priv->rx_buf[6], source, 6);
                memcpy(priv->rx_buf, header->addr1, 6);
-                               
+
                atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
 
                if (priv->do_rx_crc) {
@@ -1033,17 +1035,17 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
                                memset(priv->frag_source, 0xff, 6);
                        }
                }
-               
+
        } else if (priv->frag_no == frag_no &&
                   priv->frag_seq == seq_no &&
                   memcmp(priv->frag_source, source, 6) == 0) {
-               
-               atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len], 
+
+               atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
                                   rx_packet_loc, msdu_size);
                if (priv->do_rx_crc) {
                        u32 netcrc;
-                       crc = crc32_le(crc, 
-                                      &priv->rx_buf[12 + priv->frag_len], 
+                       crc = crc32_le(crc,
+                                      &priv->rx_buf[12 + priv->frag_len],
                                       msdu_size);
                        atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
                        if ((crc ^ 0xffffffff) != netcrc) {
@@ -1052,7 +1054,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
                                more_frags = 1; /* don't send broken assembly */
                        }
                }
-               
+
                priv->frag_len += msdu_size;
                priv->frag_no++;
 
@@ -1062,60 +1064,60 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr
                                priv->stats.rx_dropped++;
                        } else {
                                skb_reserve(skb, 2);
-                               memcpy(skb_put(skb, priv->frag_len + 12), 
+                               memcpy(skb_put(skb, priv->frag_len + 12),
                                       priv->rx_buf,
                                       priv->frag_len + 12);
                                priv->dev->last_rx = jiffies;
                                skb->dev = priv->dev;
                                skb->protocol = eth_type_trans(skb, priv->dev);
-                               skb->ip_summed = CHECKSUM_NONE; 
+                               skb->ip_summed = CHECKSUM_NONE;
                                netif_rx(skb);
                                priv->stats.rx_bytes += priv->frag_len + 12;
                                priv->stats.rx_packets++;
                        }
                }
-               
        } else
                priv->wstats.discard.fragment++;
 }
-               
+
 static void rx_done_irq(struct atmel_private *priv)
 {
        int i;
        struct ieee80211_hdr_4addr header;
-       
-       for (i = 0; 
+
+       for (i = 0;
             atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
                     i < priv->host_info.rx_desc_count;
             i++) {
-                               
+
                u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
                u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
                u32 crc = 0xffffffff;
-               
+
                if (status != RX_STATUS_SUCCESS) {
                        if (status == 0xc1) /* determined by experiment */
                                priv->wstats.discard.nwid++;
                        else
-                               priv->stats.rx_errors++; 
+                               priv->stats.rx_errors++;
                        goto next;
                }
 
                msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
                rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
-               
+
                if (msdu_size < 30) {
-                       priv->stats.rx_errors++; 
+                       priv->stats.rx_errors++;
                        goto next;
                }
-               
+
                /* Get header as far as end of seq_ctl */
                atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
                frame_ctl = le16_to_cpu(header.frame_ctl);
                seq_control = le16_to_cpu(header.seq_ctl);
 
-               /* probe for CRC use here if needed  once five packets have arrived with
-                  the same crc status, we assume we know what's happening and stop probing */
+               /* probe for CRC use here if needed  once five packets have
+                  arrived with the same crc status, we assume we know what's
+                  happening and stop probing */
                if (priv->probe_crc) {
                        if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
                                priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
@@ -1130,34 +1132,33 @@ static void rx_done_irq(struct atmel_private *priv)
                                        priv->probe_crc = 0;
                        }
                }
-                   
+
                /* don't CRC header when WEP in use */
                if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
                        crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
                }
                msdu_size -= 24; /* header */
 
-               if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { 
-                       
+               if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
                        int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
                        u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
                        u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
-                       
-                       if (!more_fragments && packet_fragment_no == 0 ) {
+
+                       if (!more_fragments && packet_fragment_no == 0) {
                                fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
                        } else {
                                frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
                                             packet_sequence_no, packet_fragment_no, more_fragments);
                        }
                }
-               
+
                if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
                        /* copy rest of packet into buffer */
                        atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
-                       
+
                        /* we use the same buffer for frag reassembly and control packets */
                        memset(priv->frag_source, 0xff, 6);
-                       
+
                        if (priv->do_rx_crc) {
                                /* last 4 octets is crc */
                                msdu_size -= 4;
@@ -1170,18 +1171,18 @@ static void rx_done_irq(struct atmel_private *priv)
 
                        atmel_management_frame(priv, &header, msdu_size,
                                               atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
-               } 
+               }
 
-       next:
+next:
                /* release descriptor */
-               atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);  
-               
+               atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
+
                if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
-                       priv->rx_desc_head++;                                   
+                       priv->rx_desc_head++;
                else
                        priv->rx_desc_head = 0;
        }
-}      
+}
 
 static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -1189,7 +1190,7 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
        struct atmel_private *priv = netdev_priv(dev);
        u8 isr;
        int i = -1;
-       static u8 irq_order[] = { 
+       static u8 irq_order[] = {
                ISR_OUT_OF_RANGE,
                ISR_RxCOMPLETE,
                ISR_TxCOMPLETE,
@@ -1199,20 +1200,19 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
                ISR_IBSS_MERGE,
                ISR_GENERIC_IRQ
        };
-               
 
-       if (priv->card && priv->present_callback && 
+       if (priv->card && priv->present_callback &&
            !(*priv->present_callback)(priv->card))
                return IRQ_HANDLED;
 
        /* In this state upper-level code assumes it can mess with
           the card unhampered by interrupts which may change register state.
           Note that even though the card shouldn't generate interrupts
-          the inturrupt line may be shared. This allows card setup 
+          the inturrupt line may be shared. This allows card setup
           to go on without disabling interrupts for a long time. */
        if (priv->station_state == STATION_STATE_DOWN)
                return IRQ_NONE;
-       
+
        atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
 
        while (1) {
@@ -1221,36 +1221,36 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
                        printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
                        return IRQ_HANDLED;
                }
-               
+
                isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
                atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-               
+
                if (!isr) {
                        atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
                        return i == -1 ? IRQ_NONE : IRQ_HANDLED;
                }
-               
+
                atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
-               
+
                for (i = 0; i < sizeof(irq_order)/sizeof(u8); i++)
                        if (isr & irq_order[i])
                                break;
-               
+
                if (!atmel_lock_mac(priv)) {
                        /* failed to contact card */
                        printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
                        return IRQ_HANDLED;
                }
-               
+
                isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
                isr ^= irq_order[i];
                atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
                atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-               
+
                switch (irq_order[i]) {
-                       
-               case ISR_OUT_OF_RANGE: 
-                       if (priv->operating_mode == IW_MODE_INFRA && 
+
+               case ISR_OUT_OF_RANGE:
+                       if (priv->operating_mode == IW_MODE_INFRA &&
                            priv->station_state == STATION_STATE_READY) {
                                priv->station_is_associated = 0;
                                atmel_scan(priv, 1);
@@ -1261,24 +1261,24 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
                        priv->wstats.discard.misc++;
                        /* fall through */
                case ISR_RxCOMPLETE:
-                       rx_done_irq(priv); 
+                       rx_done_irq(priv);
                        break;
-                       
+
                case ISR_TxCOMPLETE:
-                       tx_done_irq(priv); 
+                       tx_done_irq(priv);
                        break;
-                       
+
                case ISR_FATAL_ERROR:
                        printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
                        atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
                        break;
-                       
-               case ISR_COMMAND_COMPLETE: 
+
+               case ISR_COMMAND_COMPLETE:
                        atmel_command_irq(priv);
                        break;
 
                case ISR_IBSS_MERGE:
-                       atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS, 
+                       atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
                                      priv->CurrentBSSID, 6);
                        /* The WPA stuff cares about the current AP address */
                        if (priv->use_wpa)
@@ -1288,24 +1288,23 @@ static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs
                        printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
                        break;
                }
-       }       
+       }
 }
 
-
-static struct net_device_stats *atmel_get_stats (struct net_device *dev)
+static struct net_device_stats *atmel_get_stats(struct net_device *dev)
 {
        struct atmel_private *priv = netdev_priv(dev);
        return &priv->stats;
 }
 
-static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev)
+static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
 {
        struct atmel_private *priv = netdev_priv(dev);
 
-       /* update the link quality here in case we are seeing no beacons 
+       /* update the link quality here in case we are seeing no beacons
           at all to drive the process */
        atmel_smooth_qual(priv);
-       
+
        priv->wstats.status = priv->station_state;
 
        if (priv->operating_mode == IW_MODE_INFRA) {
@@ -1328,8 +1327,8 @@ static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev)
                                        | IW_QUAL_NOISE_INVALID;
                priv->wstats.miss.beacon = 0;
        }
-       
-       return (&priv->wstats);
+
+       return &priv->wstats;
 }
 
 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
@@ -1343,21 +1342,21 @@ static int atmel_change_mtu(struct net_device *dev, int new_mtu)
 static int atmel_set_mac_address(struct net_device *dev, void *p)
 {
        struct sockaddr *addr = p;
-        
+
         memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
        return atmel_open(dev);
 }
 
 EXPORT_SYMBOL(atmel_open);
 
-int atmel_open (struct net_device *dev)
+int atmel_open(struct net_device *dev)
 {
        struct atmel_private *priv = netdev_priv(dev);
        int i, channel;
 
        /* any scheduled timer is no longer needed and might screw things up.. */
        del_timer_sync(&priv->management_timer);
-       
+
        /* Interrupts will not touch the card once in this state... */
        priv->station_state = STATION_STATE_DOWN;
 
@@ -1377,7 +1376,7 @@ int atmel_open (struct net_device *dev)
        priv->site_survey_state = SITE_SURVEY_IDLE;
        priv->station_is_associated = 0;
 
-       if (!reset_atmel_card(dev)) 
+       if (!reset_atmel_card(dev))
                return -EAGAIN;
 
        if (priv->config_reg_domain) {
@@ -1391,26 +1390,26 @@ int atmel_open (struct net_device *dev)
                if (i == sizeof(channel_table)/sizeof(channel_table[0])) {
                        priv->reg_domain = REG_DOMAIN_MKK1;
                        printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
-               } 
+               }
        }
-       
+
        if ((channel = atmel_validate_channel(priv, priv->channel)))
                priv->channel = channel;
 
-       /* this moves station_state on.... */ 
-       atmel_scan(priv, 1);    
+       /* this moves station_state on.... */
+       atmel_scan(priv, 1);
 
        atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
        return 0;
 }
 
-static int atmel_close (struct net_device *dev)
+static int atmel_close(struct net_device *dev)
 {
        struct atmel_private *priv = netdev_priv(dev);
-               
+
        atmel_enter_state(priv, STATION_STATE_DOWN);
-       
-       if (priv->bus_type == BUS_TYPE_PCCARD) 
+
+       if (priv->bus_type == BUS_TYPE_PCCARD)
                atmel_write16(dev, GCR, 0x0060);
        atmel_write16(dev, GCR, 0x0040);
        return 0;
@@ -1438,43 +1437,46 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
        int i;
        char *p = buf;
        char *s, *r, *c;
-       
-       p += sprintf(p, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
-       
+
+       p += sprintf(p, "Driver version:\t\t%d.%d\n",
+                    DRIVER_MAJOR, DRIVER_MINOR);
+
        if (priv->station_state != STATION_STATE_DOWN) {
-               p += sprintf(p, "Firmware version:\t%d.%d build %d\nFirmware location:\t", 
+               p += sprintf(p, "Firmware version:\t%d.%d build %d\n"
+                               "Firmware location:\t",
                             priv->host_info.major_version,
                             priv->host_info.minor_version,
                             priv->host_info.build_version);
-               
-               if (priv->card_type != CARD_TYPE_EEPROM) 
+
+               if (priv->card_type != CARD_TYPE_EEPROM)
                        p += sprintf(p, "on card\n");
-               else if (priv->firmware) 
-                       p += sprintf(p, "%s loaded by host\n", priv->firmware_id);
+               else if (priv->firmware)
+                       p += sprintf(p, "%s loaded by host\n",
+                                    priv->firmware_id);
                else
-                       p += sprintf(p, "%s loaded by hotplug\n", priv->firmware_id);
-               
-               switch(priv->card_type) {
+                       p += sprintf(p, "%s loaded by hotplug\n",
+                                    priv->firmware_id);
+
+               switch (priv->card_type) {
                case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
                case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
                case CARD_TYPE_EEPROM: c = "EEPROM"; break;
                default: c = "<unknown>";
                }
 
-               
                r = "<unknown>";
                for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++)
                        if (priv->reg_domain == channel_table[i].reg_domain)
                                r = channel_table[i].name;
-               
+
                p += sprintf(p, "MAC memory type:\t%s\n", c);
                p += sprintf(p, "Regulatory domain:\t%s\n", r);
-               p += sprintf(p, "Host CRC checking:\t%s\n", 
+               p += sprintf(p, "Host CRC checking:\t%s\n",
                             priv->do_rx_crc ? "On" : "Off");
                p += sprintf(p, "WPA-capable firmware:\t%s\n",
                             priv->use_wpa ? "Yes" : "No");
        }
-       
+
        switch(priv->station_state) {
        case STATION_STATE_SCANNING: s = "Scanning"; break;
        case STATION_STATE_JOINNING: s = "Joining"; break;
@@ -1486,9 +1488,9 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
        case STATION_STATE_DOWN: s = "Down"; break;
        default: s = "<unknown>";
        }
-      
+
        p += sprintf(p, "Current state:\t\t%s\n", s);
-       return  p - buf;
+       return p - buf;
 }
 
 static int atmel_read_proc(char *page, char **start, off_t off,
@@ -1504,9 +1506,12 @@ static int atmel_read_proc(char *page, char **start, off_t off,
         return len;
 }
 
-struct net_device *init_atmel_card( unsigned short irq, unsigned long port, const AtmelFWType fw_type,  
-                                   struct device *sys_dev, int (*card_present)(void *), void *card)
+struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
+                                  const AtmelFWType fw_type,
+                                  struct device *sys_dev,
+                                  int (*card_present)(void *), void *card)
 {
+       struct proc_dir_entry *ent;
        struct net_device *dev;
        struct atmel_private *priv;
        int rc;
@@ -1514,11 +1519,11 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
        /* Create the network device object. */
         dev = alloc_etherdev(sizeof(*priv));
         if (!dev) {
-               printk(KERN_ERR "atmel:  Couldn't alloc_etherdev\n");
+               printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
                return NULL;
         }
        if (dev_alloc_name(dev, dev->name) < 0) {
-               printk(KERN_ERR "atmel:  Couldn't get name!\n");
+               printk(KERN_ERR "atmel: Couldn't get name!\n");
                goto err_out_free;
        }
 
@@ -1550,7 +1555,7 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
        memset(priv->BSSID, 0, 6);
        priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
        priv->station_was_associated = 0;
-       
+
        priv->last_survey = jiffies;
        priv->preamble = LONG_PREAMBLE;
        priv->operating_mode = IW_MODE_INFRA;
@@ -1586,7 +1591,7 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
        spin_lock_init(&priv->timerlock);
        priv->management_timer.function = atmel_management_timer;
        priv->management_timer.data = (unsigned long) dev;
-       
+
        dev->open = atmel_open;
        dev->stop = atmel_close;
        dev->change_mtu = atmel_change_mtu;
@@ -1597,44 +1602,46 @@ struct net_device *init_atmel_card( unsigned short irq, unsigned long port, cons
        dev->do_ioctl = atmel_ioctl;
        dev->irq = irq;
        dev->base_addr = port;
-       
+
        SET_NETDEV_DEV(dev, sys_dev);
-       
+
        if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) {
-               printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc );
+               printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
                goto err_out_free;
        }
 
-       if (!request_region(dev->base_addr, 32, 
+       if (!request_region(dev->base_addr, 32,
                            priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
                goto err_out_irq;
        }
-       
+
        if (register_netdev(dev))
                goto err_out_res;
-       
+
        if (!probe_atmel_card(dev)){
                unregister_netdev(dev);
                goto err_out_res;
        }
-       
+
        netif_carrier_off(dev);
-       
-       create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);        
-       
+
+       ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
+       if (!ent)
+               printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
+
        printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
               dev->name, DRIVER_MAJOR, DRIVER_MINOR,
               dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
               dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
-       
+
        SET_MODULE_OWNER(dev);
        return dev;
-       
- err_out_res:
+
+err_out_res:
        release_region( dev->base_addr, 32);
- err_out_irq:
+err_out_irq:
        free_irq(dev->irq, dev);
- err_out_free:
+err_out_free:
        free_netdev(dev);
        return NULL;
 }
@@ -1644,12 +1651,12 @@ EXPORT_SYMBOL(init_atmel_card);
 void stop_atmel_card(struct net_device *dev)
 {
        struct atmel_private *priv = netdev_priv(dev);
-               
+
        /* put a brick on it... */
-       if (priv->bus_type == BUS_TYPE_PCCARD) 
+       if (priv->bus_type == BUS_TYPE_PCCARD)
                atmel_write16(dev, GCR, 0x0060);
        atmel_write16(dev, GCR, 0x0040);
-       
+
        del_timer_sync(&priv->management_timer);
        unregister_netdev(dev);
        remove_proc_entry("driver/atmel", NULL);
@@ -1675,13 +1682,13 @@ static int atmel_set_essid(struct net_device *dev,
                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 
                priv->connect_to_any_BSS = 0;
-               
+
                /* Check the size of the string */
                if (dwrq->length > MAX_SSID_LENGTH + 1)
-                        return -E2BIG ;
+                        return -E2BIG;
                if (index != 0)
                        return -EINVAL;
-               
+
                memcpy(priv->new_SSID, extra, dwrq->length - 1);
                priv->new_SSID_size = dwrq->length - 1;
        }
@@ -1706,7 +1713,7 @@ static int atmel_get_essid(struct net_device *dev,
                extra[priv->SSID_size] = '\0';
                dwrq->length = priv->SSID_size + 1;
        }
-       
+
        dwrq->flags = !priv->connect_to_any_BSS; /* active */
 
        return 0;
@@ -1768,7 +1775,7 @@ static int atmel_set_encode(struct net_device *dev,
                /* WE specify that if a valid key is set, encryption
                 * should be enabled (user may turn it off later)
                 * This is also how "iwconfig ethX key on" works */
-               if (index == current_index && 
+               if (index == current_index &&
                    priv->wep_key_len[index] > 0) {
                        priv->wep_is_on = 1;
                        priv->exclude_unencrypted = 1;
@@ -1783,18 +1790,18 @@ static int atmel_set_encode(struct net_device *dev,
        } else {
                /* Do we want to just set the transmit key index ? */
                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-               if ( index>=0 && index < 4 ) {
+               if (index >= 0 && index < 4) {
                        priv->default_key = index;
                } else
                        /* Don't complain if only change the mode */
-                       if(!dwrq->flags & IW_ENCODE_MODE) {
+                       if (!dwrq->flags & IW_ENCODE_MODE) {
                                return -EINVAL;
                        }
        }
        /* Read the flags */
-       if(dwrq->flags & IW_ENCODE_DISABLED) {
+       if (dwrq->flags & IW_ENCODE_DISABLED) {
                priv->wep_is_on = 0;
-               priv->encryption_level = 0;     
+               priv->encryption_level = 0;
                priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
        } else {
                priv->wep_is_on = 1;
@@ -1806,15 +1813,14 @@ static int atmel_set_encode(struct net_device *dev,
                        priv->encryption_level = 1;
                }
        }
-       if(dwrq->flags & IW_ENCODE_RESTRICTED)
+       if (dwrq->flags & IW_ENCODE_RESTRICTED)
                priv->exclude_unencrypted = 1;
-               if(dwrq->flags & IW_ENCODE_OPEN) 
+       if(dwrq->flags & IW_ENCODE_OPEN)
                priv->exclude_unencrypted = 0;
-       
+
        return -EINPROGRESS;            /* Call commit handler */
 }
 
-
 static int atmel_get_encode(struct net_device *dev,
                            struct iw_request_info *info,
                            struct iw_point *dwrq,
@@ -1822,7 +1828,7 @@ static int atmel_get_encode(struct net_device *dev,
 {
        struct atmel_private *priv = netdev_priv(dev);
        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-       
+
        if (!priv->wep_is_on)
                dwrq->flags = IW_ENCODE_DISABLED;
        else {
@@ -1843,7 +1849,7 @@ static int atmel_get_encode(struct net_device *dev,
                memset(extra, 0, 16);
                memcpy(extra, priv->wep_keys[index], dwrq->length);
        }
-       
+
        return 0;
 }
 
@@ -1862,17 +1868,17 @@ static int atmel_set_rate(struct net_device *dev,
                          char *extra)
 {
        struct atmel_private *priv = netdev_priv(dev);
-       
+
        if (vwrq->fixed == 0) {
                priv->tx_rate = 3;
                priv->auto_tx_rate = 1;
        } else {
                priv->auto_tx_rate = 0;
-               
+
                /* Which type of value ? */
-               if((vwrq->value < 4) && (vwrq->value >= 0)) {
+               if ((vwrq->value < 4) && (vwrq->value >= 0)) {
                        /* Setting by rate index */
-               priv->tx_rate = vwrq->value;
+                       priv->tx_rate = vwrq->value;
                } else {
                /* Setting by frequency value */
                        switch (vwrq->value) {
@@ -1899,7 +1905,7 @@ static int atmel_set_mode(struct net_device *dev,
                return -EINVAL;
 
        priv->operating_mode = *uwrq;
-       return -EINPROGRESS;  
+       return -EINPROGRESS;
 }
 
 static int atmel_get_mode(struct net_device *dev,
@@ -1908,7 +1914,7 @@ static int atmel_get_mode(struct net_device *dev,
                          char *extra)
 {
        struct atmel_private *priv = netdev_priv(dev);
-       
+
        *uwrq = priv->operating_mode;
        return 0;
 }
@@ -1962,9 +1968,9 @@ static int atmel_set_retry(struct net_device *dev,
                           char *extra)
 {
        struct atmel_private *priv = netdev_priv(dev);
-       
-       if(!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
-               if(vwrq->flags & IW_RETRY_MAX)
+
+       if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
+               if (vwrq->flags & IW_RETRY_MAX)
                        priv->long_retry = vwrq->value;
                else if (vwrq->flags & IW_RETRY_MIN)
                        priv->short_retry = vwrq->value;
@@ -1973,9 +1979,9 @@ static int atmel_set_retry(struct net_device *dev,
                        priv->long_retry = vwrq->value;
                        priv->short_retry = vwrq->value;
                }
-               return -EINPROGRESS;            
+               return -EINPROGRESS;
        }
-          
+
        return -EINVAL;
 }
 
@@ -1989,13 +1995,13 @@ static int atmel_get_retry(struct net_device *dev,
        vwrq->disabled = 0;      /* Can't be disabled */
 
        /* Note : by default, display the min retry number */
-       if((vwrq->flags & IW_RETRY_MAX)) {
+       if (vwrq->flags & IW_RETRY_MAX) {
                vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
                vwrq->value = priv->long_retry;
        } else {
                vwrq->flags = IW_RETRY_LIMIT;
                vwrq->value = priv->short_retry;
-               if(priv->long_retry != priv->short_retry)
+               if (priv->long_retry != priv->short_retry)
                        vwrq->flags |= IW_RETRY_MIN;
        }
 
@@ -2010,13 +2016,13 @@ static int atmel_set_rts(struct net_device *dev,
        struct atmel_private *priv = netdev_priv(dev);
        int rthr = vwrq->value;
 
-       if(vwrq->disabled)
+       if (vwrq->disabled)
                rthr = 2347;
-       if((rthr < 0) || (rthr > 2347)) {
+       if ((rthr < 0) || (rthr > 2347)) {
                return -EINVAL;
        }
        priv->rts_threshold = rthr;
-       
+
        return -EINPROGRESS;            /* Call commit handler */
 }
 
@@ -2026,7 +2032,7 @@ static int atmel_get_rts(struct net_device *dev,
                         char *extra)
 {
        struct atmel_private *priv = netdev_priv(dev);
-       
+
        vwrq->value = priv->rts_threshold;
        vwrq->disabled = (vwrq->value >= 2347);
        vwrq->fixed = 1;
@@ -2042,14 +2048,14 @@ static int atmel_set_frag(struct net_device *dev,
        struct atmel_private *priv = netdev_priv(dev);
        int fthr = vwrq->value;
 
-       if(vwrq->disabled)
+       if (vwrq->disabled)
                fthr = 2346;
-       if((fthr < 256) || (fthr > 2346)) {
+       if ((fthr < 256) || (fthr > 2346)) {
                return -EINVAL;
        }
        fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
        priv->frag_threshold = fthr;
-       
+
        return -EINPROGRESS;            /* Call commit handler */
 }
 
@@ -2077,21 +2083,21 @@ static int atmel_set_freq(struct net_device *dev,
 {
        struct atmel_private *priv = netdev_priv(dev);
        int rc = -EINPROGRESS;          /* Call commit handler */
-       
+
        /* If setting by frequency, convert to a channel */
-       if((fwrq->e == 1) &&
-          (fwrq->m >= (int) 241200000) &&
-          (fwrq->m <= (int) 248700000)) {
+       if ((fwrq->e == 1) &&
+           (fwrq->m >= (int) 241200000) &&
+           (fwrq->m <= (int) 248700000)) {
                int f = fwrq->m / 100000;
                int c = 0;
-               while((c < 14) && (f != frequency_list[c]))
+               while ((c < 14) && (f != frequency_list[c]))
                        c++;
                /* Hack to fall through... */
                fwrq->e = 0;
                fwrq->m = c + 1;
        }
        /* Setting by channel number */
-       if((fwrq->m > 1000) || (fwrq->e > 0))
+       if ((fwrq->m > 1000) || (fwrq->e > 0))
                rc = -EOPNOTSUPP;
        else {
                int channel = fwrq->m;
@@ -2099,7 +2105,7 @@ static int atmel_set_freq(struct net_device *dev,
                        priv->channel = channel;
                } else {
                        rc = -EINVAL;
-               } 
+               }
        }
        return rc;
 }
@@ -2130,7 +2136,7 @@ static int atmel_set_scan(struct net_device *dev,
         * This is not an error, while the device perform scanning,
         * traffic doesn't flow, so it's a perfect DoS...
         * Jean II */
-       
+
        if (priv->station_state == STATION_STATE_DOWN)
                return -EAGAIN;
 
@@ -2142,15 +2148,15 @@ static int atmel_set_scan(struct net_device *dev,
        /* Initiate a scan command */
        if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
                return -EBUSY;
-               
+
        del_timer_sync(&priv->management_timer);
        spin_lock_irqsave(&priv->irqlock, flags);
-       
+
        priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
        priv->fast_scan = 0;
        atmel_scan(priv, 0);
        spin_unlock_irqrestore(&priv->irqlock, flags);
-       
+
        return 0;
 }
 
@@ -2163,11 +2169,11 @@ static int atmel_get_scan(struct net_device *dev,
        int i;
        char *current_ev = extra;
        struct iw_event iwe;
-       
+
        if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
                return -EAGAIN;
-       
-       for(i=0; i<priv->BSS_list_entries; i++) { 
+
+       for (i = 0; i < priv->BSS_list_entries; i++) {
                iwe.cmd = SIOCGIWAP;
                iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
                memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
@@ -2179,16 +2185,16 @@ static int atmel_get_scan(struct net_device *dev,
                iwe.cmd = SIOCGIWESSID;
                iwe.u.data.flags = 1;
                current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
-               
+
                iwe.cmd = SIOCGIWMODE;
                iwe.u.mode = priv->BSSinfo[i].BSStype;
                current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
-       
+
                iwe.cmd = SIOCGIWFREQ;
                iwe.u.freq.m = priv->BSSinfo[i].channel;
                iwe.u.freq.e = 0;
                current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
-               
+
                iwe.cmd = SIOCGIWENCODE;
                if (priv->BSSinfo[i].UsingWEP)
                        iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
@@ -2196,13 +2202,12 @@ static int atmel_get_scan(struct net_device *dev,
                        iwe.u.data.flags = IW_ENCODE_DISABLED;
                iwe.u.data.length = 0;
                current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
-               
        }
 
        /* Length of data */
        dwrq->length = (current_ev - extra);
-       dwrq->flags = 0;   
-       
+       dwrq->flags = 0;
+
        return 0;
 }
 
@@ -2213,7 +2218,7 @@ static int atmel_get_range(struct net_device *dev,
 {
        struct atmel_private *priv = netdev_priv(dev);
        struct iw_range *range = (struct iw_range *) extra;
-       int k,i,j;
+       int k, i, j;
 
        dwrq->length = sizeof(struct iw_range);
        memset(range, 0, sizeof(struct iw_range));
@@ -2226,14 +2231,14 @@ static int atmel_get_range(struct net_device *dev,
                        break;
                }
        if (range->num_channels != 0) {
-               for(k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
+               for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
                        range->freq[k].i = i; /* List index */
-                       range->freq[k].m = frequency_list[i-1] * 100000;
+                       range->freq[k].m = frequency_list[i - 1] * 100000;
                        range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
                }
                range->num_frequency = k;
        }
-       
+
        range->max_qual.qual = 100;
        range->max_qual.level = 100;
        range->max_qual.noise = 0;
@@ -2261,11 +2266,11 @@ static int atmel_get_range(struct net_device *dev,
        range->encoding_size[1] = 13;
        range->num_encoding_sizes = 2;
        range->max_encoding_tokens = 4;
-       
+
        range->pmp_flags = IW_POWER_ON;
        range->pmt_flags = IW_POWER_ON;
        range->pm_capa = 0;
-       
+
        range->we_version_source = WIRELESS_EXT;
        range->we_version_compiled = WIRELESS_EXT;
        range->retry_capa = IW_RETRY_LIMIT ;
@@ -2289,7 +2294,7 @@ static int atmel_set_wap(struct net_device *dev,
 
        if (awrq->sa_family != ARPHRD_ETHER)
                return -EINVAL;
-       
+
        if (memcmp(bcast, awrq->sa_data, 6) == 0) {
                del_timer_sync(&priv->management_timer);
                spin_lock_irqsave(&priv->irqlock, flags);
@@ -2297,8 +2302,8 @@ static int atmel_set_wap(struct net_device *dev,
                spin_unlock_irqrestore(&priv->irqlock, flags);
                return 0;
        }
-       
-       for(i=0; i<priv->BSS_list_entries; i++) {
+
+       for (i = 0; i < priv->BSS_list_entries; i++) {
                if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
                        if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
                                return -EINVAL;
@@ -2313,10 +2318,10 @@ static int atmel_set_wap(struct net_device *dev,
                        }
                }
        }
-               
+
        return -EINVAL;
 }
-       
+
 static int atmel_config_commit(struct net_device *dev,
                               struct iw_request_info *info,    /* NULL */
                               void *zwrq,                      /* NULL */
@@ -2325,18 +2330,18 @@ static int atmel_config_commit(struct net_device *dev,
        return atmel_open(dev);
 }
 
-static const iw_handler                atmel_handler[] =
+static const iw_handler atmel_handler[] =
 {
        (iw_handler) atmel_config_commit,       /* SIOCSIWCOMMIT */
-       (iw_handler) atmel_get_name,            /* SIOCGIWNAME */
+       (iw_handler) atmel_get_name,            /* SIOCGIWNAME */
        (iw_handler) NULL,                      /* SIOCSIWNWID */
        (iw_handler) NULL,                      /* SIOCGIWNWID */
        (iw_handler) atmel_set_freq,            /* SIOCSIWFREQ */
        (iw_handler) atmel_get_freq,            /* SIOCGIWFREQ */
        (iw_handler) atmel_set_mode,            /* SIOCSIWMODE */
        (iw_handler) atmel_get_mode,            /* SIOCGIWMODE */
-       (iw_handler) NULL,                      /* SIOCSIWSENS */
-       (iw_handler) NULL,                      /* SIOCGIWSENS */
+       (iw_handler) NULL,                      /* SIOCSIWSENS */
+       (iw_handler) NULL,                      /* SIOCGIWSENS */
        (iw_handler) NULL,                      /* SIOCSIWRANGE */
        (iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
        (iw_handler) NULL,                      /* SIOCSIWPRIV */
@@ -2350,13 +2355,13 @@ static const iw_handler         atmel_handler[] =
        (iw_handler) atmel_set_wap,             /* SIOCSIWAP */
        (iw_handler) atmel_get_wap,             /* SIOCGIWAP */
        (iw_handler) NULL,                      /* -- hole -- */
-       (iw_handler) NULL,                      /* SIOCGIWAPLIST */
+       (iw_handler) NULL,                      /* SIOCGIWAPLIST */
        (iw_handler) atmel_set_scan,            /* SIOCSIWSCAN */
        (iw_handler) atmel_get_scan,            /* SIOCGIWSCAN */
        (iw_handler) atmel_set_essid,           /* SIOCSIWESSID */
        (iw_handler) atmel_get_essid,           /* SIOCGIWESSID */
-       (iw_handler) NULL,                      /* SIOCSIWNICKN */
-       (iw_handler) NULL,                      /* SIOCGIWNICKN */
+       (iw_handler) NULL,                      /* SIOCSIWNICKN */
+       (iw_handler) NULL,                      /* SIOCGIWNICKN */
        (iw_handler) NULL,                      /* -- hole -- */
        (iw_handler) NULL,                      /* -- hole -- */
        (iw_handler) atmel_set_rate,            /* SIOCSIWRATE */
@@ -2365,8 +2370,8 @@ static const iw_handler           atmel_handler[] =
        (iw_handler) atmel_get_rts,             /* SIOCGIWRTS */
        (iw_handler) atmel_set_frag,            /* SIOCSIWFRAG */
        (iw_handler) atmel_get_frag,            /* SIOCGIWFRAG */
-       (iw_handler) NULL,                      /* SIOCSIWTXPOW */
-       (iw_handler) NULL,                      /* SIOCGIWTXPOW */
+       (iw_handler) NULL,                      /* SIOCSIWTXPOW */
+       (iw_handler) NULL,                      /* SIOCGIWTXPOW */
        (iw_handler) atmel_set_retry,           /* SIOCSIWRETRY */
        (iw_handler) atmel_get_retry,           /* SIOCGIWRETRY */
        (iw_handler) atmel_set_encode,          /* SIOCSIWENCODE */
@@ -2375,39 +2380,51 @@ static const iw_handler         atmel_handler[] =
        (iw_handler) atmel_get_power,           /* SIOCGIWPOWER */
 };
 
-
-static const iw_handler                atmel_private_handler[] =
+static const iw_handler atmel_private_handler[] =
 {
        NULL,                           /* SIOCIWFIRSTPRIV */
 };
 
 typedef struct atmel_priv_ioctl {
        char id[32];
-       unsigned char __user *data;             
-       unsigned short len;             
+       unsigned char __user *data;
+       unsigned short len;
 } atmel_priv_ioctl;
 
-       
-#define ATMELFWL SIOCIWFIRSTPRIV
-#define ATMELIDIFC ATMELFWL + 1
-#define ATMELRD ATMELFWL + 2
-#define ATMELMAGIC 0x51807 
+#define ATMELFWL       SIOCIWFIRSTPRIV
+#define ATMELIDIFC     ATMELFWL + 1
+#define ATMELRD                ATMELFWL + 2
+#define ATMELMAGIC 0x51807
 #define REGDOMAINSZ 20
 
 static const struct iw_priv_args atmel_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { ATMELFWL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (atmel_priv_ioctl), IW_PRIV_TYPE_NONE, "atmelfwl" },
-  { ATMELIDIFC, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "atmelidifc" },
-  { ATMELRD, IW_PRIV_TYPE_CHAR | REGDOMAINSZ, IW_PRIV_TYPE_NONE, "regdomain" },
+       {
+               .cmd = ATMELFWL,
+               .set_args = IW_PRIV_TYPE_BYTE
+                               | IW_PRIV_SIZE_FIXED
+                               | sizeof (atmel_priv_ioctl),
+               .get_args = IW_PRIV_TYPE_NONE,
+               .name = "atmelfwl"
+       }, {
+               .cmd = ATMELIDIFC,
+               .set_args = IW_PRIV_TYPE_NONE,
+               .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+               .name = "atmelidifc"
+       }, {
+               .cmd = ATMELRD,
+               .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
+               .get_args = IW_PRIV_TYPE_NONE,
+               .name = "regdomain"
+       },
 };
 
-static const struct iw_handler_def     atmel_handler_def =
+static const struct iw_handler_def atmel_handler_def =
 {
        .num_standard   = sizeof(atmel_handler)/sizeof(iw_handler),
-       .num_private    = sizeof(atmel_private_handler)/sizeof(iw_handler), 
-       .num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args), 
+       .num_private    = sizeof(atmel_private_handler)/sizeof(iw_handler),
+       .num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args),
        .standard       = (iw_handler *) atmel_handler,
-       .private        = (iw_handler *) atmel_private_handler, 
+       .private        = (iw_handler *) atmel_private_handler,
        .private_args   = (struct iw_priv_args *) atmel_private_args,
        .get_wireless_stats = atmel_get_wireless_stats
 };
@@ -2419,13 +2436,13 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        atmel_priv_ioctl com;
        struct iwreq *wrq = (struct iwreq *) rq;
        unsigned char *new_firmware;
-       char domain[REGDOMAINSZ+1];
+       char domain[REGDOMAINSZ + 1];
 
        switch (cmd) {
        case ATMELIDIFC:
-               wrq->u.param.value = ATMELMAGIC;                
+               wrq->u.param.value = ATMELMAGIC;
                break;
-       
+
        case ATMELFWL:
                if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
                        rc = -EFAULT;
@@ -2449,7 +2466,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                }
 
                kfree(priv->firmware);
-               
+
                priv->firmware = new_firmware;
                priv->firmware_length = com.len;
                strncpy(priv->firmware_id, com.id, 31);
@@ -2461,7 +2478,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                        rc = -EFAULT;
                        break;
                }
-               
+
                if (!capable(CAP_NET_ADMIN)) {
                        rc = -EPERM;
                        break;
@@ -2484,15 +2501,15 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                                rc = 0;
                        }
                }
-               
+
                if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
                        rc = atmel_open(dev);
                break;
-               
+
        default:
                rc = -EOPNOTSUPP;
        }
-       
+
        return rc;
 }
 
@@ -2503,17 +2520,17 @@ struct auth_body {
        u8 el_id;
        u8 chall_text_len;
        u8 chall_text[253];
-}; 
+};
 
 static void atmel_enter_state(struct atmel_private *priv, int new_state)
 {
        int old_state = priv->station_state;
-               
+
        if (new_state == old_state)
                return;
-       
+
        priv->station_state = new_state;
-               
+
        if (new_state == STATION_STATE_READY) {
                netif_start_queue(priv->dev);
                netif_carrier_on(priv->dev);
@@ -2540,7 +2557,7 @@ static void atmel_scan(struct atmel_private *priv, int specific_ssid)
                u8 options;
                u8 SSID_size;
        } cmd;
-       
+
        memset(cmd.BSSID, 0xff, 6);
 
        if (priv->fast_scan) {
@@ -2554,17 +2571,17 @@ static void atmel_scan(struct atmel_private *priv, int specific_ssid)
                cmd.min_channel_time = cpu_to_le16(10);
                cmd.max_channel_time = cpu_to_le16(120);
        }
-       
+
        cmd.options = 0;
-       
+
        if (!specific_ssid)
                cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
-       
-       cmd.channel = (priv->channel & 0x7f); 
+
+       cmd.channel = (priv->channel & 0x7f);
        cmd.scan_type = SCAN_TYPE_ACTIVE;
-       cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ? 
+       cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
                BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
-       
+
        atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
 
        /* This must come after all hardware access to avoid being messed up
@@ -2591,16 +2608,15 @@ static void join(struct atmel_private *priv, int type)
        cmd.BSS_type = type;
        cmd.timeout = cpu_to_le16(2000);
 
-       atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
+       atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
 }
 
-
 static void start(struct atmel_private *priv, int type)
 {
        struct {
                u8 BSSID[6];
                u8 SSID[MAX_SSID_LENGTH];
-               u8 BSS_type;                                
+               u8 BSS_type;
                u8 channel;
                u8 SSID_size;
                u8 reserved[3];
@@ -2612,13 +2628,14 @@ static void start(struct atmel_private *priv, int type)
        cmd.BSS_type = type;
        cmd.channel = (priv->channel & 0x7f);
 
-       atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd)); 
+       atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
 }
 
-static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 channel)
+static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
+                               u8 channel)
 {
        int rejoin = 0;
-       int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+       int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ?
                SHORT_PREAMBLE : LONG_PREAMBLE;
 
        if (priv->preamble != new) {
@@ -2626,48 +2643,48 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
                rejoin = 1;
                atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
        }
-               
+
        if (priv->channel != channel) {
                priv->channel = channel;
                rejoin = 1;
                atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
        }
-       
+
        if (rejoin) {
                priv->station_is_associated = 0;
                atmel_enter_state(priv, STATION_STATE_JOINNING);
-               
+
                if (priv->operating_mode == IW_MODE_INFRA)
                        join(priv, BSS_TYPE_INFRASTRUCTURE);
-               else 
+               else
                        join(priv, BSS_TYPE_AD_HOC);
-       } 
+       }
 }
 
-
-static void send_authentication_request(struct atmel_private *priv, u16 system, u8 *challenge, int challenge_len)
+static void send_authentication_request(struct atmel_private *priv, u16 system,
+                                       u8 *challenge, int challenge_len)
 {
        struct ieee80211_hdr_4addr header;
        struct auth_body auth;
-       
-       header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); 
-       header.duration_id      = cpu_to_le16(0x8000);  
+
+       header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+       header.duration_id = cpu_to_le16(0x8000);
        header.seq_ctl = 0;
        memcpy(header.addr1, priv->CurrentBSSID, 6);
        memcpy(header.addr2, priv->dev->dev_addr, 6);
        memcpy(header.addr3, priv->CurrentBSSID, 6);
-       
-       if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1) 
+
+       if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
                /* no WEP for authentication frames with TrSeqNo 1 */
                 header.frame_ctl |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-       
-       auth.alg = cpu_to_le16(system); 
+
+       auth.alg = cpu_to_le16(system);
 
        auth.status = 0;
        auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
-       priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1; 
+       priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
        priv->CurrentAuthentTransactionSeqNum += 2;
-       
+
        if (challenge_len != 0) {
                auth.el_id = 16; /* challenge_text */
                auth.chall_text_len = challenge_len;
@@ -2685,7 +2702,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
        struct ieee80211_hdr_4addr header;
        struct ass_req_format {
                u16 capability;
-               u16 listen_interval; 
+               u16 listen_interval;
                u8 ap[6]; /* nothing after here directly accessible */
                u8 ssid_el_id;
                u8 ssid_len;
@@ -2694,15 +2711,15 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
                u8 sup_rates_len;
                u8 rates[4];
        } body;
-               
-       header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | 
+
+       header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
        header.duration_id = cpu_to_le16(0x8000);
        header.seq_ctl = 0;
 
-       memcpy(header.addr1, priv->CurrentBSSID, 6); 
+       memcpy(header.addr1, priv->CurrentBSSID, 6);
        memcpy(header.addr2, priv->dev->dev_addr, 6);
-       memcpy(header.addr3, priv->CurrentBSSID, 6); 
+       memcpy(header.addr3, priv->CurrentBSSID, 6);
 
        body.capability = cpu_to_le16(C80211_MGMT_CAPABILITY_ESS);
        if (priv->wep_is_on)
@@ -2711,18 +2728,18 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
                body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_ShortPreamble);
 
        body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
-       
+
        /* current AP address - only in reassoc frame */
        if (is_reassoc) {
-               memcpy(body.ap,  priv->CurrentBSSID, 6);
+               memcpy(body.ap, priv->CurrentBSSID, 6);
                ssid_el_p = (u8 *)&body.ssid_el_id;
                bodysize = 18 + priv->SSID_size;
        } else {
                ssid_el_p = (u8 *)&body.ap[0];
                bodysize = 12 + priv->SSID_size;
        }
-               
-       ssid_el_p[0]= C80211_MGMT_ElementID_SSID;
+
+       ssid_el_p[0] = C80211_MGMT_ElementID_SSID;
        ssid_el_p[1] = priv->SSID_size;
        memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
        ssid_el_p[2 + priv->SSID_size] = C80211_MGMT_ElementID_SupportedRates;
@@ -2732,7 +2749,8 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
        atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
 }
 
-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
+static int is_frame_from_current_bss(struct atmel_private *priv,
+                                    struct ieee80211_hdr_4addr *header)
 {
        if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
                return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@@ -2745,29 +2763,29 @@ static int retrieve_bss(struct atmel_private *priv)
        int i;
        int max_rssi = -128;
        int max_index = -1;
-       
+
        if (priv->BSS_list_entries == 0)
                return -1;
-                       
+
        if (priv->connect_to_any_BSS) {
-               /* Select a BSS with the max-RSSI but of the same type and of the same WEP mode
-                  and that it is not marked as 'bad' (i.e. we had previously failed to connect to
-                  this BSS with the settings that we currently use) */
+               /* Select a BSS with the max-RSSI but of the same type and of
+                  the same WEP mode and that it is not marked as 'bad' (i.e.
+                  we had previously failed to connect to this BSS with the
+                  settings that we currently use) */
                priv->current_BSS = 0;
-               for(i=0; i<priv->BSS_list_entries; i++) { 
+               for (i = 0; i < priv->BSS_list_entries; i++) {
                        if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
-                           ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) || 
+                           ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
                             (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
                            !(priv->BSSinfo[i].channel & 0x80)) {
                                max_rssi = priv->BSSinfo[i].RSSI;
                                priv->current_BSS = max_index = i;
                        }
-                       
                }
                return max_index;
        }
-               
-       for(i=0; i<priv->BSS_list_entries; i++) {
+
+       for (i = 0; i < priv->BSS_list_entries; i++) {
                if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
                    memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
                    priv->operating_mode == priv->BSSinfo[i].BSStype &&
@@ -2781,19 +2799,19 @@ static int retrieve_bss(struct atmel_private *priv)
        return max_index;
 }
 
-
-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
-                          u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
-                          u8 ssid_len, u8 *ssid, int is_beacon)
+static void store_bss_info(struct atmel_private *priv,
+                          struct ieee80211_hdr_4addr *header, u16 capability,
+                          u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
+                          u8 *ssid, int is_beacon)
 {
        u8 *bss = capability & C80211_MGMT_CAPABILITY_ESS ? header->addr2 : header->addr3;
        int i, index;
-               
-       for (index = -1, i = 0; i < priv->BSS_list_entries; i++) 
-               if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) 
+
+       for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
+               if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
                        index = i;
 
-        /* If we process a probe and an entry from this BSS exists 
+        /* If we process a probe and an entry from this BSS exists
           we will update the BSS entry with the info from this BSS.
           If we process a beacon we will only update RSSI */
 
@@ -2820,8 +2838,8 @@ static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4add
                priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
        else if (capability & C80211_MGMT_CAPABILITY_ESS)
                priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
-       
-       priv->BSSinfo[index].preamble = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+
+       priv->BSSinfo[index].preamble = capability & C80211_MGMT_CAPABILITY_ShortPreamble ?
                SHORT_PREAMBLE : LONG_PREAMBLE;
 }
 
@@ -2831,8 +2849,8 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
        u16 status = le16_to_cpu(auth->status);
        u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
        u16 system = le16_to_cpu(auth->alg);
-       
-       if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) { 
+
+       if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) {
                /* no WEP */
                if (priv->station_was_associated) {
                        atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
@@ -2842,20 +2860,20 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
                        atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
                        send_association_request(priv, 0);
                        return;
-               } 
+               }
        }
-               
-       if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { 
+
+       if (status == C80211_MGMT_SC_Success && priv->wep_is_on) {
                /* WEP */
                if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
                        return;
-                               
+
                if (trans_seq_no == 0x0002 &&
                    auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
                        send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
                        return;
                }
-               
+
                if (trans_seq_no == 0x0004) {
                        if(priv->station_was_associated) {
                                atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
@@ -2865,10 +2883,10 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
                                atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
                                send_association_request(priv, 0);
                                return;
-                       } 
+                       }
                }
-       }                       
-       
+       }
+
        if (status == C80211_MGMT_SC_AuthAlgNotSupported) {
                /* Do opensystem first, then try sharedkey */
                if (system ==  C80211_MGMT_AAN_OPENSYSTEM) {
@@ -2876,17 +2894,16 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
                        send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
                } else if (priv->connect_to_any_BSS) {
                        int bss_index;
-                       
+
                        priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-                       
+
                        if ((bss_index  = retrieve_bss(priv)) != -1) {
                                atmel_join_bss(priv, bss_index);
                                return;
                        }
                }
        }
-       
-       
+
        priv->AuthenticationRequestRetryCnt = 0;
        atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
        priv->station_is_associated = 0;
@@ -2902,38 +2919,44 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
                u8 length;
                u8 rates[4];
        } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
-       
-               u16 status = le16_to_cpu(ass_resp->status);
+
+       u16 status = le16_to_cpu(ass_resp->status);
        u16 ass_id = le16_to_cpu(ass_resp->ass_id);
-       u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
-       
+       u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
+
        if (frame_len < 8 + rates_len)
                return;
-       
+
        if (status == C80211_MGMT_SC_Success) {
                if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE)
                        priv->AssociationRequestRetryCnt = 0;
                else
                        priv->ReAssociationRequestRetryCnt = 0;
-               
-               atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
-               atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
+
+               atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+                               MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
+               atmel_set_mib(priv, Phy_Mib_Type,
+                             PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
                if (priv->power_mode == 0) {
                        priv->listen_interval = 1;
-                       atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
-                       atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+                       atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+                                      MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
+                       atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+                                       MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
                } else {
                        priv->listen_interval = 2;
-                       atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
-                       atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
+                       atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+                                      MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
+                       atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+                                       MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
                }
-               
+
                priv->station_is_associated = 1;
                priv->station_was_associated = 1;
                atmel_enter_state(priv, STATION_STATE_READY);
                return;
        }
-       
+
        if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE &&
            status != C80211_MGMT_SC_AssDeniedBSSRate &&
            status != C80211_MGMT_SC_SupportCapabilities &&
@@ -2943,7 +2966,7 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
                send_association_request(priv, 0);
                return;
        }
-               
+
        if (subtype == C80211_SUBTYPE_MGMT_REASS_RESPONSE &&
            status != C80211_MGMT_SC_AssDeniedBSSRate &&
            status != C80211_MGMT_SC_SupportCapabilities &&
@@ -2953,17 +2976,16 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
                send_association_request(priv, 1);
                return;
        }
-       
+
        atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
        priv->station_is_associated = 0;
-       
-       if(priv->connect_to_any_BSS) {
+
+       if (priv->connect_to_any_BSS) {
                int bss_index;
                priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-               
-               if ((bss_index = retrieve_bss(priv)) != -1) 
+
+               if ((bss_index = retrieve_bss(priv)) != -1)
                        atmel_join_bss(priv, bss_index);
-               
        }
 }
 
@@ -2977,7 +2999,7 @@ void atmel_join_bss(struct atmel_private *priv, int bss_index)
        /* The WPA stuff cares about the current AP address */
        if (priv->use_wpa)
                build_wpa_mib(priv);
-       
+
        /* When switching to AdHoc turn OFF Power Save if needed */
 
        if (bss->BSStype == IW_MODE_ADHOC &&
@@ -2985,25 +3007,28 @@ void atmel_join_bss(struct atmel_private *priv, int bss_index)
            priv->power_mode) {
                priv->power_mode = 0;
                priv->listen_interval = 1;
-               atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
-               atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+               atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+                              MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
+               atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+                               MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
        }
-               
+
        priv->operating_mode = bss->BSStype;
-       priv->channel = bss->channel & 0x7f;    
+       priv->channel = bss->channel & 0x7f;
        priv->beacon_period = bss->beacon_period;
-       
+
        if (priv->preamble != bss->preamble) {
                priv->preamble = bss->preamble;
-               atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
+               atmel_set_mib8(priv, Local_Mib_Type,
+                              LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
        }
-       
+
        if (!priv->wep_is_on && bss->UsingWEP) {
                atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
                priv->station_is_associated = 0;
                return;
        }
-               
+
        if (priv->wep_is_on && !bss->UsingWEP) {
                atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
                priv->station_is_associated = 0;
@@ -3011,30 +3036,28 @@ void atmel_join_bss(struct atmel_private *priv, int bss_index)
        }
 
        atmel_enter_state(priv, STATION_STATE_JOINNING);
-       
+
        if (priv->operating_mode == IW_MODE_INFRA)
                join(priv, BSS_TYPE_INFRASTRUCTURE);
-       else 
+       else
                join(priv, BSS_TYPE_AD_HOC);
 }
 
-
 static void restart_search(struct atmel_private *priv)
 {
        int bss_index;
-       
+
        if (!priv->connect_to_any_BSS) {
                atmel_scan(priv, 1);
        } else {
                priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-               
-               if ((bss_index = retrieve_bss(priv)) != -1) 
+
+               if ((bss_index = retrieve_bss(priv)) != -1)
                        atmel_join_bss(priv, bss_index);
                else
                        atmel_scan(priv, 0);
-               
-       } 
-}      
+       }
+}
 
 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
 {
@@ -3050,21 +3073,21 @@ static void smooth_rssi(struct atmel_private *priv, u8 rssi)
        }
 
        rssi = rssi * 100 / max_rssi;
-       if((rssi + old) % 2)
-               priv->wstats.qual.level =  ((rssi + old)/2) + 1;
+       if ((rssi + old) % 2)
+               priv->wstats.qual.level = (rssi + old) / 2 + 1;
        else
-               priv->wstats.qual.level =  ((rssi + old)/2);            
+               priv->wstats.qual.level = (rssi + old) / 2;
        priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
        priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
 }
 
 static void atmel_smooth_qual(struct atmel_private *priv)
 {
-       unsigned long time_diff = (jiffies - priv->last_qual)/HZ;
+       unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
        while (time_diff--) {
                priv->last_qual += HZ;
-               priv->wstats.qual.qual = priv->wstats.qual.qual/2;
-               priv->wstats.qual.qual += 
+               priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
+               priv->wstats.qual.qual +=
                        priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
                priv->beacons_this_sec = 0;
        }
@@ -3073,15 +3096,17 @@ static void atmel_smooth_qual(struct atmel_private *priv)
 }
 
 /* deals with incoming managment frames. */
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
-                     u16 frame_len, u8 rssi)
+static void atmel_management_frame(struct atmel_private *priv,
+                                  struct ieee80211_hdr_4addr *header,
+                                  u16 frame_len, u8 rssi)
 {
        u16 subtype;
-       
-       switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE) {
-       case C80211_SUBTYPE_MGMT_BEACON :
+
+       subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE;
+       switch (subtype) {
+       case C80211_SUBTYPE_MGMT_BEACON:
        case C80211_SUBTYPE_MGMT_ProbeResponse:
-               
+
                /* beacon frame has multiple variable-length fields -
                   never let an engineer loose with a data structure design. */
                {
@@ -3099,7 +3124,7 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
                                u8 ds_length;
                                /* ds here */
                        } *beacon = (struct beacon_format *)priv->rx_buf;
-                       
+
                        u8 channel, rates_length, ssid_length;
                        u64 timestamp = le64_to_cpu(beacon->timestamp);
                        u16 beacon_interval = le16_to_cpu(beacon->interval);
@@ -3107,7 +3132,7 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
                        u8 *beaconp = priv->rx_buf;
                        ssid_length = beacon->ssid_length;
                        /* this blows chunks. */
-                       if (frame_len < 14 || frame_len < ssid_length + 15) 
+                       if (frame_len < 14 || frame_len < ssid_length + 15)
                                return;
                        rates_length = beaconp[beacon->ssid_length + 15];
                        if (frame_len < ssid_length + rates_length + 18)
@@ -3115,10 +3140,10 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
                        if (ssid_length >  MAX_SSID_LENGTH)
                                return;
                        channel = beaconp[ssid_length + rates_length + 18];
-                      
+
                        if (priv->station_state == STATION_STATE_READY) {
                                smooth_rssi(priv, rssi);
-                               if (is_frame_from_current_bss(priv, header)) { 
+                               if (is_frame_from_current_bss(priv, header)) {
                                        priv->beacons_this_sec++;
                                        atmel_smooth_qual(priv);
                                        if (priv->last_beacon_timestamp) {
@@ -3132,41 +3157,43 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
                                        handle_beacon_probe(priv, capability, channel);
                                }
                        }
-                       
-                       if (priv->station_state == STATION_STATE_SCANNING ) 
-                               store_bss_info(priv, header, capability, beacon_interval, channel,
-                                              rssi, ssid_length, &beacon->rates_el_id,
-                                              subtype == C80211_SUBTYPE_MGMT_BEACON) ;
+
+                       if (priv->station_state == STATION_STATE_SCANNING)
+                               store_bss_info(priv, header, capability,
+                                              beacon_interval, channel, rssi,
+                                              ssid_length,
+                                              &beacon->rates_el_id,
+                                              subtype == C80211_SUBTYPE_MGMT_BEACON);
                }
                break;
-               
+
        case C80211_SUBTYPE_MGMT_Authentication:
 
                if (priv->station_state == STATION_STATE_AUTHENTICATING)
                        authenticate(priv, frame_len);
-       
+
                break;
-               
+
        case C80211_SUBTYPE_MGMT_ASS_RESPONSE:
        case C80211_SUBTYPE_MGMT_REASS_RESPONSE:
-               
-               if (priv->station_state == STATION_STATE_ASSOCIATING || 
+
+               if (priv->station_state == STATION_STATE_ASSOCIATING ||
                    priv->station_state == STATION_STATE_REASSOCIATING)
                        associate(priv, frame_len, subtype);
-               
+
                break;
 
        case C80211_SUBTYPE_MGMT_DISASSOSIATION:
-               if (priv->station_is_associated && 
-                   priv->operating_mode == IW_MODE_INFRA && 
+               if (priv->station_is_associated &&
+                   priv->operating_mode == IW_MODE_INFRA &&
                    is_frame_from_current_bss(priv, header)) {
                        priv->station_was_associated = 0;
                        priv->station_is_associated = 0;
-                       
+
                        atmel_enter_state(priv, STATION_STATE_JOINNING);
                        join(priv, BSS_TYPE_INFRASTRUCTURE);
                }
-               
+
                break;
 
        case C80211_SUBTYPE_MGMT_Deauthentication:
@@ -3177,7 +3204,7 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
                        atmel_enter_state(priv, STATION_STATE_JOINNING);
                        join(priv, BSS_TYPE_INFRASTRUCTURE);
                }
-               
+
                break;
        }
 }
@@ -3185,76 +3212,73 @@ static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_
 /* run when timer expires */
 static void atmel_management_timer(u_long a)
 {
-  struct net_device *dev = (struct net_device *) a;
-  struct atmel_private *priv = netdev_priv(dev);
-  unsigned long flags;
-  
-  /* Check if the card has been yanked. */
-  if (priv->card && priv->present_callback && 
-      !(*priv->present_callback)(priv->card))
-         return;
-  
-  spin_lock_irqsave(&priv->irqlock, flags);
-
-  switch (priv->station_state) {
-         
-  case STATION_STATE_AUTHENTICATING:
-         if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
-                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-                 priv->station_is_associated = 0;
-                 priv->AuthenticationRequestRetryCnt = 0;
-                 restart_search(priv);
-         } else {
-                 priv->AuthenticationRequestRetryCnt++;
-                 priv->CurrentAuthentTransactionSeqNum = 0x0001;
-                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-                 send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
-         }
-         
-         break;
+       struct net_device *dev = (struct net_device *) a;
+       struct atmel_private *priv = netdev_priv(dev);
+       unsigned long flags;
 
-  case STATION_STATE_ASSOCIATING:
-         if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
-                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-                 priv->station_is_associated = 0;
-                 priv->AssociationRequestRetryCnt = 0;
-                 restart_search(priv);
-         } else {
-                 priv->AssociationRequestRetryCnt++;
-                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-                 send_association_request(priv, 0);
-         }
+       /* Check if the card has been yanked. */
+       if (priv->card && priv->present_callback &&
+               !(*priv->present_callback)(priv->card))
+               return;
 
-         break;
-                 
-  case STATION_STATE_REASSOCIATING:    
-         if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
-                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-                 priv->station_is_associated = 0;
-                 priv->ReAssociationRequestRetryCnt = 0;
-                 restart_search(priv);
-         } else {
-                 priv->ReAssociationRequestRetryCnt++;
-                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-                 send_association_request(priv, 1);
-         }
+       spin_lock_irqsave(&priv->irqlock, flags);
+
+       switch (priv->station_state) {
 
+       case STATION_STATE_AUTHENTICATING:
+               if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
+                       atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+                       priv->station_is_associated = 0;
+                       priv->AuthenticationRequestRetryCnt = 0;
+                       restart_search(priv);
+               } else {
+                       priv->AuthenticationRequestRetryCnt++;
+                       priv->CurrentAuthentTransactionSeqNum = 0x0001;
+                       mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+                       send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
+         }
          break;
-  
-  default:
+
+       case STATION_STATE_ASSOCIATING:
+               if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+                       atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+                       priv->station_is_associated = 0;
+                       priv->AssociationRequestRetryCnt = 0;
+                       restart_search(priv);
+               } else {
+                       priv->AssociationRequestRetryCnt++;
+                       mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+                       send_association_request(priv, 0);
+               }
          break;
-  }
-  
-  spin_unlock_irqrestore(&priv->irqlock, flags);
+
+       case STATION_STATE_REASSOCIATING:
+               if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+                       atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+                       priv->station_is_associated = 0;
+                       priv->ReAssociationRequestRetryCnt = 0;
+                       restart_search(priv);
+               } else {
+                       priv->ReAssociationRequestRetryCnt++;
+                       mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+                       send_association_request(priv, 1);
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       spin_unlock_irqrestore(&priv->irqlock, flags);
 }
-  
+
 static void atmel_command_irq(struct atmel_private *priv)
 {
        u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
        u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
        int fast_scan;
-       
-       if (status == CMD_STATUS_IDLE || 
+
+       if (status == CMD_STATUS_IDLE ||
            status == CMD_STATUS_IN_PROGRESS)
                return;
 
@@ -3266,20 +3290,20 @@ static void atmel_command_irq(struct atmel_private *priv)
                        atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
                                      (u8 *)priv->CurrentBSSID, 6);
                        atmel_enter_state(priv, STATION_STATE_READY);
-               }                       
+               }
                break;
-               
+
        case CMD_Scan:
                fast_scan = priv->fast_scan;
                priv->fast_scan = 0;
-               
+
                if (status != CMD_STATUS_COMPLETE) {
                        atmel_scan(priv, 1);
                } else {
                        int bss_index = retrieve_bss(priv);
                        if (bss_index != -1) {
                                atmel_join_bss(priv, bss_index);
-                       } else if (priv->operating_mode == IW_MODE_ADHOC && 
+                       } else if (priv->operating_mode == IW_MODE_ADHOC &&
                                   priv->SSID_size != 0) {
                                start(priv, BSS_TYPE_AD_HOC);
                        } else {
@@ -3289,16 +3313,16 @@ static void atmel_command_irq(struct atmel_private *priv)
                        priv->site_survey_state = SITE_SURVEY_COMPLETED;
                }
                break;
-               
+
        case CMD_SiteSurvey:
                priv->fast_scan = 0;
-               
+
                if (status != CMD_STATUS_COMPLETE)
                        return;
-               
+
                priv->site_survey_state = SITE_SURVEY_COMPLETED;
                if (priv->station_is_associated) {
-                       atmel_enter_state(priv, STATION_STATE_READY);                           
+                       atmel_enter_state(priv, STATION_STATE_READY);
                } else {
                        atmel_scan(priv, 1);
                }
@@ -3312,16 +3336,15 @@ static void atmel_command_irq(struct atmel_private *priv)
                        } else {
                                priv->AuthenticationRequestRetryCnt = 0;
                                atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
-                               
+
                                mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
                                priv->CurrentAuthentTransactionSeqNum = 0x0001;
                                send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
                        }
                        return;
                }
-               
+
                atmel_scan(priv, 1);
-               
        }
 }
 
@@ -3333,20 +3356,20 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
 
        if (priv->card_type == CARD_TYPE_SPI_FLASH)
                atmel_set_gcr(priv->dev, GCR_REMAP);
-       
+
        /* wake up on-board processor */
        atmel_clear_gcr(priv->dev, 0x0040);
        atmel_write16(priv->dev, BSR, BSS_SRAM);
-       
+
        if (priv->card_type == CARD_TYPE_SPI_FLASH)
                mdelay(100);
 
        /* and wait for it */
-       for (i =  LOOP_RETRY_LIMIT; i; i--) {
+       for (i = LOOP_RETRY_LIMIT; i; i--) {
                mr1 = atmel_read16(priv->dev, MR1);
                mr3 = atmel_read16(priv->dev, MR3);
-               
-               if (mr3 & MAC_BOOT_COMPLETE) 
+
+               if (mr3 & MAC_BOOT_COMPLETE)
                        break;
                if (mr1 & MAC_BOOT_COMPLETE &&
                    priv->bus_type == BUS_TYPE_PCCARD)
@@ -3357,35 +3380,36 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
                printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
                return 0;
        }
-               
+
        if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
                printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
                return 0;
        }
-       
-       /* now check for completion of MAC initialization through  
-          the FunCtrl field of the IFACE, poll MR1 to detect completion of       
-          MAC initialization, check completion status, set interrupt mask,  
-          enables interrupts and calls Tx and Rx initialization functions */  
-       
+
+       /* now check for completion of MAC initialization through
+          the FunCtrl field of the IFACE, poll MR1 to detect completion of
+          MAC initialization, check completion status, set interrupt mask,
+          enables interrupts and calls Tx and Rx initialization functions */
+
        atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
-       
-       for (i =  LOOP_RETRY_LIMIT; i; i--) {
+
+       for (i = LOOP_RETRY_LIMIT; i; i--) {
                mr1 = atmel_read16(priv->dev, MR1);
                mr3 = atmel_read16(priv->dev, MR3);
-               
-               if (mr3 & MAC_INIT_COMPLETE) 
+
+               if (mr3 & MAC_INIT_COMPLETE)
                        break;
                if (mr1 & MAC_INIT_COMPLETE &&
                    priv->bus_type == BUS_TYPE_PCCARD)
                        break;
        }
-       
+
        if (i == 0) {
-               printk(KERN_ALERT "%s: MAC failed to initialise.\n", priv->dev->name);
+               printk(KERN_ALERT "%s: MAC failed to initialise.\n",
+                               priv->dev->name);
                return 0;
        }
-       
+
        /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
        if ((mr3 & MAC_INIT_COMPLETE) &&
            !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
@@ -3398,9 +3422,9 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
                return 0;
        }
 
-       atmel_copy_to_host(priv->dev, (unsigned char *)iface, 
+       atmel_copy_to_host(priv->dev, (unsigned char *)iface,
                           priv->host_info_base, sizeof(*iface));
-        
+
        iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
        iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
        iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
@@ -3424,16 +3448,16 @@ static int probe_atmel_card(struct net_device *dev)
 {
        int rc = 0;
        struct atmel_private *priv = netdev_priv(dev);
-        
+
        /* reset pccard */
-       if (priv->bus_type == BUS_TYPE_PCCARD) 
+       if (priv->bus_type == BUS_TYPE_PCCARD)
                atmel_write16(dev, GCR, 0x0060);
-       
+
        atmel_write16(dev, GCR, 0x0040);
        mdelay(500);
-       
+
        if (atmel_read16(dev, MR2) == 0) {
-               /* No stored firmware so load a small stub which just 
+               /* No stored firmware so load a small stub which just
                   tells us the MAC address */
                int i;
                priv->card_type = CARD_TYPE_EEPROM;
@@ -3442,7 +3466,7 @@ static int probe_atmel_card(struct net_device *dev)
                atmel_set_gcr(dev, GCR_REMAP);
                atmel_clear_gcr(priv->dev, 0x0040);
                atmel_write16(dev, BSR, BSS_SRAM);
-               for (i =  LOOP_RETRY_LIMIT; i; i--) 
+               for (i = LOOP_RETRY_LIMIT; i; i--)
                        if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
                                break;
                if (i == 0) {
@@ -3451,7 +3475,7 @@ static int probe_atmel_card(struct net_device *dev)
                        atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
                        /* got address, now squash it again until the network
                           interface is opened */
-                       if (priv->bus_type == BUS_TYPE_PCCARD) 
+                       if (priv->bus_type == BUS_TYPE_PCCARD)
                                atmel_write16(dev, GCR, 0x0060);
                        atmel_write16(dev, GCR, 0x0040);
                        rc = 1;
@@ -3459,7 +3483,7 @@ static int probe_atmel_card(struct net_device *dev)
        } else if (atmel_read16(dev, MR4) == 0) {
                /* Mac address easy in this case. */
                priv->card_type = CARD_TYPE_PARALLEL_FLASH;
-               atmel_write16(dev,  BSR, 1);    
+               atmel_write16(dev,  BSR, 1);
                atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
                atmel_write16(dev,  BSR, 0x200);
                rc = 1;
@@ -3469,16 +3493,16 @@ static int probe_atmel_card(struct net_device *dev)
                priv->card_type = CARD_TYPE_SPI_FLASH;
                if (atmel_wakeup_firmware(priv)) {
                        atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
-                       
+
                        /* got address, now squash it again until the network
                           interface is opened */
-                       if (priv->bus_type == BUS_TYPE_PCCARD) 
+                       if (priv->bus_type == BUS_TYPE_PCCARD)
                                atmel_write16(dev, GCR, 0x0060);
                        atmel_write16(dev, GCR, 0x0040);
                        rc = 1;
                }
        }
-       
+
        if (rc) {
                if (dev->dev_addr[0] == 0xFF) {
                        u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
@@ -3486,27 +3510,27 @@ static int probe_atmel_card(struct net_device *dev)
                        memcpy(dev->dev_addr, default_mac, 6);
                }
        }
-       
+
        return rc;
 }
 
-static void build_wep_mib(struct atmel_private *priv)
 /* Move the encyption information on the MIB structure.
    This routine is for the pre-WPA firmware: later firmware has
    a different format MIB and a different routine. */
+static void build_wep_mib(struct atmel_private *priv)
 {
        struct { /* NB this is matched to the hardware, don't change. */
-               u8 wep_is_on;                 
+               u8 wep_is_on;
                u8 default_key; /* 0..3 */
                u8 reserved;
                u8 exclude_unencrypted;
-               
+
                u32 WEPICV_error_count;
                u32 WEP_excluded_count;
-               
+
                u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
-               u8 encryption_level; /* 0, 1, 2 */
-               u8 reserved2[3]; 
+               u8 encryption_level; /* 0, 1, 2 */
+               u8 reserved2[3];
        } mib;
        int i;
 
@@ -3515,54 +3539,55 @@ static void build_wep_mib(struct atmel_private *priv)
                if (priv->wep_key_len[priv->default_key] > 5)
                        mib.encryption_level = 2;
                else
-                       mib.encryption_level = 1;       
+                       mib.encryption_level = 1;
        } else {
                mib.encryption_level = 0;
        }
 
        mib.default_key = priv->default_key;
        mib.exclude_unencrypted = priv->exclude_unencrypted;
-       
-       for(i = 0; i < MAX_ENCRYPTION_KEYS;  i++)
+
+       for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
                memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
-               
+
        atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
 }
 
 static void build_wpa_mib(struct atmel_private *priv)
 {
-       /* This is for the later (WPA enabled) firmware. */        
+       /* This is for the later (WPA enabled) firmware. */
 
        struct { /* NB this is matched to the hardware, don't change. */
                u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
                u8 receiver_address[6];
-               u8 wep_is_on;                 
+               u8 wep_is_on;
                u8 default_key; /* 0..3 */
                u8 group_key;
                u8 exclude_unencrypted;
                u8 encryption_type;
                u8 reserved;
-               
+
                u32 WEPICV_error_count;
                u32 WEP_excluded_count;
-               
+
                u8 key_RSC[4][8];
        } mib;
-       
+
        int i;
 
        mib.wep_is_on = priv->wep_is_on;
        mib.exclude_unencrypted = priv->exclude_unencrypted;
        memcpy(mib.receiver_address, priv->CurrentBSSID, 6);
-       
+
        /* zero all the keys before adding in valid ones. */
        memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
-       
+
        if (priv->wep_is_on) {
-               /* There's a comment in the Atmel code to the effect that this is only valid
-                  when still using WEP, it may need to be set to something to use WPA */
+               /* There's a comment in the Atmel code to the effect that this
+                  is only valid when still using WEP, it may need to be set to
+                  something to use WPA */
                memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
-               
+
                mib.default_key = mib.group_key = 255;
                for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
                        if (priv->wep_key_len[i] > 0) {
@@ -3570,12 +3595,12 @@ static void build_wpa_mib(struct atmel_private *priv)
                                if (i == priv->default_key) {
                                        mib.default_key = i;
                                        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
-                                       mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite; 
+                                       mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
                                } else {
                                        mib.group_key = i;
                                        priv->group_cipher_suite = priv->pairwise_cipher_suite;
                                        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
-                                       mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;  
+                                       mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
                                }
                        }
                }
@@ -3583,47 +3608,47 @@ static void build_wpa_mib(struct atmel_private *priv)
                        mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
                if (mib.group_key == 255)
                        mib.group_key = mib.default_key;
-               
+
        }
-       
+
        atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
 }
-                                       
-static int reset_atmel_card(struct net_device *dev) 
+
+static int reset_atmel_card(struct net_device *dev)
 {
        /* do everything necessary to wake up the hardware, including
           waiting for the lightning strike and throwing the knife switch....
 
-          set all the Mib values which matter in the card to match 
+          set all the Mib values which matter in the card to match
           their settings in the atmel_private structure. Some of these
           can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
           can only be changed by tearing down the world and coming back through
           here.
 
-          This routine is also responsible for initialising some 
-          hardware-specific fields in the atmel_private structure, 
+          This routine is also responsible for initialising some
+          hardware-specific fields in the atmel_private structure,
           including a copy of the firmware's hostinfo stucture
           which is the route into the rest of the firmare datastructures. */
 
        struct atmel_private *priv = netdev_priv(dev);
        u8 configuration;
-       
+
        /* data to add to the firmware names, in priority order
           this implemenents firmware versioning */
-       
+
        static char *firmware_modifier[] = {
                "-wpa",
                "",
                NULL
        };
-               
+
        /* reset pccard */
-       if (priv->bus_type == BUS_TYPE_PCCARD) 
+       if (priv->bus_type == BUS_TYPE_PCCARD)
                atmel_write16(priv->dev, GCR, 0x0060);
-               
+
        /* stop card , disable interrupts */
        atmel_write16(priv->dev, GCR, 0x0040);
-               
+
        if (priv->card_type == CARD_TYPE_EEPROM) {
                /* copy in firmware if needed */
                const struct firmware *fw_entry = NULL;
@@ -3636,13 +3661,13 @@ static int reset_atmel_card(struct net_device *dev)
                                               "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
                                               dev->name);
                                        printk(KERN_INFO
-                                              "%s: if not, use the firmware= module parameter.\n", 
+                                              "%s: if not, use the firmware= module parameter.\n",
                                               dev->name);
                                        strcpy(priv->firmware_id, "atmel_at76c502.bin");
                                }
                                if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
-                                       printk(KERN_ALERT 
-                                              "%s: firmware %s is missing, cannot continue.\n", 
+                                       printk(KERN_ALERT
+                                              "%s: firmware %s is missing, cannot continue.\n",
                                               dev->name, priv->firmware_id);
                                        return 0;
                                }
@@ -3654,7 +3679,7 @@ static int reset_atmel_card(struct net_device *dev)
                                while (fw_table[fw_index].fw_type != priv->firmware_type
                                                && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
                                        fw_index++;
-                               
+
                                /* construct the actual firmware file name */
                                if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
                                        int i;
@@ -3669,24 +3694,24 @@ static int reset_atmel_card(struct net_device *dev)
                                        }
                                }
                                if (!success) {
-                                       printk(KERN_ALERT 
-                                              "%s: firmware %s is missing, cannot start.\n", 
+                                       printk(KERN_ALERT
+                                              "%s: firmware %s is missing, cannot start.\n",
                                               dev->name, priv->firmware_id);
                                        priv->firmware_id[0] = '\0';
-                                       return 0;       
+                                       return 0;
                                }
                        }
-                       
+
                        fw = fw_entry->data;
                        len = fw_entry->size;
                }
-               
+
                if (len <= 0x6000) {
                        atmel_write16(priv->dev, BSR, BSS_IRAM);
                        atmel_copy_to_card(priv->dev, 0, fw, len);
                        atmel_set_gcr(priv->dev, GCR_REMAP);
                } else {
-                       /* Remap */ 
+                       /* Remap */
                        atmel_set_gcr(priv->dev, GCR_REMAP);
                        atmel_write16(priv->dev, BSR, BSS_IRAM);
                        atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
@@ -3708,45 +3733,45 @@ static int reset_atmel_card(struct net_device *dev)
           the 3com broken-ness filter. */
        priv->use_wpa = (priv->host_info.major_version == 4);
        priv->radio_on_broken = (priv->host_info.major_version == 5);
-       
+
         /* unmask all irq sources */
        atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
-       
+
        /* int Tx system and enable Tx */
        atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
        atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
        atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
        atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
 
-       priv->tx_desc_free = priv->host_info.tx_desc_count;             
-       priv->tx_desc_head = 0;                                                                 
-       priv->tx_desc_tail = 0;                                                                 
+       priv->tx_desc_free = priv->host_info.tx_desc_count;
+       priv->tx_desc_head = 0;
+       priv->tx_desc_tail = 0;
        priv->tx_desc_previous = 0;
        priv->tx_free_mem = priv->host_info.tx_buff_size;
-       priv->tx_buff_head = 0; 
-       priv->tx_buff_tail = 0; 
-               
-       configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
-       atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+       priv->tx_buff_head = 0;
+       priv->tx_buff_tail = 0;
+
+       configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
+       atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
                                   configuration | FUNC_CTRL_TxENABLE);
 
        /* init Rx system and enable */
        priv->rx_desc_head = 0;
-       
-       configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
-       atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+
+       configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
+       atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
                                   configuration | FUNC_CTRL_RxENABLE);
-                       
+
        if (!priv->radio_on_broken) {
-               if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == 
+               if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
                    CMD_STATUS_REJECTED_RADIO_OFF) {
-                       printk(KERN_INFO 
+                       printk(KERN_INFO
                               "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
                               dev->name);
                         return 0;
                }
        }
-       
+
        /* set up enough MIB values to run. */
        atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
        atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
@@ -3755,7 +3780,7 @@ static int reset_atmel_card(struct net_device *dev)
        atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
        atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
        atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
-       atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS, 
+       atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
                      priv->dev->dev_addr, 6);
        atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
        atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
@@ -3766,42 +3791,44 @@ static int reset_atmel_card(struct net_device *dev)
                build_wpa_mib(priv);
        else
                build_wep_mib(priv);
-       
+
        return 1;
 }
 
-static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+static void atmel_send_command(struct atmel_private *priv, int command,
+                              void *cmd, int cmd_size)
 {
        if (cmd)
-               atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET), 
+               atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
                                   cmd, cmd_size);
-       
+
        atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
        atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
 }
-       
-static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+
+static int atmel_send_command_wait(struct atmel_private *priv, int command,
+                                  void *cmd, int cmd_size)
 {
        int i, status;
-       
+
        atmel_send_command(priv, command, cmd, cmd_size);
-       
+
        for (i = 5000; i; i--) {
                status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
-               if (status != CMD_STATUS_IDLE && 
+               if (status != CMD_STATUS_IDLE &&
                    status != CMD_STATUS_IN_PROGRESS)
                        break;
                udelay(20);
        }
-       
+
        if (i == 0) {
                printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
                status =  CMD_STATUS_HOST_ERROR;
-       } else { 
+       } else {
                if (command != CMD_EnableRadio)
                        status = CMD_STATUS_COMPLETE;
        }
-       
+
        return status;
 }
 
@@ -3827,7 +3854,8 @@ static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 dat
        atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
 }
 
-static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data)
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
+                           u16 data)
 {
        struct get_set_mib m;
        m.type = type;
@@ -3839,7 +3867,8 @@ static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 d
        atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
 }
 
-static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
+                         u8 *data, int data_len)
 {
        struct get_set_mib m;
        m.type = type;
@@ -3848,23 +3877,24 @@ static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *dat
 
        if (data_len > MIB_MAX_DATA_BYTES)
                printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
-       
+
        memcpy(m.data, data, data_len);
        atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
 }
 
-static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
+                         u8 *data, int data_len)
 {
        struct get_set_mib m;
        m.type = type;
        m.size = data_len;
        m.index = index;
-       
+
        if (data_len > MIB_MAX_DATA_BYTES)
                printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
-       
+
        atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
-       atmel_copy_to_host(priv->dev, data, 
+       atmel_copy_to_host(priv->dev, data,
                           atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
 }
 
@@ -3873,11 +3903,12 @@ static void atmel_writeAR(struct net_device *dev, u16 data)
        int i;
        outw(data, dev->base_addr + AR);
        /* Address register appears to need some convincing..... */
-       for (i = 0; data != inw(dev->base_addr + AR) && i<10; i++)
+       for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
                outw(data, dev->base_addr + AR);
 }
 
-static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len)
+static void atmel_copy_to_card(struct net_device *dev, u16 dest,
+                              unsigned char *src, u16 len)
 {
        int i;
        atmel_writeAR(dev, dest);
@@ -3894,7 +3925,8 @@ static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *
                atmel_write8(dev, DR, *src);
 }
 
-static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len)
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
+                              u16 src, u16 len)
 {
        int i;
        atmel_writeAR(dev, src);
@@ -3930,22 +3962,24 @@ static int atmel_lock_mac(struct atmel_private *priv)
                        break;
                udelay(20);
        }
-       
-       if (!i) return 0; /* timed out */
-       
+
+       if (!i)
+               return 0; /* timed out */
+
        atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
        if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
                atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-               if (!j--) return 0; /* timed out */
+               if (!j--)
+                       return 0; /* timed out */
                goto retry;
        }
-       
+
        return 1;
 }
 
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
 {
-               atmel_writeAR(priv->dev, pos);  
+       atmel_writeAR(priv->dev, pos);
        atmel_write16(priv->dev, DR, data); /* card is little-endian */
        atmel_write16(priv->dev, DR, data >> 16);
 }
@@ -4017,9 +4051,9 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
                                  serial output, since SO is normally high.  But it
                                  does cause 8 clock cycles and thus 8 bits to be
                                  clocked in to the chip.  See Atmel's SPI
-                                 controller (e.g. AT91M55800) timing and 4K 
+                                 controller (e.g. AT91M55800) timing and 4K
                                  SPI EEPROM manuals */
-                                
+
        .set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
        .set NVRAM_IMAGE, 0x02000200
        .set NVRAM_LENGTH, 0x0200
@@ -4032,24 +4066,24 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
        .set MR4, 0xC
 RESET_VECTOR:
         b RESET_HANDLER
-UNDEF_VECTOR:  
+UNDEF_VECTOR:
         b HALT1
-SWI_VECTOR:            
+SWI_VECTOR:
         b HALT1
-IABORT_VECTOR: 
+IABORT_VECTOR:
         b HALT1
-DABORT_VECTOR:         
-RESERVED_VECTOR:    
+DABORT_VECTOR:
+RESERVED_VECTOR:
         b HALT1
-IRQ_VECTOR:    
+IRQ_VECTOR:
         b HALT1
-FIQ_VECTOR:    
+FIQ_VECTOR:
        b HALT1
 HALT1: b HALT1
 RESET_HANDLER:
        mov     r0, #CPSR_INITIAL
        msr     CPSR_c, r0      /* This is probably unnecessary */
-                       
+
 /* I'm guessing this is initializing clock generator electronics for SPI */
        ldr     r0, =SPI_CGEN_BASE
        mov     r1, #0
@@ -4061,7 +4095,7 @@ RESET_HANDLER:
        str     r1, [r0, #28]
        mov     r1, #1
        str     r1, [r0, #8]
-       
+
        ldr     r0, =MRBASE
        mov     r1, #0
        strh    r1, [r0, #MR1]
@@ -4094,7 +4128,7 @@ GET_WHOLE_NVRAM:
        ldmia   sp!, {lr}
        bx      lr
 .endfunc
-       
+
 .func Get_MAC_Addr, GET_MAC_ADDR
 GET_MAC_ADDR:
        stmdb   sp!, {lr}
@@ -4110,13 +4144,13 @@ GET_MAC_ADDR:
 .func Delay9, DELAY9
 DELAY9:
        adds    r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
-DELAYLOOP:     
+DELAYLOOP:
        beq     DELAY9_done
        subs    r0, r0, #1
        b       DELAYLOOP
-DELAY9_done:   
+DELAY9_done:
        bx      lr
-.endfunc       
+.endfunc
 
 .func SP_Init, SP_INIT
 SP_INIT:
@@ -4145,26 +4179,26 @@ SP_INIT:
        ldr     r0, [r0, #SP_RDR]
        bx      lr
 .endfunc
-.func NVRAM_Init, NVRAM_INIT   
+.func NVRAM_Init, NVRAM_INIT
 NVRAM_INIT:
        ldr     r1, =SP_BASE
        ldr     r0, [r1, #SP_RDR]
        mov     r0, #NVRAM_CMD_RDSR
        str     r0, [r1, #SP_TDR]
-SP_loop1:      
+SP_loop1:
        ldr     r0, [r1, #SP_SR]
        tst     r0, #SP_TDRE
        beq     SP_loop1
 
        mov     r0, #SPI_8CLOCKS
-       str     r0, [r1, #SP_TDR] 
-SP_loop2:      
+       str     r0, [r1, #SP_TDR]
+SP_loop2:
        ldr     r0, [r1, #SP_SR]
        tst     r0, #SP_TDRE
        beq     SP_loop2
 
        ldr     r0, [r1, #SP_RDR]
-SP_loop3:      
+SP_loop3:
        ldr     r0, [r1, #SP_SR]
        tst     r0, #SP_RDRF
        beq     SP_loop3
@@ -4173,7 +4207,7 @@ SP_loop3:
        and     r0, r0, #255
        bx      lr
 .endfunc
-       
+
 .func NVRAM_Xfer, NVRAM_XFER
        /* r0 = dest address */
        /* r1 = not used */
@@ -4185,11 +4219,11 @@ NVRAM_XFER:
        mov     r4, r3          /* save r3 (length) */
        mov     r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
        and     r0, r0, #8
-       add     r0, r0, #NVRAM_CMD_READ 
+       add     r0, r0, #NVRAM_CMD_READ
        ldr     r1, =NVRAM_SCRATCH
        strb    r0, [r1, #0]    /* save command in NVRAM_SCRATCH[0] */
        strb    r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
-_local1:       
+_local1:
        bl      NVRAM_INIT
        tst     r0, #NVRAM_SR_RDY
        bne     _local1
@@ -4211,7 +4245,7 @@ NVRAM_XFER2:
        cmp     r0, #0
        bls     _local2
        ldr     r5, =NVRAM_SCRATCH
-_local4:       
+_local4:
        ldrb    r6, [r5, r3]
        str     r6, [r4, #SP_TDR]
 _local3:
@@ -4225,7 +4259,7 @@ _local2:
        mov     r3, #SPI_8CLOCKS
        str     r3, [r4, #SP_TDR]
        ldr     r0, [r4, #SP_RDR]
-_local5:       
+_local5:
        ldr     r0, [r4, #SP_SR]
        tst     r0, #SP_RDRF
        beq     _local5
@@ -4233,12 +4267,12 @@ _local5:
        mov     r0, #0
        cmp     r2, #0  /* r2 is # of bytes to copy in */
        bls     _local6
-_local7:       
+_local7:
        ldr     r5, [r4, #SP_SR]
        tst     r5, #SP_TDRE
        beq     _local7
        str     r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
-_local8:       
+_local8:
        ldr     r5, [r4, #SP_SR]
        tst     r5, #SP_RDRF
        beq     _local8
index fc62235bfc24c169c1a04f4e93926f7782e94dcc..353ccb93134b79e70e38bb4a349cd681018c9576 100644 (file)
@@ -1,3 +1,4 @@
+hostap-y := hostap_main.o
 obj-$(CONFIG_HOSTAP) += hostap.o
 
 obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
index 77d2a21d4cd00f879abe206480f80ea75441aca7..44cd3fcd15720916d0cf9984a02bc8adb2afcb83 100644 (file)
@@ -175,7 +175,7 @@ that only one external action is invoked at a time.
 #define DRV_COPYRIGHT  "Copyright(c) 2003-2005 Intel Corporation"
 
 /* Debugging stuff */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define CONFIG_IPW2100_RX_DEBUG        /* Reception debugging */
 #endif
 
@@ -208,7 +208,7 @@ MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 
 static u32 ipw2100_debug_level = IPW_DL_NONE;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW_DEBUG(level, message...) \
 do { \
        if (ipw2100_debug_level & (level)) { \
@@ -219,9 +219,9 @@ do { \
 } while (0)
 #else
 #define IPW_DEBUG(level, message...) do {} while (0)
-#endif                         /* CONFIG_IPW_DEBUG */
+#endif                         /* CONFIG_IPW2100_DEBUG */
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *command_types[] = {
        "undefined",
        "unused",               /* HOST_ATTENTION */
@@ -2081,7 +2081,7 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
        priv->status &= ~STATUS_SCANNING;
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW2100_HANDLER(v, f) { v, f, # v }
 struct ipw2100_status_indicator {
        int status;
@@ -2094,7 +2094,7 @@ struct ipw2100_status_indicator {
        int status;
        void (*cb) (struct ipw2100_priv * priv, u32 status);
 };
-#endif                         /* CONFIG_IPW_DEBUG */
+#endif                         /* CONFIG_IPW2100_DEBUG */
 
 static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
 {
@@ -2149,7 +2149,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
 static void isr_rx_complete_command(struct ipw2100_priv *priv,
                                    struct ipw2100_cmd_header *cmd)
 {
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
                IPW_DEBUG_HC("Command completed '%s (%d)'\n",
                             command_types[cmd->host_command_reg],
@@ -2167,7 +2167,7 @@ static void isr_rx_complete_command(struct ipw2100_priv *priv,
        wake_up_interruptible(&priv->wait_command_queue);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *frame_types[] = {
        "COMMAND_STATUS_VAL",
        "STATUS_CHANGE_VAL",
@@ -2290,7 +2290,7 @@ static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
 
 static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 {
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
        struct ipw2100_status *status = &priv->status_queue.drv[i];
        u32 match, reg;
        int j;
@@ -2312,7 +2312,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
        }
 #endif
 
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
        /* Halt the fimrware so we can get a good image */
        write_register(priv->net_dev, IPW_REG_RESET_REG,
                       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
@@ -2716,7 +2716,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
        list_del(element);
        DEC_STAT(&priv->fw_pend_stat);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        {
                int i = txq->oldest;
                IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
@@ -2782,7 +2782,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
                               "something else: ids %d=%d.\n",
                               priv->net_dev->name, txq->oldest, packet->index);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
                if (packet->info.c_struct.cmd->host_command_reg <
                    sizeof(command_types) / sizeof(*command_types))
                        IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
@@ -2975,7 +2975,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
 
                IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
                             packet->index, tbd->host_addr, tbd->buf_length);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
                if (packet->info.d_struct.txb->nr_frags > 1)
                        IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
                                       packet->info.d_struct.txb->nr_frags);
@@ -3827,7 +3827,7 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr,
                       priv->rx_interrupts, priv->inta_other);
        out += sprintf(out, "firmware resets: %d\n", priv->resets);
        out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        out += sprintf(out, "packet mismatch image: %s\n",
                       priv->snapshot[0] ? "YES" : "NO");
 #endif
@@ -3982,7 +3982,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
 
 static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static ssize_t show_debug_level(struct device_driver *d, char *buf)
 {
        return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
@@ -4011,7 +4011,7 @@ static ssize_t store_debug_level(struct device_driver *d,
 
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
                   store_debug_level);
-#endif                         /* CONFIG_IPW_DEBUG */
+#endif                         /* CONFIG_IPW2100_DEBUG */
 
 static ssize_t show_fatal_error(struct device *d,
                                struct device_attribute *attr, char *buf)
@@ -4937,7 +4937,7 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
        };
        int err;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        if (bssid != NULL)
                IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
                             bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
@@ -6858,7 +6858,7 @@ static int __init ipw2100_init(void)
 
        ret = pci_module_init(&ipw2100_pci_driver);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        ipw2100_debug_level = debug;
        driver_create_file(&ipw2100_pci_driver.driver,
                           &driver_attr_debug_level);
@@ -6873,7 +6873,7 @@ static int __init ipw2100_init(void)
 static void __exit ipw2100_exit(void)
 {
        /* FIXME: IPG: check that we have no instances of the devices open */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
        driver_remove_file(&ipw2100_pci_driver.driver,
                           &driver_attr_debug_level);
 #endif
@@ -8558,7 +8558,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
 
                quality = min(beacon_qual, min(tx_qual, rssi_qual));
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
                if (beacon_qual == quality)
                        IPW_DEBUG_WX("Quality clamped by Missed Beacons\n");
                else if (tx_qual == quality)
index 7c65b10bb164d00b0d2a0fb393b4ec1e97cdd85b..f6c51441fa878a85baa868a9d23af18d69f7c207 100644 (file)
@@ -73,7 +73,7 @@ struct ipw2100_rx_packet;
  * you simply need to add your entry to the ipw2100_debug_levels array.
  *
  * If you do not see debug_level in /proc/net/ipw2100 then you do not have
- * CONFIG_IPW_DEBUG defined in your kernel configuration
+ * CONFIG_IPW2100_DEBUG defined in your kernel configuration
  *
  */
 
index 5e7c7e944c9deb8190d271486737041275f85dcf..cdfe50207757392176a538f9276d13bffd730c31 100644 (file)
@@ -462,7 +462,7 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
        ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static char *ipw_error_desc(u32 val)
 {
        switch (val) {
@@ -1235,7 +1235,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
                              const char *buf, size_t count)
 {
        struct ipw_priv *priv = dev_get_drvdata(d);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
        struct net_device *dev = priv->net_dev;
 #endif
        char buffer[] = "00000000";
@@ -1754,7 +1754,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
                IPW_ERROR("Firmware error detected.  Restarting.\n");
                if (priv->error) {
                        IPW_ERROR("Sysfs 'error' log already exists.\n");
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
                        if (ipw_debug_level & IPW_DL_FW_ERRORS) {
                                struct ipw_fw_error *error =
                                    ipw_alloc_error_log(priv);
@@ -1770,7 +1770,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
                        else
                                IPW_ERROR("Error allocating sysfs 'error' "
                                          "log.\n");
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
                        if (ipw_debug_level & IPW_DL_FW_ERRORS)
                                ipw_dump_error_log(priv, priv->error);
 #endif
@@ -3778,7 +3778,7 @@ static const struct ipw_status_code ipw_status_codes[] = {
        {0x2E, "Cipher suite is rejected per security policy"},
 };
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static const char *ipw_get_status_code(u16 status)
 {
        int i;
@@ -4250,7 +4250,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
                                        if (priv->
                                            status & (STATUS_ASSOCIATED |
                                                      STATUS_AUTH)) {
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
                                                struct notif_authenticate *auth
                                                    = &notif->u.auth;
                                                IPW_DEBUG(IPW_DL_NOTIF |
@@ -4944,12 +4944,11 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
        struct ipw_rx_queue *rxq;
        int i;
 
-       rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
+       rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);
        if (unlikely(!rxq)) {
                IPW_ERROR("memory allocation failed\n");
                return NULL;
        }
-       memset(rxq, 0, sizeof(*rxq));
        spin_lock_init(&rxq->lock);
        INIT_LIST_HEAD(&rxq->rx_free);
        INIT_LIST_HEAD(&rxq->rx_used);
@@ -5828,7 +5827,7 @@ static void ipw_bg_adhoc_check(void *data)
        up(&priv->sem);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static void ipw_debug_config(struct ipw_priv *priv)
 {
        IPW_DEBUG_INFO("Scan completed, no valid APs matched "
@@ -7456,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);
 
@@ -7648,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 */
@@ -7662,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 */
@@ -7815,7 +7811,7 @@ static void ipw_rx(struct ipw_priv *priv)
 
        while (i != r) {
                rxb = priv->rxq->queue[i];
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
                if (unlikely(rxb == NULL)) {
                        printk(KERN_CRIT "Queue not allocated!\n");
                        break;
@@ -9657,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);
@@ -9673,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;
@@ -10956,7 +10950,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        priv->net_dev = net_dev;
        priv->pci_dev = pdev;
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
        ipw_debug_level = debug;
 #endif
        spin_lock_init(&priv->lock);
index 1c98db0652c9458a9c61079e8e91cd8a6edb4d39..e65620a4d79ea957d624be65f3e89cf12c54c099 100644 (file)
@@ -1301,14 +1301,14 @@ struct ipw_priv {
 
 /* debug macros */
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 #define IPW_DEBUG(level, fmt, args...) \
 do { if (ipw_debug_level & (level)) \
   printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \
          in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
 #else
 #define IPW_DEBUG(level, fmt, args...) do {} while (0)
-#endif                         /* CONFIG_IPW_DEBUG */
+#endif                         /* CONFIG_IPW2200_DEBUG */
 
 /*
  * To use the debug system;
@@ -1332,7 +1332,7 @@ do { if (ipw_debug_level & (level)) \
  * you simply need to add your entry to the ipw_debug_levels array.
  *
  * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IPW_DEBUG defined in your kernel configuration
+ * CONFIG_IPW2200_DEBUG defined in your kernel configuration
  *
  */
 
index 3a4f49f4effbfd647371bae04c040ec761d924a3..f28ebdd3958a557466ff347abc21b3c8f14d1a49 100644 (file)
@@ -1098,6 +1098,23 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_EESSC,      quirk_alder_ioapic );
 #endif
 
+enum ide_combined_type { COMBINED = 0, IDE = 1, LIBATA = 2 };
+/* Defaults to combined */
+static enum ide_combined_type combined_mode;
+
+static int __init combined_setup(char *str)
+{
+       if (!strncmp(str, "ide", 3))
+               combined_mode = IDE;
+       else if (!strncmp(str, "libata", 6))
+               combined_mode = LIBATA;
+       else /* "combined" or anything else defaults to old behavior */
+               combined_mode = COMBINED;
+
+       return 1;
+}
+__setup("combined_mode=", combined_setup);
+
 #ifdef CONFIG_SCSI_SATA_INTEL_COMBINED
 static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
 {
@@ -1164,6 +1181,19 @@ static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
        if (prog & comb)
                return;
 
+       /* Don't reserve any so the IDE driver can get them (but only if
+        * combined_mode=ide).
+        */
+       if (combined_mode == IDE)
+               return;
+
+       /* Grab them both for libata if combined_mode=libata. */
+       if (combined_mode == LIBATA) {
+               request_region(0x1f0, 8, "libata");     /* port 0 */
+               request_region(0x170, 8, "libata");     /* port 1 */
+               return;
+       }
+
        /* SATA port is in legacy mode.  Reserve port so that
         * IDE driver does not attempt to use it.  If request_region
         * fails, it will be obvious at boot time, so we don't bother
diff --git a/drivers/scsi/.gitignore b/drivers/scsi/.gitignore
new file mode 100644 (file)
index 0000000..b385af3
--- /dev/null
@@ -0,0 +1,3 @@
+53c700_d.h
+53c7xx_d.h
+53c7xx_u.h
index e7ad269041a4bdc36b1c95c8a24996cae519baa6..4ce7438608ecb68a374146276eff3308da099589 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 362d78483d091b47ccfbc925ca3d8f8dd7eef90c..a8c83bb036303dd44b9eea46857679f512e392be 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 9cb5dd48383fbdde590270a36ac13512dafabb64..7894b8ea84bde7341cc39a6da81c956a6740c1ab 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 20dd85a77813a03fa9314a7c65f98a4ecd75e7e0..4c42065dea88bbc2623264ada6ff5d0329406c61 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 cba9655d0f14075af5903b7d0c82ab5b6989f36a..9f0ddbe6dc765ef6decb10dfb30c0693cd92440b 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 9df23b654cec1aa929cb3d7f5eb7ae4b3b089c67..cb2ee25f213f1cc3d2dfd6a1b17ed9ade8c6f276 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 83467a05dc8e3e31f150ca2e030746a1e854b5a7..887eaa2a3ebf129cd61a5f0ffa401c14c867bd0f 100644 (file)
@@ -243,7 +243,7 @@ static const struct ata_port_operations ahci_ops = {
        .port_stop              = ahci_port_stop,
 };
 
-static struct ata_port_info ahci_port_info[] = {
+static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci */
        {
                .sht            = &ahci_sht,
@@ -643,7 +643,8 @@ static void ahci_eng_timeout(struct ata_port *ap)
                 * not being called from the SCSI EH.
                 */
                qc->scsidone = scsi_finish_command;
-               ata_qc_complete(qc, AC_ERR_OTHER);
+               qc->err_mask |= AC_ERR_OTHER;
+               ata_qc_complete(qc);
        }
 
        spin_unlock_irqrestore(&host_set->lock, flags);
@@ -664,7 +665,8 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
        ci = readl(port_mmio + PORT_CMD_ISSUE);
        if (likely((ci & 0x1) == 0)) {
                if (qc) {
-                       ata_qc_complete(qc, 0);
+                       assert(qc->err_mask == 0);
+                       ata_qc_complete(qc);
                        qc = NULL;
                }
        }
@@ -681,8 +683,10 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
                /* command processing has stopped due to error; restart */
                ahci_restart_port(ap, status);
 
-               if (qc)
-                       ata_qc_complete(qc, err_mask);
+               if (qc) {
+                       qc->err_mask |= AC_ERR_OTHER;
+                       ata_qc_complete(qc);
+               }
        }
 
        return 1;
diff --git a/drivers/scsi/aic7xxx/.gitignore b/drivers/scsi/aic7xxx/.gitignore
new file mode 100644 (file)
index 0000000..b8ee24d
--- /dev/null
@@ -0,0 +1,6 @@
+aic79xx_reg.h
+aic79xx_reg_print.c
+aic79xx_seq.h
+aic7xxx_reg.h
+aic7xxx_reg_print.c
+aic7xxx_seq.h
index 6aab9dacdeeaaef59144cb5d5f072cb05deddef3..1c8f872e2dd41be16151067ebfb9553a6a6c6ab9 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 d866213f42b8be6521a4b39dc78907c58b2a02b4..fd389e9f9460a7af31fd9510848f5dd13fac3b96 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 13f23043c8a370f507fc5e8599e5735a4c265c6f..06d7601cdf565626c74bf196494b41cbb36809ca 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 b7b20c689c245567026bf60b2b2a6913e1a7e703..09ed05727bcbb7f972be03d471e26328fa87d90d 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 333d69dd84ef5ad0febfefeb07a30e7153288a72..0ea27873b9fffaa054ec6b535d60a8afe8a59337 100644 (file)
  *
  *  Hardware documentation available at http://developer.intel.com/
  *
+ * Documentation
+ *     Publically available from Intel web site. Errata documentation
+ * is also publically available. As an aide to anyone hacking on this
+ * driver the list of errata that are relevant is below.going back to
+ * PIIX4. Older device documentation is now a bit tricky to find.
+ *
+ * The chipsets all follow very much the same design. The orginal Triton
+ * series chipsets do _not_ support independant device timings, but this
+ * is fixed in Triton II. With the odd mobile exception the chips then
+ * change little except in gaining more modes until SATA arrives. This
+ * driver supports only the chips with independant timing (that is those
+ * with SITRE and the 0x44 timing register). See pata_oldpiix and pata_mpiix
+ * for the early chip drivers.
+ *
+ * Errata of note:
+ *
+ * Unfixable
+ *     PIIX4    errata #9      - Only on ultra obscure hw
+ *     ICH3     errata #13     - Not observed to affect real hw
+ *                               by Intel
+ *
+ * Things we must deal with
+ *     PIIX4   errata #10      - BM IDE hang with non UDMA
+ *                               (must stop/start dma to recover)
+ *     440MX   errata #15      - As PIIX4 errata #10
+ *     PIIX4   errata #15      - Must not read control registers
+ *                               during a PIO transfer
+ *     440MX   errata #13      - As PIIX4 errata #15
+ *     ICH2    errata #21      - DMA mode 0 doesn't work right
+ *     ICH0/1  errata #55      - As ICH2 errata #21
+ *     ICH2    spec c #9       - Extra operations needed to handle
+ *                               drive hotswap [NOT YET SUPPORTED]
+ *     ICH2    spec c #20      - IDE PRD must not cross a 64K boundary
+ *                               and must be dword aligned
+ *     ICH2    spec c #24      - UDMA mode 4,5 t85/86 should be 6ns not 3.3
+ *
+ * Should have been BIOS fixed:
+ *     450NX:  errata #19      - DMA hangs on old 450NX
+ *     450NX:  errata #20      - DMA hangs on old 450NX
+ *     450NX:  errata #25      - Corruption with DMA on old 450NX
+ *     ICH3    errata #15      - IDE deadlock under high load
+ *                               (BIOS must set dev 31 fn 0 bit 23)
+ *     ICH3    errata #18      - Don't use native mode
  */
 
 #include <linux/kernel.h>
@@ -78,9 +121,7 @@ enum {
        ich5_sata               = 1,
        piix4_pata              = 2,
        ich6_sata               = 3,
-       ich6_sata_rm            = 4,
-       ich7_sata               = 5,
-       esb2_sata               = 6,
+       ich6_sata_ahci          = 4,
 
        PIIX_AHCI_DEVICE        = 6,
 };
@@ -111,11 +152,11 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
        { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
        { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
-       { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
-       { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
-       { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
-       { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
-       { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_sata },
+       { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 
        { }     /* terminate list */
 };
@@ -258,31 +299,7 @@ static struct ata_port_info piix_port_info[] = {
                .port_ops       = &piix_sata_ops,
        },
 
-       /* ich6_sata_rm */
-       {
-               .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
-                                 PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-                                 ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
-               .port_ops       = &piix_sata_ops,
-       },
-
-       /* ich7_sata */
-       {
-               .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
-                                 PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-                                 ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
-               .port_ops       = &piix_sata_ops,
-       },
-
-       /* esb2_sata */
+       /* ich6_sata_ahci */
        {
                .sht            = &piix_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
@@ -602,6 +619,40 @@ static int piix_disable_ahci(struct pci_dev *pdev)
        return rc;
 }
 
+/**
+ *     piix_check_450nx_errata -       Check for problem 450NX setup
+ *     
+ *     Check for the present of 450NX errata #19 and errata #25. If
+ *     they are found return an error code so we can turn off DMA
+ */
+
+static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
+{
+       struct pci_dev *pdev = NULL;
+       u16 cfg;
+       u8 rev;
+       int no_piix_dma = 0;
+       
+       while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL)
+       {
+               /* Look for 450NX PXB. Check for problem configurations
+                  A PCI quirk checks bit 6 already */
+               pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+               pci_read_config_word(pdev, 0x41, &cfg);
+               /* Only on the original revision: IDE DMA can hang */
+               if(rev == 0x00)
+                       no_piix_dma = 1;
+               /* On all revisions below 5 PXB bus lock must be disabled for IDE */
+               else if(cfg & (1<<14) && rev < 5)
+                       no_piix_dma = 2;
+       }
+       if(no_piix_dma)
+               dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n");
+       if(no_piix_dma == 2)
+               dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n");
+       return no_piix_dma;
+}              
+
 /**
  *     piix_init_one - Register PIIX ATA PCI device with kernel services
  *     @pdev: PCI device to register
@@ -676,7 +727,15 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                           "combined mode detected (p=%u, s=%u)\n",
                           pata_chan, sata_chan);
        }
-
+       if (piix_check_450nx_errata(pdev)) {
+               /* This writes into the master table but it does not
+                  really matter for this errata as we will apply it to
+                  all the PIIX devices on the board */
+               port_info[0]->mwdma_mask = 0;
+               port_info[0]->udma_mask = 0;
+               port_info[1]->mwdma_mask = 0;
+               port_info[1]->udma_mask = 0;
+       }
        return ata_pci_init_one(pdev, port_info, 2);
 }
 
index 2ae31ceb32a8fc97b11d2d1618ca749a84420d36..57295bcea3e766a4ae87d760ab6bf4cf1be35b32 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 ccbbae2bf478291ff169d73a24f467f8ff0f7d05..0920220f331394a147337c1a14ba0007535961aa 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 09bc81557b6ede1cfa24f5ddae2f20e8365acfaf..30a335349ceeb279109bc8b3d5cb45aaba06b847 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 fa2cb3582cfa5a2c1348d974bcfa3566e5e47d73..b6714da4d6e2185fb5a15acf627a8d528e2628c5 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 6bec673c925c20e0efb9d68010e016b91ddbde66..b639332131f1b8cb7dd251cfbdf58af919553a55 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 3d8009f55342c9f0d93270ec5780739030428e1c..10bcf42cb65c0a0eaf021b4052a068019c9658d2 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 d23ae68fae0d8d6821b8045cfff25eba70a3e356..855f2dfd18afb9612b84754130162c6f8ed559a1 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 d0a0fdbd0fc4a658d5b900647c0ab4b238db45d3..9ea1025879147ca524999e9595c53413ea808b1f 100644 (file)
@@ -605,7 +605,7 @@ void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
        tf->command = ata_rw_cmds[index + lba48 + write];
 }
 
-static const char * xfer_mode_str[] = {
+static const char * const xfer_mode_str[] = {
        "UDMA/16",
        "UDMA/25",
        "UDMA/33",
@@ -1046,28 +1046,103 @@ static unsigned int ata_pio_modes(const struct ata_device *adev)
        return modes;
 }
 
-static int ata_qc_wait_err(struct ata_queued_cmd *qc,
-                          struct completion *wait)
+struct ata_exec_internal_arg {
+       unsigned int err_mask;
+       struct ata_taskfile *tf;
+       struct completion *waiting;
+};
+
+int ata_qc_complete_internal(struct ata_queued_cmd *qc)
 {
-       int rc = 0;
+       struct ata_exec_internal_arg *arg = qc->private_data;
+       struct completion *waiting = arg->waiting;
 
-       if (wait_for_completion_timeout(wait, 30 * HZ) < 1) {
-               /* timeout handling */
-               unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap));
+       if (!(qc->err_mask & ~AC_ERR_DEV))
+               qc->ap->ops->tf_read(qc->ap, arg->tf);
+       arg->err_mask = qc->err_mask;
+       arg->waiting = NULL;
+       complete(waiting);
 
-               if (!err_mask) {
-                       printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n",
-                              qc->ap->id, qc->tf.command);
-               } else {
-                       printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n",
-                              qc->ap->id, qc->tf.command);
-                       rc = -EIO;
+       return 0;
+}
+
+/**
+ *     ata_exec_internal - execute libata internal command
+ *     @ap: Port to which the command is sent
+ *     @dev: Device to which the command is sent
+ *     @tf: Taskfile registers for the command and the result
+ *     @dma_dir: Data tranfer direction of the command
+ *     @buf: Data buffer of the command
+ *     @buflen: Length of data buffer
+ *
+ *     Executes libata internal command with timeout.  @tf contains
+ *     command on entry and result on return.  Timeout and error
+ *     conditions are reported via return value.  No recovery action
+ *     is taken after a command times out.  It's caller's duty to
+ *     clean up after timeout.
+ *
+ *     LOCKING:
+ *     None.  Should be called with kernel context, might sleep.
+ */
+
+static unsigned
+ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+                 struct ata_taskfile *tf,
+                 int dma_dir, void *buf, unsigned int buflen)
+{
+       u8 command = tf->command;
+       struct ata_queued_cmd *qc;
+       DECLARE_COMPLETION(wait);
+       unsigned long flags;
+       struct ata_exec_internal_arg arg;
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+
+       qc = ata_qc_new_init(ap, dev);
+       BUG_ON(qc == NULL);
+
+       qc->tf = *tf;
+       qc->dma_dir = dma_dir;
+       if (dma_dir != DMA_NONE) {
+               ata_sg_init_one(qc, buf, buflen);
+               qc->nsect = buflen / ATA_SECT_SIZE;
+       }
+
+       arg.waiting = &wait;
+       arg.tf = tf;
+       qc->private_data = &arg;
+       qc->complete_fn = ata_qc_complete_internal;
+
+       if (ata_qc_issue(qc))
+               goto issue_fail;
+
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
+               spin_lock_irqsave(&ap->host_set->lock, flags);
+
+               /* We're racing with irq here.  If we lose, the
+                * following test prevents us from completing the qc
+                * again.  If completion irq occurs after here but
+                * before the caller cleans up, it will result in a
+                * spurious interrupt.  We can live with that.
+                */
+               if (arg.waiting) {
+                       qc->err_mask = AC_ERR_OTHER;
+                       ata_qc_complete(qc);
+                       printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
+                              ap->id, command);
                }
 
-               ata_qc_complete(qc, err_mask);
+               spin_unlock_irqrestore(&ap->host_set->lock, flags);
        }
 
-       return rc;
+       return arg.err_mask;
+
+ issue_fail:
+       ata_qc_free(qc);
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       return AC_ERR_OTHER;
 }
 
 /**
@@ -1099,9 +1174,8 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
        u16 tmp;
        unsigned long xfer_modes;
        unsigned int using_edd;
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       unsigned long flags;
+       struct ata_taskfile tf;
+       unsigned int err_mask;
        int rc;
 
        if (!ata_dev_present(dev)) {
@@ -1122,40 +1196,26 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
 
        ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
 
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
-
-       ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-       qc->dma_dir = DMA_FROM_DEVICE;
-       qc->tf.protocol = ATA_PROT_PIO;
-       qc->nsect = 1;
-
 retry:
+       ata_tf_init(ap, &tf, device);
+
        if (dev->class == ATA_DEV_ATA) {
-               qc->tf.command = ATA_CMD_ID_ATA;
+               tf.command = ATA_CMD_ID_ATA;
                DPRINTK("do ATA identify\n");
        } else {
-               qc->tf.command = ATA_CMD_ID_ATAPI;
+               tf.command = ATA_CMD_ID_ATAPI;
                DPRINTK("do ATAPI identify\n");
        }
 
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
+       tf.protocol = ATA_PROT_PIO;
 
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-       if (rc)
-               goto err_out;
-       else
-               ata_qc_wait_err(qc, &wait);
+       err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+                                    dev->id, sizeof(dev->id));
 
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       ap->ops->tf_read(ap, &qc->tf);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       if (err_mask) {
+               if (err_mask & ~AC_ERR_DEV)
+                       goto err_out;
 
-       if (qc->tf.command & ATA_ERR) {
                /*
                 * arg!  EDD works for all test cases, but seems to return
                 * the ATA signature for some ATAPI devices.  Until the
@@ -1168,13 +1228,9 @@ retry:
                 * to have this problem.
                 */
                if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
-                       u8 err = qc->tf.feature;
+                       u8 err = tf.feature;
                        if (err & ATA_ABORTED) {
                                dev->class = ATA_DEV_ATAPI;
-                               qc->cursg = 0;
-                               qc->cursg_ofs = 0;
-                               qc->cursect = 0;
-                               qc->nsect = 1;
                                goto retry;
                        }
                }
@@ -1444,11 +1500,23 @@ void __sata_phy_reset(struct ata_port *ap)
        } while (time_before(jiffies, timeout));
 
        /* TODO: phy layer with polling, timeouts, etc. */
-       if (sata_dev_present(ap))
+       sstatus = scr_read(ap, SCR_STATUS);
+       if (sata_dev_present(ap)) {
+               const char *speed;
+               u32 tmp;
+
+               tmp = (sstatus >> 4) & 0xf;
+               if (tmp & (1 << 0))
+                       speed = "1.5";
+               else if (tmp & (1 << 1))
+                       speed = "3.0";
+               else
+                       speed = "<unknown>";
+               printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
+                      ap->id, speed, sstatus);
                ata_port_probe(ap);
-       else {
-               sstatus = scr_read(ap, SCR_STATUS);
-               printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n",
+       } else {
+               printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
                       ap->id, sstatus);
                ata_port_disable(ap);
        }
@@ -2071,7 +2139,7 @@ static void ata_pr_blacklisted(const struct ata_port *ap,
                ap->id, dev->devno);
 }
 
-static const char * ata_dma_blacklist [] = {
+static const char * const ata_dma_blacklist [] = {
        "WDC AC11000H",
        "WDC AC22100H",
        "WDC AC32500H",
@@ -2266,34 +2334,23 @@ static int ata_choose_xfer_mode(const struct ata_port *ap,
 
 static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 {
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       int rc;
-       unsigned long flags;
+       struct ata_taskfile tf;
 
        /* set up set-features taskfile */
        DPRINTK("set features - xfer mode\n");
 
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
-
-       qc->tf.command = ATA_CMD_SET_FEATURES;
-       qc->tf.feature = SETFEATURES_XFER;
-       qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       qc->tf.protocol = ATA_PROT_NODATA;
-       qc->tf.nsect = dev->xfer_mode;
-
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       ata_tf_init(ap, &tf, dev->devno);
+       tf.command = ATA_CMD_SET_FEATURES;
+       tf.feature = SETFEATURES_XFER;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       tf.nsect = dev->xfer_mode;
 
-       if (rc)
+       if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+               printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n",
+                      ap->id);
                ata_port_disable(ap);
-       else
-               ata_qc_wait_err(qc, &wait);
+       }
 
        DPRINTK("EXIT\n");
 }
@@ -2308,41 +2365,25 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 
 static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
 {
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       unsigned long flags;
-       int rc;
-
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
+       struct ata_taskfile tf;
 
-       ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-       qc->dma_dir = DMA_FROM_DEVICE;
+       ata_tf_init(ap, &tf, dev->devno);
 
        if (dev->class == ATA_DEV_ATA) {
-               qc->tf.command = ATA_CMD_ID_ATA;
+               tf.command = ATA_CMD_ID_ATA;
                DPRINTK("do ATA identify\n");
        } else {
-               qc->tf.command = ATA_CMD_ID_ATAPI;
+               tf.command = ATA_CMD_ID_ATAPI;
                DPRINTK("do ATAPI identify\n");
        }
 
-       qc->tf.flags |= ATA_TFLAG_DEVICE;
-       qc->tf.protocol = ATA_PROT_PIO;
-       qc->nsect = 1;
-
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       tf.flags |= ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_PIO;
 
-       if (rc)
+       if (ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+                             dev->id, sizeof(dev->id)))
                goto err_out;
 
-       ata_qc_wait_err(qc, &wait);
-
        swap_buf_le16(dev->id, ATA_ID_WORDS);
 
        ata_dump_id(dev);
@@ -2351,6 +2392,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
 
        return;
 err_out:
+       printk(KERN_ERR "ata%u: failed to reread ID, disabled\n", ap->id);
        ata_port_disable(ap);
 }
 
@@ -2364,10 +2406,7 @@ err_out:
 
 static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 {
-       DECLARE_COMPLETION(wait);
-       struct ata_queued_cmd *qc;
-       int rc;
-       unsigned long flags;
+       struct ata_taskfile tf;
        u16 sectors = dev->id[6];
        u16 heads   = dev->id[3];
 
@@ -2378,26 +2417,18 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
        /* set up init dev params taskfile */
        DPRINTK("init dev params \n");
 
-       qc = ata_qc_new_init(ap, dev);
-       BUG_ON(qc == NULL);
-
-       qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
-       qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       qc->tf.protocol = ATA_PROT_NODATA;
-       qc->tf.nsect = sectors;
-       qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
-
-       qc->waiting = &wait;
-       qc->complete_fn = ata_qc_complete_noop;
-
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       rc = ata_qc_issue(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       ata_tf_init(ap, &tf, dev->devno);
+       tf.command = ATA_CMD_INIT_DEV_PARAMS;
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.protocol = ATA_PROT_NODATA;
+       tf.nsect = sectors;
+       tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-       if (rc)
+       if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+               printk(KERN_ERR "ata%u: failed to init parameters, disabled\n",
+                      ap->id);
                ata_port_disable(ap);
-       else
-               ata_qc_wait_err(qc, &wait);
+       }
 
        DPRINTK("EXIT\n");
 }
@@ -2765,7 +2796,7 @@ skip_map:
  *     None.  (grabs host lock)
  */
 
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        unsigned long flags;
@@ -2773,7 +2804,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
        spin_lock_irqsave(&ap->host_set->lock, flags);
        ap->flags &= ~ATA_FLAG_NOINTR;
        ata_irq_on(ap);
-       ata_qc_complete(qc, err_mask);
+       ata_qc_complete(qc);
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 }
 
@@ -2790,10 +2821,14 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
 
 static unsigned long ata_pio_poll(struct ata_port *ap)
 {
+       struct ata_queued_cmd *qc;
        u8 status;
        unsigned int poll_state = HSM_ST_UNKNOWN;
        unsigned int reg_state = HSM_ST_UNKNOWN;
 
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       assert(qc != NULL);
+
        switch (ap->hsm_task_state) {
        case HSM_ST:
        case HSM_ST_POLL:
@@ -2813,6 +2848,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
        status = ata_chk_status(ap);
        if (status & ATA_BUSY) {
                if (time_after(jiffies, ap->pio_task_timeout)) {
+                       qc->err_mask |= AC_ERR_ATA_BUS;
                        ap->hsm_task_state = HSM_ST_TMOUT;
                        return 0;
                }
@@ -2847,29 +2883,31 @@ static int ata_pio_complete (struct ata_port *ap)
         * msecs, then chk-status again.  If still busy, fall back to
         * HSM_ST_POLL state.
         */
-       drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-       if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+       drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+       if (drv_stat & ATA_BUSY) {
                msleep(2);
-               drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-               if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+               drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+               if (drv_stat & ATA_BUSY) {
                        ap->hsm_task_state = HSM_ST_LAST_POLL;
                        ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
                        return 0;
                }
        }
 
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       assert(qc != NULL);
+
        drv_stat = ata_wait_idle(ap);
        if (!ata_ok(drv_stat)) {
+               qc->err_mask |= __ac_err_mask(drv_stat);
                ap->hsm_task_state = HSM_ST_ERR;
                return 0;
        }
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       assert(qc != NULL);
-
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, 0);
+       assert(qc->err_mask == 0);
+       ata_poll_qc_complete(qc);
 
        /* another command may start at this point */
 
@@ -3177,6 +3215,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
 err_out:
        printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
              ap->id, dev->devno);
+       qc->err_mask |= AC_ERR_ATA_BUS;
        ap->hsm_task_state = HSM_ST_ERR;
 }
 
@@ -3215,8 +3254,16 @@ static void ata_pio_block(struct ata_port *ap)
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
 
+       /* check error */
+       if (status & (ATA_ERR | ATA_DF)) {
+               qc->err_mask |= AC_ERR_DEV;
+               ap->hsm_task_state = HSM_ST_ERR;
+               return;
+       }
+
+       /* transfer data if any */
        if (is_atapi_taskfile(&qc->tf)) {
-               /* no more data to transfer or unsupported ATAPI command */
+               /* DRQ=0 means no more data to transfer */
                if ((status & ATA_DRQ) == 0) {
                        ap->hsm_task_state = HSM_ST_LAST;
                        return;
@@ -3226,6 +3273,7 @@ static void ata_pio_block(struct ata_port *ap)
        } else {
                /* handle BSY=0, DRQ=0 as error */
                if ((status & ATA_DRQ) == 0) {
+                       qc->err_mask |= AC_ERR_ATA_BUS;
                        ap->hsm_task_state = HSM_ST_ERR;
                        return;
                }
@@ -3243,9 +3291,14 @@ static void ata_pio_error(struct ata_port *ap)
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
 
+       /* make sure qc->err_mask is available to 
+        * know what's wrong and recover
+        */
+       assert(qc->err_mask);
+
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
+       ata_poll_qc_complete(qc);
 }
 
 static void ata_pio_task(void *_data)
@@ -3347,7 +3400,8 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
                       ap->id, qc->tf.command, drv_stat, host_stat);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, ac_err_mask(drv_stat));
+               qc->err_mask |= ac_err_mask(drv_stat);
+               ata_qc_complete(qc);
                break;
        }
 
@@ -3446,15 +3500,10 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
        return qc;
 }
 
-int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
-{
-       return 0;
-}
-
 static void __ata_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       unsigned int tag, do_clear = 0;
+       unsigned int tag;
 
        qc->flags = 0;
        tag = qc->tag;
@@ -3462,17 +3511,8 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
                if (tag == ap->active_tag)
                        ap->active_tag = ATA_TAG_POISON;
                qc->tag = ATA_TAG_POISON;
-               do_clear = 1;
-       }
-
-       if (qc->waiting) {
-               struct completion *waiting = qc->waiting;
-               qc->waiting = NULL;
-               complete(waiting);
-       }
-
-       if (likely(do_clear))
                clear_bit(tag, &ap->qactive);
+       }
 }
 
 /**
@@ -3488,7 +3528,6 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
 void ata_qc_free(struct ata_queued_cmd *qc)
 {
        assert(qc != NULL);     /* ata_qc_from_tag _might_ return NULL */
-       assert(qc->waiting == NULL);    /* nothing should be waiting */
 
        __ata_qc_complete(qc);
 }
@@ -3505,7 +3544,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
  *     spin_lock_irqsave(host_set lock)
  */
 
-void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_qc_complete(struct ata_queued_cmd *qc)
 {
        int rc;
 
@@ -3522,7 +3561,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
        qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
        /* call completion callback */
-       rc = qc->complete_fn(qc, err_mask);
+       rc = qc->complete_fn(qc);
 
        /* if callback indicates not to complete command (non-zero),
         * return immediately
@@ -3960,7 +3999,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
                ap->ops->irq_clear(ap);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, ac_err_mask(status));
+               qc->err_mask |= ac_err_mask(status);
+               ata_qc_complete(qc);
                break;
 
        default:
@@ -4054,13 +4094,17 @@ static void atapi_packet_task(void *_data)
 
        /* sleep-wait for BSY to clear */
        DPRINTK("busy wait\n");
-       if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
-               goto err_out_status;
+       if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
+               qc->err_mask |= AC_ERR_ATA_BUS;
+               goto err_out;
+       }
 
        /* make sure DRQ is set */
        status = ata_chk_status(ap);
-       if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)
+       if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
+               qc->err_mask |= AC_ERR_ATA_BUS;
                goto err_out;
+       }
 
        /* send SCSI cdb */
        DPRINTK("send cdb\n");
@@ -4092,10 +4136,8 @@ static void atapi_packet_task(void *_data)
 
        return;
 
-err_out_status:
-       status = ata_chk_status(ap);
 err_out:
-       ata_poll_qc_complete(qc, __ac_err_mask(status));
+       ata_poll_qc_complete(qc);
 }
 
 
index 2282c04fee4635097c0f3566f4251e6bd7cc5238..e0439be4b5731fd2b8390c479f0c756043030af7 100644 (file)
@@ -418,7 +418,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
        int i;
 
        /* Based on the 3ware driver translation table */
-       static unsigned char sense_table[][4] = {
+       static const unsigned char sense_table[][4] = {
                /* BBD|ECC|ID|MAR */
                {0xd1,          ABORTED_COMMAND, 0x00, 0x00},   // Device busy                  Aborted command
                /* BBD|ECC|ID */
@@ -449,7 +449,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
                {0x80,          MEDIUM_ERROR, 0x11, 0x04},      // Block marked bad               Medium error, unrecovered read error
                {0xFF, 0xFF, 0xFF, 0xFF}, // END mark
        };
-       static unsigned char stat_table[][4] = {
+       static const unsigned char stat_table[][4] = {
                /* Must be first because BUSY means no other bits valid */
                {0x80,          ABORTED_COMMAND, 0x47, 0x00},   // Busy, fake parity for now
                {0x20,          HARDWARE_ERROR,  0x00, 0x00},   // Device fault
@@ -1203,12 +1203,11 @@ nothing_to_do:
        return 1;
 }
 
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
-                               unsigned int err_mask)
+static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *cmd = qc->scsicmd;
        u8 *cdb = cmd->cmnd;
-       int need_sense = (err_mask != 0);
+       int need_sense = (qc->err_mask != 0);
 
        /* For ATA pass thru (SAT) commands, generate a sense block if
         * user mandated it or if there's an error.  Note that if we
@@ -1532,7 +1531,7 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
        return 0;
 }
 
-static const char *inq_83_str = "Linux ATA-SCSI simulator";
+static const char * const inq_83_str = "Linux ATA-SCSI simulator";
 
 /**
  *     ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
@@ -1955,9 +1954,9 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
        done(cmd);
 }
 
-static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask)
+static int atapi_sense_complete(struct ata_queued_cmd *qc)
 {
-       if (err_mask && ((err_mask & AC_ERR_DEV) == 0))
+       if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
                /* FIXME: not quite right; we don't want the
                 * translation of taskfile registers into
                 * a sense descriptors, since that's only
@@ -2015,15 +2014,18 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
 
        qc->complete_fn = atapi_sense_complete;
 
-       if (ata_qc_issue(qc))
-               ata_qc_complete(qc, AC_ERR_OTHER);
+       if (ata_qc_issue(qc)) {
+               qc->err_mask |= AC_ERR_OTHER;
+               ata_qc_complete(qc);
+       }
 
        DPRINTK("EXIT\n");
 }
 
-static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+static int atapi_qc_complete(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *cmd = qc->scsicmd;
+       unsigned int err_mask = qc->err_mask;
 
        VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
 
index 8ebaa694d18e423ba88545127f806d71b781da34..251e53bdc6e03af366fae3c912047b554a4a30b8 100644 (file)
@@ -39,7 +39,6 @@ struct ata_scsi_args {
 
 /* libata-core.c */
 extern int atapi_enabled;
-extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
                                      struct ata_device *dev);
 extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
index 3062b39fbdb97ca7e12e0a66a7af6f43c346cb5b..38ffa8d6e62901ed94231c45c42571750308e107 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 89e8222bc7cc4801ec981ee1c13523957744ce97..5625a8c2a8fde79eaf3620d0ef1857fe2511f5f1 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 d527d05a607fb4c4686d4f26a4ba136139eec65d..f1e708946e66d47a753ac5d9f0081f76c908fd56 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 084e7628ce172dc087a41d35b4d678fd7581f860..ed6c81660e03563f94d7720970086e17dd9af08b 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 bcc29ec126dc1a29761885fe31193f75c1ad29d9..20f1a0713db2dbd7d2210f4f85defa36deadd7c1 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 259eeb161b82ce0e3ac55f706150c653f39a5bbe..a1f751e79405fee9fdc32db86bfc47bd7dcdcd31 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 86c41981188b33b5d3c7a204411d79a52d01dce1..1ea565e0561ffe0432fed2e751a59f21e6ea5d8f 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 07498118359de9f7a02beadc177af154ce4acc07..b7a603a45328f2dd95753f7384f56ef2e1ec7c02 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 507a6af56f42d51ad52687a2f15889aca267729a..fbead786031f9ec948df36249d557d6e646a2d17 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 c63275e66e2e6644c1e187904b4838476eda8e37..9ee8218404c058bc44e40157c891ad6464c2a605 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 e2c08c5d83fb3d75b605d2596152951baa6114e0..7b785ade8b072ed414a15fb7112e012b4edc73d5 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 4f0466fbd5f277045432f13af2657af224c227e5..fa681a934ffe112e1cf3b600aa506e68261b1959 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 578143e93a6f3b6c8afa4d64e1b7cda7e7a05515..4a6feb1e5e3d1249748cff23b770eb86412bb156 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 7363e12663acab0a92711ec59569b7014b0ba456..17419e30ffc87aeabdaa58981334450b680b3dc6 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 4b5d420d2f4d36c017e01a3541d7d277c890f67b..d18a4bc2498c5271be970ed2c9d8d77dee0e6a28 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 644b91bdb0282cfd0269c569fc3bdeaa04719d2f..882fb1a0b57560ca493fc6cc7e16cb2d4e1a0d66 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 243470936fab4e18b1aeab916b023a3040bedb07..32350707b940d93234a2f1f5d337437b40967d3f 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 05c7b83cef0944e0a5dd109c45fca8f337180f4a..6a7bef2e6118e6ddbfcb62ff4b3a6b849b8a49e9 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 f557f17ca00ce76fba678a9ba7028310a31edfa9..e8df0c9ec1e646992c5e3354d04868da4dba2d3f 100644 (file)
@@ -464,14 +464,12 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
                        continue;
                qc = ata_qc_from_tag(ap, ap->active_tag);
                if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
-                       unsigned int err_mask = 0;
-
                        if ((status & (aPERR | aPSD | aUIRQ)))
-                               err_mask = AC_ERR_OTHER;
+                               qc->err_mask |= AC_ERR_OTHER;
                        else if (pp->pkt[0] != cDONE)
-                               err_mask = AC_ERR_OTHER;
+                               qc->err_mask |= AC_ERR_OTHER;
 
-                       ata_qc_complete(qc, err_mask);
+                       ata_qc_complete(qc);
                }
        }
        return handled;
@@ -501,7 +499,8 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
                
                                /* complete taskfile transaction */
                                pp->state = adma_state_idle;
-                               ata_qc_complete(qc, ac_err_mask(status));
+                               qc->err_mask |= ac_err_mask(status);
+                               ata_qc_complete(qc);
                                handled = 1;
                        }
                }
index c1c1c687bcbd2cbf37f60b933c364c0910c688ec..5205c4e7d6fffb84c5608b2d687c195831322694 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 b169687d08ff4d01145a4879f3fdb5f5eb41f18e..40c0de1258897966413cad237debe24377769aa7 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 48e460eef05a8818bd5003323b9d242cde141a6e..2efca52dff50c45629b82c6a9d3c3a2ea137d497 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 7b3efd5312975547ac0e36c3ae971e4018649c36..79d8a914f9d0f4ddb213fd1bd9d5b63f68c39138 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 fedcb0d3fc72a3f08af716db0ee828030907a7f4..bec81adcf4fd7938f07417b39c26ce4c1d921c47 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 c46d2469b85f9e6e22c617fb71ece366de4a4552..7d973bd9022bb84773a11aa490ed39df1608133a 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 c58c9d97b041e4e79121fb940d962d812ea62d40..24304300d7b57b1fa359cd73660636590702e1b4 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 5b1c12041a4fd054ffb00bed6bb9eefda1665930..5ec5f44602ac8ebd7d18aa1865523fc4873233df 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 9321cdf45680cb35c0c92d570c6e7fd3fe77ee3c..b2bf16a9bf4bffd094164a852a39295eb0fbfc10 100644 (file)
@@ -431,7 +431,7 @@ static const struct ata_port_operations mv6_ops = {
        .host_stop              = mv_host_stop,
 };
 
-static struct ata_port_info mv_port_info[] = {
+static const struct ata_port_info mv_port_info[] = {
        {  /* chip_504x */
                .sht            = &mv_sht,
                .host_flags     = MV_COMMON_FLAGS,
@@ -1243,8 +1243,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                                VPRINTK("port %u IRQ found for qc, "
                                        "ata_status 0x%x\n", port,ata_status);
                                /* mark qc status appropriately */
-                               if (!(qc->tf.ctl & ATA_NIEN))
-                                       ata_qc_complete(qc, err_mask);
+                               if (!(qc->tf.ctl & ATA_NIEN)) {
+                                       qc->err_mask |= err_mask;
+                                       ata_qc_complete(qc);
+                               }
                        }
                }
        }
@@ -1865,7 +1867,8 @@ static void mv_eng_timeout(struct ata_port *ap)
                 */
                spin_lock_irqsave(&ap->host_set->lock, flags);
                qc->scsidone = scsi_finish_command;
-               ata_qc_complete(qc, AC_ERR_OTHER);
+               qc->err_mask |= AC_ERR_OTHER;
+               ata_qc_complete(qc);
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        }
 }
index 2691625f9bce0bf2bf85e9670c39070a7b607786..da7fa04b8a7346713ce60895baa79d30fdf777ff 100644 (file)
@@ -161,7 +161,7 @@ static const struct ata_port_operations pdc_pata_ops = {
        .host_stop              = ata_pci_host_stop,
 };
 
-static struct ata_port_info pdc_port_info[] = {
+static const struct ata_port_info pdc_port_info[] = {
        /* board_2037x */
        {
                .sht            = &pdc_ata_sht,
@@ -401,7 +401,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
        case ATA_PROT_NODATA:
                printk(KERN_ERR "ata%u: command timeout\n", ap->id);
                drv_stat = ata_wait_idle(ap);
-               ata_qc_complete(qc, __ac_err_mask(drv_stat));
+               qc->err_mask |= __ac_err_mask(drv_stat);
+               ata_qc_complete(qc);
                break;
 
        default:
@@ -410,7 +411,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
                printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
                       ap->id, qc->tf.command, drv_stat);
 
-               ata_qc_complete(qc, ac_err_mask(drv_stat));
+               qc->err_mask |= ac_err_mask(drv_stat);
+               ata_qc_complete(qc);
                break;
        }
 
@@ -422,21 +424,21 @@ out:
 static inline unsigned int pdc_host_intr( struct ata_port *ap,
                                           struct ata_queued_cmd *qc)
 {
-       unsigned int handled = 0, err_mask = 0;
+       unsigned int handled = 0;
        u32 tmp;
        void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
 
        tmp = readl(mmio);
        if (tmp & PDC_ERR_MASK) {
-               err_mask = AC_ERR_DEV;
+               qc->err_mask |= AC_ERR_DEV;
                pdc_reset_port(ap);
        }
 
        switch (qc->tf.protocol) {
        case ATA_PROT_DMA:
        case ATA_PROT_NODATA:
-               err_mask |= ac_err_mask(ata_wait_idle(ap));
-               ata_qc_complete(qc, err_mask);
+               qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+               ata_qc_complete(qc);
                handled = 1;
                break;
 
@@ -703,7 +705,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                probe_ent->port[3].scr_addr = base + 0x700;
                break;
        case board_2037x:
-                       probe_ent->n_ports = 2;
+               probe_ent->n_ports = 2;
                break;
        case board_20619:
                probe_ent->n_ports = 4;
@@ -713,7 +715,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 
                probe_ent->port[2].scr_addr = base + 0x600;
                probe_ent->port[3].scr_addr = base + 0x700;
-                break;
+               break;
        default:
                BUG();
                break;
index a8987f5ff5ccac5fac723cfc1138fd033bdf8422..de05e2883f9c4273c64948e1c7e4bee67e420086 100644 (file)
@@ -170,7 +170,7 @@ static const struct ata_port_operations qs_ata_ops = {
        .bmdma_status           = qs_bmdma_status,
 };
 
-static struct ata_port_info qs_port_info[] = {
+static const struct ata_port_info qs_port_info[] = {
        /* board_2068_idx */
        {
                .sht            = &qs_ata_sht,
@@ -409,8 +409,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
                                        case 3: /* device error */
                                                pp->state = qs_state_idle;
                                                qs_enter_reg_mode(qc->ap);
-                                               ata_qc_complete(qc,
-                                                       ac_err_mask(sDST));
+                                               qc->err_mask |= ac_err_mask(sDST);
+                                               ata_qc_complete(qc);
                                                break;
                                        default:
                                                break;
@@ -447,7 +447,8 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
 
                                /* complete taskfile transaction */
                                pp->state = qs_state_idle;
-                               ata_qc_complete(qc, ac_err_mask(status));
+                               qc->err_mask |= ac_err_mask(status);
+                               ata_qc_complete(qc);
                                handled = 1;
                        }
                }
index 36091868560dca76686d1e4a32aa7b5af78d0263..d2053487c73b985efbd6fa1b44e70a60a246ce57 100644 (file)
@@ -176,7 +176,7 @@ static const struct ata_port_operations sil_ops = {
        .host_stop              = ata_pci_host_stop,
 };
 
-static struct ata_port_info sil_port_info[] = {
+static const struct ata_port_info sil_port_info[] = {
        /* sil_3112 */
        {
                .sht            = &sil_sht,
index e0d6f194f54f50217b047083300c32133b35e18e..a0ad3ed2200a8dd55db0a47605e5fae84c882116 100644 (file)
@@ -654,7 +654,8 @@ static void sil24_eng_timeout(struct ata_port *ap)
         */
        printk(KERN_ERR "ata%u: command timeout\n", ap->id);
        qc->scsidone = scsi_finish_command;
-       ata_qc_complete(qc, AC_ERR_OTHER);
+       qc->err_mask |= AC_ERR_OTHER;
+       ata_qc_complete(qc);
 
        sil24_reset_controller(ap);
 }
@@ -711,8 +712,10 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
                sil24_reset_controller(ap);
        }
 
-       if (qc)
-               ata_qc_complete(qc, err_mask);
+       if (qc) {
+               qc->err_mask |= err_mask;
+               ata_qc_complete(qc);
+       }
 }
 
 static inline void sil24_host_intr(struct ata_port *ap)
@@ -734,8 +737,10 @@ static inline void sil24_host_intr(struct ata_port *ap)
                 */
                sil24_update_tf(ap);
 
-               if (qc)
-                       ata_qc_complete(qc, ac_err_mask(pp->tf.command));
+               if (qc) {
+                       qc->err_mask |= ac_err_mask(pp->tf.command);
+                       ata_qc_complete(qc);
+               }
        } else
                sil24_error_intr(ap, slot_stat);
 }
index ac7b0d819ebc910a2325b756a24d3525da7b3a4b..94b253b80da851860ccd3235551dcb7fe88fc1d9 100644 (file)
@@ -215,7 +215,7 @@ static const struct ata_port_operations pdc_20621_ops = {
        .host_stop              = pdc20621_host_stop,
 };
 
-static struct ata_port_info pdc_port_info[] = {
+static const struct ata_port_info pdc_port_info[] = {
        /* board_20621 */
        {
                .sht            = &pdc_sata_sht,
@@ -719,7 +719,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
                        VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
                                readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
                        /* get drive status; clear intr; complete txn */
-                       ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+                       qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+                       ata_qc_complete(qc);
                        pdc20621_pop_hdma(qc);
                }
 
@@ -757,7 +758,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
                        VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
                                readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
                        /* get drive status; clear intr; complete txn */
-                       ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+                       qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+                       ata_qc_complete(qc);
                        pdc20621_pop_hdma(qc);
                }
                handled = 1;
@@ -767,7 +769,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
 
                status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
                DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
-               ata_qc_complete(qc, ac_err_mask(status));
+               qc->err_mask |= ac_err_mask(status);
+               ata_qc_complete(qc);
                handled = 1;
 
        } else {
@@ -882,7 +885,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
        case ATA_PROT_DMA:
        case ATA_PROT_NODATA:
                printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-               ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap)));
+               qc->err_mask |= __ac_err_mask(ata_wait_idle(ap));
+               ata_qc_complete(qc);
                break;
 
        default:
@@ -891,7 +895,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
                printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
                       ap->id, qc->tf.command, drv_stat);
 
-               ata_qc_complete(qc, ac_err_mask(drv_stat));
+               qc->err_mask |= ac_err_mask(drv_stat);
+               ata_qc_complete(qc);
                break;
        }
 
index e69477d1889bd8e6ab67f862f99d9c3ccc8de7af..f01ec0a7c506f2a68ec8fc993ec643a58d47f1fa 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 c0ae9e965f6f26f71d591456280fbb4dad11a912..a2333d2c7af0be4712651b2780b7cc10566dab3b 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 dc249cb970ea49589d5f351585695a560a437c0b..a7f3f0c84db75537a7cc06d6c7275cef01880874 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 d632d9e1493cb1fe83b9e1171fd9e9a1fba875d3..f04e7e11f57a884ac08766e670aa82a81c8d5125 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 4e6709f448e198b6299204730c0771a03cf7a064..05ebb9cef961534abd81120d8cc8c3422fc5cead 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 46349293de088603099405b48884fe505f665188..15842b1f0f4a3499f20a06f6529fa5e38e4ca917 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 2a1a99a2ef5633fbffe80cd214d160a18063c6fa..685b997306cfcd4ca8758621e6e815d9d17da01c 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 38a53b5f9e9a53e8cbc06a545f87070e4989a248..46da6fe10ad54d1d25dc1784071365d8fe288287 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 03fcbab30033976abcd4d21f5a2bde5016510ecd..3d3ad7d1b779687046c741f799524a7f91b36aa1 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 b55c2a8a547cdc852174b27d68d4c486b39b5a98..221e96e2620a66f3b9cb264e9c387c85f9ef7add 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 fb4012b5c1884b8117a0b2155dd634879352acd7..a4d9be7c6874b471db06fe4a02503db46eb246bb 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 78274dc91f5c74c0320702735856d90b4390968c..9dde8df2f5c9feccf5d3ae98daad805b37bcecd3 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 dd592f6a252962cb42f00f09ef5342651985f294..c4aade8f5345a34f949434df43f20fa847b139d1 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 790acac160bcb33b8bfb2426b2e147f09814563e..411209048d74ba7ccadcf3da0bf0df3de81e48e6 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 c041bfd56e12c4cc87ed3e906bbbdc7460528274..25cced91c8a63c0e3b85ad4e062e71be27f07eaa 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 2d9437d7242bbd674ef646b62b76f315b3b116fa..3659dd7b9d760e9a0917a37e083ce3e84097e22d 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 fd36cf9858cbb0e2cf48816fcea6aa43b0b86dbb..9916a2a22558c992644505ff9b2ae193e0162c15 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 43f6810a4045191f17aa6ce4374ac696517b7de4..66ec35beab5baf1dbe9ca57653ef2856758bd1fa 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 cdd92d82f4b26b4810ac315ff26e4b3817cb88fb..7b39f4a35e9885eb2b0ad219659985524c749731 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 7ea7151f5d1ddfbe352093dbb0d98163bbf12df8..851f2706f220942c417041eaa1f1589b24d8d353 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 7fc0b97173e1ec396e2a215391d031717b62502e..1fffd2b3c654d93da2ef9f49d1b4ac929dd3d5a0 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 d3d52f14d7c01d55b2c663ae8ec8d9672e2e3bdc..cc92d0c70cd710ed2ea42c94f54beb38d5d96aa9 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 1564ca203a3e6b0d62217fd4a8c2529689215eeb..8260f040d39c8ea82ba2eeb84cb810de062b132a 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 3a264a40821646c4db6cf9f965d7374944301afd..2456090bb2411734b908bcb7a63fc6700899774d 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 a34d403ccc6c4e170b143e8937c9f18bdd038a6f..92bf9b14a7a2bb98fdd0cc772d7496f86dc77637 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 994b7566bcac8ba175646ced2a981c228d59fbf1..15d69298ab6ec9668e14bc83a091c15eb17e53f1 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 1538bede52773ad2f1e6fb3662c8bd6012766d8a..bdfbbb083b69f5738231348771c4b0cf0bd6a9f2 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 a50c2bc506f245d34bb0785d81cf3856151bd65e..3639c3f8d3578f0fdb9fa5841ed04a410f379b99 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 f429862e0974b2d7e3f1285daefa5d77d219f606..550ddfa71a4378d5f653a1cc885f01c0cf507aac 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 85099718c6837d96ccafe58035613a73aa6d02bb..4c4a776ab1cd3ba3022d6e4574e1f88d450ff549 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 9d59dc62e6d2271c61773651c5163559bdb64a7b..af0a41e7870e0955eaf04e4e63608be04150982d 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 d0cbbb7f0385df42d3152646b51cfbedf1667d3f..b28336148658f6ba453b0b6454876bfe1d064323 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 2e6593e6c1bd66223ef57293a013ae8be5962395..9baa6296fc95de6992a7795c948e5cf8b190f8c5 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 7fe7fb484d1048b3be77508072ed4d1dcc903a93..5c76e3aaaa5e9aaa290936da377ed574011500c4 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 50858273f8d3e980ea1651f6b47b51ff2656623c..3ad9ee8b84a9bdb05d15d94c21d12fad90f9dee4 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 1b4751412970fe2cb4ff7674997217199b632156..248279e44c99d57c969a8ef03057b850da0cfb57 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 963a5dfd209670a8d93dcc1825d24eb600af6da8..fd2aaccdcbac7a4d04cc65f74743ea92541299fe 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 5f8af35e763306ee3d2778b0a4faf8459b8af931..f13f004d311f674b545af196ab0e7d0571050b77 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 357e75335f17d87396c88dfcb729899176ae2a49..dba4cc0260770ebf8d6c39963cd8345c80a98b2a 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1999 Michael Gee      <michael@linuxspecific.com>
  * Copyright (c) 1999 Pavel Machek     <pavel@suse.cz>
- * Copyright (c) 2000 Randy Dunlap     <rddunlap@osdl.org>
+ * Copyright (c) 2000 Randy Dunlap     <rdunlap@xenotime.net>
  * Copyright (c) 2000 Vojtech Pavlik   <vojtech@suse.cz>
  # Copyright (c) 2001 Pete Zaitcev     <zaitcev@redhat.com>
  # Copyright (c) 2001 David Paschal    <paschal@rcsis.com>
@@ -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 86d5c380892d08efc4eb556031ddb3afe038ba03..28329ddf187c2f57cefee9e03395f1ee8912e707 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 419c9943a7cbde9428aef14df1f266bd7e32c142..ad742cec94fa09d1e8b5f5b1b9f0cf249b9e9e57 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 83e815d3cd52e088cae80a38a51fc0213535ab32..2684e15b813b6cde3001c660aaeff7e8f097b04d 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 b1d6e9af732d743d741ccc3b4d4c013fc74b2dc0..2b68998fe4b34fd0809f1dab9b4f078f7243306f 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 da24c31ee00d97138d5db16d8e575b013a5056ff..0018bbc4de3414bae4bd447e619b169239e593fc 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 c8a1b350e2cf045ee71585d1b12a5ff8fe396186..591b5aad1a18a018719b7a977ab3f43fe7184b8a 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 f78bd124d2906e57b099b5910428f9a15e3b8170..650d5ee5871b2f1e6c3f8d7f628c11cd91bed2b1 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 bf23f8978024b146c755dc3bb125c4f8947a5b87..29d5f45a8456369f39dd1ed79d8853b40a5cefa7 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 fe74f99ca5f4bb8dc5f981cce78e86115702c3d2..319de03944e7a39d9d0bac12a46afc4f8c32a023 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 e80ef946782559e4bd2f6f83f27b2d10a9463a84..56a3520863a969f366a1be30ea7c0618317de4a4 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 1c4a68499dce53cd060b27deb0d05c6658a01a04..4647e1ebc68d08fcfadae61bd9e0f4310c23abc0 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 c655d46c8aed5ef7c0cd31510155613985c40a86..9734cb76dd6c24ff499204aa7ff5c60ecae7865f 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 ea09aaa3cab69370d87ed49d5b9c2acc58eb4f35..0cea9782d7d428ed07fd34018e5df98e4fe6e9c1 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 b35ac6d334f8e3aa5246c5d4d1e832349ce02994..65e084a2c87e13804d4a83c16bf8c0564bd26743 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 58321d3f314cffaeb5f6a7404dd9db5fce34de01..e3020f4b17be9a4ea8572768d234ac9301da33f3 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 29f52a44b92801248624dc6a70be09d76cbb924d..9dd3d14c64f3cd6c04a4cb908b9a0ae618c81f86 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 82caf336e9b6491e5c56b9579303881c8d24e6b6..69b0b9be7a641fbdd670bb19683e684b7fe45db0 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 13f73a836e455033c002c49d6efea2219262ac3d..08ca0f849dab03ddbf9688aeb1e77dd811dbf8c6 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 bf03ec0d8ee2222038ee0d928ef61feac9ea94fd..9b13bf2fa98d2c3bab626642a1ea925e183ed9e9 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 82f64986bc2269c2a185bfb1d05169ff9479d0a4..584b8dc65119f80187efc3aa2368125bfba870f4 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 c6fec96785fefa2a27e7076468a177a3b28fdb12..a1b7c3813d3a955321d08961b0a5fc98faecbff4 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 bf1d9abc07ac37a87d18a3422aaeb23980e880e5..a4b12404ae085ed0cfb405c4d9958e2e647e60e1 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 72e3b12a19268c937434b933245d6ad7d014c518..4b2226d77b342dd68082733a2aac20e41be25fa9 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 9d65ec30799012730f8f939f6996e9904477250d..acde8868da21f959cf36a9ea28df3901434ade18 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 e46528c825bfdc5183914a552a202d3c99999bc1..3ef2c0cdf1db2fe26c6235ea3410a36e543be617 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 a7722a6a5a5b40cf7bf18dbd4fbfb75e4b15fe33..517360b77d8e68521995655d7c53c5dc2a7e59ee 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 e73faf831b24bce4c1a0a16a9b017cdaae274f16..5056b7459994d6c891297f8d45f946802aa4fc84 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 151154df37fa105bf62038b9e4e9c8ee1f03d7bf..5832953086f81987adb5b5566d51e51ce78b3015 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 79efaf7d86a398a9806b44efb8e12097c8cff501..dfe121d3588723b87bcfd891bcc9c908ff364392 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 e576db57a926f3b6152b59e60b6b3df152263f4b..8b4b887a7d417715fe73edcfd3f223a26f2d8638 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 7e46887d9e126cee73feb311db535b03d92f8e6f..b6076004a4374d54c3ae641a5f606e8a0c0da529 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 1d973bcf56aa983659938665573ca51c5be60100..049871145d63735bd1fff17ee55dcc23a4ffd826 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 950543aa5ac72a6c10f593136e6179c8ec053308..458f2acdeb0a5695a2754edb45a8e3a28c9ae32d 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 1e53934907c089b0067d13142e4c4356ee9ff3cc..509dd0a04c54f5e8e5bf9d4164a635133095c9ce 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 07cb17db42fc1eb8d473649f45873f43d9d821b5..d512d9f488fe6aa7528f00e498af073d404d61d7 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 a32558b4048e5a98b0c698e18dd12abac43500eb..df29b8078b54b4e8452029d0e0c533359d4c8908 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 0e2505c073db31d559039e884c2190f8c939fbae..a6693b0d1c4cc92c20b04957c9630bac3a8224f5 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 15840db092a5125ce5c8db20a5106428155e22e9..1949b54f41f2500abfdd24372fb5ea19e37df0f7 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 9a2a47db9494d62e595865ac02038e6ce9a04320..f7bdc506e6132785a100f557635c7f665adc7c29 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 26ca5b890a610e5e7c396df218098638060fb983..b44d398de0714fb62533a0ac00df9ecbbbeb85eb 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 a3e44ef1df435684b121cfd110bd2e62463921aa..5f52979af1c736905ba0ed08f52dab03135a5d76 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 1220a5004a5c160e12d417ce840564baa5ff2b84..192a03b2897145ba00155ebe8d5e74f887ae2cdd 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 440377c7a0da733db0932bf15230b73e9f733ef0..4dff8473553dd9fc8eba3ebe33378741c8bc7898 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 4a50acb39d29acd9ebcdb470f482e402027719ac..7618ae5c104f7d7c999b4d37a51498e2358f80fc 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 fd48e74e78ed362bc158c2561bbb3dec07cd4b14..f6d5cead542bd734de71e58a1f0a0f5914697135 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 a32cfe51b77de11236b98199ba00461784f479d6..b4a051b549d1543d36c6883f83aa21e7ef2cc991 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 52cc18cd247d63e25f773c028813391410848a11..f018953a5485238e088ad1b9483177b077d3ae2b 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 b7476233ef5d46bc8a3b1d5ca73192e66a267e61..fdf0f788062c3fadd64d520db8854cac1e6c0084 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 7420c6b84284d34cfbad641216ce056d49f852aa..3b3c7b4120a26c51fb8e8af875f75aa02a201242 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 226b6f90a9072b2d95ea8315a821822c73363939..2f3edc26cb5057f2da7eba68e06b1482eb246b30 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 230f6b1b314a0019a153b526b973409513fab999..af526135d210752c09e346566c909fe046322c67 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 dc099bbe12bf2529281a4217eafebbdd8a8d99c3..48df4cfd5a42274b7a756f37ce6869c646a590e3 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 43112f040b6de336bf9b2e3428aa3b49e44c115f..e278489a80c6520941fe30723ea50c305717bd72 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 f526aebea5022526471d374313f182450e7f863b..1bfc105ad4d6811adda2d403870b591bb33c8a6b 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 27b23c55bbc70232023bd6f835ce5a8d736c6c8d..18d8eaf408d502224a00b37599b6dba5e335a58d 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 7503f5b96f59c2134d63feebf829ce4a752518f0..6a5700e9d4280eb7575426be882920953f1705dd 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 ba41fc7b95c2168c7314b0d04f4d4f4177e9b9e5..a42c222941245b16088a8e45341e3e4cad7104be 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 9fe2c2710d13d52ffe09e3ea2fafa7949e271772..e2ede583518f5acb41f23a540c3816f8639914cc 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 036c485d1d1eeb6ef582930f9f9356cc858f943e..3a0e8ce67ebedc10c22b38a224db5b3fcad63fc1 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 53099190952ce022338b7fad0df8c82c941bcbcd..359c4b2df735917ff685920f160a1fa7ee1c7476 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 5524fd70210b3dc984b1160dd7a9a19249280404..09ca6128ac209a213ca76e2c656d1daca2d662ac 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 f69e443cd1bcda63b6c4e4eb6396676f85a3124e..b2ae29af59404f89434b7e5d7f1f2d7cd229d7cc 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 b2e66e3b90aa4e6453b756affbddd82cb5bbb854..8d1a1c357d5a6d7c01b39fc7b53036a5780f218a 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 0fd0fa9fec21f172d703f16fed7e34b246ed35a8..774038b352cd1e7644eb42c97fc0cbe9e877fc89 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 4459406126036675c89ec2405d5feb64e5af59ad..b0551cdb280b236542735ce94e4a2fa85696501c 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 24efb21969c6ce34d15490bb70c576b5879ce7a2..4bd113325ef9b1441d7b244a7cb2ea8b106a69e1 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 0bc0b1247a6bc69f4a6ce2fdf5c86a04b0509014..1c73155c8d772cda08a5ca0934021161488563bd 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 67612c81cb9fda53cc2313d3cde8a7b8cb410246..04d69339c05442fe16d3af4d810271a3def209a7 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 b293db3c28c3728eec1fbb4fe949ccf30d32ef1a..449b2501acf365ac0b105c0bfd4d15b0fa4bf8d5 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 b33044d56a1eaba415fbe8fc6a21537b14119229..6671317b495f4c996319463fd29796ae92a5b99e 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 c8155209bf4b4dc07d1c4560c1ea3ac2643e6167..3824df33094e237d10a26058ebb91945f7ba2bad 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 189986af2ac7db3c30e76be6055dbcfeea1f8d85..52fea2e08db87358f0d1073dfba5e2bc555b323b 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 1dc3e0f73014eeb5efad58cb58193972738ed98e..d8cde1017985af8705868a23abcf3ca32cfa9f88 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 7e93ac96490f6176bfb143b99f7f15a9431fd00e..981d8a5fbfd9e9dd1a361e6939839d1cc629baaa 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 2703e205bc8fd5d307efe2a3096fce34cc39ce4b..1336745b8f553e7b130fac742456111163529c54 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 067a81486921d1a393170ddf1f64a32033e73bd5..605a3c87e05c2ef106e0a156a06fc8480b1f857d 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 a30d4a6ee8240237943f5ad009582ebc3a490150..b3418d2bcc699257e68698703e544d5a5a844bde 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 9590dbac5d9a55e78c268d77fdd87e65fa727aa5..384fa37698050bea738eaa3a37f4cf8428583677 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 41ef2b606751fc38c034ba8906809170fe78d9ec..3260d595441f5837323539b8add11ac5c997e28b 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 85f3725334b017a48c8ca5c0129becf0f97d8add..cc3dae3f34e0361ae6b0b70a7b574d3eaf929fce 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 3c93921cb6b38e59a8d00ff9b20929feac98a06e..877b081a3a6e9edb708b0ec0cac27fe796136ebc 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 605a2afe34ed614d485aea86195ef7550b073a31..84fa1728f052969d527ded2e85ffa31e78810784 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 1cabe7ed91f5a90386af744b3e757d3e8d15db6f..4081990b7d1a97626bb937fa6ae03f8f3dcf9e4d 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 17d0190ef64ecce708999654a8e278c96d6a3558..611612146ae976ef4a2a48799d8da4db2969b1e8 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 542120ef1fd2891015255212e4df7be1c507449c..541181695040b865ec73fae31b2c8616c0875d38 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 37ef365a2472323a190dc6e4d692558889418cae..be5f5e142dd0d9427d14c82eca0b51ea56e23aba 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 c008c981862bfad424f70b7f33e2ff4703332454..63f1f3ba8e0b3576f2cee0918f369c433f9d8dc6 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 f05cfb83c82d99b57d76123dc3da2d2f95d0a0c9..ec801e8bb1bba093142449e956393e29f67bfe86 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 2455e9a85674584c976db10942e35577c7e1cd31..faf1e86be687db900e4aeb15965ca52b012971d3 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 b5776518020f13dc0bfd680f2788900ecf3ede05..def3bb8e22901509bf35b618d14fb3402f8a2f43 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 b3799b1a2b0d56910ab38f2633f64ea477d2ba18..78e6a43b1087037e81bdbb74b2489b590676ccdc 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 683e3df5d607de3c191f60d04562fcebb5ff030e..156a2f1cb39ae5869a67fab648038b45065fc132 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 89856aa0e3b8c5c5e4bd7f684ac035e66e68a56e..4fe863389cb76a522cb3a8437495efd521329664 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 c0ecbab6f6ba0d311ca26d84a74896e22da7b5c8..49991ac1bf3b843420543013c14df70dea443526 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 787dd3591d6a214efb038fc0d3a053fd06e8d864..8ca52be23976a93406b21ec99e45f4ef7ce0140a 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 680d13957af4b27e8ffed4858eafbf8021ae861a..9c5ab251370c5b78e578b24e0d1aaafbe0d61744 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 2f52261c7cc13eb0e23dd7f8430dfe9df3fe4b9f..f3a8e2807c3b8afd87d605e12ff50849d1adcb28 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 1f29d883732720602336e341fd3cb2490f084cfe..dbf1f063098c58f7c6424bff49e4d8e56a34034b 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 18022a74a3dc72f4606f0c2af472520187e4b333..343f6f22822043c954cdeca1915d0b746152049a 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 84bc0ee4f0616c890a687259fea73939413589ff..4144777ea18b29fc6bf9adbcb3dc667093b2ecb2 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 c9787001cf2a1e97ced97d799fe902d83256b469..da46b351e188eed017254eb28dad90fb4d0cb4fa 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 e581e4ae84830d82ac65f973c4fb1c781665fa21..6d18d4eaba358b94e3f73e75fd2bfc8f1963fc96 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 af9290ed257bc17b3a5f1762ee1bd0411acb8745..af18355e94cc3fcc3e98bc684a18f191a712f24c 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 dc74644a603d6b72b051cd8387abe588515e43ae..8fc414bd5b24ba1bc7c6db856df06f8704470853 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 0b0546dcc7b9346a72c5ba0388dfefd064f61908..79a766e9ca23170160c69f182f1cd69e28d313c2 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 06e04b442ff1e9fa9f16fe63df3915a81e874a92..eb863b3f2d7950d3880ed78472328631ffda9bcd 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 773ea3eca086821e51aeab56a9685a0779d48327..00d45f8600deeccccfa398bd79606f9168ec6296 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 */
@@ -714,7 +727,7 @@ typedef enum {
  */
 
 /* FTDI_SIO_GET_MODEM_STATUS */
-/* Retreive the current value of the modem status register */
+/* Retrieve the current value of the modem status register */
 
 #define FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE 0xc0
 #define FTDI_SIO_GET_MODEM_STATUS_REQUEST FTDI_SIO_GET_MODEM_STATUS
index 35820bda7ae19bfe56b1d33528558f653cafde82..452efce72714aae72aedc2426d6a50a4b9dfabe5 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 53a47c31cd0ea32f6e2985e85fcb0304d0a49820..4ddac620fc0cbc23c8b8c44c5fcf4f11e8f114dc 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 8eadfb70560132a5224567be0804fdacd4d03385..e9719da2aca1ed2700e8b57467b9e9a672553e45 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 dc4c498bd1eded80f10e15bf7dbdf7753787bfe8..faedbeb6ba49a1a958f03cb182cb3780b7d71296 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 5112d7aac05506d6822c9b0b053d8592226d350b..123fa8a904e65a15a9c7a5eb7b0a44dc07e043e7 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 c7c3a3c305feae0bd7dcbb5bf4b1b8aaf7eae29f..e3463de99de41fc8f4fc47b38d097052fd46d9cc 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 832b6d6734c0f6c1886f2e8ad365234e32dab31c..2edf9cabad201d739e1209130af7c4df60e6e2dc 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 d5d066488100202b88afe7f7e441a4db0adb50ff..06d07cea0b70a3a4a0a09f6265a247b4550e8013 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 7744b8148bc5618fb626b2ddb93c59082bed7c75..2dd191f5fe766962e37e9a0a5971334b216e7d1c 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 19f329e9bdcf5afb161dc17e8512a433945b09d3..a59010421444b9419bd0e3990f87cf8b2dd9edf5 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 5cfc13b5e56f59aecdc14191577aef116a572b70..7472ed6bf62653dd581af8d3eb8333b17be13e13 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 cd4f48bd83b614552372d2c5669aa275ba55ccd0..b0441c35f98fcc8b708e5569623017b931be9b54 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 a8951c0fd0209bdffc6d585715d3f58771a554f7..4e2f7dfb58b260960c9fd8658cca09a4459d39e0 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 9456dd9dd13672047beb7d63cbec7ebdd37cfee5..d9c21e275130a59a76bdc89a9de7ae3bf35280c9 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 ca5dbadb9b7e821c73b4d0fa62ba7435439cf96c..b6d6cab9c85911831fd046d8926f8e0cbf1df084 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 3caf97072ac014947cd036380f1a82ec8e824497..762d8ff9a1e4f808069cbd40dae6128d5f5e1521 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 7716000045b73dd632d41f1104c9696b8d715077..3fd2405304fdc156c588772b692962057f849d29 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 41a45a5025b21275c818819ef77895468eba91fd..f037210561905ecd1149e31570a98a112f26dc27 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 c22bdc0c4dfde9b02cdc13b490a0d7d6b3b1a446..f0215f850d2d3eea98faf2b6569075f596aec3cd 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 205dbf7201daa27f0fb366195d22798ff7d31fb5..abb830cb77bd926365d20c67ed5516b2d11d0b49 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 0c4881d18cd59b0c30f63b4a3401da3eb3813623..8bc8337c99c454f0db72816fbee43eec29475c3d 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 238a5a871ed665cd9ecd6a2f415c2314d9ead4e6..d7d27c3385b384ea090a033ebd6da14dc0512038 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 a473c1c345593453b6a1775a960f0e477c013197..49b1fbe61f25e446a60b8ecf8a8bc09780aeeb5d 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 18c3183be769d3bea41cafce1e7b226bb29325b9..a7c3c4734d839ea83d8195374f81361e71ced15b 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 c41d64dbb0f0ec39d50901ffe771715b31a62a48..92be101feba70882baea621b27adde4df0f153b5 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 44ab8f9978fe9d3a44fd2675674f3395ac8949b0..8cbba22508a47d77d3a39897d4138e7be5a7f7ae 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 5a9321705a7426000e1197813c35b54123c85f70..01e430654a131a5a353afd09c8639f6ddeb6cedb 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 7372386f33d5958298f1f868684ea918e81c07ab..4c1b2bd2e2e41edcc0378b2a8b8aadf90efe7319 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 89401a59f95273cc904688098c9179d082e78658..55ee2d36d585824a589113e29cea2f0e94a1bebc 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 02bff01ab09c3721783242dec9dd9b279b808347..845bed4b80317fb336cbe14ca227f8fa41907a17 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 0ea2f5ab66ba206a5d2113ebcecded8f34c207ef..fb8bacaae27cbcb5eaaf6f845fc5e10dc8ddaa7f 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 c9d78d6188b1b33ce9c21d22777e845e22047772..c03089a9ec3899b33e6582852b41e6bcd4127488 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 0a362cc781ad48676063d7b4b88dc0d2d90fc3bf..633a715850a43fe6f7654ee7cb659575b51c4acd 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 f5f47a34b1683980c1aba2076ef6a7b5bd4ed9c1..dc301e567cfc6c6ec5037b7ff26246d72276e09b 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 3847ebed2aa439792bbcd7c69dacdf47654fe1ae..dbcf23980ff13f3f305857b78f297c1838940d69 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 98b09711a73957a8b02a32dccaf6d1c13312825c..7259fd1f6b0d2672a10567d41a3037b741903dda 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 6c3a53f8f26c6fcb0456c846d012a9f5989cddc8..5d02f16b7d0e7b007720486d7f2722b37f58f85e 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 4f01ccc02aa4c47750a22a5d338641aa86442b3e..156db84cb36371aa4709b293b25492e49b71f099 100644 (file)
@@ -594,7 +594,7 @@ static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo)
 }
 
 /*
- * Retreive PLL infos by different means (BIOS, Open Firmware, register probing...)
+ * Retrieve PLL infos by different means (BIOS, Open Firmware, register probing...)
  */
 static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
 {
@@ -660,17 +660,17 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
 
 #ifdef CONFIG_PPC_OF
        /*
-        * Retreive PLL infos from Open Firmware first
+        * Retrieve PLL infos from Open Firmware first
         */
                if (!force_measure_pll && radeon_read_xtal_OF(rinfo) == 0) {
-                       printk(KERN_INFO "radeonfb: Retreived PLL infos from Open Firmware\n");
+                       printk(KERN_INFO "radeonfb: Retrieved PLL infos from Open Firmware\n");
                goto found;
        }
 #endif /* CONFIG_PPC_OF */
 
        /*
         * Check out if we have an X86 which gave us some PLL informations
-        * and if yes, retreive them
+        * and if yes, retrieve them
         */
        if (!force_measure_pll && rinfo->bios_seg) {
                u16 pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30);
@@ -682,7 +682,7 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
                rinfo->pll.ppll_min     = BIOS_IN32(pll_info_block + 0x12);
                rinfo->pll.ppll_max     = BIOS_IN32(pll_info_block + 0x16);
 
-               printk(KERN_INFO "radeonfb: Retreived PLL infos from BIOS\n");
+               printk(KERN_INFO "radeonfb: Retrieved PLL infos from BIOS\n");
                goto found;
        }
 
@@ -691,7 +691,7 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
         * probe them
         */
        if (radeon_probe_pll_params(rinfo) == 0) {
-               printk(KERN_INFO "radeonfb: Retreived PLL infos from registers\n");
+               printk(KERN_INFO "radeonfb: Retrieved PLL infos from registers\n");
                goto found;
        }
 
@@ -702,7 +702,7 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
 
 found:
        /*
-        * Some methods fail to retreive SCLK and MCLK values, we apply default
+        * Some methods fail to retrieve SCLK and MCLK values, we apply default
         * settings in this case (200Mhz). If that really happne often, we could
         * fetch from registers instead...
         */
@@ -2393,7 +2393,7 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
               rinfo->mapped_vram/1024);
 
        /*
-        * Map the BIOS ROM if any and retreive PLL parameters from
+        * Map the BIOS ROM if any and retrieve PLL parameters from
         * the BIOS. We skip that on mobility chips as the real panel
         * values we need aren't in the ROM but in the BIOS image in
         * memory. This is definitely not the best meacnism though,
index 15fb250451e59a0628029819dfebbfc62d7fede9..b9146306df49a94df1b6443baa48a9fb17417ce3 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 a93c2bf94c331a7b20326caa5a36c217fab3f023..6a9a75d40f735c209c4e95aefab71178f07990fd 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 460554b07ff91501739ae7b2f21ea14392ea5e51..38d3e8023a0795273595b46ef8647ebaee9952e6 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 818634120b693c70c4e8fedc85c925e12f5d1482..55ac0324aaf1649f1326994f31267ad90e542063 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 f2ca782aba33d23a52b7c6ff93e3a5c03577beb1..30cae3602867b532773fb6c0074f5663c04d2734 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 50a7749cfca1bc73c0331ca032db93adaf5f348f..02f44094bda9da4d0fc21b8c798243cc29750f05 100644 (file)
@@ -884,7 +884,7 @@ ToDo/Notes:
 
        - Add handling for initialized_size != data_size in compressed files.
        - Reduce function local stack usage from 0x3d4 bytes to just noise in
-         fs/ntfs/upcase.c. (Randy Dunlap <rddunlap@osdl.ord>)
+         fs/ntfs/upcase.c. (Randy Dunlap <rdunlap@xenotime.net>)
        - Remove compiler warnings for newer gcc.
        - Pages are no longer kmapped by mm/filemap.c::generic_file_write()
          around calls to ->{prepare,commit}_write.  Adapt NTFS appropriately
index 991253927658bf2a2673c70c8ec99789f709f59f..46efbf52cbeca2c1962c1222bde634393193206c 100644 (file)
 #include <linux/buffer_head.h>
 #include <linux/bitops.h>
 
+#if 0
 int qnx4_new_block(struct super_block *sb)
 {
        return 0;
 }
+#endif  /*  0  */
 
 static void count_bits(register const char *bmPart, register int size,
                       int *const tf)
index a091ee4f430df6cc83317b59c4a2fc363c005080..df3468a22fea498889a5af4523556439d9f880bf 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 72e120798677a0ff20852c4a528bc8c4c5c9aa12..02091eaac0b45557aa2152cdb56533e3e4191c6d 100644 (file)
@@ -115,8 +115,8 @@ static struct dentry *__get_xa_root(struct super_block *s)
 }
 
 /* Returns the dentry (or NULL) referring to the root of the extended
- * attribute directory tree. If it has already been retreived, it is used.
- * Otherwise, we attempt to retreive it from disk. It may also return
+ * attribute directory tree. If it has already been retrieved, it is used.
+ * Otherwise, we attempt to retrieve it from disk. It may also return
  * a pointer-encoded error.
  */
 static inline struct dentry *get_xa_root(struct super_block *s)
index b9ded26b10a90b49972e3654d15ad198054c5faf..6598a5037ac80c915bcdbf08269e7a855d051686 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *     Block allocation handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index d95c6e38a45591bd8b3dff70aff4ce993c40e8e0..1b82a4adc2f7594ae11cc9151200be3135449f8d 100644 (file)
  *
  *     AT&T gives permission for the free use of the CRC source code.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 82440b731142f0b1ec8d2e2281ca30d0087b9f3f..f5222527fe39fca5cb0d8997c4140ad9959a253b 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Directory handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 9a61ecc5451b07422e6c44563b8c0ac306a1a4d3..fe751a2a0e478d5debb692a7ae23d0c1dc750b6a 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *     Directory related functions
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 01f520c71dc1287102ef44b3fa2884cdeecd1876..8a388289040dbb66de764c8ccc92fdade27253eb 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *  File handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *    linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
index 2dde6b888c2bac2e21d22c590a333ea5648e5b92..5887d78cde431cb05bfb3289b547195ae52421b1 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Fsync handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *      linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
index a7e5d40f1ebc002a354abb68c6a0a89e95594656..c9b707b470ca4433fbb08bb7821d7f78d85343ea 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *     Inode allocation handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index b83890beaaacbec45e199c9cf8fc78599423ff07..4014f17d382e70ddc3662521515347748af01910 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Inode handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *    linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
index 2da5087dfe05e5eac788a9726e4e09c8b942e27c..08421610766737540d96abd8405fec0b14e28aed 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Low Level Device Routines for the UDF filesystem
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index fd321f9ace83a1c7d06ce346f1adf6bded6331d3..cc8ca3254db11f95d669f8b93321f6ee2c61517d 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *     Miscellaneous routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index ac191ed7df0ac74cf57ca06152fd2b5fcd6367f5..ca732e79c48bb60af77c28dfe8f0a4f75b9f64b1 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *      Inode name handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *      E-mail regarding any portion of the Linux UDF file system should be
- *      directed to the development team mailing list (run by majordomo):
- *              linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *      This file is distributed under the terms of the GNU General Public
  *      License (GPL). Copies of the GPL can be obtained from:
index 4d36f264be0d00f05be048a5a4c0d94cd1e35737..dabf2b841db83c1ad00139e7c94054a858caa263 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *      Partition handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *      E-mail regarding any portion of the Linux UDF file system should be
- *      directed to the development team mailing list (run by majordomo):
- *              linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *      This file is distributed under the terms of the GNU General Public
  *      License (GPL). Copies of the GPL can be obtained from:
index 15bd4f24c5b762907d643c231a53e8016d23160b..4a6f49adc609b051b16bea2e5e59d7719b1e5ed7 100644 (file)
  *    http://www.ecma.ch/
  *    http://www.iso.org/
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *       linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
index 43f3051ef756484c58d14b959d42bb26f103b83a..674bb40edc839475cb4bdf5f1fd3b789808ee144 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *     Symlink handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 7dc8a5572ca1900f5ee94db2c9a3695c88a2f909..e1b0e8cfecb4947a120c2c5eeb78848b7604fa32 100644 (file)
@@ -4,11 +4,6 @@
  * PURPOSE
  *     Truncate handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 5a80efd8debc9b7357668743a45411618c6c4d64..706c92e1dcc937f256c022bc0fcf596b020f21c1 100644 (file)
  *     UTF-8 is explained in the IETF RFC XXXX.
  *             ftp://ftp.internic.net/rfc/rfcxxxx.txt
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team's mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 578ed3f1a6071d831248a6164694ac4d1492c712..302201f1a0978b0a0c7db477edb498a7fc57fd9e 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 7399d431edfeeb1a4771833ef3c2e20a85e3a1c0..d02de721ecc185cdcfcbe6f5e707083c477e5413 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 7d062fb2e34380eabfa60394345e7d27df694a34..15cc6f2da792dc7dec67d6698b863bb47750b667 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 1bddb3f3a289eddfa320a4519689c3081d9d1c0e..d3eb0f1e42085c7911aaa6f5d4303d38a78cd022 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 b664bd5b66635a473abb21691502da08c122e4f6..02be7b3a8a83fd3fcd652472a4b3848c45cbd255 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 ce31b739fd80ff211e5583cf4b2c6cc762f6a037..0e6d9852008ca36c4826a27f46b9cc26b303ab62 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 5036f595f8c927d1ebbb167d7e9e8cf93ae84603..c0411ec9d651785200e64d45734983db17d2fcbc 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 ddf1739dc7fd1968954ff0eed7d9053346f1360f..4807aa1d2e3d865fe41c70045da8d4ccd0a4bbfc 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 7232528e2d0c13771f6f62af20de13455aedb30b..36d0fb95ea89dc5113919f03cc0dde9896a6efeb 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 e78443981349df080c2812d82927429f10aa2d85..abea2fdd868971bd1ae499a56e2aa4f58441fbed 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 b1bcf7c66516f78bb4bbc553f0244f7b7535bb63..13f4c00484632b0a396c4b3ecf14e5b40251ca84 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 c42f88a9b9f986d25b3f859d38b9f3794ff17378..4058dd086a029d8a16515f6933fb65eb69ceab90 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 */
diff --git a/include/asm-mips/.gitignore b/include/asm-mips/.gitignore
deleted file mode 100644 (file)
index 4ec57ad..0000000
+++ /dev/null
@@ -1 +0,0 @@
-asm_offsets.h
index 5496f9064a6aa6cab1c4d586606b9b867f3e6326..3b0c8aaf6e8bfaf62ec78fd854fe790a7af3f907 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 55b98c67fd82d60ef49fe64e7892f335082fc4c1..15d8c2b5158408b13588229a0581b0577eae4f7a 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 5727229b0444aee452dd73f79a850d8f18ac89a0..1996eaa8aeae9abe0644277c87e384809d378957 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 b07c578b22ea677d55f9bf147d8791a18c75a20e..61232760cc3bd50e5d5b72248f23d03dd3fdf87a 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 5163d1ff2f1bd365826c4b391859af045dfe96a0..1c526086004543db2afff93f9bed227a1366aecc 100644 (file)
@@ -470,6 +470,7 @@ found_middle:
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* __KERNEL__ */
 
index e1ff63e092276b1daeef1d5e9062a47dd4e96dc9..ce9c3ad45fe027ba8756ba6ab037981313ed347c 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 bfbd795a0a80579e1168dff755de89f837c4a687..41722b5e45ef02da75ec02d35eed5c90ac7f8a91 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 6388b8376c50227bc8609d87a40e52451f74a435..6efc0162fb09b8e2fa6beb9de1eb5ebfc4ffdf15 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 b91e799763fdf4f3896b20abb17563323f717b76..8955d2376ac824e5e3a7bd3e97459b442f206cf7 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 05a0d374404b0fb5ae24cfff181f6cf77aec6a75..a4d5d090945347fd89d70a2c2555bdb7112c7e06 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 e76ee889e21dadf98702fdc1756b540752b1b355..0a2065f1a372dc8619bfa3cbc6924b7b0c8fb2b2 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 685fd3720df5b2105c86d3be588eb9cf0061b360..b60ffe32cd21b34acfeee792d8d5ff3f66f94bd7 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 38c2fb7ebe091bc7c252193a614abca2c5c244bb..6a2a19f14bb26bb3f4f49815b566c2a4e8353cab 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 a33a31e71bbc6cb02acf3409c926137c8664b882..a18500d196e12aa1c0c0c3ba8bdd8d4df6ca2036 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 d068176b7ad7f4d7242e2417f87e3f67043b1d23..c31650df92412de9c6514e81bc5955e8f8a02dcb 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 71fab4311e92624ff985793df2d9c14777b7e46c..088529f549657214b9ce1352b7d2210a2caadaec 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 5f49a30eb6f25d92a5d616e6c0889df7787b0d01..745c988359c0bb29628609062c7d7a59c424ba45 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 e677f73f13dd7f5a6db8455152c7f90faabf8f50..4fab3d0a4bcef5e7d6e0c9047b30b09afdead916 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 33e8a19a1a0fbaec33122f4f931c3d577fc975c9..9e2eb9a602ebdc7154e0ef3a629a9868e219e8c4 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 e0b922785d985e5c2a03598303ad011cb0dbc9d4..93bbed5c6cf426a61683ec8204363f75f67fc08b 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 41ea7dbc175573ac56cbff151f78ab4f27ae0b32..e828e172ccbf1f2d80b6838c43000d0379117abb 100644 (file)
@@ -136,6 +136,8 @@ enum {
        ATA_TMOUT_BOOT_QUICK    = 7 * HZ,       /* hueristic */
        ATA_TMOUT_CDB           = 30 * HZ,
        ATA_TMOUT_CDB_QUICK     = 5 * HZ,
+       ATA_TMOUT_INTERNAL      = 30 * HZ,
+       ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
 
        /* ATA bus states */
        BUS_UNKNOWN             = 0,
@@ -195,7 +197,7 @@ struct ata_port;
 struct ata_queued_cmd;
 
 /* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask);
+typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
 
 struct ata_ioports {
        unsigned long           cmd_addr;
@@ -280,9 +282,9 @@ struct ata_queued_cmd {
        /* DO NOT iterate over __sg manually, use ata_for_each_sg() */
        struct scatterlist      *__sg;
 
-       ata_qc_cb_t             complete_fn;
+       unsigned int            err_mask;
 
-       struct completion       *waiting;
+       ata_qc_cb_t             complete_fn;
 
        void                    *private_data;
 };
@@ -331,8 +333,6 @@ struct ata_port {
 
        u8                      ctl;    /* cache of ATA control register */
        u8                      last_ctl;       /* Cache last written value */
-       unsigned int            bus_state;
-       unsigned int            port_state;
        unsigned int            pio_mask;
        unsigned int            mwdma_mask;
        unsigned int            udma_mask;
@@ -478,7 +478,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 extern u8   ata_bmdma_status(struct ata_port *ap);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask);
+extern void ata_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eng_timeout(struct ata_port *ap);
 extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
                              void (*done)(struct scsi_cmnd *));
@@ -670,6 +670,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
        qc->cursect = qc->cursg = qc->cursg_ofs = 0;
        qc->nsect = 0;
        qc->nbytes = qc->curbytes = 0;
+       qc->err_mask = 0;
 
        ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
 }
index d6a41e6577f61a3b2729247af897532ab3b44ea3..28195a2d8ff0a50501a5ab180ef6bf3b252cbb28 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 936f8b76114ea95901ccb74190f2ebc96fc2a3a7..7fda03d338d1c40a76e2acd6d7a4c80d4910b198 100644 (file)
@@ -684,6 +684,7 @@ extern int          netif_rx(struct sk_buff *skb);
 extern int             netif_rx_ni(struct sk_buff *skb);
 #define HAVE_NETIF_RECEIVE_SKB 1
 extern int             netif_receive_skb(struct sk_buff *skb);
+extern int             dev_valid_name(const char *name);
 extern int             dev_ioctl(unsigned int cmd, void __user *);
 extern int             dev_ethtool(struct ifreq *);
 extern unsigned                dev_get_flags(const struct net_device *);
@@ -801,12 +802,16 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits)
        return (1 << debug_value) - 1;
 }
 
-/* Schedule rx intr now? */
+/* Test if receive needs to be scheduled */
+static inline int __netif_rx_schedule_prep(struct net_device *dev)
+{
+       return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
 
+/* Test if receive needs to be scheduled but only if up */
 static inline int netif_rx_schedule_prep(struct net_device *dev)
 {
-       return netif_running(dev) &&
-               !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
+       return netif_running(dev) && __netif_rx_schedule_prep(dev);
 }
 
 /* Add interface to tail of rx poll list. This assumes that _prep has
index 9093f118f99d0ff809bb8a3ac423f3ffddc82aef..4f01710485cd98fb725704823c980b1eaf771c9a 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 724066778affe84f50bbdf8d6a08a245e26132f4..6351c4055acea365d682d33c89f42b5b8a16b035 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 e87b233615b349a4d982174779eaceaa7c1f127f..d10f35338507021c219bac8ce1d235b8a0c05b30 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 7b2adb3322d5a6052504058e152cc0f94828c06e..5d6456bcdebac8e4099809369407583bf04b8d69 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 f7e0ae018712257a11b67ffa6cd12eafb988c34b..ef753654daa56810568aa73bca8b952c533fd588 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 8c5d6001a923c5042b74dc1a0fc2bf6e30251f9b..483cfc47ec34203535f2fe0f0ed776c95da7c077 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 1739c2d5b95b449669b887aa86aeb324d836c1f2..9f4019156fd8e7045e442df7f7661d7032b0642e 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 0e9682c9def5e0d1a198486435618978829d33ac..799be674794459e9a857a4c7218ad31d0cd05883 100644 (file)
@@ -59,8 +59,7 @@
 /*
  * Must define these before including other files, inline functions need them
  */
-#define LOCK_SECTION_NAME                       \
-        ".text.lock." __stringify(KBUILD_BASENAME)
+#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME
 
 #define LOCK_SECTION_START(extra)               \
         ".subsection 1\n\t"                     \
index 4be34ef8c2f714c56660e19d4f59845123e35750..93fa765e47d30e9f10c7ab05f0954822bac21d49 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 0e1da6602e054c24ee3f27f8dfe8b5d288e00c69..f2bb2396853f5319000e70bcb9bf71784e933c18 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 46e2bb9453539e11ec583fc4a68a1c52bfc1dd5c..36c684e1b11040476fb685d8067a3831a00b4e2d 100644 (file)
  *    http://www.osta.org/ *    http://www.ecma.ch/
  *    http://www.iso.org/
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 62b15a4214e6608b8b5554ae07de8e3677dd3c0b..1e7508420fcfb6fab284ab15203d1cb1670f4ac2 100644 (file)
@@ -3,11 +3,6 @@
  *
  * This file is intended for the Linux kernel/module. 
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index 1966a6dbb4b6f70301470e381d845d7efe4b824e..b15ff2e99c91ff36a9c4a20fc719766914002f77 100644 (file)
@@ -3,11 +3,6 @@
  * 
  * This include file is for the Linux kernel/module.
  *
- * CONTACTS
- *     E-mail regarding any portion of the Linux UDF file system should be
- *     directed to the development team mailing list (run by majordomo):
- *             linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *     This file is distributed under the terms of the GNU General Public
  *     License (GPL). Copies of the GPL can be obtained from:
index b60e0b4a25c41fd4cb91d333f0d001643c9cc424..85a55658831c5f0acdf8edda61921f7df7e14e77 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 d81b050e5955b5b7aea41bf582d873689e2a710f..e59d1bd52d4ff3ff651a62adc0787db7037fd0b3 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 0fb077d68441f864281d8473dd9744c37d9d80df..82fbb758e28f398bbcc0e2a3728a433d81ea6f82 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 b5d785ab4a0ea3cd41fe6ac2c82edcaf68274c0a..bfc1779fc753fcf0c1a13a086bf5fc2b7c999b65 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 47048b1d179a61c6d5c1c53775d6d83ec92ae9c1..90fcc98e676f349239b66d9a6840502fcb0e33f0 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 6c196a5baf24bda85e3789163ebe4a6cdf74eb31..bee8b84d329db3522f0e9fc7f3991e4579f7963c 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 9a5c94b1a0eca9d703ed72d8c8474b274db94a80..ec7eb86eb2035fa7ed44dce421b7a0579d617329 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 52d8b1a73d521b5bb792148a2f17fff854aec9d6..c5b96b2b81554e452630774254c1a2ae4e9a9f34 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 6cdebeee5f961318bc5c8e942b1a2f92e4b276ce..e7c3f20fbafc6de85b683d41588f2d1646ca4989 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 225fc751d46485101468be810298d020bb68e5fb..03b766afdc395cab12fe65f083714667627b4b78 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 5a2beed5a7701e0c69d7793a6eb3b60667abd84e..25f708ff020e9b158e26fe95c56b2706774c8bdf 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 f943306ce5ff3104092f604ed4d23c5c93de9855..227adcbdfec801e313f9e4c49a029a8f4347be90 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 b0c99060b78d721f285c7b23a34525dd1d592e62..50234fa56a6843a16f803e2d22616e4489d8e7b6 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 b0c47e2eccf10849d7ca097eeeaf3b08c307837e..d599c6bfbb86bc5eb0e83f91f9f7fb417d4631f2 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 07840baa934125280a97a3261fcb25da1840588e..135d80fd658ebf2c8d027440a1e9580f1c2b1ba3 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 28f7b2103505edc6cd4389e96aeca02845b1192d..1da294c47522a31dce68280c2dd9b677c7c38bac 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 7fda471002b6b3b19b9bfda4cbca64ad4e75c497..0965515f40cfabba4e3839007ca51ebac6d22113 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 e4563bbee6ea2baab2d6e61571dc2bd78cc1502e..f7e7fd728b67049a42f6e6f8a2b82bd4dd7b7c2e 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 14de4ebd12113f4b31b05991159428d842cd78cf..e000fa2cd5f62824059afb171439120e573bab74 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 3b5559a023a4603eff8723ca92eda35c9016eba9..7d2674fde19a87020a225ada56b64a97c118ff44 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 0a2ad51cff8223dd1936e958a498d6dbd8644b2d..860bbac4c4ee37dd0d3431c120f9ddf5a8fd3746 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 f85d6e4b74426b97f75b472403c6e5c82ca9cdb2..bbac87eeb422603a91377918f0e4b3bd9acc4689 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 34c07731933db95b38cbb05a4db4ccefde2d6d7e..6fa9ae1907417f2a113c6509ee4031ce169c43e3 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 bd08964b72c085b76b88d578af328f4efeab9435..b225d8472b7e7536fbf4baa610eeec139ee59a4e 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 357691f6a45f1d19f6e2709fd604c59eee74fa25..63f7db99c2a67c526dffd96a090621f5542e6765 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 f47917469b12121c9b3d770514f474ae5bf7a9d7..e67b28a0248c3ce5c8c831634a475ae9017eeafc 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 b52cc52ffe39f1475488c0d904753519a6df531f..11641c9384f78ae48f5a41272f223066102cc96c 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 8e7794ee27ffb8d05f1a0ed0560825ed6f8a975a..f5c22d77feab60e030c826bcc6abe92eee1d2d26 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 f1c3bc54526a18efcfaeff470017bbd4d59ba2e8..8a6bef6f91ebc39192805530255c6a6f94a63bc1 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 982b4ecd187b9393b9470a3da7462bdd878a0e52..6961700ff3a03584309a7c40b4fccd6f83bd8220 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 d78025f9fbea218bc6a09201534d619ca8893bae..77f21c65bbca2e1f2a460d167bc390d76eb6eb50 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 b9d4176b2d156004ff4c007362e266f47a7d892c..b0b645988bd86687ac06b170f468e1239f4576f0 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 4e86f2de6638cc5445baa85ba4b9f56a6e78f000..61f724c1036faa2df0225e42385f0adde88995ab 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 107b9d791a1f1d31fc478bc31b7fedbe25c2ba22..766fba1369ce5a45262d78521a63e59980c1f832 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 1cdb8791213781f7115cd554c29fb3aaee893c38..07d7b50cdd76fc9ed52d1f98609898703e807161 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 20da282d4abbb78041fd5f1bacc868dcc1a021a2..41cfc29be8993562e3d265d5a38d02e3d9b576f1 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 b090a11d7e1c87ee20eb7458f3e0bb3ed3651cce..4d69dee66d4d0327ce174e49000fe983abdbbb0d 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 85cfd88461c8d79337400f5a28ecd0aec63014da..e94ca4d360358bb535224bca0766af0f706cef61 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 6bdc4afb248380d7180f7d9a68bf869cd09fd4c1..54a89611e9c5abc04f89013112c9ff9202dece6f 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 9fc0759fa9421a38c9a22cfb10ed087fd0b1ec2d..aa29b797ca2b353537665d010afb81b08cc33238 100644 (file)
@@ -461,8 +461,8 @@ config OBSOLETE_MODPARM
          If unsure, say Y.
 
 config MODVERSIONS
-       bool "Module versioning support (EXPERIMENTAL)"
-       depends on MODULES && EXPERIMENTAL
+       bool "Module versioning support"
+       depends on MODULES
        help
          Usually, you have to use modules compiled with your kernel.
          Saying Y here makes it sometimes possible to use modules
index 27f97f9b46362c4fa316619fdcc8e0d29751bbd3..54aaf561cf6626fc09acadf4b1ece9a12bb217cb 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();
 }
 
diff --git a/kernel/.gitignore b/kernel/.gitignore
new file mode 100644 (file)
index 0000000..f2ab700
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Generated files
+#
+config_data.h
+config_data.gz
index 986f7af31e0a5773ab82c1957912c3735f57931e..009e1ebdcb88e57b62d64daafb4be1be9468a514 100644 (file)
@@ -3,7 +3,7 @@
  * Echo the kernel .config file used to build the kernel
  *
  * Copyright (C) 2002 Khalid Aziz <khalid_aziz@hp.com>
- * Copyright (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+ * Copyright (C) 2002 Randy Dunlap <rdunlap@xenotime.net>
  * Copyright (C) 2002 Al Stone <ahs3@fc.hp.com>
  * Copyright (C) 2002 Hewlett-Packard Company
  *
index 7982656b9c830d7ea1c819d427240ca5a797a210..a5144e43aae136896ae646e4048fbdc13b75b25e 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 2684a92da22bdbc3cdc98d4680c27c70fe315943..f2c541774dcd77e14a7dc8cc47c53a36b3b6f3bb 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 d7b266136bf64168d0ce7ac8cc5796801fc11f13..3a180cfd7b48ee37116f9b78a1dc98081a9528d5 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 1b683f302657d376f438b8f9ea68805bdd14118c..e8753c7fcad17d1464e06006af3abb96dad6ba30 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 ea616e3fc98e73f3806a5dc04e9770b6fba38425..fb031fe9be9ed140bce6fdfe6092f3ab6df8ff87 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 9778c6acd53bb5785482794f33fb903be719c215..ccbaf69afc5b0d000b1c389bb11ebdc33657bb9f 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 beb045bf5714bd54e4b9d60fef75498959a31b2c..5e22343b6090a5aabf6ad593c601ff44d89c4711 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 1d6d0a15c099a8c4e8f38a63ed78925c0c6f827e..84e6c93a044ad50e934fe8aaa008b4e48354d0fc 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 f8986f8814319a242beb06788af564e7f70f3b34..8f8dd931b2948b1746c7163f97084c307442155a 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 e3bb11ca4235562af24b7748873ef8de5ba1d362..7f0781e4326f0cb944d6f43bc121eb9f3b695a49 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 6c34261b232e4cd2d9d0b254e7ae8701a3dfd021..757d2dd3b02f1bb710e49e982ca3c55a790cbae7 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 9cb00dc6c08c6d18b4cf1031a4405e144d1f69c0..6b61323ce23cad772371657cf18833027f56d0f9 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 f8f184942aaf47899a246d50afd3076b55b64bdc..188cc1ac49eb76ab2c5c806cbb03a406a3c59bf7 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 f564ee99782d248dab471e124f3d02dadeb5512a..0b33a7b3a00cd5c05b0b8e16ec91f0aec4a58599 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 975abe254b7a9b37462974fdc7448f9cd22cac8d..11321197338ee802a70808db37b69a7e574375f4 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 b88220a64cd8e0a7009971cc09f6507fc3f9b117..c387852f753afaf5b37c62cad02bd3fc2877fac7 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 23422bd53a5e04192d9f452ed3bd36cd0f54ac71..223f8270daeef94bb139f7c8df6d2efa99c41a77 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 917311c6828b9c5c70d2290c617c4ebaf9be3405..a43a9c1d50d7daa21c732523e9d2cdb3d36e3a9e 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 bdf95a74d8cd3294ec5765dabf94de1edd20de93..c5bd631ffcd5793d67c29009151c380b6af03cac 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 ac09b6a2352317cde8ee4a43a2db1a01a3caab71..cc047f7fb6efc9c4deb42d6aab17f48a778d0474 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 c70b3be230265fda2951a5d25bff0516c0921f4d..b84fc6075fe1ad9f33d1de0a2947f607de6a32a1 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 662975be3d1d1aaef6f20aecccbb9a01128cace1..9f6e0193ae100cef83b4952b7a3fc20c70b7a1ae 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 aae26ae2e61f5ec990c0a7f5d23caeaa1e642e68..ce617b3dbbb8dbb4c9a77cfcfe70c25c5748f304 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 1bcfef51ac581562988c54fe9cee885572f819d6..f8d322e1ea9276c3f581fbda2393c829b6fd17f0 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 a5efc9ae010bb144260258c51ae7556447c5c421..5081287923d52dce220fa21a3fb1b3a0f81a354a 100644 (file)
@@ -626,7 +626,7 @@ struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mas
  *     Network device names need to be valid file names to
  *     to allow sysfs to work
  */
-static int dev_valid_name(const char *name)
+int dev_valid_name(const char *name)
 {
        return !(*name == '\0' 
                 || !strcmp(name, ".")
@@ -3270,13 +3270,13 @@ EXPORT_SYMBOL(__dev_get_by_index);
 EXPORT_SYMBOL(__dev_get_by_name);
 EXPORT_SYMBOL(__dev_remove_pack);
 EXPORT_SYMBOL(__skb_linearize);
+EXPORT_SYMBOL(dev_valid_name);
 EXPORT_SYMBOL(dev_add_pack);
 EXPORT_SYMBOL(dev_alloc_name);
 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 3a10e0bc90e8a51ae4542ee4258f60f0d4509c64..8964d344558889bdf6c62c2d4383a265a38a433c 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 7e95b39de9fdd369d0ae0011a42c993c554f37f2..c4f25385029f86ae4c0bcdd7d3fe0d3b151727df 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 49424a42a2c0385b2924510a11ff89dfdfcfcf2f..281a632fa6a6eaf37085797076177f394b55327a 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 7fc3e9e28c34c3353b3e48082916d4cb737ad5e8..06cad2d63e8adafa21215da07ed3d2e64bb3ffd1 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 83fee37de38ee7caa37f102eec58adc383e5a585..070f91cfde598cf20c20b1b291479a832922657b 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 13cc3be4f056fb92f86cd660b6dcd29ba88ed30d..6465b0e4c8cbe734190e01052703de66d8ed29c8 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 15bfd03e8024e95c9804c20f29d09cd8e5abc985..35e25259fd95712a0145853eeea4f01493ad5599 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 7b5970fc9e407f7886332cba4d95b8ee3cf2c011..587eb7787debf04561517a0e0f0a070d5bff84e3 100644 (file)
@@ -175,7 +175,7 @@ __u32 in_aton(const char *str)
                if (*str != '\0')
                {
                        val = 0;
-                       while (*str != '\0' && *str != '.')
+                       while (*str != '\0' && *str != '.' && *str != '\n')
                        {
                                val *= 10;
                                val += *str - '0';
index 344a8da153fc90d798497d4ec821b8ccf509a56d..87b27fff6e3b9122715cb44454c0e052d5b2a267 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 c9a62cca22fcf1a92db7861d9c96049c59f03297..ce9cb77c5c29c272b7f6462c0b0a835cd1383454 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 d0fd6c60c574d2277839cda38955bf7223da586c..f7dfb5f67b873adb3c2613b215c83177c1e83c7b 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 c37eeeaf5c6e21982c341391d8d8db1a9929bdb9..de681c6ad081307c8fd1069eb6c370b4854177cd 100644 (file)
@@ -21,6 +21,8 @@
 
 #define CCID_MAX 255
 
+struct tcp_info;
+
 struct ccid {
        unsigned char   ccid_id;
        const char      *ccid_name;
index f97b85d55ad80ebab0e8388783eafb7a5ad3bcc8..93f26dd6e6cbd79f636086316f41800aee6d2faf 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 f675d8e642d3e4d2d57c706fc18652c26ba25e7e..3f78c00e3822277ca7ef1eef8adbb39cb82372ad 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 3454d59419006d7f83e4d3858cfecb3e93af773d..b6cba72b44e84e723b397969c4704a880c671f50 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 656e13e38cfb69622e02df1d54aadd08e334bdfc..3f244670764ae94fad1826439a748f860d1b808c 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 1393461898bbb277994c7707d009ddebbf68ac90..29261fc198e76161215d275109ba7163390901db 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 74ff870258785b3790bb325b62aebe2435f3769a..efd7ffb903a149a46d38d57e691b20bfba416c67 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 8a6b2a9e458189bca3b86cc8ddc28f46ac8dd7b8..65b11ea90d858818db105a4855b2a285aacf7ab2 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 d402e9020c684126bf9a1f418e7e7c9549a6e9dd..78ec5344be86e6f65f2c02121a84145bf4bc1cfc 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 8d0cc3cf3e491a636f258af31262b36f54a1efa4..33ab256cfd4a2c00eeda867fa5ecc309f5db50bc 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 369f25b60f3f3a3966ccfb2ba93982cece27dd21..44bda85e678f50c03a0974cacdbe4dd48b95b94c 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 34fdac51df965d45d22b850da9aa379e17cfeac0..c792994d795257a90aaa87ad33d305db31613dd2 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 03efaacbdb737349999667995d092aaf96485491..4cc6f41c693087484b9876f22b5754bb45af0614 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 e55136ae09f40708bbcdd50004abe97822ba0a71..011cca7ae02bee12f4cd61c609a9105b06a5b23e 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 f0435d00db6befe152f8afaf730d6bdf1b975d6b..c54edd76de098d2b3826f439d3bf1a03973a4139 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 d368cf24900095f4d8a6fefc9b105fb4204eb023..966a071a408c86203985917886d0dcf2360abcf2 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 035ad2c9e1bad3cdc9fd1382004bfcca2da966eb..aed537fa2c88507440c68daf87076c6a56332cb6 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 b425748f02d7cbc1a088fcfb4bcecb1e68fc34cf..37432088fe6d3d97c353d6491d31e6bd404d7862 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 04a6fe3e95a2629c3421b8a247672c330a4c3346..7b9bb28e2ee9587a7c287f616f36f93d80b2b7cb 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 1b18ce66e7b7ac1781c8c334c9f44d3dbac017a2..73bfcae8af9c367b3d88ffdf9f8e14afa476e927 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 19b1b984d68743cd22d935421cbbe44b6360b5fc..18f5e509281a29f2b52e296a7622bc7d934c45c9 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 7ea0209cb1697ddd50bbf5a98b4cf8f89a5d484a..e2890ec8159ec39edabd8e9d463c20aa88defdaa 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 0b298bbc1518139d4dec18e6a8ebed9eb99a020e..0dd4d06e456d7e3d56ee44482db85e882ff2e1c7 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 6d2a6ac070e35d035a7401ca89cc8f8b53449743..ef4724de7350ad3ccf613b19a55afe4c662b0ab7 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 705e3ce86df9534fc2c1e530d7c80320dd6e3e08..e320b32373e5703edac6e7b7f9e2c3310100cd1b 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 92e23b2ad4d211c810341bc74389bc9ce32381cb..be5a519cd2f8737c12659dbd2b76ee480a11eb68 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 4a195c724f012df7b4c1e036a310b71747f34362..34758118c10ca4a791ab80764b003bec60f50707 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 3fe021f1a566ad40353fa8a92e1c6d049409a7ad..ae20281d8deb085e58eec67def12fef96da3b1fd 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 39061ed53cfdd2471f2293a2e44c8a76109f478d..c49908192047032d035cd75b531e9784896b0466 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 e8d29fe736d29ade84886500ec61bab103a54ceb..33228115cda43725481b4882a060f84b445b776b 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 a010e9a68811cf325f75b6b894849cd2a58303cc..417f126c749e0539d335ee7c3e1c3a35a516a124 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 2fc3fd38924f21844bd82841148db79fa491e884..ce5fe3f74a3d868cc68a3a395e7685c0608bbbd0 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 8ce0ce2ee48e1d75308aaa3711b23989a4a07214..ce2b70ce4018dffdbb6842ad6b47129f5209a75c 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 473d0f2b2e0d6b5a4252f7c825ea870a2afc2c91..e45846ae570bba9c3b3da568e5e8b7e46598e7f3 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 dbe12da8d8b3960fe7dc796de97eae2546e1528d..d3f6c468faf43ac20e4a8e56e1d5325ca96f14e0 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 eba64e2bd397c2f219bb4c545a5704f5bf892630..2a830de3a6993cf47bf42d60c8ea409f3baaab7d 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 4f2d8725730958f498b3d319c9e3dca68cd50722..6986e11d65cca0fb6f94383076e902ac8eb23a78 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 fc718df17b40d9b1a0719d39798331cf30a2fca3..d64e2ec8da7b454f0bd6bc273c9b4fde707fcb9e 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 e8674baaa8d99034ee0d56a7fdbdfc66d205abf6..bb3613ec448c59438158fbf72c95116810fbd659 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 302b7eb507c97ebae6365f6b99122650174e95b5..caa3b7d2e48a04db0b05b08c0df3e357f8cb7386 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 d7eb680101c25311233b9195faedca1aa17d812b..9b176a942ac519f1b24b4953e375707d7e709029 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 2a3a8c59c6551f087e73d4007963055969fe8f7c..81d90354c92828513866092eff1f23f63b134927 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 1a0843cd58a9e40d84e03b003ed0984e16763edf..1aca94a9fd8b977ef877fb8e507e808eb8aa2de5 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 9bdcf31b760eee5a35a0cba61c69f734b056f02c..c935c5086d3351af11542845ebcd8371dfef91b0 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 f3bc320dce93a66e5902f4032d2ee05cf2a1f41f..9fee19c4c6179958f5ea5eb39c4a550e67b314ee 100644 (file)
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
index 67b3e2fc1fa142afb5e0cfcf0e77480fd8caf09b..e7004741ac73ca0bd3b661c436e2de54b03a380d 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 561cda326fa8092cf2b27da87cac78d68cded80e..6e5cb92a5c83b114d4751093f13e6691c323a15f 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 ce456dbf09a54967c4edde5d648ffd3661e400a1..32ba37ba72d855cadbd92979df7edf1734f388ca 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 453e94a0bbd7330cb58d26dcb607260751d46770..8b0505b093170af4839c0bba98d115b552772d0a 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 478e5c7c7e8e1801fb010ebf7055c10c709434c0..c36ccf057a19fe53942de7a387b7c328fcd24664 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 0e878fd6215c16cd6b422c4e001d4dfefa7d0606..bc28b1160a3aad85c93ee520f5c6a3ce660b7bf0 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 8ae5f2e0aefa259ba17a5de3540aed4738ec0178..89d9175d8f288360463fde69a0248acc763abba4 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 6f7c50e44a39c8ff602bfcb30c0ac7c3245f6635..7775e6cc68be3a4597dc94b4d5ab0fc5e928a614 100644 (file)
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
index 2e5ced3d80622b77577826da486e721da6bed560..1bca714bda3d63c244afea44b39a9d26bb0814a9 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 3c2e9639bba62c777bd05d2121d8e09a668f6982..bba15630469599b7a4d93d32baf03f86b93d1e20 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 e52847fa10f5d5ca61bf46107ae5212c25f541cc..0366eedb4d7056ce322098129894201798b1e76e 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 744abb9d377a4399463261d759f5f7e83acae2dd..57956dee60c8d354861debd7c1e8f75c97e59e52 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 f2dcac7c76607830e28c092494238b9ea548e2ae..46becbe4fe58d5474fda87efbc0635f3c2cbee4a 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 dd476b191f4b5c135802839a840aa6bb34f88ed6..a88bcc551244129ae5df46681374c47f9d07b106 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 8acb7ed40b47f7c5e25adae81f774601ffaa15ba..4f95d477805c051628ac2ee2fdf440d37f0b6e1c 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 45886c8475e84dbd25ab1da3eebb1a5562a20263..2a26d167e1495774e3c7941ced08f39db0398397 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 275a174c6fe69c56bf2296cb33323d910a34c49e..27860510ca6dacb4464f65352b5f4e9c917c9921 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 1a53924041fce975327d0f12b3b90d99d53cfb07..03f554857a4d935fdda0398af1f92d12db0e98f3 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 0d7dc668db46f53ae7cd4430c047233c00ae950e..39d49dc333a7f0dc47e1bbd1f8d7a7c02c3f2cfb 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 a34e60ea48a15f3b33a0531a4d5cc260a9e62f17..e20be3331f674b14470d1d2b009843f4f6c01747 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 01444a02b48b9b40b93b209b746260cbcfedb48b..16984d4a8a065b26a48d51a5bd08c80781d2f21a 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 ef98b14ac56d0f6dd2ed726689eccf3391e4e040..00aa80e9324323305fb72b365f75f96243390d1c 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 1d0cd86621b1fd31030f5aefafdce48bb3514ffa..035f2092d73ac93a639b0122ed1c8b51867dae0b 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 c7cc62c8dc12cfe8fc2f99810a9070a6a09e4304..e688c687d62d37e6c7537a3a58ffcfe751d5543a 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 bf2e23086bcead8b15e02d2a63f1194a40c72093..0a461232329fa328dcf20186054f87049ec3a7bc 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 4d5021e1929b991861c0fc788be99c8b568fcb79..e9f83e5b28ce93a7e2a3e76a878526ec227ad497 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 1b66a2ac4321cb3dfe42326a03baa0897b016f37..2b9b7f6c7f7c101867d1318bcc56d64b995eb0ed 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 b7325e0b406a8486fad7bc6da6b24f5ade426415..a7623ead39a8b6a91fe34b81afd5193d9ed6cce3 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 13e7e6e8df161ef009250b58c520717dfdf153cc..3b7403495052e31efb9bbaa4c33e740fd99685f2 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 2422a5f7195d002b457f0ced6e43c3dcd5998bff..223abaa72bc53b24b0e39356582cacf86c18e988 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 6460eec834b7b9f9ca354f0b91622698fc2d4cb8..9601fd7f9d66f2a03912fe90b6a2398acb614cf1 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 a60585fd85ad0207ff28d3345b6b53839a15a5b3..704fb73e6c5ff35f83147a96a84fe45be40d471b 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 d9546380fa048ac13d125b20ead9544bd2a64b3d..68afc53be6628a0b26c7fc6cf6556ff8c9b4bdc8 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 f3629730eb157950c9adc0caec507d1a28379e15..13cc7f89558373994ef23d8cf3dd2d09884c003a 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 8bfbe9970793cba6ed493d103d37627517dec2bd..6de8ee1a5ad9ec85227d9527b9b1374ca73e8952 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 be6faf311387ce8d6f5adf1b7ec251b5b89752f2..113374dc342c1fdd116173572131853437076d48 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 01d5f46d4e40056f865a9f2e5d0547f232f957c6..4154f3a8b6cf3e28a5c8a81f0274279a594c6f70 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 1cf02765fb5cae2ed7882149122dd3c9996197e4..89d12b4817a9fddec6254c24cf5c93f231a7dec5 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 8523c76ebf768b9f2096a00fce912c14065c7562..b4c4beba0ede942c774bb4d9c49c30c682871e44 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 55917fb170949cfdcd5dd427dc8baf7201c14a17..626dd39685f2c43675871206fb1d7d360b273359 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 3620718defe61947040716fe3138478c3b49397c..c63868dd2ca29c711e3153234578bc8368f4d8d7 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 f829a4ad3ccca1657ca9e0308ecefd032160a598..1cf305a9f8ddf4067e6e9529c86eb71b25e3a349 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 95d469271c4d1879a75e6d9d3235b786f76f8691..ea43ef1d94a75de4f9278c00b2c5347cd28b6399 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 0cd1d1bd9033ced7e87f26ef5193983e24951159..ae4653bfd65462fe31340bf6cf46324d8cf93385 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 dde37793d20b00a2a7dbad7cc374873c43032f5e..268918d5deea174ec27d03e3d96d4d5ea2288a92 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 24bc0cde43a174d4090d4b6d5897c68246e5c966..65937de1b58c5af723a4732e9ee11eb4b611c849 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 c2c52af9e5602c4be485c5f4212c170c4e1b79a6..f3e5ffbd592f9ee4c3bd04c661453fe6ccda64d5 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 a66900cda2afc79273b2722c9e6d755a9b8725f9..66f1d12ea578319f144044313a6776cefa7090d2 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 8827389abaf72a0f568251aeefeeea14809123b6..2947bc56d8a025948b803fabd088cf220ef01c4a 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 5cc8731eb55b8585a75dfc97ea2226b565e75956..d8538dcea8130b0209941ec0f5eb1ab795a49cd0 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 34b3bb86840912da024646f070170f9c933c650e..0dc519b404042c25b1e25a912762ae5ed2d162c0 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 6f92f9c62990ab4854178cc67e72c2a71b2f64f7..fbfa96754417cbf18f3b8bace4577394806b6e9f 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 b8bb78af8b8a2f3de3f521bed6bd6fc6fb55d0d9..254f9074690011a66e0382fbef5f65892e81b32e 100644 (file)
@@ -364,7 +364,7 @@ static void iriap_disconnect_request(struct iriap_cb *self)
 /*
  * Function iriap_getvaluebyclass (addr, name, attr)
  *
- *    Retreive all values from attribute in all objects with given class
+ *    Retrieve all values from attribute in all objects with given class
  *    name
  */
 int iriap_getvaluebyclass_request(struct iriap_cb *self,
index 39031684b65cdac53cd4a3cd0fa6a0b89c973fe1..52efd04cbedbb64ea409e1d81f5d608d8e52caa4 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 c3f0b07834537e3935615e35b7af3078ec975b04..8171c53bc0ed064d1bd199fda3484023a233cf9e 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 cba63729313d5690ccc724c505e8d967ac544618..e10512e229b60e2c3cc216f01a5550a9ca7ba006 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 f28460b61e47cd66649044f961011955dff39800..55afdda3d9407af4f1d7bfd4a0bdd7db77c5a8cf 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 96020d7087e8f131c3ebab3d6d0355cc595809fd..7849cac14d3a4ab24d8ab03abd8f959fde19a8f8 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 287cfcc56951a86d145bd442a5dd7e9229de44e5..3b1378498d50b12647f2ea433a341b16502e1ac9 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 e5d82d711cae2ea36e1e36e652fdeebd0b5db591..63b0e4afeb3342da4cdda6d63e95c4053872564a 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 e5241dceaa571d897dfdf2db6c938e6f334af10b..1230f0ae832e9d52bdd50e4411a56e0ebd795510 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 3e2462760413ee5871cbd3061f57be83df6c1aa1..f69e5ed9bd060b55f29212938d6f97efb27061bf 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 829fdbc4400be21af83e3846fd913cd746fdca3b..63090be2315a9c7a0c7ab30bc5d354f7c35a6385 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 82fb07aa06a51306ce580a7c248f98b936dcabd2..ba528320483743dc0ef028b8e5bf08d981efbbf8 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 6cf0342706b5bd489b305085dee76e81d3ce0648..c4a2a8c4c339b38c75d4c67caf10fbcc6ac5d8ca 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 dec68a60477310c700dfdec911cc2ebcd719218b..9d05e13e92f69c8f276db2f8a53bed71988ff1ea 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 b24ff2c1aef510ce9d4be716b19caa504baf08a9..238f1bffa6845e94b3e0bec1f6d5ad0da4c0e695 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 fa3be2b8fb5ffcaa88ac19e5919f7703461f90ef..15c05165c905173b49a3e109f109a96cc5d607a9 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 9313716334648fa90c7c39c6faaba289cebbe5d7..a40991ef72c92b4d6a59368b67c15ed7ea2c70e7 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 f775d78aa59d3402ea467331c301e66acfdfd26e..de693b43c8eae08c18db0cbd2adf357a218e8eb3 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 823947170a335bac4dd074b654be41fe81a0f2fa..2d7d8a5db2ac5c8c69c793ce1f368e9fb5a756e7 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 475bfb4972d9ff9a3a4a610877f847031e48c161..557a7d90b92a1a9f5c31430d81d2ed3a7222d3b5 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 9df888e932c57097cd803629d08a8e9f70e8cafa..fc04d185fa3348d8dabc2387f5465b59d3d81b97 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 268ddaf2dc0f6baa8ca2f5ccf0c6a7bf5b98d480..68d73e2dd155e33c2ca06e7bbd283b5a66738609 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 3145103cdf5471b1d688b0593e04237cadc5dd2e..06fa217f58a99cb93b72b28ca99e85b7dc3739cd 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 c6a51911e71e082a232f73444b3c36deb42a0d08..d68eba481291fd1bb1467c0c526e7f3e0e445b49 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 acc73ba8bade52770d1babc0bbf19e8abfe1cbef..5f6ae79b8b1627db8a71be971712b2a6ace18de4 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 6ffc64e1712d291f40723109db1a774e507c738c..411802bd4d37e604fe7a337bff2c7becaf84fccb 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 59fec59b2132df1ab43e782d2a469a84bf373dd0..7a43ae4721edd95fd6748974f68b8cf40c2f5e7b 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 020d73cc8414916f6a0bf65b2fbe675ec5759ead..16459c7f54b2c71123cbcd05fd49f8ad0d786de5 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 d19e274b9c4a346b48bf32558ddec3db69fd5942..64a447375fdb7a976e4fabe58da292d3c5817d31 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 479effc97666e92092d7e735c6cd85b113462304..e12d0be5f9762f7fe595c6645a1d1f34dffeaac8 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 0cdd9a07e043714615a42d448bd79bbdf8eed514..92e2b804c6061a9442b951b99b0d99f8067a657a 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 b46d68bb9e170fac6fc127a6aee8771ec4b14b57..a234e524a4901ad05c11a818575ed23e82c1e265 100644 (file)
@@ -1,4 +1,7 @@
+#
+# Generated files
+#
 conmakehash
 kallsyms
 pnmtologo
-
+bin2c
index 67763eeb8a3e7f5b003be3e646439aca99b43881..6f6b48f39f0ae1517fe7485c3883f9cc127f20fe 100644 (file)
@@ -19,4 +19,4 @@ subdir-$(CONFIG_MODVERSIONS) += genksyms
 subdir-$(CONFIG_MODULES)     += mod
 
 # Let clean descend into subdirs
-subdir-        += basic lxdialog kconfig package
+subdir-        += basic kconfig package
index 0f81dcfd6909aec0f873fdef797fec5fca75f44a..550798f57da5028401f05f67f9e483c6e6a2beda 100644 (file)
@@ -81,8 +81,10 @@ obj-dirs     := $(addprefix $(obj)/,$(obj-dirs))
 # Note: It's possible that one object gets potentially linked into more
 #       than one module. In that case KBUILD_MODNAME will be set to foo_bar,
 #       where foo and bar are the name of the modules.
-basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
-modname_flags  = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
+name-fix = $(subst $(comma),_,$(subst -,_,$1))
+basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(*F)))"
+modname_flags  = $(if $(filter 1,$(words $(modname))),\
+                 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
 
 _c_flags       = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
 _a_flags       = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
@@ -113,7 +115,7 @@ endif
 
 c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
                 $(__c_flags) $(modkern_cflags) \
-                $(basename_flags) $(modname_flags)
+                -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
 
 a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
                 $(__a_flags) $(modkern_aflags)
index 0b61bea869f7580d0d5af1d5c56345be61a8597c..679124b11e12645b088877fbee8d3d6e901cb24e 100644 (file)
@@ -130,9 +130,22 @@ void usage(void)
        exit(1);
 }
 
+/*
+ * Print out the commandline prefixed with cmd_<target filename> :=
+ * If commandline contains '#' escape with '\' so make to not see
+ * the '#' as a start-of-comment symbol
+ **/
 void print_cmdline(void)
 {
-       printf("cmd_%s := %s\n\n", target, cmdline);
+       char *p = cmdline;
+
+       printf("cmd_%s := ", target);
+       for (; *p; p++) {
+               if (*p == '#')
+                       printf("\\");
+               printf("%c", *p);
+       }
+       printf("\n\n");
 }
 
 char * str_config  = NULL;
index 591309d855186bc56f70ffa57671e916bdc09d3f..1a2e39b8e3e5be20db687ace9d0ff05a17d502a9 100644 (file)
@@ -1,6 +1,6 @@
 /***************************************************************************
  * binoffset.c
- * (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+ * (C) 2002 Randy Dunlap <rdunlap@xenotime.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
index df10db662eb1d510c7811c8d31c29d398ca8da9c..9f84e562318d68983c4cf4f6a9fb69670b7f3b3f 100755 (executable)
@@ -3,7 +3,7 @@
 # checkversion find uses of LINUX_VERSION_CODE, KERNEL_VERSION, or
 # UTS_RELEASE without including <linux/version.h>, or cases of
 # including <linux/version.h> that don't need it.
-# Copyright (C) 2003, Randy Dunlap <rddunlap@osdl.org>
+# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
 
 $| = 1;
 
diff --git a/scripts/genksyms/.gitignore b/scripts/genksyms/.gitignore
new file mode 100644 (file)
index 0000000..be5cadb
--- /dev/null
@@ -0,0 +1,4 @@
+keywords.c
+lex.c
+parse.[ch]
+genksyms
index eabaf7401cd686daee5ac4be33598a3c7e64c60b..ee4647805c586b18e08549aca340f570d35aafdc 100644 (file)
@@ -1,7 +1,38 @@
-/* ANSI-C code produced by gperf version 2.7.2 */
+/* ANSI-C code produced by gperf version 3.0.1 */
 /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf  */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+#line 1 "scripts/genksyms/keywords.gperf"
+
+#line 3 "scripts/genksyms/keywords.gperf"
 struct resword { const char *name; int token; };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 68, duplicates = 0 */
 
 #ifdef __GNUC__
 __inline
@@ -15,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len)
 {
   static const unsigned char asso_values[] =
     {
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113,   5,
-      113, 113, 113, 113, 113, 113,   0, 113, 113, 113,
-        0, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113,   0, 113,   0, 113,  20,
-       25,   0,  35,  30, 113,  20, 113, 113,  40,  30,
-       30,   0,   0, 113,   0,  51,   0,  15,   5, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 15,
+      71, 71, 71, 71, 71, 71, 15, 71, 71, 71,
+      10, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71,  0, 71,  0, 71,  5,
+       5,  0, 10, 20, 71, 25, 71, 71, 20,  0,
+      20, 30, 25, 71, 10,  5,  0, 20, 15, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71
     };
   return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
 }
@@ -56,77 +87,112 @@ is_reserved_word (register const char *str, register unsigned int len)
       TOTAL_KEYWORDS = 41,
       MIN_WORD_LENGTH = 3,
       MAX_WORD_LENGTH = 17,
-      MIN_HASH_VALUE = 4,
-      MAX_HASH_VALUE = 112
+      MIN_HASH_VALUE = 3,
+      MAX_HASH_VALUE = 70
     };
 
   static const struct resword wordlist[] =
     {
-      {""}, {""}, {""}, {""},
-      {"auto", AUTO_KEYW},
-      {""}, {""},
+      {""}, {""}, {""},
+#line 24 "scripts/genksyms/keywords.gperf"
+      {"asm", ASM_KEYW},
+      {""},
+#line 7 "scripts/genksyms/keywords.gperf"
+      {"__asm", ASM_KEYW},
+      {""},
+#line 8 "scripts/genksyms/keywords.gperf"
       {"__asm__", ASM_KEYW},
       {""},
+#line 21 "scripts/genksyms/keywords.gperf"
       {"_restrict", RESTRICT_KEYW},
+#line 50 "scripts/genksyms/keywords.gperf"
       {"__typeof__", TYPEOF_KEYW},
+#line 9 "scripts/genksyms/keywords.gperf"
       {"__attribute", ATTRIBUTE_KEYW},
-      {"__restrict__", RESTRICT_KEYW},
+#line 11 "scripts/genksyms/keywords.gperf"
+      {"__const", CONST_KEYW},
+#line 10 "scripts/genksyms/keywords.gperf"
       {"__attribute__", ATTRIBUTE_KEYW},
+#line 12 "scripts/genksyms/keywords.gperf"
+      {"__const__", CONST_KEYW},
+#line 16 "scripts/genksyms/keywords.gperf"
+      {"__signed__", SIGNED_KEYW},
+#line 42 "scripts/genksyms/keywords.gperf"
+      {"static", STATIC_KEYW},
       {""},
-      {"__volatile", VOLATILE_KEYW},
+#line 15 "scripts/genksyms/keywords.gperf"
+      {"__signed", SIGNED_KEYW},
+#line 30 "scripts/genksyms/keywords.gperf"
+      {"char", CHAR_KEYW},
       {""},
+#line 43 "scripts/genksyms/keywords.gperf"
+      {"struct", STRUCT_KEYW},
+#line 22 "scripts/genksyms/keywords.gperf"
+      {"__restrict__", RESTRICT_KEYW},
+#line 23 "scripts/genksyms/keywords.gperf"
+      {"restrict", RESTRICT_KEYW},
+#line 33 "scripts/genksyms/keywords.gperf"
+      {"enum", ENUM_KEYW},
+#line 17 "scripts/genksyms/keywords.gperf"
+      {"__volatile", VOLATILE_KEYW},
+#line 34 "scripts/genksyms/keywords.gperf"
+      {"extern", EXTERN_KEYW},
+#line 18 "scripts/genksyms/keywords.gperf"
       {"__volatile__", VOLATILE_KEYW},
-      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
-      {""}, {""}, {""},
-      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
+#line 37 "scripts/genksyms/keywords.gperf"
       {"int", INT_KEYW},
-      {"char", CHAR_KEYW},
-      {""}, {""},
-      {"__const", CONST_KEYW},
+      {""},
+#line 31 "scripts/genksyms/keywords.gperf"
+      {"const", CONST_KEYW},
+#line 32 "scripts/genksyms/keywords.gperf"
+      {"double", DOUBLE_KEYW},
+      {""},
+#line 13 "scripts/genksyms/keywords.gperf"
       {"__inline", INLINE_KEYW},
-      {"__const__", CONST_KEYW},
+#line 29 "scripts/genksyms/keywords.gperf"
+      {"auto", AUTO_KEYW},
+#line 14 "scripts/genksyms/keywords.gperf"
       {"__inline__", INLINE_KEYW},
-      {""}, {""}, {""}, {""},
-      {"__asm", ASM_KEYW},
-      {"extern", EXTERN_KEYW},
+#line 41 "scripts/genksyms/keywords.gperf"
+      {"signed", SIGNED_KEYW},
       {""},
-      {"register", REGISTER_KEYW},
+#line 46 "scripts/genksyms/keywords.gperf"
+      {"unsigned", UNSIGNED_KEYW},
       {""},
-      {"float", FLOAT_KEYW},
+#line 40 "scripts/genksyms/keywords.gperf"
+      {"short", SHORT_KEYW},
+#line 49 "scripts/genksyms/keywords.gperf"
       {"typeof", TYPEOF_KEYW},
+#line 44 "scripts/genksyms/keywords.gperf"
       {"typedef", TYPEDEF_KEYW},
-      {""}, {""},
-      {"_Bool", BOOL_KEYW},
-      {"double", DOUBLE_KEYW},
-      {""}, {""},
-      {"enum", ENUM_KEYW},
-      {""}, {""}, {""},
+#line 48 "scripts/genksyms/keywords.gperf"
       {"volatile", VOLATILE_KEYW},
+      {""},
+#line 35 "scripts/genksyms/keywords.gperf"
+      {"float", FLOAT_KEYW},
+      {""}, {""},
+#line 39 "scripts/genksyms/keywords.gperf"
+      {"register", REGISTER_KEYW},
+#line 47 "scripts/genksyms/keywords.gperf"
       {"void", VOID_KEYW},
-      {"const", CONST_KEYW},
-      {"short", SHORT_KEYW},
-      {"struct", STRUCT_KEYW},
       {""},
-      {"restrict", RESTRICT_KEYW},
+#line 36 "scripts/genksyms/keywords.gperf"
+      {"inline", INLINE_KEYW},
       {""},
-      {"__signed__", SIGNED_KEYW},
+#line 5 "scripts/genksyms/keywords.gperf"
+      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
       {""},
-      {"asm", ASM_KEYW},
-      {""}, {""},
-      {"inline", INLINE_KEYW},
-      {""}, {""}, {""},
-      {"union", UNION_KEYW},
-      {""}, {""}, {""}, {""}, {""}, {""},
-      {"static", STATIC_KEYW},
+#line 20 "scripts/genksyms/keywords.gperf"
+      {"_Bool", BOOL_KEYW},
+      {""},
+#line 6 "scripts/genksyms/keywords.gperf"
+      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
       {""}, {""}, {""}, {""}, {""}, {""},
-      {"__signed", SIGNED_KEYW},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {""}, {""}, {""}, {""}, {""},
-      {"unsigned", UNSIGNED_KEYW},
-      {""}, {""}, {""}, {""},
+#line 38 "scripts/genksyms/keywords.gperf"
       {"long", LONG_KEYW},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {"signed", SIGNED_KEYW}
+      {""}, {""}, {""}, {""}, {""},
+#line 45 "scripts/genksyms/keywords.gperf"
+      {"union", UNION_KEYW}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
index d9bfbb5948f2bb1dd42dd8d0760a1c3e008b7e98..1218053ee960e390020aa2a85067797673e1ebcd 100644 (file)
@@ -2036,49 +2036,131 @@ fini:
 
   return token;
 }
-#ifndef YYSTYPE
-#define YYSTYPE int
-#endif
-#define        ASM_KEYW        257
-#define        ATTRIBUTE_KEYW  258
-#define        AUTO_KEYW       259
-#define        BOOL_KEYW       260
-#define        CHAR_KEYW       261
-#define        CONST_KEYW      262
-#define        DOUBLE_KEYW     263
-#define        ENUM_KEYW       264
-#define        EXTERN_KEYW     265
-#define        FLOAT_KEYW      266
-#define        INLINE_KEYW     267
-#define        INT_KEYW        268
-#define        LONG_KEYW       269
-#define        REGISTER_KEYW   270
-#define        RESTRICT_KEYW   271
-#define        SHORT_KEYW      272
-#define        SIGNED_KEYW     273
-#define        STATIC_KEYW     274
-#define        STRUCT_KEYW     275
-#define        TYPEDEF_KEYW    276
-#define        UNION_KEYW      277
-#define        UNSIGNED_KEYW   278
-#define        VOID_KEYW       279
-#define        VOLATILE_KEYW   280
-#define        TYPEOF_KEYW     281
-#define        EXPORT_SYMBOL_KEYW      282
-#define        ASM_PHRASE      283
-#define        ATTRIBUTE_PHRASE        284
-#define        BRACE_PHRASE    285
-#define        BRACKET_PHRASE  286
-#define        EXPRESSION_PHRASE       287
-#define        CHAR    288
-#define        DOTS    289
-#define        IDENT   290
-#define        INT     291
-#define        REAL    292
-#define        STRING  293
-#define        TYPE    294
-#define        OTHER   295
-#define        FILENAME        296
+/* A Bison parser, made by GNU Bison 2.0.  */
 
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, 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.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ASM_KEYW = 258,
+     ATTRIBUTE_KEYW = 259,
+     AUTO_KEYW = 260,
+     BOOL_KEYW = 261,
+     CHAR_KEYW = 262,
+     CONST_KEYW = 263,
+     DOUBLE_KEYW = 264,
+     ENUM_KEYW = 265,
+     EXTERN_KEYW = 266,
+     FLOAT_KEYW = 267,
+     INLINE_KEYW = 268,
+     INT_KEYW = 269,
+     LONG_KEYW = 270,
+     REGISTER_KEYW = 271,
+     RESTRICT_KEYW = 272,
+     SHORT_KEYW = 273,
+     SIGNED_KEYW = 274,
+     STATIC_KEYW = 275,
+     STRUCT_KEYW = 276,
+     TYPEDEF_KEYW = 277,
+     UNION_KEYW = 278,
+     UNSIGNED_KEYW = 279,
+     VOID_KEYW = 280,
+     VOLATILE_KEYW = 281,
+     TYPEOF_KEYW = 282,
+     EXPORT_SYMBOL_KEYW = 283,
+     ASM_PHRASE = 284,
+     ATTRIBUTE_PHRASE = 285,
+     BRACE_PHRASE = 286,
+     BRACKET_PHRASE = 287,
+     EXPRESSION_PHRASE = 288,
+     CHAR = 289,
+     DOTS = 290,
+     IDENT = 291,
+     INT = 292,
+     REAL = 293,
+     STRING = 294,
+     TYPE = 295,
+     OTHER = 296,
+     FILENAME = 297
+   };
+#endif
+#define ASM_KEYW 258
+#define ATTRIBUTE_KEYW 259
+#define AUTO_KEYW 260
+#define BOOL_KEYW 261
+#define CHAR_KEYW 262
+#define CONST_KEYW 263
+#define DOUBLE_KEYW 264
+#define ENUM_KEYW 265
+#define EXTERN_KEYW 266
+#define FLOAT_KEYW 267
+#define INLINE_KEYW 268
+#define INT_KEYW 269
+#define LONG_KEYW 270
+#define REGISTER_KEYW 271
+#define RESTRICT_KEYW 272
+#define SHORT_KEYW 273
+#define SIGNED_KEYW 274
+#define STATIC_KEYW 275
+#define STRUCT_KEYW 276
+#define TYPEDEF_KEYW 277
+#define UNION_KEYW 278
+#define UNSIGNED_KEYW 279
+#define VOID_KEYW 280
+#define VOLATILE_KEYW 281
+#define TYPEOF_KEYW 282
+#define EXPORT_SYMBOL_KEYW 283
+#define ASM_PHRASE 284
+#define ATTRIBUTE_PHRASE 285
+#define BRACE_PHRASE 286
+#define BRACKET_PHRASE 287
+#define EXPRESSION_PHRASE 288
+#define CHAR 289
+#define DOTS 290
+#define IDENT 291
+#define INT 292
+#define REAL 293
+#define STRING 294
+#define TYPE 295
+#define OTHER 296
+#define FILENAME 297
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
 
 extern YYSTYPE yylval;
+
+
+
index 2c6b1286b638ae78125cf39289520191a3881e63..99d7c258696de1a799f882f54a41d9f782dd31c2 100644 (file)
+/* A Bison parser, made by GNU Bison 2.0.  */
 
-/*  A Bison parser, made from scripts/genksyms/parse.y
-    by GNU Bison version 1.28  */
-
-#define YYBISON 1  /* Identify Bison output.  */
-
-#define        ASM_KEYW        257
-#define        ATTRIBUTE_KEYW  258
-#define        AUTO_KEYW       259
-#define        BOOL_KEYW       260
-#define        CHAR_KEYW       261
-#define        CONST_KEYW      262
-#define        DOUBLE_KEYW     263
-#define        ENUM_KEYW       264
-#define        EXTERN_KEYW     265
-#define        FLOAT_KEYW      266
-#define        INLINE_KEYW     267
-#define        INT_KEYW        268
-#define        LONG_KEYW       269
-#define        REGISTER_KEYW   270
-#define        RESTRICT_KEYW   271
-#define        SHORT_KEYW      272
-#define        SIGNED_KEYW     273
-#define        STATIC_KEYW     274
-#define        STRUCT_KEYW     275
-#define        TYPEDEF_KEYW    276
-#define        UNION_KEYW      277
-#define        UNSIGNED_KEYW   278
-#define        VOID_KEYW       279
-#define        VOLATILE_KEYW   280
-#define        TYPEOF_KEYW     281
-#define        EXPORT_SYMBOL_KEYW      282
-#define        ASM_PHRASE      283
-#define        ATTRIBUTE_PHRASE        284
-#define        BRACE_PHRASE    285
-#define        BRACKET_PHRASE  286
-#define        EXPRESSION_PHRASE       287
-#define        CHAR    288
-#define        DOTS    289
-#define        IDENT   290
-#define        INT     291
-#define        REAL    292
-#define        STRING  293
-#define        TYPE    294
-#define        OTHER   295
-#define        FILENAME        296
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, 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.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ASM_KEYW = 258,
+     ATTRIBUTE_KEYW = 259,
+     AUTO_KEYW = 260,
+     BOOL_KEYW = 261,
+     CHAR_KEYW = 262,
+     CONST_KEYW = 263,
+     DOUBLE_KEYW = 264,
+     ENUM_KEYW = 265,
+     EXTERN_KEYW = 266,
+     FLOAT_KEYW = 267,
+     INLINE_KEYW = 268,
+     INT_KEYW = 269,
+     LONG_KEYW = 270,
+     REGISTER_KEYW = 271,
+     RESTRICT_KEYW = 272,
+     SHORT_KEYW = 273,
+     SIGNED_KEYW = 274,
+     STATIC_KEYW = 275,
+     STRUCT_KEYW = 276,
+     TYPEDEF_KEYW = 277,
+     UNION_KEYW = 278,
+     UNSIGNED_KEYW = 279,
+     VOID_KEYW = 280,
+     VOLATILE_KEYW = 281,
+     TYPEOF_KEYW = 282,
+     EXPORT_SYMBOL_KEYW = 283,
+     ASM_PHRASE = 284,
+     ATTRIBUTE_PHRASE = 285,
+     BRACE_PHRASE = 286,
+     BRACKET_PHRASE = 287,
+     EXPRESSION_PHRASE = 288,
+     CHAR = 289,
+     DOTS = 290,
+     IDENT = 291,
+     INT = 292,
+     REAL = 293,
+     STRING = 294,
+     TYPE = 295,
+     OTHER = 296,
+     FILENAME = 297
+   };
+#endif
+#define ASM_KEYW 258
+#define ATTRIBUTE_KEYW 259
+#define AUTO_KEYW 260
+#define BOOL_KEYW 261
+#define CHAR_KEYW 262
+#define CONST_KEYW 263
+#define DOUBLE_KEYW 264
+#define ENUM_KEYW 265
+#define EXTERN_KEYW 266
+#define FLOAT_KEYW 267
+#define INLINE_KEYW 268
+#define INT_KEYW 269
+#define LONG_KEYW 270
+#define REGISTER_KEYW 271
+#define RESTRICT_KEYW 272
+#define SHORT_KEYW 273
+#define SIGNED_KEYW 274
+#define STATIC_KEYW 275
+#define STRUCT_KEYW 276
+#define TYPEDEF_KEYW 277
+#define UNION_KEYW 278
+#define UNSIGNED_KEYW 279
+#define VOID_KEYW 280
+#define VOLATILE_KEYW 281
+#define TYPEOF_KEYW 282
+#define EXPORT_SYMBOL_KEYW 283
+#define ASM_PHRASE 284
+#define ATTRIBUTE_PHRASE 285
+#define BRACE_PHRASE 286
+#define BRACKET_PHRASE 287
+#define EXPRESSION_PHRASE 288
+#define CHAR 289
+#define DOTS 290
+#define IDENT 291
+#define INT 292
+#define REAL 293
+#define STRING 294
+#define TYPE 295
+#define OTHER 296
+#define FILENAME 297
+
+
+
+
+/* Copy the first part of user declarations.  */
 #line 24 "scripts/genksyms/parse.y"
 
 
@@ -75,661 +170,1000 @@ remove_list(struct string_list **pb, struct string_list **pe)
   free_list(b, e);
 }
 
-#ifndef YYSTYPE
-#define YYSTYPE int
-#endif
+
+
+/* Enabling traces.  */
 #ifndef YYDEBUG
-#define YYDEBUG 1
+# define YYDEBUG 1
 #endif
 
-#include <stdio.h>
-
-#ifndef __cplusplus
-#ifndef __STDC__
-#define const
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
 #endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
 
-#define        YYFINAL         172
-#define        YYFLAG          -32768
-#define        YYNTBASE        52
-
-#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 96)
-
-static const char yytranslate[] = {     0,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,    46,
-    47,    48,     2,    45,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,    51,    43,     2,
-    49,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,    50,     2,    44,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
-     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
-    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
-    37,    38,    39,    40,    41,    42
-};
+/* Copy the second part of user declarations.  */
 
-#if YYDEBUG != 0
-static const short yyprhs[] = {     0,
-     0,     2,     5,     6,     9,    10,    14,    16,    18,    20,
-    22,    25,    28,    32,    33,    35,    37,    41,    46,    47,
-    49,    51,    54,    56,    58,    60,    62,    64,    66,    68,
-    70,    72,    77,    80,    83,    86,    90,    94,    98,   101,
-   104,   107,   109,   111,   113,   115,   117,   119,   121,   123,
-   125,   127,   129,   132,   133,   135,   137,   140,   142,   144,
-   146,   148,   151,   153,   155,   160,   165,   168,   172,   176,
-   179,   181,   183,   185,   190,   195,   198,   202,   206,   209,
-   211,   215,   216,   218,   220,   224,   227,   230,   232,   233,
-   235,   237,   242,   247,   250,   254,   258,   262,   263,   265,
-   268,   272,   276,   277,   279,   281,   284,   288,   291,   292,
-   294,   296,   300,   303,   306,   308,   311,   312,   314,   317,
-   318,   320
-};
 
-static const short yyrhs[] = {    53,
-     0,    52,    53,     0,     0,    54,    55,     0,     0,    22,
-    56,    57,     0,    57,     0,    81,     0,    93,     0,    95,
-     0,     1,    43,     0,     1,    44,     0,    61,    58,    43,
-     0,     0,    59,     0,    60,     0,    59,    45,    60,     0,
-    71,    94,    92,    82,     0,     0,    62,     0,    63,     0,
-    62,    63,     0,    64,     0,    65,     0,     5,     0,    16,
-     0,    20,     0,    11,     0,    13,     0,    66,     0,    70,
-     0,    27,    46,    62,    47,     0,    21,    36,     0,    23,
-    36,     0,    10,    36,     0,    21,    36,    84,     0,    23,
-    36,    84,     0,    10,    36,    31,     0,    10,    31,     0,
-    21,    84,     0,    23,    84,     0,     7,     0,    18,     0,
-    14,     0,    15,     0,    19,     0,    24,     0,    12,     0,
-     9,     0,    25,     0,     6,     0,    40,     0,    48,    68,
-     0,     0,    69,     0,    70,     0,    69,    70,     0,     8,
-     0,    26,     0,    30,     0,    17,     0,    67,    71,     0,
-    72,     0,    36,     0,    72,    46,    75,    47,     0,    72,
-    46,     1,    47,     0,    72,    32,     0,    46,    71,    47,
-     0,    46,     1,    47,     0,    67,    73,     0,    74,     0,
-    36,     0,    40,     0,    74,    46,    75,    47,     0,    74,
-    46,     1,    47,     0,    74,    32,     0,    46,    73,    47,
-     0,    46,     1,    47,     0,    76,    35,     0,    76,     0,
-    77,    45,    35,     0,     0,    77,     0,    78,     0,    77,
-    45,    78,     0,    62,    79,     0,    67,    79,     0,    80,
-     0,     0,    36,     0,    40,     0,    80,    46,    75,    47,
-     0,    80,    46,     1,    47,     0,    80,    32,     0,    46,
-    79,    47,     0,    46,     1,    47,     0,    61,    71,    31,
-     0,     0,    83,     0,    49,    33,     0,    50,    85,    44,
-     0,    50,     1,    44,     0,     0,    86,     0,    87,     0,
-    86,    87,     0,    61,    88,    43,     0,     1,    43,     0,
-     0,    89,     0,    90,     0,    89,    45,    90,     0,    73,
-    92,     0,    36,    91,     0,    91,     0,    51,    33,     0,
-     0,    30,     0,    29,    43,     0,     0,    29,     0,    28,
-    46,    36,    47,    43,     0
-};
+/* Line 213 of yacc.c.  */
+#line 202 "scripts/genksyms/parse.c"
 
-#endif
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
 
-#if YYDEBUG != 0
-static const short yyrline[] = { 0,
-   101,   103,   106,   109,   112,   114,   115,   116,   117,   118,
-   119,   120,   123,   137,   139,   142,   151,   163,   169,   171,
-   174,   176,   179,   186,   189,   191,   192,   193,   194,   197,
-   199,   200,   204,   206,   208,   212,   219,   226,   235,   236,
-   237,   240,   242,   243,   244,   245,   246,   247,   248,   249,
-   250,   251,   254,   259,   261,   264,   266,   269,   270,   270,
-   271,   278,   280,   283,   293,   295,   297,   299,   301,   307,
-   309,   312,   314,   315,   317,   319,   321,   323,   327,   329,
-   330,   333,   335,   338,   340,   344,   349,   352,   355,   357,
-   365,   369,   371,   373,   375,   377,   381,   390,   392,   396,
-   401,   403,   406,   408,   411,   413,   416,   419,   423,   425,
-   428,   430,   433,   435,   436,   439,   443,   445,   448,   452,
-   454,   457
-};
-#endif
+# ifndef YYFREE
+#  define YYFREE free
+# endif
+# ifndef YYMALLOC
+#  define YYMALLOC malloc
+# endif
 
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+        || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE))                    \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         register YYSIZE_T yyi;                \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)                                       \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
+       Stack = &yyptr->Stack;                                          \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (0)
 
-#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
-
-static const char * const yytname[] = {   "$","error","$undefined.","ASM_KEYW",
-"ATTRIBUTE_KEYW","AUTO_KEYW","BOOL_KEYW","CHAR_KEYW","CONST_KEYW","DOUBLE_KEYW",
-"ENUM_KEYW","EXTERN_KEYW","FLOAT_KEYW","INLINE_KEYW","INT_KEYW","LONG_KEYW",
-"REGISTER_KEYW","RESTRICT_KEYW","SHORT_KEYW","SIGNED_KEYW","STATIC_KEYW","STRUCT_KEYW",
-"TYPEDEF_KEYW","UNION_KEYW","UNSIGNED_KEYW","VOID_KEYW","VOLATILE_KEYW","TYPEOF_KEYW",
-"EXPORT_SYMBOL_KEYW","ASM_PHRASE","ATTRIBUTE_PHRASE","BRACE_PHRASE","BRACKET_PHRASE",
-"EXPRESSION_PHRASE","CHAR","DOTS","IDENT","INT","REAL","STRING","TYPE","OTHER",
-"FILENAME","';'","'}'","','","'('","')'","'*'","'='","'{'","':'","declaration_seq",
-"declaration","@1","declaration1","@2","simple_declaration","init_declarator_list_opt",
-"init_declarator_list","init_declarator","decl_specifier_seq_opt","decl_specifier_seq",
-"decl_specifier","storage_class_specifier","type_specifier","simple_type_specifier",
-"ptr_operator","cvar_qualifier_seq_opt","cvar_qualifier_seq","cvar_qualifier",
-"declarator","direct_declarator","nested_declarator","direct_nested_declarator",
-"parameter_declaration_clause","parameter_declaration_list_opt","parameter_declaration_list",
-"parameter_declaration","m_abstract_declarator","direct_m_abstract_declarator",
-"function_definition","initializer_opt","initializer","class_body","member_specification_opt",
-"member_specification","member_declaration","member_declarator_list_opt","member_declarator_list",
-"member_declarator","member_bitfield_declarator","attribute_opt","asm_definition",
-"asm_phrase_opt","export_definition", NULL
-};
 #endif
 
-static const short yyr1[] = {     0,
-    52,    52,    54,    53,    56,    55,    55,    55,    55,    55,
-    55,    55,    57,    58,    58,    59,    59,    60,    61,    61,
-    62,    62,    63,    63,    64,    64,    64,    64,    64,    65,
-    65,    65,    65,    65,    65,    65,    65,    65,    65,    65,
-    65,    66,    66,    66,    66,    66,    66,    66,    66,    66,
-    66,    66,    67,    68,    68,    69,    69,    70,    70,    70,
-    70,    71,    71,    72,    72,    72,    72,    72,    72,    73,
-    73,    74,    74,    74,    74,    74,    74,    74,    75,    75,
-    75,    76,    76,    77,    77,    78,    79,    79,    80,    80,
-    80,    80,    80,    80,    80,    80,    81,    82,    82,    83,
-    84,    84,    85,    85,    86,    86,    87,    87,    88,    88,
-    89,    89,    90,    90,    90,    91,    92,    92,    93,    94,
-    94,    95
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  4
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   535
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  52
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  45
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  124
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  174
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   297
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      46,    48,    47,     2,    45,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    51,    43,
+       2,    49,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    50,     2,    44,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42
 };
 
-static const short yyr2[] = {     0,
-     1,     2,     0,     2,     0,     3,     1,     1,     1,     1,
-     2,     2,     3,     0,     1,     1,     3,     4,     0,     1,
-     1,     2,     1,     1,     1,     1,     1,     1,     1,     1,
-     1,     4,     2,     2,     2,     3,     3,     3,     2,     2,
-     2,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-     1,     1,     2,     0,     1,     1,     2,     1,     1,     1,
-     1,     2,     1,     1,     4,     4,     2,     3,     3,     2,
-     1,     1,     1,     4,     4,     2,     3,     3,     2,     1,
-     3,     0,     1,     1,     3,     2,     2,     1,     0,     1,
-     1,     4,     4,     2,     3,     3,     3,     0,     1,     2,
-     3,     3,     0,     1,     1,     2,     3,     2,     0,     1,
-     1,     3,     2,     2,     1,     2,     0,     1,     2,     0,
-     1,     5
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned short int yyprhs[] =
+{
+       0,     0,     3,     5,     8,     9,    12,    13,    17,    19,
+      21,    23,    25,    28,    31,    35,    36,    38,    40,    44,
+      49,    50,    52,    54,    57,    59,    61,    63,    65,    67,
+      69,    71,    73,    75,    81,    86,    89,    92,    95,    99,
+     103,   107,   110,   113,   116,   118,   120,   122,   124,   126,
+     128,   130,   132,   134,   136,   138,   141,   142,   144,   146,
+     149,   151,   153,   155,   157,   160,   162,   164,   169,   174,
+     177,   181,   185,   188,   190,   192,   194,   199,   204,   207,
+     211,   215,   218,   220,   224,   225,   227,   229,   233,   236,
+     239,   241,   242,   244,   246,   251,   256,   259,   263,   267,
+     271,   272,   274,   277,   281,   285,   286,   288,   290,   293,
+     297,   300,   301,   303,   305,   309,   312,   315,   317,   320,
+     321,   323,   326,   327,   329
 };
 
-static const short yydefact[] = {     3,
-     3,     1,     0,     2,     0,    25,    51,    42,    58,    49,
-     0,    28,    48,    29,    44,    45,    26,    61,    43,    46,
-    27,     0,     5,     0,    47,    50,    59,     0,     0,     0,
-    60,    52,     4,     7,    14,    20,    21,    23,    24,    30,
-    31,     8,     9,    10,    11,    12,    39,    35,    33,     0,
-    40,    19,    34,    41,     0,     0,   119,    64,     0,    54,
-     0,    15,    16,     0,   120,    63,    22,    38,    36,     0,
-   109,     0,     0,   105,     6,    14,    37,     0,     0,     0,
-     0,    53,    55,    56,    13,     0,    62,   121,    97,   117,
-    67,     0,   108,   102,    72,    73,     0,     0,     0,   117,
-    71,     0,   110,   111,   115,   101,     0,   106,   120,    32,
-     0,    69,    68,    57,    17,   118,    98,     0,    89,     0,
-    80,    83,    84,   114,     0,    72,     0,   116,    70,   113,
-    76,     0,   107,     0,   122,     0,    18,    99,    66,    90,
-    52,     0,    89,    86,    88,    65,    79,     0,    78,    77,
-     0,     0,   112,   100,     0,    91,     0,    87,    94,     0,
-    81,    85,    75,    74,    96,    95,     0,     0,    93,    92,
-     0,     0
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      53,     0,    -1,    54,    -1,    53,    54,    -1,    -1,    55,
+      56,    -1,    -1,    22,    57,    58,    -1,    58,    -1,    82,
+      -1,    94,    -1,    96,    -1,     1,    43,    -1,     1,    44,
+      -1,    62,    59,    43,    -1,    -1,    60,    -1,    61,    -1,
+      60,    45,    61,    -1,    72,    95,    93,    83,    -1,    -1,
+      63,    -1,    64,    -1,    63,    64,    -1,    65,    -1,    66,
+      -1,     5,    -1,    16,    -1,    20,    -1,    11,    -1,    13,
+      -1,    67,    -1,    71,    -1,    27,    46,    63,    47,    48,
+      -1,    27,    46,    63,    48,    -1,    21,    36,    -1,    23,
+      36,    -1,    10,    36,    -1,    21,    36,    85,    -1,    23,
+      36,    85,    -1,    10,    36,    31,    -1,    10,    31,    -1,
+      21,    85,    -1,    23,    85,    -1,     7,    -1,    18,    -1,
+      14,    -1,    15,    -1,    19,    -1,    24,    -1,    12,    -1,
+       9,    -1,    25,    -1,     6,    -1,    40,    -1,    47,    69,
+      -1,    -1,    70,    -1,    71,    -1,    70,    71,    -1,     8,
+      -1,    26,    -1,    30,    -1,    17,    -1,    68,    72,    -1,
+      73,    -1,    36,    -1,    73,    46,    76,    48,    -1,    73,
+      46,     1,    48,    -1,    73,    32,    -1,    46,    72,    48,
+      -1,    46,     1,    48,    -1,    68,    74,    -1,    75,    -1,
+      36,    -1,    40,    -1,    75,    46,    76,    48,    -1,    75,
+      46,     1,    48,    -1,    75,    32,    -1,    46,    74,    48,
+      -1,    46,     1,    48,    -1,    77,    35,    -1,    77,    -1,
+      78,    45,    35,    -1,    -1,    78,    -1,    79,    -1,    78,
+      45,    79,    -1,    63,    80,    -1,    68,    80,    -1,    81,
+      -1,    -1,    36,    -1,    40,    -1,    81,    46,    76,    48,
+      -1,    81,    46,     1,    48,    -1,    81,    32,    -1,    46,
+      80,    48,    -1,    46,     1,    48,    -1,    62,    72,    31,
+      -1,    -1,    84,    -1,    49,    33,    -1,    50,    86,    44,
+      -1,    50,     1,    44,    -1,    -1,    87,    -1,    88,    -1,
+      87,    88,    -1,    62,    89,    43,    -1,     1,    43,    -1,
+      -1,    90,    -1,    91,    -1,    90,    45,    91,    -1,    74,
+      93,    -1,    36,    92,    -1,    92,    -1,    51,    33,    -1,
+      -1,    30,    -1,    29,    43,    -1,    -1,    29,    -1,    28,
+      46,    36,    48,    43,    -1
 };
 
-static const short yydefgoto[] = {     1,
-     2,     3,    33,    52,    34,    61,    62,    63,    71,    36,
-    37,    38,    39,    40,    64,    82,    83,    41,   109,    66,
-   100,   101,   120,   121,   122,   123,   144,   145,    42,   137,
-   138,    51,    72,    73,    74,   102,   103,   104,   105,   117,
-    43,    90,    44
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short int yyrline[] =
+{
+       0,   102,   102,   103,   107,   107,   113,   113,   115,   116,
+     117,   118,   119,   120,   124,   138,   139,   143,   151,   164,
+     170,   171,   175,   176,   180,   186,   190,   191,   192,   193,
+     194,   198,   199,   200,   201,   205,   207,   209,   213,   220,
+     227,   236,   237,   238,   242,   243,   244,   245,   246,   247,
+     248,   249,   250,   251,   252,   256,   261,   262,   266,   267,
+     271,   271,   271,   272,   280,   281,   285,   294,   296,   298,
+     300,   302,   309,   310,   314,   315,   316,   318,   320,   322,
+     324,   329,   330,   331,   335,   336,   340,   341,   346,   351,
+     353,   357,   358,   366,   370,   372,   374,   376,   378,   383,
+     392,   393,   398,   403,   404,   408,   409,   413,   414,   418,
+     420,   425,   426,   430,   431,   435,   436,   437,   441,   445,
+     446,   450,   454,   455,   459
 };
+#endif
 
-static const short yypact[] = {-32768,
-    15,-32768,   197,-32768,    23,-32768,-32768,-32768,-32768,-32768,
-   -18,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,   -28,-32768,   -25,-32768,-32768,-32768,   -26,   -22,   -12,
--32768,-32768,-32768,-32768,    49,   493,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,    27,    -8,   101,
--32768,   493,    -8,-32768,   493,    10,-32768,-32768,    11,     9,
-    18,    26,-32768,    49,   -15,   -13,-32768,-32768,-32768,    25,
-    24,    48,   149,-32768,-32768,    49,-32768,   414,    39,    40,
-    47,-32768,     9,-32768,-32768,    49,-32768,-32768,-32768,    66,
--32768,   241,-32768,-32768,    50,-32768,     5,    65,    42,    66,
-    17,    56,    55,-32768,-32768,-32768,    60,-32768,    75,-32768,
-    80,-32768,-32768,-32768,-32768,-32768,    81,    82,   370,    85,
-    98,    89,-32768,-32768,    88,-32768,    91,-32768,-32768,-32768,
--32768,   284,-32768,    24,-32768,   103,-32768,-32768,-32768,-32768,
--32768,     8,    43,-32768,    30,-32768,-32768,   457,-32768,-32768,
-    92,    93,-32768,-32768,    95,-32768,    96,-32768,-32768,   327,
--32768,-32768,-32768,-32768,-32768,-32768,    99,   104,-32768,-32768,
-   148,-32768
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "ASM_KEYW", "ATTRIBUTE_KEYW",
+  "AUTO_KEYW", "BOOL_KEYW", "CHAR_KEYW", "CONST_KEYW", "DOUBLE_KEYW",
+  "ENUM_KEYW", "EXTERN_KEYW", "FLOAT_KEYW", "INLINE_KEYW", "INT_KEYW",
+  "LONG_KEYW", "REGISTER_KEYW", "RESTRICT_KEYW", "SHORT_KEYW",
+  "SIGNED_KEYW", "STATIC_KEYW", "STRUCT_KEYW", "TYPEDEF_KEYW",
+  "UNION_KEYW", "UNSIGNED_KEYW", "VOID_KEYW", "VOLATILE_KEYW",
+  "TYPEOF_KEYW", "EXPORT_SYMBOL_KEYW", "ASM_PHRASE", "ATTRIBUTE_PHRASE",
+  "BRACE_PHRASE", "BRACKET_PHRASE", "EXPRESSION_PHRASE", "CHAR", "DOTS",
+  "IDENT", "INT", "REAL", "STRING", "TYPE", "OTHER", "FILENAME", "';'",
+  "'}'", "','", "'('", "'*'", "')'", "'='", "'{'", "':'", "$accept",
+  "declaration_seq", "declaration", "@1", "declaration1", "@2",
+  "simple_declaration", "init_declarator_list_opt", "init_declarator_list",
+  "init_declarator", "decl_specifier_seq_opt", "decl_specifier_seq",
+  "decl_specifier", "storage_class_specifier", "type_specifier",
+  "simple_type_specifier", "ptr_operator", "cvar_qualifier_seq_opt",
+  "cvar_qualifier_seq", "cvar_qualifier", "declarator",
+  "direct_declarator", "nested_declarator", "direct_nested_declarator",
+  "parameter_declaration_clause", "parameter_declaration_list_opt",
+  "parameter_declaration_list", "parameter_declaration",
+  "m_abstract_declarator", "direct_m_abstract_declarator",
+  "function_definition", "initializer_opt", "initializer", "class_body",
+  "member_specification_opt", "member_specification", "member_declaration",
+  "member_declarator_list_opt", "member_declarator_list",
+  "member_declarator", "member_bitfield_declarator", "attribute_opt",
+  "asm_definition", "asm_phrase_opt", "export_definition", 0
 };
+#endif
 
-static const short yypgoto[] = {-32768,
-   152,-32768,-32768,-32768,   119,-32768,-32768,    94,     0,   -55,
-   -35,-32768,-32768,-32768,   -69,-32768,-32768,   -56,   -30,-32768,
-   -76,-32768,  -122,-32768,-32768,    29,   -62,-32768,-32768,-32768,
--32768,   -17,-32768,-32768,   105,-32768,-32768,    52,    86,    83,
--32768,-32768,-32768
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,    59,   125,    44,    40,    42,    41,    61,
+     123,    58
 };
+# endif
 
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    52,    53,    53,    55,    54,    57,    56,    56,    56,
+      56,    56,    56,    56,    58,    59,    59,    60,    60,    61,
+      62,    62,    63,    63,    64,    64,    65,    65,    65,    65,
+      65,    66,    66,    66,    66,    66,    66,    66,    66,    66,
+      66,    66,    66,    66,    67,    67,    67,    67,    67,    67,
+      67,    67,    67,    67,    67,    68,    69,    69,    70,    70,
+      71,    71,    71,    71,    72,    72,    73,    73,    73,    73,
+      73,    73,    74,    74,    75,    75,    75,    75,    75,    75,
+      75,    76,    76,    76,    77,    77,    78,    78,    79,    80,
+      80,    81,    81,    81,    81,    81,    81,    81,    81,    82,
+      83,    83,    84,    85,    85,    86,    86,    87,    87,    88,
+      88,    89,    89,    90,    90,    91,    91,    91,    92,    93,
+      93,    94,    95,    95,    96
+};
 
-#define        YYLAST          533
-
-
-static const short yytable[] = {    78,
-    67,    99,    35,    84,    65,   125,    54,    49,   155,   152,
-    53,    80,    47,    88,   171,    89,     9,    48,    91,    55,
-   127,    50,   129,    56,    50,    18,   114,    99,    81,    99,
-    57,    69,    92,    87,    27,    77,   119,   168,    31,   -89,
-   126,    50,    67,   140,    96,    79,    58,   156,   131,   143,
-    97,    76,    60,   142,   -89,    60,    59,    68,    60,    95,
-    85,   159,   132,    96,    99,    45,    46,    93,    94,    97,
-    86,    60,   143,   143,    98,   160,   119,   126,   140,   157,
-   158,    96,   156,    67,    58,   111,   112,    97,   142,    60,
-    60,   106,   119,   113,    59,   116,    60,   128,   133,   134,
-    98,    70,    93,    88,   119,     6,     7,     8,     9,    10,
-    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-    21,    22,   135,    24,    25,    26,    27,    28,   139,   136,
-    31,   146,   147,   148,   149,   154,   -19,   150,   163,   164,
-    32,   165,   166,   -19,  -103,   169,   -19,   172,   -19,   107,
-   170,   -19,     4,     6,     7,     8,     9,    10,    11,    12,
-    13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-    75,    24,    25,    26,    27,    28,   162,   108,    31,   115,
-   124,     0,   130,     0,   -19,   153,     0,     0,    32,     0,
-     0,   -19,  -104,     0,   -19,     0,   -19,     5,     0,   -19,
-     0,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-    15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-    25,    26,    27,    28,    29,    30,    31,     0,     0,     0,
-     0,     0,   -19,     0,     0,     0,    32,     0,     0,   -19,
-     0,   118,   -19,     0,   -19,     6,     7,     8,     9,    10,
-    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-    21,    22,     0,    24,    25,    26,    27,    28,     0,     0,
-    31,     0,     0,     0,     0,   -82,     0,     0,     0,     0,
-    32,     0,     0,     0,   151,     0,     0,   -82,     6,     7,
-     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-    18,    19,    20,    21,    22,     0,    24,    25,    26,    27,
-    28,     0,     0,    31,     0,     0,     0,     0,   -82,     0,
-     0,     0,     0,    32,     0,     0,     0,   167,     0,     0,
-   -82,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-    15,    16,    17,    18,    19,    20,    21,    22,     0,    24,
-    25,    26,    27,    28,     0,     0,    31,     0,     0,     0,
-     0,   -82,     0,     0,     0,     0,    32,     0,     0,     0,
-     0,     0,     0,   -82,     6,     7,     8,     9,    10,    11,
-    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-    22,     0,    24,    25,    26,    27,    28,     0,     0,    31,
-     0,     0,     0,     0,     0,   140,     0,     0,     0,   141,
-     0,     0,     0,     0,     0,   142,     0,    60,     6,     7,
-     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-    18,    19,    20,    21,    22,     0,    24,    25,    26,    27,
-    28,     0,     0,    31,     0,     0,     0,     0,     0,     0,
-     0,     0,     0,    32,     0,     0,     0,     0,     0,     0,
-   110,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-    15,    16,    17,    18,    19,    20,    21,    22,     0,    24,
-    25,    26,    27,    28,     0,     0,    31,     0,     0,     0,
-     0,   161,     0,     0,     0,     0,    32,     6,     7,     8,
-     9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-    19,    20,    21,    22,     0,    24,    25,    26,    27,    28,
-     0,     0,    31,     0,     0,     0,     0,     0,     0,     0,
-     0,     0,    32
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     1,     2,     0,     2,     0,     3,     1,     1,
+       1,     1,     2,     2,     3,     0,     1,     1,     3,     4,
+       0,     1,     1,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     5,     4,     2,     2,     2,     3,     3,
+       3,     2,     2,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     2,     0,     1,     1,     2,
+       1,     1,     1,     1,     2,     1,     1,     4,     4,     2,
+       3,     3,     2,     1,     1,     1,     4,     4,     2,     3,
+       3,     2,     1,     3,     0,     1,     1,     3,     2,     2,
+       1,     0,     1,     1,     4,     4,     2,     3,     3,     3,
+       0,     1,     2,     3,     3,     0,     1,     1,     2,     3,
+       2,     0,     1,     1,     3,     2,     2,     1,     2,     0,
+       1,     2,     0,     1,     5
 };
 
-static const short yycheck[] = {    55,
-    36,    71,     3,    60,    35,     1,    24,    36,     1,   132,
-    36,     1,    31,    29,     0,    31,     8,    36,    32,    46,
-    97,    50,    99,    46,    50,    17,    83,    97,    59,    99,
-    43,    49,    46,    64,    26,    53,    92,   160,    30,    32,
-    36,    50,    78,    36,    40,    36,    36,    40,    32,   119,
-    46,    52,    48,    46,    47,    48,    46,    31,    48,    36,
-    43,    32,    46,    40,   134,    43,    44,    43,    44,    46,
-    45,    48,   142,   143,    51,    46,   132,    36,    36,   142,
-   143,    40,    40,   119,    36,    47,    47,    46,    46,    48,
-    48,    44,   148,    47,    46,    30,    48,    33,    43,    45,
-    51,     1,    43,    29,   160,     5,     6,     7,     8,     9,
-    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-    20,    21,    43,    23,    24,    25,    26,    27,    47,    49,
-    30,    47,    35,    45,    47,    33,    36,    47,    47,    47,
-    40,    47,    47,    43,    44,    47,    46,     0,    48,     1,
-    47,    51,     1,     5,     6,     7,     8,     9,    10,    11,
-    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-    52,    23,    24,    25,    26,    27,   148,    73,    30,    86,
-    95,    -1,   100,    -1,    36,   134,    -1,    -1,    40,    -1,
-    -1,    43,    44,    -1,    46,    -1,    48,     1,    -1,    51,
-    -1,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-    14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
-    24,    25,    26,    27,    28,    29,    30,    -1,    -1,    -1,
-    -1,    -1,    36,    -1,    -1,    -1,    40,    -1,    -1,    43,
-    -1,     1,    46,    -1,    48,     5,     6,     7,     8,     9,
-    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-    20,    21,    -1,    23,    24,    25,    26,    27,    -1,    -1,
-    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,    -1,
-    40,    -1,    -1,    -1,     1,    -1,    -1,    47,     5,     6,
-     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-    17,    18,    19,    20,    21,    -1,    23,    24,    25,    26,
-    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    35,    -1,
-    -1,    -1,    -1,    40,    -1,    -1,    -1,     1,    -1,    -1,
-    47,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-    14,    15,    16,    17,    18,    19,    20,    21,    -1,    23,
-    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,
-    -1,    35,    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,
-    -1,    -1,    -1,    47,     5,     6,     7,     8,     9,    10,
-    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-    21,    -1,    23,    24,    25,    26,    27,    -1,    -1,    30,
-    -1,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    40,
-    -1,    -1,    -1,    -1,    -1,    46,    -1,    48,     5,     6,
-     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-    17,    18,    19,    20,    21,    -1,    23,    24,    25,    26,
-    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,    -1,
-    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,
-    47,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-    14,    15,    16,    17,    18,    19,    20,    21,    -1,    23,
-    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,
-    -1,    35,    -1,    -1,    -1,    -1,    40,     5,     6,     7,
-     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-    18,    19,    20,    21,    -1,    23,    24,    25,    26,    27,
-    -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-    -1,    -1,    40
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       4,     4,     2,     0,     1,     3,     0,    26,    53,    44,
+      60,    51,     0,    29,    50,    30,    46,    47,    27,    63,
+      45,    48,    28,     0,     6,     0,    49,    52,    61,     0,
+       0,     0,    62,    54,     5,     8,    15,    21,    22,    24,
+      25,    31,    32,     9,    10,    11,    12,    13,    41,    37,
+      35,     0,    42,    20,    36,    43,     0,     0,   121,    66,
+       0,    56,     0,    16,    17,     0,   122,    65,    23,    40,
+      38,     0,   111,     0,     0,   107,     7,    15,    39,     0,
+       0,     0,     0,    55,    57,    58,    14,     0,    64,   123,
+      99,   119,    69,     0,   110,   104,    74,    75,     0,     0,
+       0,   119,    73,     0,   112,   113,   117,   103,     0,   108,
+     122,     0,    34,     0,    71,    70,    59,    18,   120,   100,
+       0,    91,     0,    82,    85,    86,   116,     0,    74,     0,
+     118,    72,   115,    78,     0,   109,     0,    33,   124,     0,
+      19,   101,    68,    92,    54,     0,    91,    88,    90,    67,
+      81,     0,    80,    79,     0,     0,   114,   102,     0,    93,
+       0,    89,    96,     0,    83,    87,    77,    76,    98,    97,
+       0,     0,    95,    94
 };
-/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
-#line 3 "/usr/lib/bison.simple"
-/* This file comes from bison-1.28.  */
 
-/* Skeleton output parser for bison,
-   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+      -1,     1,     2,     3,    34,    53,    35,    62,    63,    64,
+      72,    37,    38,    39,    40,    41,    65,    83,    84,    42,
+     110,    67,   101,   102,   122,   123,   124,   125,   147,   148,
+      43,   140,   141,    52,    73,    74,    75,   103,   104,   105,
+     106,   119,    44,    91,    45
+};
 
-   This program is free software; you can redistribute 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.
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -128
+static const short int yypact[] =
+{
+    -128,    13,  -128,   329,  -128,  -128,    36,  -128,  -128,  -128,
+    -128,  -128,   -16,  -128,  -128,  -128,  -128,  -128,  -128,  -128,
+    -128,  -128,  -128,   -25,  -128,   -24,  -128,  -128,  -128,   -29,
+      -4,   -22,  -128,  -128,  -128,  -128,   -28,   495,  -128,  -128,
+    -128,  -128,  -128,  -128,  -128,  -128,  -128,  -128,  -128,    16,
+     -23,   103,  -128,   495,   -23,  -128,   495,    35,  -128,  -128,
+       3,    15,     9,    17,  -128,   -28,   -15,    -8,  -128,  -128,
+    -128,    47,    23,    44,   150,  -128,  -128,   -28,  -128,   372,
+      33,    48,    49,  -128,    15,  -128,  -128,   -28,  -128,  -128,
+    -128,    64,  -128,   197,  -128,  -128,    50,  -128,    21,    65,
+      37,    64,    14,    56,    55,  -128,  -128,  -128,    59,  -128,
+      74,    57,  -128,    63,  -128,  -128,  -128,  -128,  -128,    76,
+      83,   416,    84,    99,    90,  -128,  -128,    88,  -128,    89,
+    -128,  -128,  -128,  -128,   241,  -128,    23,  -128,  -128,   105,
+    -128,  -128,  -128,  -128,  -128,     8,    46,  -128,    26,  -128,
+    -128,   459,  -128,  -128,    92,    93,  -128,  -128,    94,  -128,
+      96,  -128,  -128,   285,  -128,  -128,  -128,  -128,  -128,  -128,
+      97,   100,  -128,  -128
+};
 
-   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.
+/* YYPGOTO[NTERM-NUM].  */
+static const short int yypgoto[] =
+{
+    -128,  -128,   151,  -128,  -128,  -128,   119,  -128,  -128,    66,
+       0,   -56,   -36,  -128,  -128,  -128,   -70,  -128,  -128,   -51,
+     -31,  -128,   -11,  -128,  -127,  -128,  -128,    27,   -81,  -128,
+    -128,  -128,  -128,   -19,  -128,  -128,   107,  -128,  -128,    43,
+      86,    82,  -128,  -128,  -128
+};
 
-   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.  */
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -107
+static const short int yytable[] =
+{
+      79,    68,   100,    36,    81,    66,    55,   155,    59,   158,
+      85,    50,    54,     4,    89,    48,    90,    56,    60,    61,
+      49,    58,   127,    10,    92,    51,    51,    51,   100,    82,
+     100,    70,    19,   116,    88,    78,   171,   121,    93,    59,
+     -91,    28,    57,    68,   143,    32,   133,    69,   159,    60,
+      61,   146,    86,    77,   145,    61,   -91,   128,   162,    96,
+     134,    97,    87,    97,   160,   161,   100,    98,    61,    98,
+      61,    80,   163,   128,    99,   146,   146,    97,   121,    46,
+      47,   113,   143,    98,    61,    68,   159,   129,   107,   131,
+      94,    95,   145,    61,   118,   121,   114,   115,   130,   135,
+     136,    99,    94,    89,    71,   137,   138,   121,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,   139,    25,    26,    27,    28,
+      29,   142,   149,    32,   150,   151,   152,   153,   157,   -20,
+     166,   167,   168,    33,   169,   172,   -20,  -105,   173,   -20,
+     -20,   108,     5,   117,   -20,     7,     8,     9,    10,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    76,    25,    26,    27,    28,    29,   165,   156,
+      32,   109,   126,   132,     0,     0,   -20,     0,     0,     0,
+      33,     0,     0,   -20,  -106,     0,   -20,   -20,   120,     0,
+       0,   -20,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,     0,
+      25,    26,    27,    28,    29,     0,     0,    32,     0,     0,
+       0,     0,   -84,     0,     0,     0,     0,    33,     0,     0,
+       0,     0,   154,     0,     0,   -84,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,     0,    25,    26,    27,    28,    29,     0,
+       0,    32,     0,     0,     0,     0,   -84,     0,     0,     0,
+       0,    33,     0,     0,     0,     0,   170,     0,     0,   -84,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,     0,    25,    26,
+      27,    28,    29,     0,     0,    32,     0,     0,     0,     0,
+     -84,     0,     0,     0,     0,    33,     0,     0,     0,     0,
+       6,     0,     0,   -84,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+       0,     0,     0,     0,     0,   -20,     0,     0,     0,    33,
+       0,     0,   -20,     0,     0,   -20,   -20,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,     0,    25,    26,    27,    28,    29,
+       0,     0,    32,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    33,     0,     0,     0,     0,     0,     0,   111,
+     112,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    23,     0,    25,
+      26,    27,    28,    29,     0,     0,    32,     0,     0,     0,
+       0,     0,   143,     0,     0,     0,   144,     0,     0,     0,
+       0,     0,   145,    61,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,     0,    25,    26,    27,    28,    29,     0,     0,    32,
+       0,     0,     0,     0,   164,     0,     0,     0,     0,    33,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,     0,    25,    26,
+      27,    28,    29,     0,     0,    32,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    33
+};
 
-/* As a special exception, when this file is copied by Bison into a
-   Bison output file, you may use that output file without restriction.
-   This special exception was added by the Free Software Foundation
-   in version 1.24 of Bison.  */
+static const short int yycheck[] =
+{
+      56,    37,    72,     3,     1,    36,    25,   134,    36,     1,
+      61,    36,    36,     0,    29,    31,    31,    46,    46,    47,
+      36,    43,     1,     8,    32,    50,    50,    50,    98,    60,
+     100,    50,    17,    84,    65,    54,   163,    93,    46,    36,
+      32,    26,    46,    79,    36,    30,    32,    31,    40,    46,
+      47,   121,    43,    53,    46,    47,    48,    36,    32,    36,
+      46,    40,    45,    40,   145,   146,   136,    46,    47,    46,
+      47,    36,    46,    36,    51,   145,   146,    40,   134,    43,
+      44,    48,    36,    46,    47,   121,    40,    98,    44,   100,
+      43,    44,    46,    47,    30,   151,    48,    48,    33,    43,
+      45,    51,    43,    29,     1,    48,    43,   163,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    49,    23,    24,    25,    26,
+      27,    48,    48,    30,    35,    45,    48,    48,    33,    36,
+      48,    48,    48,    40,    48,    48,    43,    44,    48,    46,
+      47,     1,     1,    87,    51,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    53,    23,    24,    25,    26,    27,   151,   136,
+      30,    74,    96,   101,    -1,    -1,    36,    -1,    -1,    -1,
+      40,    -1,    -1,    43,    44,    -1,    46,    47,     1,    -1,
+      -1,    51,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    -1,
+      23,    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,
+      -1,    -1,    35,    -1,    -1,    -1,    -1,    40,    -1,    -1,
+      -1,    -1,     1,    -1,    -1,    48,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    -1,    23,    24,    25,    26,    27,    -1,
+      -1,    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,
+      -1,    40,    -1,    -1,    -1,    -1,     1,    -1,    -1,    48,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    -1,    23,    24,
+      25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,
+      35,    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,
+       1,    -1,    -1,    48,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      -1,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    40,
+      -1,    -1,    43,    -1,    -1,    46,    47,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    -1,    23,    24,    25,    26,    27,
+      -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,    47,
+      48,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    -1,    23,
+      24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,
+      -1,    -1,    36,    -1,    -1,    -1,    40,    -1,    -1,    -1,
+      -1,    -1,    46,    47,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    -1,    23,    24,    25,    26,    27,    -1,    -1,    30,
+      -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,    -1,    40,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    -1,    23,    24,
+      25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    40
+};
 
-/* This is the parser code that is written into each bison parser
-  when the %semantic_parser declaration is not specified in the grammar.
-  It was written by Richard Stallman by simplifying the hairy parser
-  used when %semantic_parser is specified.  */
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,    53,    54,    55,     0,    54,     1,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    40,    56,    58,    62,    63,    64,    65,
+      66,    67,    71,    82,    94,    96,    43,    44,    31,    36,
+      36,    50,    85,    57,    36,    85,    46,    46,    43,    36,
+      46,    47,    59,    60,    61,    68,    72,    73,    64,    31,
+      85,     1,    62,    86,    87,    88,    58,    62,    85,    63,
+      36,     1,    72,    69,    70,    71,    43,    45,    72,    29,
+      31,    95,    32,    46,    43,    44,    36,    40,    46,    51,
+      68,    74,    75,    89,    90,    91,    92,    44,     1,    88,
+      72,    47,    48,    48,    48,    48,    71,    61,    30,    93,
+       1,    63,    76,    77,    78,    79,    92,     1,    36,    74,
+      33,    74,    93,    32,    46,    43,    45,    48,    43,    49,
+      83,    84,    48,    36,    40,    46,    68,    80,    81,    48,
+      35,    45,    48,    48,     1,    76,    91,    33,     1,    40,
+      80,    80,    32,    46,    35,    79,    48,    48,    48,    48,
+       1,    76,    48,    48
+};
 
-#ifndef YYSTACK_USE_ALLOCA
-#ifdef alloca
-#define YYSTACK_USE_ALLOCA
-#else /* alloca not defined */
-#ifdef __GNUC__
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#else /* not GNU C.  */
-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
-#define YYSTACK_USE_ALLOCA
-#include <alloca.h>
-#else /* not sparc */
-/* We think this test detects Watcom and Microsoft C.  */
-/* This used to test MSDOS, but that is a bad idea
-   since that symbol is in the user namespace.  */
-#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
-#if 0 /* No need for malloc.h, which pollutes the namespace;
-        instead, just don't use alloca.  */
-#include <malloc.h>
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
 #endif
-#else /* not MSDOS, or __TURBOC__ */
-#if defined(_AIX)
-/* I don't know what this was needed for, but it pollutes the namespace.
-   So I turned it off.   rms, 2 May 1997.  */
-/* #include <malloc.h>  */
- #pragma alloca
-#define YYSTACK_USE_ALLOCA
-#else /* not MSDOS, or __TURBOC__, or _AIX */
-#if 0
-#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
-                and on HPUX 10.  Eventually we can turn this on.  */
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#endif /* __hpux */
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
 #endif
-#endif /* not _AIX */
-#endif /* not MSDOS, or __TURBOC__ */
-#endif /* not sparc */
-#endif /* not GNU C */
-#endif /* alloca not defined */
-#endif /* YYSTACK_USE_ALLOCA not defined */
-
-#ifdef YYSTACK_USE_ALLOCA
-#define YYSTACK_ALLOC alloca
-#else
-#define YYSTACK_ALLOC malloc
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
 #endif
-
-/* Note: there must be only one dollar sign in this file.
-   It is replaced by the list of actions, each action
-   as one case of the switch.  */
 
 #define yyerrok                (yyerrstatus = 0)
 #define yyclearin      (yychar = YYEMPTY)
-#define YYEMPTY                -2
+#define YYEMPTY                (-2)
 #define YYEOF          0
+
 #define YYACCEPT       goto yyacceptlab
-#define YYABORT        goto yyabortlab
-#define YYERROR                goto yyerrlab1
-/* Like YYERROR except do call yyerror.
-   This remains here temporarily to ease the
-   transition to the new meaning of YYERROR, for GCC.
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
    Once GCC version 2 has supplanted version 1, this can go.  */
+
 #define YYFAIL         goto yyerrlab
+
 #define YYRECOVERING()  (!!yyerrstatus)
-#define YYBACKUP(token, value) \
+
+#define YYBACKUP(Token, Value)                                 \
 do                                                             \
   if (yychar == YYEMPTY && yylen == 1)                         \
-    { yychar = (token), yylval = (value);                      \
-      yychar1 = YYTRANSLATE (yychar);                          \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
       YYPOPSTACK;                                              \
       goto yybackup;                                           \
     }                                                          \
   else                                                         \
-    { yyerror ("syntax error: cannot back up"); YYERROR; }     \
+    {                                                          \
+      yyerror ("syntax error: cannot back up");\
+      YYERROR;                                                 \
+    }                                                          \
 while (0)
 
+
 #define YYTERROR       1
 #define YYERRCODE      256
 
-#ifndef YYPURE
-#define YYLEX          yylex()
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (N)                                                           \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (0)
 #endif
 
-#ifdef YYPURE
-#ifdef YYLSP_NEEDED
-#ifdef YYLEX_PARAM
-#define YYLEX          yylex(&yylval, &yylloc, YYLEX_PARAM)
-#else
-#define YYLEX          yylex(&yylval, &yylloc)
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+              (Loc).first_line, (Loc).first_column,    \
+              (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
 #endif
-#else /* not YYLSP_NEEDED */
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
 #ifdef YYLEX_PARAM
-#define YYLEX          yylex(&yylval, YYLEX_PARAM)
+# define YYLEX yylex (YYLEX_PARAM)
 #else
-#define YYLEX          yylex(&yylval)
+# define YYLEX yylex ()
 #endif
-#endif /* not YYLSP_NEEDED */
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)         \
+do {                                                           \
+  if (yydebug)                                                 \
+    {                                                          \
+      YYFPRINTF (stderr, "%s ", Title);                                \
+      yysymprint (stderr,                                      \
+                  Type, Value);        \
+      YYFPRINTF (stderr, "\n");                                        \
+    }                                                          \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short int *bottom;
+    short int *top;
 #endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
 
-/* If nonreentrant, generate the variables here */
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (0)
 
-#ifndef YYPURE
 
-int    yychar;                 /*  the lookahead symbol                */
-YYSTYPE        yylval;                 /*  the semantic value of the           */
-                               /*  lookahead symbol                    */
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
 
-#ifdef YYLSP_NEEDED
-YYLTYPE yylloc;                        /*  location data for the lookahead     */
-                               /*  symbol                              */
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
 #endif
+{
+  int yyi;
+  unsigned int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+             yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
 
-int yynerrs;                   /*  number of parse errors so far       */
-#endif  /* not YYPURE */
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (Rule);            \
+} while (0)
 
-#if YYDEBUG != 0
-int yydebug;                   /*  nonzero means print parse trace     */
-/* Since this is uninitialized, it does not stop multiple parsers
-   from coexisting.  */
-#endif
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
 
-/*  YYINITDEPTH indicates the initial size of the parser's stacks      */
 
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
 #ifndef        YYINITDEPTH
-#define YYINITDEPTH 200
+# define YYINITDEPTH 200
 #endif
 
-/*  YYMAXDEPTH is the maximum size the stacks can grow to
-    (effective only if the built-in stack extension method is used).  */
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
 
-#if YYMAXDEPTH == 0
-#undef YYMAXDEPTH
-#endif
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
 
 #ifndef YYMAXDEPTH
-#define YYMAXDEPTH 10000
+# define YYMAXDEPTH 10000
 #endif
+
 \f
-/* Define __yy_memcpy.  Note that the size argument
-   should be passed with type unsigned int, because that is what the non-GCC
-   definitions require.  With GCC, __builtin_memcpy takes an arg
-   of type size_t, but it can handle unsigned int.  */
-
-#if __GNUC__ > 1               /* GNU C and GNU C++ define this.  */
-#define __yy_memcpy(TO,FROM,COUNT)     __builtin_memcpy(TO,FROM,COUNT)
-#else                          /* not GNU C or C++ */
-#ifndef __cplusplus
-
-/* This is the most reliable way to avoid incompatibilities
-   in available built-in functions on various systems.  */
-static void
-__yy_memcpy (to, from, count)
-     char *to;
-     char *from;
-     unsigned int count;
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
 {
-  register char *f = from;
-  register char *t = to;
-  register int i = count;
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
 
-  while (i-- > 0)
-    *t++ = *f++;
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
 }
+#  endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
 
-#else /* __cplusplus */
+\f
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
 
-/* This is the most reliable way to avoid incompatibilities
-   in available built-in functions on various systems.  */
+#if defined (__STDC__) || defined (__cplusplus)
 static void
-__yy_memcpy (char *to, char *from, unsigned int count)
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
 {
-  register char *t = to;
-  register char *f = from;
-  register int i = count;
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
 
-  while (i-- > 0)
-    *t++ = *f++;
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
 }
 
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
 #endif
-#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+        break;
+    }
+}
 \f
-#line 217 "/usr/lib/bison.simple"
 
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
-   into yyparse.  The argument should have type void *.
-   It should actually point to an object.
-   Grammar actions can access the variable by casting it
-   to the proper pointer type.  */
+/* Prevent warnings from -Wmissing-prototypes.  */
 
 #ifdef YYPARSE_PARAM
-#ifdef __cplusplus
-#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL
-#else /* not __cplusplus */
-#define YYPARSE_PARAM_ARG YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-#endif /* not __cplusplus */
-#else /* not YYPARSE_PARAM */
-#define YYPARSE_PARAM_ARG
-#define YYPARSE_PARAM_DECL
-#endif /* not YYPARSE_PARAM */
-
-/* Prevent warning if -Wstrict-prototypes.  */
-#ifdef __GNUC__
-#ifdef YYPARSE_PARAM
-int yyparse (void *);
-#else
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
 int yyparse (void);
+#else
+int yyparse ();
 #endif
-#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
 
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
 int
-yyparse(YYPARSE_PARAM_ARG)
-     YYPARSE_PARAM_DECL
+yyparse ()
+
+#endif
+#endif
 {
+  
   register int yystate;
   register int yyn;
-  register short *yyssp;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  register short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
   register YYSTYPE *yyvsp;
-  int yyerrstatus;     /*  number of tokens to shift before error messages enabled */
-  int yychar1 = 0;             /*  lookahead token as an internal (translated) token number */
-
-  short        yyssa[YYINITDEPTH];     /*  the state stack                     */
-  YYSTYPE yyvsa[YYINITDEPTH];  /*  the semantic value stack            */
 
-  short *yyss = yyssa;         /*  refer to the stacks thru separate pointers */
-  YYSTYPE *yyvs = yyvsa;       /*  to allow yyoverflow to reallocate them elsewhere */
 
-#ifdef YYLSP_NEEDED
-  YYLTYPE yylsa[YYINITDEPTH];  /*  the location stack                  */
-  YYLTYPE *yyls = yylsa;
-  YYLTYPE *yylsp;
 
-#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
-#else
 #define YYPOPSTACK   (yyvsp--, yyssp--)
-#endif
 
-  int yystacksize = YYINITDEPTH;
-  int yyfree_stacks = 0;
+  YYSIZE_T yystacksize = YYINITDEPTH;
 
-#ifdef YYPURE
-  int yychar;
-  YYSTYPE yylval;
-  int yynerrs;
-#ifdef YYLSP_NEEDED
-  YYLTYPE yylloc;
-#endif
-#endif
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
 
-  YYSTYPE yyval;               /*  the variable used to return         */
-                               /*  semantic values from the action     */
-                               /*  routines                            */
 
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
   int yylen;
 
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Starting parse\n");
-#endif
+  YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
@@ -741,833 +1175,872 @@ yyparse(YYPARSE_PARAM_ARG)
      so that they stay on the same level as the state stack.
      The wasted elements are never initialized.  */
 
-  yyssp = yyss - 1;
+  yyssp = yyss;
   yyvsp = yyvs;
-#ifdef YYLSP_NEEDED
-  yylsp = yyls;
-#endif
 
-/* Push a new state, which is found in  yystate  .  */
-/* In all cases, when you get here, the value and location stacks
-   have just been pushed. so pushing a state here evens the stacks.  */
-yynewstate:
 
-  *++yyssp = yystate;
+  yyvsp[0] = yylval;
 
-  if (yyssp >= yyss + yystacksize - 1)
-    {
-      /* Give user a chance to reallocate the stack */
-      /* Use copies of these so that the &'s don't force the real ones into memory. */
-      YYSTYPE *yyvs1 = yyvs;
-      short *yyss1 = yyss;
-#ifdef YYLSP_NEEDED
-      YYLTYPE *yyls1 = yyls;
-#endif
+  goto yysetstate;
 
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
       /* Get the current used size of the three stacks, in elements.  */
-      int size = yyssp - yyss + 1;
+      YYSIZE_T yysize = yyssp - yyss + 1;
 
 #ifdef yyoverflow
-      /* Each stack pointer address is followed by the size of
-        the data in use in that stack, in bytes.  */
-#ifdef YYLSP_NEEDED
-      /* This used to be a conditional around just the two extra args,
-        but that might be undefined if yyoverflow is a macro.  */
-      yyoverflow("parser stack overflow",
-                &yyss1, size * sizeof (*yyssp),
-                &yyvs1, size * sizeof (*yyvsp),
-                &yyls1, size * sizeof (*yylsp),
-                &yystacksize);
-#else
-      yyoverflow("parser stack overflow",
-                &yyss1, size * sizeof (*yyssp),
-                &yyvs1, size * sizeof (*yyvsp),
-                &yystacksize);
-#endif
-
-      yyss = yyss1; yyvs = yyvs1;
-#ifdef YYLSP_NEEDED
-      yyls = yyls1;
-#endif
+      {
+       /* Give user a chance to reallocate the stack. Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       short int *yyss1 = yyss;
+
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow ("parser stack overflow",
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+
+                   &yystacksize);
+
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
 #else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
       /* Extend the stack our own way.  */
-      if (yystacksize >= YYMAXDEPTH)
-       {
-         yyerror("parser stack overflow");
-         if (yyfree_stacks)
-           {
-             free (yyss);
-             free (yyvs);
-#ifdef YYLSP_NEEDED
-             free (yyls);
-#endif
-           }
-         return 2;
-       }
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyoverflowlab;
       yystacksize *= 2;
-      if (yystacksize > YYMAXDEPTH)
+      if (YYMAXDEPTH < yystacksize)
        yystacksize = YYMAXDEPTH;
-#ifndef YYSTACK_USE_ALLOCA
-      yyfree_stacks = 1;
-#endif
-      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
-      __yy_memcpy ((char *)yyss, (char *)yyss1,
-                  size * (unsigned int) sizeof (*yyssp));
-      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
-      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
-                  size * (unsigned int) sizeof (*yyvsp));
-#ifdef YYLSP_NEEDED
-      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
-      __yy_memcpy ((char *)yyls, (char *)yyls1,
-                  size * (unsigned int) sizeof (*yylsp));
-#endif
+
+      {
+       short int *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyoverflowlab;
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
 #endif /* no yyoverflow */
 
-      yyssp = yyss + size - 1;
-      yyvsp = yyvs + size - 1;
-#ifdef YYLSP_NEEDED
-      yylsp = yyls + size - 1;
-#endif
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
 
-#if YYDEBUG != 0
-      if (yydebug)
-       fprintf(stderr, "Stack size increased to %d\n", yystacksize);
-#endif
 
-      if (yyssp >= yyss + yystacksize - 1)
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
        YYABORT;
     }
 
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Entering state %d\n", yystate);
-#endif
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
   goto yybackup;
- yybackup:
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
 
 /* Do appropriate processing given the current state.  */
-/* Read a lookahead token if we need one and don't already have one.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
 /* yyresume: */
 
-  /* First try to decide what to do without reference to lookahead token.  */
+  /* First try to decide what to do without reference to look-ahead token.  */
 
   yyn = yypact[yystate];
-  if (yyn == YYFLAG)
+  if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a lookahead token if don't already have one.  */
-
-  /* yychar is either YYEMPTY or YYEOF
-     or a valid token in external form.  */
+  /* Not known => get a look-ahead token if don't already have one.  */
 
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
-#if YYDEBUG != 0
-      if (yydebug)
-       fprintf(stderr, "Reading a token: ");
-#endif
+      YYDPRINTF ((stderr, "Reading a token: "));
       yychar = YYLEX;
     }
 
-  /* Convert token to internal form (in yychar1) for indexing tables with */
-
-  if (yychar <= 0)             /* This means end of input. */
+  if (yychar <= YYEOF)
     {
-      yychar1 = 0;
-      yychar = YYEOF;          /* Don't call YYLEX any more */
-
-#if YYDEBUG != 0
-      if (yydebug)
-       fprintf(stderr, "Now at end of input.\n");
-#endif
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
     }
   else
     {
-      yychar1 = YYTRANSLATE(yychar);
-
-#if YYDEBUG != 0
-      if (yydebug)
-       {
-         fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
-         /* Give the individual parser a way to print the precise meaning
-            of a token, for further debugging info.  */
-#ifdef YYPRINT
-         YYPRINT (stderr, yychar, yylval);
-#endif
-         fprintf (stderr, ")\n");
-       }
-#endif
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
     }
 
-  yyn += yychar1;
-  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
     goto yydefault;
-
   yyn = yytable[yyn];
-
-  /* yyn is what to do for this token type in this state.
-     Negative => reduce, -yyn is rule number.
-     Positive => shift, yyn is new state.
-       New state is final state => don't bother to shift,
-       just return success.
-     0, or most negative number => error.  */
-
-  if (yyn < 0)
+  if (yyn <= 0)
     {
-      if (yyn == YYFLAG)
+      if (yyn == 0 || yyn == YYTABLE_NINF)
        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
-  else if (yyn == 0)
-    goto yyerrlab;
 
   if (yyn == YYFINAL)
     YYACCEPT;
 
-  /* Shift the lookahead token.  */
-
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
-#endif
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
   /* Discard the token being shifted unless it is eof.  */
   if (yychar != YYEOF)
     yychar = YYEMPTY;
 
   *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
-  *++yylsp = yylloc;
-#endif
 
-  /* count tokens shifted since error; after three, turn off error status.  */
-  if (yyerrstatus) yyerrstatus--;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
 
   yystate = yyn;
   goto yynewstate;
 
-/* Do the default action for the current state.  */
-yydefault:
 
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
   yyn = yydefact[yystate];
   if (yyn == 0)
     goto yyerrlab;
+  goto yyreduce;
 
-/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
 yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
   yylen = yyr2[yyn];
-  if (yylen > 0)
-    yyval = yyvsp[1-yylen]; /* implement default value of the action */
-
-#if YYDEBUG != 0
-  if (yydebug)
-    {
-      int i;
 
-      fprintf (stderr, "Reducing via rule %d (line %d), ",
-              yyn, yyrline[yyn]);
-
-      /* Print the symbols being reduced, and their result.  */
-      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
-       fprintf (stderr, "%s ", yytname[yyrhs[i]]);
-      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
-    }
-#endif
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
 
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
 
-  switch (yyn) {
 
-case 3:
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 4:
 #line 107 "scripts/genksyms/parse.y"
-{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;
-    break;}
-case 4:
+    { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;}
+    break;
+
+  case 5:
 #line 109 "scripts/genksyms/parse.y"
-{ free_list(*yyvsp[0], NULL); *yyvsp[0] = NULL; ;
-    break;}
-case 5:
+    { free_list(*(yyvsp[0]), NULL); *(yyvsp[0]) = NULL; ;}
+    break;
+
+  case 6:
 #line 113 "scripts/genksyms/parse.y"
-{ is_typedef = 1; ;
-    break;}
-case 6:
+    { is_typedef = 1; ;}
+    break;
+
+  case 7:
 #line 114 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 11:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 12:
 #line 119 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 12:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 13:
 #line 120 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 13:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 14:
 #line 125 "scripts/genksyms/parse.y"
-{ if (current_name) {
-                   struct string_list *decl = (*yyvsp[0])->next;
-                   (*yyvsp[0])->next = NULL;
+    { if (current_name) {
+                   struct string_list *decl = (*(yyvsp[0]))->next;
+                   (*(yyvsp[0]))->next = NULL;
                    add_symbol(current_name,
                               is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
                               decl, is_extern);
                    current_name = NULL;
                  }
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 14:
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 15:
 #line 138 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 16:
+    { (yyval) = NULL; ;}
+    break;
+
+  case 17:
 #line 144 "scripts/genksyms/parse.y"
-{ struct string_list *decl = *yyvsp[0];
-                 *yyvsp[0] = NULL;
+    { struct string_list *decl = *(yyvsp[0]);
+                 *(yyvsp[0]) = NULL;
                  add_symbol(current_name,
                             is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
                  current_name = NULL;
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 17:
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 18:
 #line 152 "scripts/genksyms/parse.y"
-{ struct string_list *decl = *yyvsp[0];
-                 *yyvsp[0] = NULL;
-                 free_list(*yyvsp[-1], NULL);
-                 *yyvsp[-1] = decl_spec;
+    { struct string_list *decl = *(yyvsp[0]);
+                 *(yyvsp[0]) = NULL;
+                 free_list(*(yyvsp[-1]), NULL);
+                 *(yyvsp[-1]) = decl_spec;
                  add_symbol(current_name,
                             is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
                  current_name = NULL;
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 18:
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 19:
 #line 165 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1] ? yyvsp[-1] : yyvsp[-2] ? yyvsp[-2] : yyvsp[-3]; ;
-    break;}
-case 19:
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]) ? (yyvsp[-1]) : (yyvsp[-2]) ? (yyvsp[-2]) : (yyvsp[-3]); ;}
+    break;
+
+  case 20:
 #line 170 "scripts/genksyms/parse.y"
-{ decl_spec = NULL; ;
-    break;}
-case 21:
+    { decl_spec = NULL; ;}
+    break;
+
+  case 22:
 #line 175 "scripts/genksyms/parse.y"
-{ decl_spec = *yyvsp[0]; ;
-    break;}
-case 22:
+    { decl_spec = *(yyvsp[0]); ;}
+    break;
+
+  case 23:
 #line 176 "scripts/genksyms/parse.y"
-{ decl_spec = *yyvsp[0]; ;
-    break;}
-case 23:
+    { decl_spec = *(yyvsp[0]); ;}
+    break;
+
+  case 24:
 #line 181 "scripts/genksyms/parse.y"
-{ /* Version 2 checksumming ignores storage class, as that
+    { /* Version 2 checksumming ignores storage class, as that
                     is really irrelevant to the linkage.  */
-                 remove_node(yyvsp[0]);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 28:
+                 remove_node((yyvsp[0]));
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 29:
 #line 193 "scripts/genksyms/parse.y"
-{ is_extern = 1; yyval = yyvsp[0]; ;
-    break;}
-case 29:
+    { is_extern = 1; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 30:
 #line 194 "scripts/genksyms/parse.y"
-{ is_extern = 0; yyval = yyvsp[0]; ;
-    break;}
-case 33:
-#line 205 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_STRUCT; yyval = yyvsp[0]; ;
-    break;}
-case 34:
-#line 207 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_UNION; yyval = yyvsp[0]; ;
-    break;}
-case 35:
-#line 209 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_ENUM; yyval = yyvsp[0]; ;
-    break;}
-case 36:
-#line 213 "scripts/genksyms/parse.y"
-{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+    { is_extern = 0; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 35:
+#line 206 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_STRUCT; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 36:
+#line 208 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_UNION; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 37:
+#line 210 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_ENUM; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 38:
+#line 214 "scripts/genksyms/parse.y"
+    { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
                  r = copy_node(i); r->tag = SYM_STRUCT;
-                 r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+                 r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
                  add_symbol(i->string, SYM_STRUCT, s, is_extern);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 37:
-#line 220 "scripts/genksyms/parse.y"
-{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 39:
+#line 221 "scripts/genksyms/parse.y"
+    { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
                  r = copy_node(i); r->tag = SYM_UNION;
-                 r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+                 r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
                  add_symbol(i->string, SYM_UNION, s, is_extern);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 38:
-#line 227 "scripts/genksyms/parse.y"
-{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 40:
+#line 228 "scripts/genksyms/parse.y"
+    { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
                  r = copy_node(i); r->tag = SYM_ENUM;
-                 r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+                 r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
                  add_symbol(i->string, SYM_ENUM, s, is_extern);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 39:
-#line 235 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 40:
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 41:
 #line 236 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 41:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 42:
 #line 237 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 52:
-#line 251 "scripts/genksyms/parse.y"
-{ (*yyvsp[0])->tag = SYM_TYPEDEF; yyval = yyvsp[0]; ;
-    break;}
-case 53:
-#line 256 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 54:
-#line 260 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 57:
-#line 266 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 61:
-#line 272 "scripts/genksyms/parse.y"
-{ /* restrict has no effect in prototypes so ignore it */
-                 remove_node(yyvsp[0]);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 62:
-#line 279 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 64:
-#line 285 "scripts/genksyms/parse.y"
-{ if (current_name != NULL) {
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 43:
+#line 238 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 54:
+#line 252 "scripts/genksyms/parse.y"
+    { (*(yyvsp[0]))->tag = SYM_TYPEDEF; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 55:
+#line 257 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 56:
+#line 261 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 59:
+#line 267 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 63:
+#line 273 "scripts/genksyms/parse.y"
+    { /* restrict has no effect in prototypes so ignore it */
+                 remove_node((yyvsp[0]));
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 64:
+#line 280 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 66:
+#line 286 "scripts/genksyms/parse.y"
+    { if (current_name != NULL) {
                    error_with_pos("unexpected second declaration name");
                    YYERROR;
                  } else {
-                   current_name = (*yyvsp[0])->string;
-                   yyval = yyvsp[0];
+                   current_name = (*(yyvsp[0]))->string;
+                   (yyval) = (yyvsp[0]);
                  }
-               ;
-    break;}
-case 65:
-#line 294 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 66:
-#line 296 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 67:
-#line 298 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 68:
-#line 300 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 69:
-#line 302 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 70:
-#line 308 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 74:
-#line 316 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 75:
-#line 318 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 76:
-#line 320 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 77:
-#line 322 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 78:
-#line 324 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 79:
-#line 328 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 81:
-#line 330 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 82:
-#line 334 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 85:
-#line 341 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 86:
-#line 346 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 87:
-#line 351 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 89:
-#line 356 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 90:
-#line 358 "scripts/genksyms/parse.y"
-{ /* For version 2 checksums, we don't want to remember
+               ;}
+    break;
+
+  case 67:
+#line 295 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 68:
+#line 297 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 69:
+#line 299 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 70:
+#line 301 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 71:
+#line 303 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 72:
+#line 309 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 76:
+#line 317 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 77:
+#line 319 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 78:
+#line 321 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 79:
+#line 323 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 80:
+#line 325 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 81:
+#line 329 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 83:
+#line 331 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 84:
+#line 335 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 87:
+#line 342 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 88:
+#line 347 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 89:
+#line 352 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 91:
+#line 357 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 92:
+#line 359 "scripts/genksyms/parse.y"
+    { /* For version 2 checksums, we don't want to remember
                     private parameter names.  */
-                 remove_node(yyvsp[0]);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 91:
-#line 366 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[0]);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 92:
-#line 370 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 93:
-#line 372 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 94:
-#line 374 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 95:
-#line 376 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 96:
-#line 378 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 97:
-#line 383 "scripts/genksyms/parse.y"
-{ struct string_list *decl = *yyvsp[-1];
-                 *yyvsp[-1] = NULL;
+                 remove_node((yyvsp[0]));
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 93:
+#line 367 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[0]));
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 94:
+#line 371 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 95:
+#line 373 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 96:
+#line 375 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 97:
+#line 377 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 98:
+#line 379 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 99:
+#line 384 "scripts/genksyms/parse.y"
+    { struct string_list *decl = *(yyvsp[-1]);
+                 *(yyvsp[-1]) = NULL;
                  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
-                 yyval = yyvsp[0];
-               ;
-    break;}
-case 98:
-#line 391 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 100:
-#line 398 "scripts/genksyms/parse.y"
-{ remove_list(yyvsp[0], &(*yyvsp[-1])->next); yyval = yyvsp[0]; ;
-    break;}
-case 101:
-#line 402 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 102:
+                 (yyval) = (yyvsp[0]);
+               ;}
+    break;
+
+  case 100:
+#line 392 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 102:
+#line 399 "scripts/genksyms/parse.y"
+    { remove_list((yyvsp[0]), &(*(yyvsp[-1]))->next); (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 103:
 #line 403 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 103:
-#line 407 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 106:
-#line 413 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 107:
-#line 418 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 108:
-#line 420 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 109:
-#line 424 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 112:
-#line 430 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 113:
-#line 434 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 114:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 104:
+#line 404 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 105:
+#line 408 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 108:
+#line 414 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 109:
+#line 419 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 110:
+#line 421 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 111:
+#line 425 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 114:
+#line 431 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 115:
 #line 435 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 116:
-#line 440 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 117:
-#line 444 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 119:
-#line 449 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 120:
-#line 453 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 122:
-#line 459 "scripts/genksyms/parse.y"
-{ export_symbol((*yyvsp[-2])->string); yyval = yyvsp[0]; ;
-    break;}
-}
-   /* the action file gets copied in in place of this dollarsign */
-#line 543 "/usr/lib/bison.simple"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 116:
+#line 436 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 118:
+#line 441 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 119:
+#line 445 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 121:
+#line 450 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 122:
+#line 454 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 124:
+#line 460 "scripts/genksyms/parse.y"
+    { export_symbol((*(yyvsp[-2]))->string); (yyval) = (yyvsp[0]); ;}
+    break;
+
+
+    }
+
+/* Line 1037 of yacc.c.  */
+#line 1816 "scripts/genksyms/parse.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
-#ifdef YYLSP_NEEDED
-  yylsp -= yylen;
-#endif
 
-#if YYDEBUG != 0
-  if (yydebug)
-    {
-      short *ssp1 = yyss - 1;
-      fprintf (stderr, "state stack now");
-      while (ssp1 != yyssp)
-       fprintf (stderr, " %d", *++ssp1);
-      fprintf (stderr, "\n");
-    }
-#endif
+
+  YY_STACK_PRINT (yyss, yyssp);
 
   *++yyvsp = yyval;
 
-#ifdef YYLSP_NEEDED
-  yylsp++;
-  if (yylen == 0)
-    {
-      yylsp->first_line = yylloc.first_line;
-      yylsp->first_column = yylloc.first_column;
-      yylsp->last_line = (yylsp-1)->last_line;
-      yylsp->last_column = (yylsp-1)->last_column;
-      yylsp->text = 0;
-    }
-  else
-    {
-      yylsp->last_line = (yylsp+yylen-1)->last_line;
-      yylsp->last_column = (yylsp+yylen-1)->last_column;
-    }
-#endif
 
-  /* Now "shift" the result of the reduction.
-     Determine what state that goes to,
-     based on the state we popped back to
-     and the rule number reduced by.  */
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
 
   yyn = yyr1[yyn];
 
-  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
-  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
     yystate = yytable[yystate];
   else
-    yystate = yydefgoto[yyn - YYNTBASE];
+    yystate = yydefgoto[yyn - YYNTOKENS];
 
   goto yynewstate;
 
-yyerrlab:   /* here on detecting error */
 
-  if (! yyerrstatus)
-    /* If not already recovering from an error, report this error.  */
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
     {
       ++yynerrs;
-
-#ifdef YYERROR_VERBOSE
+#if YYERROR_VERBOSE
       yyn = yypact[yystate];
 
-      if (yyn > YYFLAG && yyn < YYLAST)
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
        {
-         int size = 0;
-         char *msg;
-         int x, count;
-
-         count = 0;
-         /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
-         for (x = (yyn < 0 ? -yyn : 0);
-              x < (sizeof(yytname) / sizeof(char *)); x++)
-           if (yycheck[x + yyn] == x)
-             size += strlen(yytname[x]) + 15, count++;
-         msg = (char *) malloc(size + 15);
-         if (msg != 0)
+         YYSIZE_T yysize = 0;
+         int yytype = YYTRANSLATE (yychar);
+         const char* yyprefix;
+         char *yymsg;
+         int yyx;
+
+         /* Start YYX at -YYN if negative to avoid negative indexes in
+            YYCHECK.  */
+         int yyxbegin = yyn < 0 ? -yyn : 0;
+
+         /* Stay within bounds of both yycheck and yytname.  */
+         int yychecklim = YYLAST - yyn;
+         int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+         int yycount = 0;
+
+         yyprefix = ", expecting ";
+         for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+             {
+               yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+               yycount += 1;
+               if (yycount == 5)
+                 {
+                   yysize = 0;
+                   break;
+                 }
+             }
+         yysize += (sizeof ("syntax error, unexpected ")
+                    + yystrlen (yytname[yytype]));
+         yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg != 0)
            {
-             strcpy(msg, "parse error");
+             char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+             yyp = yystpcpy (yyp, yytname[yytype]);
 
-             if (count < 5)
+             if (yycount < 5)
                {
-                 count = 0;
-                 for (x = (yyn < 0 ? -yyn : 0);
-                      x < (sizeof(yytname) / sizeof(char *)); x++)
-                   if (yycheck[x + yyn] == x)
+                 yyprefix = ", expecting ";
+                 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+                   if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
                      {
-                       strcat(msg, count == 0 ? ", expecting `" : " or `");
-                       strcat(msg, yytname[x]);
-                       strcat(msg, "'");
-                       count++;
+                       yyp = yystpcpy (yyp, yyprefix);
+                       yyp = yystpcpy (yyp, yytname[yyx]);
+                       yyprefix = " or ";
                      }
                }
-             yyerror(msg);
-             free(msg);
+             yyerror (yymsg);
+             YYSTACK_FREE (yymsg);
            }
          else
-           yyerror ("parse error; also virtual memory exceeded");
+           yyerror ("syntax error; also virtual memory exhausted");
        }
       else
 #endif /* YYERROR_VERBOSE */
-       yyerror("parse error");
+       yyerror ("syntax error");
     }
 
-  goto yyerrlab1;
-yyerrlab1:   /* here on error raised explicitly by an action */
+
 
   if (yyerrstatus == 3)
     {
-      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
-
-      /* return failure if at end of input */
-      if (yychar == YYEOF)
-       YYABORT;
-
-#if YYDEBUG != 0
-      if (yydebug)
-       fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
-#endif
-
-      yychar = YYEMPTY;
+      /* If just tried and failed to reuse look-ahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+          /* If at end of input, pop the error token,
+            then the rest of the stack, then return failure.  */
+         if (yychar == YYEOF)
+            for (;;)
+              {
+
+                YYPOPSTACK;
+                if (yyssp == yyss)
+                  YYABORT;
+                yydestruct ("Error: popping",
+                             yystos[*yyssp], yyvsp);
+              }
+        }
+      else
+       {
+         yydestruct ("Error: discarding", yytoken, &yylval);
+         yychar = YYEMPTY;
+       }
     }
 
-  /* Else will try to reuse lookahead token
-     after shifting the error token.  */
-
-  yyerrstatus = 3;             /* Each real token shifted decrements this */
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
 
-  goto yyerrhandle;
 
-yyerrdefault:  /* current state does not do anything special for the error token. */
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
 
-#if 0
-  /* This is wrong; only states that explicitly want error tokens
-     should shift them.  */
-  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
-  if (yyn) goto yydefault;
+#ifdef __GNUC__
+  /* Pacify GCC when the user code never invokes YYERROR and the label
+     yyerrorlab therefore never appears in user code.  */
+  if (0)
+     goto yyerrorlab;
 #endif
 
-yyerrpop:   /* pop the current state because it cannot handle the error token */
+yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
 
-  if (yyssp == yyss) YYABORT;
-  yyvsp--;
-  yystate = *--yyssp;
-#ifdef YYLSP_NEEDED
-  yylsp--;
-#endif
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
 
-#if YYDEBUG != 0
-  if (yydebug)
+  for (;;)
     {
-      short *ssp1 = yyss - 1;
-      fprintf (stderr, "Error: state stack now");
-      while (ssp1 != yyssp)
-       fprintf (stderr, " %d", *++ssp1);
-      fprintf (stderr, "\n");
-    }
-#endif
-
-yyerrhandle:
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
 
-  yyn = yypact[yystate];
-  if (yyn == YYFLAG)
-    goto yyerrdefault;
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
 
-  yyn += YYTERROR;
-  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
-    goto yyerrdefault;
 
-  yyn = yytable[yyn];
-  if (yyn < 0)
-    {
-      if (yyn == YYFLAG)
-       goto yyerrpop;
-      yyn = -yyn;
-      goto yyreduce;
+      yydestruct ("Error: popping", yystos[yystate], yyvsp);
+      YYPOPSTACK;
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
     }
-  else if (yyn == 0)
-    goto yyerrpop;
 
   if (yyn == YYFINAL)
     YYACCEPT;
 
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Shifting error token, ");
-#endif
-
   *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
-  *++yylsp = yylloc;
-#endif
+
+
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
 
   yystate = yyn;
   goto yynewstate;
 
- yyacceptlab:
-  /* YYACCEPT comes here.  */
-  if (yyfree_stacks)
-    {
-      free (yyss);
-      free (yyvs);
-#ifdef YYLSP_NEEDED
-      free (yyls);
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yydestruct ("Error: discarding lookahead",
+              yytoken, &yylval);
+  yychar = YYEMPTY;
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here.  |
+`----------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
 #endif
-    }
-  return 0;
 
- yyabortlab:
-  /* YYABORT comes here.  */
-  if (yyfree_stacks)
-    {
-      free (yyss);
-      free (yyvs);
-#ifdef YYLSP_NEEDED
-      free (yyls);
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
 #endif
-    }
-  return 1;
+  return yyresult;
 }
-#line 463 "scripts/genksyms/parse.y"
+
+
+#line 464 "scripts/genksyms/parse.y"
 
 
 static void
@@ -1575,3 +2048,4 @@ yyerror(const char *e)
 {
   error_with_pos("%s", e);
 }
+
index d5b27e3b20c444b2b7a0d3b0de20d6ae55a0a649..f3fb2bb058e125c2197df44b82dd13472199f7f7 100644 (file)
-#ifndef YYSTYPE
-#define YYSTYPE int
+/* A Bison parser, made by GNU Bison 2.0.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, 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.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ASM_KEYW = 258,
+     ATTRIBUTE_KEYW = 259,
+     AUTO_KEYW = 260,
+     BOOL_KEYW = 261,
+     CHAR_KEYW = 262,
+     CONST_KEYW = 263,
+     DOUBLE_KEYW = 264,
+     ENUM_KEYW = 265,
+     EXTERN_KEYW = 266,
+     FLOAT_KEYW = 267,
+     INLINE_KEYW = 268,
+     INT_KEYW = 269,
+     LONG_KEYW = 270,
+     REGISTER_KEYW = 271,
+     RESTRICT_KEYW = 272,
+     SHORT_KEYW = 273,
+     SIGNED_KEYW = 274,
+     STATIC_KEYW = 275,
+     STRUCT_KEYW = 276,
+     TYPEDEF_KEYW = 277,
+     UNION_KEYW = 278,
+     UNSIGNED_KEYW = 279,
+     VOID_KEYW = 280,
+     VOLATILE_KEYW = 281,
+     TYPEOF_KEYW = 282,
+     EXPORT_SYMBOL_KEYW = 283,
+     ASM_PHRASE = 284,
+     ATTRIBUTE_PHRASE = 285,
+     BRACE_PHRASE = 286,
+     BRACKET_PHRASE = 287,
+     EXPRESSION_PHRASE = 288,
+     CHAR = 289,
+     DOTS = 290,
+     IDENT = 291,
+     INT = 292,
+     REAL = 293,
+     STRING = 294,
+     TYPE = 295,
+     OTHER = 296,
+     FILENAME = 297
+   };
 #endif
-#define        ASM_KEYW        257
-#define        ATTRIBUTE_KEYW  258
-#define        AUTO_KEYW       259
-#define        BOOL_KEYW       260
-#define        CHAR_KEYW       261
-#define        CONST_KEYW      262
-#define        DOUBLE_KEYW     263
-#define        ENUM_KEYW       264
-#define        EXTERN_KEYW     265
-#define        FLOAT_KEYW      266
-#define        INLINE_KEYW     267
-#define        INT_KEYW        268
-#define        LONG_KEYW       269
-#define        REGISTER_KEYW   270
-#define        RESTRICT_KEYW   271
-#define        SHORT_KEYW      272
-#define        SIGNED_KEYW     273
-#define        STATIC_KEYW     274
-#define        STRUCT_KEYW     275
-#define        TYPEDEF_KEYW    276
-#define        UNION_KEYW      277
-#define        UNSIGNED_KEYW   278
-#define        VOID_KEYW       279
-#define        VOLATILE_KEYW   280
-#define        TYPEOF_KEYW     281
-#define        EXPORT_SYMBOL_KEYW      282
-#define        ASM_PHRASE      283
-#define        ATTRIBUTE_PHRASE        284
-#define        BRACE_PHRASE    285
-#define        BRACKET_PHRASE  286
-#define        EXPRESSION_PHRASE       287
-#define        CHAR    288
-#define        DOTS    289
-#define        IDENT   290
-#define        INT     291
-#define        REAL    292
-#define        STRING  293
-#define        TYPE    294
-#define        OTHER   295
-#define        FILENAME        296
+#define ASM_KEYW 258
+#define ATTRIBUTE_KEYW 259
+#define AUTO_KEYW 260
+#define BOOL_KEYW 261
+#define CHAR_KEYW 262
+#define CONST_KEYW 263
+#define DOUBLE_KEYW 264
+#define ENUM_KEYW 265
+#define EXTERN_KEYW 266
+#define FLOAT_KEYW 267
+#define INLINE_KEYW 268
+#define INT_KEYW 269
+#define LONG_KEYW 270
+#define REGISTER_KEYW 271
+#define RESTRICT_KEYW 272
+#define SHORT_KEYW 273
+#define SIGNED_KEYW 274
+#define STATIC_KEYW 275
+#define STRUCT_KEYW 276
+#define TYPEDEF_KEYW 277
+#define UNION_KEYW 278
+#define UNSIGNED_KEYW 279
+#define VOID_KEYW 280
+#define VOLATILE_KEYW 281
+#define TYPEOF_KEYW 282
+#define EXPORT_SYMBOL_KEYW 283
+#define ASM_PHRASE 284
+#define ATTRIBUTE_PHRASE 285
+#define BRACE_PHRASE 286
+#define BRACKET_PHRASE 287
+#define EXPRESSION_PHRASE 288
+#define CHAR 289
+#define DOTS 290
+#define IDENT 291
+#define INT 292
+#define REAL 293
+#define STRING 294
+#define TYPE 295
+#define OTHER 296
+#define FILENAME 297
+
 
 
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
 extern YYSTYPE yylval;
+
+
+
index 099043713db499412e8e7b4ef8309115be06df3e..ca04c944b7c3f527e19f0591729e4ee6e1abd882 100644 (file)
@@ -197,6 +197,7 @@ storage_class_specifier:
 type_specifier:
        simple_type_specifier
        | cvar_qualifier
+       | TYPEOF_KEYW '(' decl_specifier_seq '*' ')'
        | TYPEOF_KEYW '(' decl_specifier_seq ')'
 
        /* References to s/u/e's defined elsewhere.  Rearrange things
index 2dac3442e0ac3e8ac586493cddf56fc1ed4d21f2..e8ad1f6b3da4891f5996735afa64603ae018f916 100644 (file)
@@ -5,6 +5,7 @@ config*
 lex.*.c
 *.tab.c
 *.tab.h
+zconf.hash.c
 
 #
 # configuration programs
index a96153fc793fa0e0113d1e1831308d8a2122a841..3d7f1ac9e00ce89e881673142ef8ca517ca3010a 100644 (file)
@@ -11,7 +11,7 @@ gconfig: $(obj)/gconf
        $< arch/$(ARCH)/Kconfig
 
 menuconfig: $(obj)/mconf
-       $(Q)$(MAKE) $(build)=scripts/lxdialog
+       $(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
        $< arch/$(ARCH)/Kconfig
 
 config: $(obj)/conf
@@ -115,6 +115,7 @@ endif
 
 clean-files    := lkc_defs.h qconf.moc .tmp_qtcheck \
                   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
+subdir- += lxdialog
 
 # Needed for systems without gettext
 KBUILD_HAVE_NLS := $(shell \
diff --git a/scripts/kconfig/lxdialog/.gitignore b/scripts/kconfig/lxdialog/.gitignore
new file mode 100644 (file)
index 0000000..90b08ff
--- /dev/null
@@ -0,0 +1,4 @@
+#
+# Generated files
+#
+lxdialog
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
new file mode 100644 (file)
index 0000000..db07ae7
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ *  checklist.c -- implements the checklist box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static int list_width, check_x, item_x;
+
+/*
+ * Print list item
+ */
+static void print_item(WINDOW * win, const char *item, int status, int choice,
+                      int selected)
+{
+       int i;
+
+       /* Clear 'residue' of last item */
+       wattrset(win, menubox_attr);
+       wmove(win, choice, 0);
+       for (i = 0; i < list_width; i++)
+               waddch(win, ' ');
+
+       wmove(win, choice, check_x);
+       wattrset(win, selected ? check_selected_attr : check_attr);
+       wprintw(win, "(%c)", status ? 'X' : ' ');
+
+       wattrset(win, selected ? tag_selected_attr : tag_attr);
+       mvwaddch(win, choice, item_x, item[0]);
+       wattrset(win, selected ? item_selected_attr : item_attr);
+       waddstr(win, (char *)item + 1);
+       if (selected) {
+               wmove(win, choice, check_x + 1);
+               wrefresh(win);
+       }
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
+            int y, int x, int height)
+{
+       wmove(win, y, x);
+
+       if (scroll > 0) {
+               wattrset(win, uarrow_attr);
+               waddch(win, ACS_UARROW);
+               waddstr(win, "(-)");
+       } else {
+               wattrset(win, menubox_attr);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+       }
+
+       y = y + height + 1;
+       wmove(win, y, x);
+
+       if ((height < item_no) && (scroll + choice < item_no - 1)) {
+               wattrset(win, darrow_attr);
+               waddch(win, ACS_DARROW);
+               waddstr(win, "(+)");
+       } else {
+               wattrset(win, menubox_border_attr);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+       }
+}
+
+/*
+ *  Display the termination buttons
+ */
+static void print_buttons(WINDOW * dialog, int height, int width, int selected)
+{
+       int x = width / 2 - 11;
+       int y = height - 2;
+
+       print_button(dialog, "Select", y, x, selected == 0);
+       print_button(dialog, " Help ", y, x + 14, selected == 1);
+
+       wmove(dialog, y, x + 1 + 14 * selected);
+       wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * in the style of radiolist (only one option turned on at a time).
+ */
+int dialog_checklist(const char *title, const char *prompt, int height,
+                    int width, int list_height, int item_no,
+                    const char *const *items)
+{
+       int i, x, y, box_x, box_y;
+       int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+       WINDOW *dialog, *list;
+
+       /* Allocate space for storing item on/off status */
+       if ((status = malloc(sizeof(int) * item_no)) == NULL) {
+               endwin();
+               fprintf(stderr,
+                       "\nCan't allocate memory in dialog_checklist().\n");
+               exit(-1);
+       }
+
+       /* Initializes status */
+       for (i = 0; i < item_no; i++) {
+               status[i] = !strcasecmp(items[i * 3 + 2], "on");
+               if ((!choice && status[i])
+                   || !strcasecmp(items[i * 3 + 2], "selected"))
+                       choice = i + 1;
+       }
+       if (choice)
+               choice--;
+
+       max_choice = MIN(list_height, item_no);
+
+       /* center dialog box on screen */
+       x = (COLS - width) / 2;
+       y = (LINES - height) / 2;
+
+       draw_shadow(stdscr, y, x, height, width);
+
+       dialog = newwin(height, width, y, x);
+       keypad(dialog, TRUE);
+
+       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+       wattrset(dialog, border_attr);
+       mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+       for (i = 0; i < width - 2; i++)
+               waddch(dialog, ACS_HLINE);
+       wattrset(dialog, dialog_attr);
+       waddch(dialog, ACS_RTEE);
+
+       print_title(dialog, title, width);
+
+       wattrset(dialog, dialog_attr);
+       print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+       list_width = width - 6;
+       box_y = height - list_height - 5;
+       box_x = (width - list_width) / 2 - 1;
+
+       /* create new window for the list */
+       list = subwin(dialog, list_height, list_width, y + box_y + 1,
+                     x + box_x + 1);
+
+       keypad(list, TRUE);
+
+       /* draw a box around the list items */
+       draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
+                menubox_border_attr, menubox_attr);
+
+       /* Find length of longest item in order to center checklist */
+       check_x = 0;
+       for (i = 0; i < item_no; i++)
+               check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
+
+       check_x = (list_width - check_x) / 2;
+       item_x = check_x + 4;
+
+       if (choice >= list_height) {
+               scroll = choice - list_height + 1;
+               choice -= scroll;
+       }
+
+       /* Print the list */
+       for (i = 0; i < max_choice; i++) {
+               print_item(list, items[(scroll + i) * 3 + 1],
+                          status[i + scroll], i, i == choice);
+       }
+
+       print_arrows(dialog, choice, item_no, scroll,
+                    box_y, box_x + check_x + 5, list_height);
+
+       print_buttons(dialog, height, width, 0);
+
+       wnoutrefresh(list);
+       wnoutrefresh(dialog);
+       doupdate();
+
+       while (key != ESC) {
+               key = wgetch(dialog);
+
+               for (i = 0; i < max_choice; i++)
+                       if (toupper(key) ==
+                           toupper(items[(scroll + i) * 3 + 1][0]))
+                               break;
+
+               if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
+                   key == '+' || key == '-') {
+                       if (key == KEY_UP || key == '-') {
+                               if (!choice) {
+                                       if (!scroll)
+                                               continue;
+                                       /* Scroll list down */
+                                       if (list_height > 1) {
+                                               /* De-highlight current first item */
+                                               print_item(list, items[scroll * 3 + 1],
+                                                          status[scroll], 0, FALSE);
+                                               scrollok(list, TRUE);
+                                               wscrl(list, -1);
+                                               scrollok(list, FALSE);
+                                       }
+                                       scroll--;
+                                       print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
+                                       wnoutrefresh(list);
+
+                                       print_arrows(dialog, choice, item_no,
+                                                    scroll, box_y, box_x + check_x + 5, list_height);
+
+                                       wrefresh(dialog);
+
+                                       continue;       /* wait for another key press */
+                               } else
+                                       i = choice - 1;
+                       } else if (key == KEY_DOWN || key == '+') {
+                               if (choice == max_choice - 1) {
+                                       if (scroll + choice >= item_no - 1)
+                                               continue;
+                                       /* Scroll list up */
+                                       if (list_height > 1) {
+                                               /* De-highlight current last item before scrolling up */
+                                               print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
+                                                          status[scroll + max_choice - 1],
+                                                          max_choice - 1, FALSE);
+                                               scrollok(list, TRUE);
+                                               wscrl(list, 1);
+                                               scrollok(list, FALSE);
+                                       }
+                                       scroll++;
+                                       print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
+                                                  status[scroll + max_choice - 1], max_choice - 1, TRUE);
+                                       wnoutrefresh(list);
+
+                                       print_arrows(dialog, choice, item_no,
+                                                    scroll, box_y, box_x + check_x + 5, list_height);
+
+                                       wrefresh(dialog);
+
+                                       continue;       /* wait for another key press */
+                               } else
+                                       i = choice + 1;
+                       }
+                       if (i != choice) {
+                               /* De-highlight current item */
+                               print_item(list, items[(scroll + choice) * 3 + 1],
+                                          status[scroll + choice], choice, FALSE);
+                               /* Highlight new item */
+                               choice = i;
+                               print_item(list, items[(scroll + choice) * 3 + 1],
+                                          status[scroll + choice], choice, TRUE);
+                               wnoutrefresh(list);
+                               wrefresh(dialog);
+                       }
+                       continue;       /* wait for another key press */
+               }
+               switch (key) {
+               case 'H':
+               case 'h':
+               case '?':
+                       fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+                       delwin(dialog);
+                       free(status);
+                       return 1;
+               case TAB:
+               case KEY_LEFT:
+               case KEY_RIGHT:
+                       button = ((key == KEY_LEFT ? --button : ++button) < 0)
+                           ? 1 : (button > 1 ? 0 : button);
+
+                       print_buttons(dialog, height, width, button);
+                       wrefresh(dialog);
+                       break;
+               case 'S':
+               case 's':
+               case ' ':
+               case '\n':
+                       if (!button) {
+                               if (!status[scroll + choice]) {
+                                       for (i = 0; i < item_no; i++)
+                                               status[i] = 0;
+                                       status[scroll + choice] = 1;
+                                       for (i = 0; i < max_choice; i++)
+                                               print_item(list, items[(scroll + i) * 3 + 1],
+                                                          status[scroll + i], i, i == choice);
+                               }
+                               wnoutrefresh(list);
+                               wrefresh(dialog);
+
+                               for (i = 0; i < item_no; i++)
+                                       if (status[i])
+                                               fprintf(stderr, "%s", items[i * 3]);
+                       } else
+                               fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+                       delwin(dialog);
+                       free(status);
+                       return button;
+               case 'X':
+               case 'x':
+                       key = ESC;
+               case ESC:
+                       break;
+               }
+
+               /* Now, update everything... */
+               doupdate();
+       }
+
+       delwin(dialog);
+       free(status);
+       return -1;              /* ESC pressed */
+}
similarity index 99%
rename from scripts/lxdialog/colors.h
rename to scripts/kconfig/lxdialog/colors.h
index 25c59528a25106c89de4cdc32c14a01942a29acd..db071df12bbbbf7f1cf17e0d212da1014e08ad21 100644 (file)
@@ -18,7 +18,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 /*
  *   Default color definitions
  *
similarity index 75%
rename from scripts/lxdialog/dialog.h
rename to scripts/kconfig/lxdialog/dialog.h
index eb63e1bb63a3beb084f75eceb7fafb7b14c2217e..af3cf716e2156ca4c9dbada932497af069d230a6 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  *  dialog.h -- common declarations for all dialog modules
  *
@@ -42,7 +41,7 @@
 #if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
 #define OLD_NCURSES 1
 #undef  wbkgdset
-#define wbkgdset(w,p) /*nothing*/
+#define wbkgdset(w,p)          /*nothing */
 #else
 #define OLD_NCURSES 0
 #endif
@@ -56,7 +55,6 @@
 #define MIN(x,y) (x < y ? x : y)
 #define MAX(x,y) (x > y ? x : y)
 
-
 #ifndef ACS_ULCORNER
 #define ACS_ULCORNER '+'
 #endif
@@ -88,7 +86,7 @@
 #define ACS_DARROW 'v'
 #endif
 
-/* 
+/*
  * Attribute names
  */
 #define screen_attr                   attributes[0]
@@ -137,35 +135,35 @@ extern const char *backtitle;
 /*
  * Function prototypes
  */
-extern void create_rc (const char *filename);
-extern int parse_rc (void);
-
-
-void init_dialog (void);
-void end_dialog (void);
-void attr_clear (WINDOW * win, int height, int width, chtype attr);
-void dialog_clear (void);
-void color_setup (void);
-void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
-void print_button (WINDOW * win, const char *label, int y, int x, int selected);
-void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
-               chtype border);
-void draw_shadow (WINDOW * win, int y, int x, int height, int width);
-
-int first_alpha (const char *string, const char *exempt);
-int dialog_yesno (const char *title, const char *prompt, int height, int width);
-int dialog_msgbox (const char *title, const char *prompt, int height,
-               int width, int pause);
-int dialog_textbox (const char *title, const char *file, int height, int width);
-int dialog_menu (const char *title, const char *prompt, int height, int width,
-               int menu_height, const char *choice, int item_no, 
-               const char * const * items);
-int dialog_checklist (const char *title, const char *prompt, int height,
-               int width, int list_height, int item_no,
-               const char * const * items, int flag);
+extern void create_rc(const char *filename);
+extern int parse_rc(void);
+
+void init_dialog(void);
+void end_dialog(void);
+void attr_clear(WINDOW * win, int height, int width, chtype attr);
+void dialog_clear(void);
+void color_setup(void);
+void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
+void print_button(WINDOW * win, const char *label, int y, int x, int selected);
+void print_title(WINDOW *dialog, const char *title, int width);
+void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box,
+             chtype border);
+void draw_shadow(WINDOW * win, int y, int x, int height, int width);
+
+int first_alpha(const char *string, const char *exempt);
+int dialog_yesno(const char *title, const char *prompt, int height, int width);
+int dialog_msgbox(const char *title, const char *prompt, int height,
+                 int width, int pause);
+int dialog_textbox(const char *title, const char *file, int height, int width);
+int dialog_menu(const char *title, const char *prompt, int height, int width,
+               int menu_height, const char *choice, int item_no,
+               const char *const *items);
+int dialog_checklist(const char *title, const char *prompt, int height,
+                    int width, int list_height, int item_no,
+                    const char *const *items);
 extern char dialog_input_result[];
-int dialog_inputbox (const char *title, const char *prompt, int height,
-               int width, const char *init);
+int dialog_inputbox(const char *title, const char *prompt, int height,
+                   int width, const char *init);
 
 /*
  * This is the base for fictitious keys, which activate
@@ -177,11 +175,3 @@ int dialog_inputbox (const char *title, const char *prompt, int height,
  *   -- uppercase chars are used to invoke the button (M_EVENT + 'O')
  */
 #define M_EVENT (KEY_MAX+1)
-
-
-/*
- * The `flag' parameter in checklist is used to select between
- * radiolist and checklist
- */
-#define FLAG_CHECK 1
-#define FLAG_RADIO 0
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
new file mode 100644 (file)
index 0000000..7795037
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ *  inputbox.c -- implements the input box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+char dialog_input_result[MAX_LEN + 1];
+
+/*
+ *  Print the termination buttons
+ */
+static void print_buttons(WINDOW * dialog, int height, int width, int selected)
+{
+       int x = width / 2 - 11;
+       int y = height - 2;
+
+       print_button(dialog, "  Ok  ", y, x, selected == 0);
+       print_button(dialog, " Help ", y, x + 14, selected == 1);
+
+       wmove(dialog, y, x + 1 + 14 * selected);
+       wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int dialog_inputbox(const char *title, const char *prompt, int height, int width,
+                    const char *init)
+{
+       int i, x, y, box_y, box_x, box_width;
+       int input_x = 0, scroll = 0, key = 0, button = -1;
+       char *instr = dialog_input_result;
+       WINDOW *dialog;
+
+       /* center dialog box on screen */
+       x = (COLS - width) / 2;
+       y = (LINES - height) / 2;
+
+       draw_shadow(stdscr, y, x, height, width);
+
+       dialog = newwin(height, width, y, x);
+       keypad(dialog, TRUE);
+
+       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+       wattrset(dialog, border_attr);
+       mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+       for (i = 0; i < width - 2; i++)
+               waddch(dialog, ACS_HLINE);
+       wattrset(dialog, dialog_attr);
+       waddch(dialog, ACS_RTEE);
+
+       print_title(dialog, title, width);
+
+       wattrset(dialog, dialog_attr);
+       print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+       /* Draw the input field box */
+       box_width = width - 6;
+       getyx(dialog, y, x);
+       box_y = y + 2;
+       box_x = (width - box_width) / 2;
+       draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
+
+       print_buttons(dialog, height, width, 0);
+
+       /* Set up the initial value */
+       wmove(dialog, box_y, box_x);
+       wattrset(dialog, inputbox_attr);
+
+       if (!init)
+               instr[0] = '\0';
+       else
+               strcpy(instr, init);
+
+       input_x = strlen(instr);
+
+       if (input_x >= box_width) {
+               scroll = input_x - box_width + 1;
+               input_x = box_width - 1;
+               for (i = 0; i < box_width - 1; i++)
+                       waddch(dialog, instr[scroll + i]);
+       } else {
+               waddstr(dialog, instr);
+       }
+
+       wmove(dialog, box_y, box_x + input_x);
+
+       wrefresh(dialog);
+
+       while (key != ESC) {
+               key = wgetch(dialog);
+
+               if (button == -1) {     /* Input box selected */
+                       switch (key) {
+                       case TAB:
+                       case KEY_UP:
+                       case KEY_DOWN:
+                               break;
+                       case KEY_LEFT:
+                               continue;
+                       case KEY_RIGHT:
+                               continue;
+                       case KEY_BACKSPACE:
+                       case 127:
+                               if (input_x || scroll) {
+                                       wattrset(dialog, inputbox_attr);
+                                       if (!input_x) {
+                                               scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
+                                               wmove(dialog, box_y, box_x);
+                                               for (i = 0; i < box_width; i++)
+                                                       waddch(dialog,
+                                                              instr[scroll + input_x + i] ?
+                                                              instr[scroll + input_x + i] : ' ');
+                                               input_x = strlen(instr) - scroll;
+                                       } else
+                                               input_x--;
+                                       instr[scroll + input_x] = '\0';
+                                       mvwaddch(dialog, box_y, input_x + box_x, ' ');
+                                       wmove(dialog, box_y, input_x + box_x);
+                                       wrefresh(dialog);
+                               }
+                               continue;
+                       default:
+                               if (key < 0x100 && isprint(key)) {
+                                       if (scroll + input_x < MAX_LEN) {
+                                               wattrset(dialog, inputbox_attr);
+                                               instr[scroll + input_x] = key;
+                                               instr[scroll + input_x + 1] = '\0';
+                                               if (input_x == box_width - 1) {
+                                                       scroll++;
+                                                       wmove(dialog, box_y, box_x);
+                                                       for (i = 0; i < box_width - 1; i++)
+                                                               waddch(dialog, instr [scroll + i]);
+                                               } else {
+                                                       wmove(dialog, box_y, input_x++ + box_x);
+                                                       waddch(dialog, key);
+                                               }
+                                               wrefresh(dialog);
+                                       } else
+                                               flash();        /* Alarm user about overflow */
+                                       continue;
+                               }
+                       }
+               }
+               switch (key) {
+               case 'O':
+               case 'o':
+                       delwin(dialog);
+                       return 0;
+               case 'H':
+               case 'h':
+                       delwin(dialog);
+                       return 1;
+               case KEY_UP:
+               case KEY_LEFT:
+                       switch (button) {
+                       case -1:
+                               button = 1;     /* Indicates "Cancel" button is selected */
+                               print_buttons(dialog, height, width, 1);
+                               break;
+                       case 0:
+                               button = -1;    /* Indicates input box is selected */
+                               print_buttons(dialog, height, width, 0);
+                               wmove(dialog, box_y, box_x + input_x);
+                               wrefresh(dialog);
+                               break;
+                       case 1:
+                               button = 0;     /* Indicates "OK" button is selected */
+                               print_buttons(dialog, height, width, 0);
+                               break;
+                       }
+                       break;
+               case TAB:
+               case KEY_DOWN:
+               case KEY_RIGHT:
+                       switch (button) {
+                       case -1:
+                               button = 0;     /* Indicates "OK" button is selected */
+                               print_buttons(dialog, height, width, 0);
+                               break;
+                       case 0:
+                               button = 1;     /* Indicates "Cancel" button is selected */
+                               print_buttons(dialog, height, width, 1);
+                               break;
+                       case 1:
+                               button = -1;    /* Indicates input box is selected */
+                               print_buttons(dialog, height, width, 0);
+                               wmove(dialog, box_y, box_x + input_x);
+                               wrefresh(dialog);
+                               break;
+                       }
+                       break;
+               case ' ':
+               case '\n':
+                       delwin(dialog);
+                       return (button == -1 ? 0 : button);
+               case 'X':
+               case 'x':
+                       key = ESC;
+               case ESC:
+                       break;
+               }
+       }
+
+       delwin(dialog);
+       return -1;              /* ESC pressed */
+}
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c
new file mode 100644 (file)
index 0000000..79f6c5f
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ *  dialog - Display simple dialog boxes from shell scripts
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void Usage(const char *name);
+
+typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
+
+struct Mode {
+       char *name;
+       int argmin, argmax, argmod;
+       jumperFn *jumper;
+};
+
+jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox;
+jumperFn j_msgbox, j_infobox;
+
+static struct Mode modes[] = {
+       {"--menu", 9, 0, 3, j_menu},
+       {"--radiolist", 9, 0, 3, j_radiolist},
+       {"--yesno", 5, 5, 1, j_yesno},
+       {"--textbox", 5, 5, 1, j_textbox},
+       {"--inputbox", 5, 6, 1, j_inputbox},
+       {"--msgbox", 5, 5, 1, j_msgbox},
+       {"--infobox", 5, 5, 1, j_infobox},
+       {NULL, 0, 0, 0, NULL}
+};
+
+static struct Mode *modePtr;
+
+#ifdef LOCALE
+#include <locale.h>
+#endif
+
+int main(int argc, const char *const *argv)
+{
+       int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
+       const char *title = NULL;
+
+#ifdef LOCALE
+       (void)setlocale(LC_ALL, "");
+#endif
+
+#ifdef TRACE
+       trace(TRACE_CALLS | TRACE_UPDATE);
+#endif
+       if (argc < 2) {
+               Usage(argv[0]);
+               exit(-1);
+       }
+
+       while (offset < argc - 1 && !end_common_opts) { /* Common options */
+               if (!strcmp(argv[offset + 1], "--title")) {
+                       if (argc - offset < 3 || title != NULL) {
+                               Usage(argv[0]);
+                               exit(-1);
+                       } else {
+                               title = argv[offset + 2];
+                               offset += 2;
+                       }
+               } else if (!strcmp(argv[offset + 1], "--backtitle")) {
+                       if (backtitle != NULL) {
+                               Usage(argv[0]);
+                               exit(-1);
+                       } else {
+                               backtitle = argv[offset + 2];
+                               offset += 2;
+                       }
+               } else if (!strcmp(argv[offset + 1], "--clear")) {
+                       if (opt_clear) {        /* Hey, "--clear" can't appear twice! */
+                               Usage(argv[0]);
+                               exit(-1);
+                       } else if (argc == 2) { /* we only want to clear the screen */
+                               init_dialog();
+                               refresh();      /* init_dialog() will clear the screen for us */
+                               end_dialog();
+                               return 0;
+                       } else {
+                               opt_clear = 1;
+                               offset++;
+                       }
+               } else          /* no more common options */
+                       end_common_opts = 1;
+       }
+
+       if (argc - 1 == offset) {       /* no more options */
+               Usage(argv[0]);
+               exit(-1);
+       }
+       /* use a table to look for the requested mode, to avoid code duplication */
+
+       for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
+               if (!strcmp(argv[offset + 1], modePtr->name))
+                       break;
+
+       if (!modePtr->name)
+               Usage(argv[0]);
+       if (argc - offset < modePtr->argmin)
+               Usage(argv[0]);
+       if (modePtr->argmax && argc - offset > modePtr->argmax)
+               Usage(argv[0]);
+
+       init_dialog();
+       retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
+
+       if (opt_clear) {        /* clear screen before exit */
+               attr_clear(stdscr, LINES, COLS, screen_attr);
+               refresh();
+       }
+       end_dialog();
+
+       exit(retval);
+}
+
+/*
+ * Print program usage
+ */
+static void Usage(const char *name)
+{
+       fprintf(stderr, "\
+\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
+\n  patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
+\n  modified/gutted for use as a Linux kernel config tool by \
+\n  William Roadcap (roadcapw@cfw.com)\
+\n\
+\n* Display dialog boxes from shell scripts *\
+\n\
+\nUsage: %s --clear\
+\n       %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
+\n\
+\nBox options:\
+\n\
+\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
+\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
+\n  --textbox   <file> <height> <width>\
+\n  --inputbox  <text> <height> <width> [<init>]\
+\n  --yesno     <text> <height> <width>\
+\n", name, name);
+       exit(-1);
+}
+
+/*
+ * These are the program jumpers
+ */
+
+int j_menu(const char *t, int ac, const char *const *av)
+{
+       return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
+                          atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
+}
+
+int j_radiolist(const char *t, int ac, const char *const *av)
+{
+       return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
+                               atoi(av[5]), (ac - 6) / 3, av + 6);
+}
+
+int j_textbox(const char *t, int ac, const char *const *av)
+{
+       return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
+}
+
+int j_yesno(const char *t, int ac, const char *const *av)
+{
+       return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
+}
+
+int j_inputbox(const char *t, int ac, const char *const *av)
+{
+       int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
+                                 ac == 6 ? av[5] : (char *)NULL);
+       if (ret == 0)
+               fprintf(stderr, dialog_input_result);
+       return ret;
+}
+
+int j_msgbox(const char *t, int ac, const char *const *av)
+{
+       return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
+}
+
+int j_infobox(const char *t, int ac, const char *const *av)
+{
+       return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
+}
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
new file mode 100644 (file)
index 0000000..09512b5
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ *  menubox.c -- implements the menu box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *  Changes by Clifford Wolf (god@clifford.at)
+ *
+ *  [ 1998-06-13 ]
+ *
+ *    *)  A bugfix for the Page-Down problem
+ *
+ *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
+ *        to the first position in the menu box.  Now lxdialog is a bit
+ *        smarter and works more like other menu systems (just have a look at
+ *        it).
+ *
+ *    *)  Formerly if I selected something my scrolling would be broken because
+ *        lxdialog is re-invoked by the Menuconfig shell script, can't
+ *        remember the last scrolling position, and just sets it so that the
+ *        cursor is at the bottom of the box.  Now it writes the temporary file
+ *        lxdialog.scrltmp which contains this information. The file is
+ *        deleted by lxdialog if the user leaves a submenu or enters a new
+ *        one, but it would be nice if Menuconfig could make another "rm -f"
+ *        just to be sure.  Just try it out - you will recognise a difference!
+ *
+ *  [ 1998-06-14 ]
+ *
+ *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
+ *        and menus change their size on the fly.
+ *
+ *    *)  If for some reason the last scrolling position is not saved by
+ *        lxdialog, it sets the scrolling so that the selected item is in the
+ *        middle of the menu box, not at the bottom.
+ *
+ * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
+ * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
+ * This fixes a bug in Menuconfig where using ' ' to descend into menus
+ * would leave mis-synchronized lxdialog.scrltmp files lying around,
+ * fscanf would read in 'scroll', and eventually that value would get used.
+ */
+
+#include "dialog.h"
+
+#define ITEM_IDENT 1   /* Indent of menu entries. Fixed for all menus */
+static int menu_width;
+
+/*
+ * Print menu item
+ */
+static void do_print_item(WINDOW * win, const char *item, int choice,
+                          int selected, int hotkey)
+{
+       int j;
+       char *menu_item = malloc(menu_width + 1);
+
+       strncpy(menu_item, item, menu_width - ITEM_IDENT);
+       menu_item[menu_width] = 0;
+       j = first_alpha(menu_item, "YyNnMmHh");
+
+       /* Clear 'residue' of last item */
+       wattrset(win, menubox_attr);
+       wmove(win, choice, 0);
+#if OLD_NCURSES
+       {
+               int i;
+               for (i = 0; i < menu_width; i++)
+                       waddch(win, ' ');
+       }
+#else
+       wclrtoeol(win);
+#endif
+       wattrset(win, selected ? item_selected_attr : item_attr);
+       mvwaddstr(win, choice, ITEM_IDENT, menu_item);
+       if (hotkey) {
+               wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+               mvwaddch(win, choice, ITEM_IDENT + j, menu_item[j]);
+       }
+       if (selected) {
+               wmove(win, choice, ITEM_IDENT + 1);
+       }
+       free(menu_item);
+       wrefresh(win);
+}
+
+#define print_item(index, choice, selected) \
+do {\
+       int hotkey = (items[(index) * 2][0] != ':'); \
+       do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
+} while (0)
+
+/*
+ * Print the scroll indicators.
+ */
+static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
+                        int height)
+{
+       int cur_y, cur_x;
+
+       getyx(win, cur_y, cur_x);
+
+       wmove(win, y, x);
+
+       if (scroll > 0) {
+               wattrset(win, uarrow_attr);
+               waddch(win, ACS_UARROW);
+               waddstr(win, "(-)");
+       } else {
+               wattrset(win, menubox_attr);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+       }
+
+       y = y + height + 1;
+       wmove(win, y, x);
+       wrefresh(win);
+
+       if ((height < item_no) && (scroll + height < item_no)) {
+               wattrset(win, darrow_attr);
+               waddch(win, ACS_DARROW);
+               waddstr(win, "(+)");
+       } else {
+               wattrset(win, menubox_border_attr);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+               waddch(win, ACS_HLINE);
+       }
+
+       wmove(win, cur_y, cur_x);
+       wrefresh(win);
+}
+
+/*
+ * Display the termination buttons.
+ */
+static void print_buttons(WINDOW * win, int height, int width, int selected)
+{
+       int x = width / 2 - 16;
+       int y = height - 2;
+
+       print_button(win, "Select", y, x, selected == 0);
+       print_button(win, " Exit ", y, x + 12, selected == 1);
+       print_button(win, " Help ", y, x + 24, selected == 2);
+
+       wmove(win, y, x + 1 + 12 * selected);
+       wrefresh(win);
+}
+
+/* scroll up n lines (n may be negative) */
+static void do_scroll(WINDOW *win, int *scroll, int n)
+{
+       /* Scroll menu up */
+       scrollok(win, TRUE);
+       wscrl(win, n);
+       scrollok(win, FALSE);
+       *scroll = *scroll + n;
+       wrefresh(win);
+}
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int dialog_menu(const char *title, const char *prompt, int height, int width,
+                int menu_height, const char *current, int item_no,
+                const char *const *items)
+{
+       int i, j, x, y, box_x, box_y;
+       int key = 0, button = 0, scroll = 0, choice = 0;
+       int first_item =  0, max_choice;
+       WINDOW *dialog, *menu;
+       FILE *f;
+
+       max_choice = MIN(menu_height, item_no);
+
+       /* center dialog box on screen */
+       x = (COLS - width) / 2;
+       y = (LINES - height) / 2;
+
+       draw_shadow(stdscr, y, x, height, width);
+
+       dialog = newwin(height, width, y, x);
+       keypad(dialog, TRUE);
+
+       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+       wattrset(dialog, border_attr);
+       mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+       for (i = 0; i < width - 2; i++)
+               waddch(dialog, ACS_HLINE);
+       wattrset(dialog, dialog_attr);
+       wbkgdset(dialog, dialog_attr & A_COLOR);
+       waddch(dialog, ACS_RTEE);
+
+       print_title(dialog, title, width);
+
+       wattrset(dialog, dialog_attr);
+       print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+       menu_width = width - 6;
+       box_y = height - menu_height - 5;
+       box_x = (width - menu_width) / 2 - 1;
+
+       /* create new window for the menu */
+       menu = subwin(dialog, menu_height, menu_width,
+                     y + box_y + 1, x + box_x + 1);
+       keypad(menu, TRUE);
+
+       /* draw a box around the menu items */
+       draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
+                menubox_border_attr, menubox_attr);
+
+       /* Set choice to default item */
+       for (i = 0; i < item_no; i++)
+               if (strcmp(current, items[i * 2]) == 0)
+                       choice = i;
+
+       /* get the scroll info from the temp file */
+       if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) {
+               if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) &&
+                   (scroll + max_choice > choice) && (scroll >= 0) &&
+                   (scroll + max_choice <= item_no)) {
+                       first_item = scroll;
+                       choice = choice - scroll;
+                       fclose(f);
+               } else {
+                       scroll = 0;
+                       remove("lxdialog.scrltmp");
+                       fclose(f);
+                       f = NULL;
+               }
+       }
+       if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
+               if (choice >= item_no - max_choice / 2)
+                       scroll = first_item = item_no - max_choice;
+               else
+                       scroll = first_item = choice - max_choice / 2;
+               choice = choice - scroll;
+       }
+
+       /* Print the menu */
+       for (i = 0; i < max_choice; i++) {
+               print_item(first_item + i, i, i == choice);
+       }
+
+       wnoutrefresh(menu);
+
+       print_arrows(dialog, item_no, scroll,
+                    box_y, box_x + ITEM_IDENT + 1, menu_height);
+
+       print_buttons(dialog, height, width, 0);
+       wmove(menu, choice, ITEM_IDENT + 1);
+       wrefresh(menu);
+
+       while (key != ESC) {
+               key = wgetch(menu);
+
+               if (key < 256 && isalpha(key))
+                       key = tolower(key);
+
+               if (strchr("ynmh", key))
+                       i = max_choice;
+               else {
+                       for (i = choice + 1; i < max_choice; i++) {
+                               j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
+                               if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+                                       break;
+                       }
+                       if (i == max_choice)
+                               for (i = 0; i < max_choice; i++) {
+                                       j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
+                                       if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+                                               break;
+                               }
+               }
+
+               if (i < max_choice ||
+                   key == KEY_UP || key == KEY_DOWN ||
+                   key == '-' || key == '+' ||
+                   key == KEY_PPAGE || key == KEY_NPAGE) {
+                       /* Remove highligt of current item */
+                       print_item(scroll + choice, choice, FALSE);
+
+                       if (key == KEY_UP || key == '-') {
+                               if (choice < 2 && scroll) {
+                                       /* Scroll menu down */
+                                       do_scroll(menu, &scroll, -1);
+
+                                       print_item(scroll, 0, FALSE);
+                               } else
+                                       choice = MAX(choice - 1, 0);
+
+                       } else if (key == KEY_DOWN || key == '+') {
+                               print_item(scroll+choice, choice, FALSE);
+
+                               if ((choice > max_choice - 3) &&
+                                   (scroll + max_choice < item_no)) {
+                                       /* Scroll menu up */
+                                       do_scroll(menu, &scroll, 1);
+
+                                       print_item(scroll+max_choice - 1,
+                                                  max_choice - 1, FALSE);
+                               } else
+                                       choice = MIN(choice + 1, max_choice - 1);
+
+                       } else if (key == KEY_PPAGE) {
+                               scrollok(menu, TRUE);
+                               for (i = 0; (i < max_choice); i++) {
+                                       if (scroll > 0) {
+                                               do_scroll(menu, &scroll, -1);
+                                               print_item(scroll, 0, FALSE);
+                                       } else {
+                                               if (choice > 0)
+                                                       choice--;
+                                       }
+                               }
+
+                       } else if (key == KEY_NPAGE) {
+                               for (i = 0; (i < max_choice); i++) {
+                                       if (scroll + max_choice < item_no) {
+                                               do_scroll(menu, &scroll, 1);
+                                               print_item(scroll+max_choice-1,
+                                                          max_choice - 1, FALSE);
+                                       } else {
+                                               if (choice + 1 < max_choice)
+                                                       choice++;
+                                       }
+                               }
+                       } else
+                               choice = i;
+
+                       print_item(scroll + choice, choice, TRUE);
+
+                       print_arrows(dialog, item_no, scroll,
+                                    box_y, box_x + ITEM_IDENT + 1, menu_height);
+
+                       wnoutrefresh(dialog);
+                       wrefresh(menu);
+
+                       continue;       /* wait for another key press */
+               }
+
+               switch (key) {
+               case KEY_LEFT:
+               case TAB:
+               case KEY_RIGHT:
+                       button = ((key == KEY_LEFT ? --button : ++button) < 0)
+                           ? 2 : (button > 2 ? 0 : button);
+
+                       print_buttons(dialog, height, width, button);
+                       wrefresh(menu);
+                       break;
+               case ' ':
+               case 's':
+               case 'y':
+               case 'n':
+               case 'm':
+               case '/':
+                       /* save scroll info */
+                       if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
+                               fprintf(f, "%d\n", scroll);
+                               fclose(f);
+                       }
+                       delwin(dialog);
+                       fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+                       switch (key) {
+                       case 's':
+                               return 3;
+                       case 'y':
+                               return 3;
+                       case 'n':
+                               return 4;
+                       case 'm':
+                               return 5;
+                       case ' ':
+                               return 6;
+                       case '/':
+                               return 7;
+                       }
+                       return 0;
+               case 'h':
+               case '?':
+                       button = 2;
+               case '\n':
+                       delwin(dialog);
+                       if (button == 2)
+                               fprintf(stderr, "%s \"%s\"\n",
+                                       items[(scroll + choice) * 2],
+                                       items[(scroll + choice) * 2 + 1] +
+                                       first_alpha(items [(scroll + choice) * 2 + 1], ""));
+                       else
+                               fprintf(stderr, "%s\n",
+                                       items[(scroll + choice) * 2]);
+
+                       remove("lxdialog.scrltmp");
+                       return button;
+               case 'e':
+               case 'x':
+                       key = ESC;
+               case ESC:
+                       break;
+               }
+       }
+
+       delwin(dialog);
+       remove("lxdialog.scrltmp");
+       return -1;              /* ESC pressed */
+}
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
new file mode 100644 (file)
index 0000000..7323f54
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  msgbox.c -- implements the message box and info box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int dialog_msgbox(const char *title, const char *prompt, int height, int width,
+                  int pause)
+{
+       int i, x, y, key = 0;
+       WINDOW *dialog;
+
+       /* center dialog box on screen */
+       x = (COLS - width) / 2;
+       y = (LINES - height) / 2;
+
+       draw_shadow(stdscr, y, x, height, width);
+
+       dialog = newwin(height, width, y, x);
+       keypad(dialog, TRUE);
+
+       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+       print_title(dialog, title, width);
+
+       wattrset(dialog, dialog_attr);
+       print_autowrap(dialog, prompt, width - 2, 1, 2);
+
+       if (pause) {
+               wattrset(dialog, border_attr);
+               mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+               for (i = 0; i < width - 2; i++)
+                       waddch(dialog, ACS_HLINE);
+               wattrset(dialog, dialog_attr);
+               waddch(dialog, ACS_RTEE);
+
+               print_button(dialog, "  Ok  ", height - 2, width / 2 - 4, TRUE);
+
+               wrefresh(dialog);
+               while (key != ESC && key != '\n' && key != ' ' &&
+                      key != 'O' && key != 'o' && key != 'X' && key != 'x')
+                       key = wgetch(dialog);
+       } else {
+               key = '\n';
+               wrefresh(dialog);
+       }
+
+       delwin(dialog);
+       return key == ESC ? -1 : 0;
+}
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
new file mode 100644 (file)
index 0000000..77848bb
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ *  textbox.c -- implements the text box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void back_lines(int n);
+static void print_page(WINDOW * win, int height, int width);
+static void print_line(WINDOW * win, int row, int width);
+static char *get_line(void);
+static void print_position(WINDOW * win, int height, int width);
+
+static int hscroll, fd, file_size, bytes_read;
+static int begin_reached = 1, end_reached, page_length;
+static char *buf, *page;
+
+/*
+ * Display text from a file in a dialog box.
+ */
+int dialog_textbox(const char *title, const char *file, int height, int width)
+{
+       int i, x, y, cur_x, cur_y, fpos, key = 0;
+       int passed_end;
+       char search_term[MAX_LEN + 1];
+       WINDOW *dialog, *text;
+
+       search_term[0] = '\0';  /* no search term entered yet */
+
+       /* Open input file for reading */
+       if ((fd = open(file, O_RDONLY)) == -1) {
+               endwin();
+               fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
+               exit(-1);
+       }
+       /* Get file size. Actually, 'file_size' is the real file size - 1,
+          since it's only the last byte offset from the beginning */
+       if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
+               endwin();
+               fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
+               exit(-1);
+       }
+       /* Restore file pointer to beginning of file after getting file size */
+       if (lseek(fd, 0, SEEK_SET) == -1) {
+               endwin();
+               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+               exit(-1);
+       }
+       /* Allocate space for read buffer */
+       if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
+               endwin();
+               fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
+               exit(-1);
+       }
+       if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+               endwin();
+               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+               exit(-1);
+       }
+       buf[bytes_read] = '\0'; /* mark end of valid data */
+       page = buf;             /* page is pointer to start of page to be displayed */
+
+       /* center dialog box on screen */
+       x = (COLS - width) / 2;
+       y = (LINES - height) / 2;
+
+       draw_shadow(stdscr, y, x, height, width);
+
+       dialog = newwin(height, width, y, x);
+       keypad(dialog, TRUE);
+
+       /* Create window for text region, used for scrolling text */
+       text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
+       wattrset(text, dialog_attr);
+       wbkgdset(text, dialog_attr & A_COLOR);
+
+       keypad(text, TRUE);
+
+       /* register the new window, along with its borders */
+       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+       wattrset(dialog, border_attr);
+       mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+       for (i = 0; i < width - 2; i++)
+               waddch(dialog, ACS_HLINE);
+       wattrset(dialog, dialog_attr);
+       wbkgdset(dialog, dialog_attr & A_COLOR);
+       waddch(dialog, ACS_RTEE);
+
+       print_title(dialog, title, width);
+
+       print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+       wnoutrefresh(dialog);
+       getyx(dialog, cur_y, cur_x);    /* Save cursor position */
+
+       /* Print first page of text */
+       attr_clear(text, height - 4, width - 2, dialog_attr);
+       print_page(text, height - 4, width - 2);
+       print_position(dialog, height, width);
+       wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
+       wrefresh(dialog);
+
+       while ((key != ESC) && (key != '\n')) {
+               key = wgetch(dialog);
+               switch (key) {
+               case 'E':       /* Exit */
+               case 'e':
+               case 'X':
+               case 'x':
+                       delwin(dialog);
+                       free(buf);
+                       close(fd);
+                       return 0;
+               case 'g':       /* First page */
+               case KEY_HOME:
+                       if (!begin_reached) {
+                               begin_reached = 1;
+                               /* First page not in buffer? */
+                               if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+                                       endwin();
+                                       fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+                                       exit(-1);
+                               }
+                               if (fpos > bytes_read) {        /* Yes, we have to read it in */
+                                       if (lseek(fd, 0, SEEK_SET) == -1) {
+                                               endwin();
+                                               fprintf(stderr, "\nError moving file pointer in "
+                                                               "dialog_textbox().\n");
+                                               exit(-1);
+                                       }
+                                       if ((bytes_read =
+                                            read(fd, buf, BUF_SIZE)) == -1) {
+                                               endwin();
+                                               fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+                                               exit(-1);
+                                       }
+                                       buf[bytes_read] = '\0';
+                               }
+                               page = buf;
+                               print_page(text, height - 4, width - 2);
+                               print_position(dialog, height, width);
+                               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
+                               wrefresh(dialog);
+                       }
+                       break;
+               case 'G':       /* Last page */
+               case KEY_END:
+
+                       end_reached = 1;
+                       /* Last page not in buffer? */
+                       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+                               endwin();
+                               fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+                               exit(-1);
+                       }
+                       if (fpos < file_size) { /* Yes, we have to read it in */
+                               if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
+                                       endwin();
+                                       fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+                                       exit(-1);
+                               }
+                               if ((bytes_read =
+                                    read(fd, buf, BUF_SIZE)) == -1) {
+                                       endwin();
+                                       fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+                                       exit(-1);
+                               }
+                               buf[bytes_read] = '\0';
+                       }
+                       page = buf + bytes_read;
+                       back_lines(height - 4);
+                       print_page(text, height - 4, width - 2);
+                       print_position(dialog, height, width);
+                       wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
+                       wrefresh(dialog);
+                       break;
+               case 'K':       /* Previous line */
+               case 'k':
+               case KEY_UP:
+                       if (!begin_reached) {
+                               back_lines(page_length + 1);
+
+                               /* We don't call print_page() here but use scrolling to ensure
+                                  faster screen update. However, 'end_reached' and
+                                  'page_length' should still be updated, and 'page' should
+                                  point to start of next page. This is done by calling
+                                  get_line() in the following 'for' loop. */
+                               scrollok(text, TRUE);
+                               wscrl(text, -1);        /* Scroll text region down one line */
+                               scrollok(text, FALSE);
+                               page_length = 0;
+                               passed_end = 0;
+                               for (i = 0; i < height - 4; i++) {
+                                       if (!i) {
+                                               /* print first line of page */
+                                               print_line(text, 0, width - 2);
+                                               wnoutrefresh(text);
+                                       } else
+                                               /* Called to update 'end_reached' and 'page' */
+                                               get_line();
+                                       if (!passed_end)
+                                               page_length++;
+                                       if (end_reached && !passed_end)
+                                               passed_end = 1;
+                               }
+
+                               print_position(dialog, height, width);
+                               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
+                               wrefresh(dialog);
+                       }
+                       break;
+               case 'B':       /* Previous page */
+               case 'b':
+               case KEY_PPAGE:
+                       if (begin_reached)
+                               break;
+                       back_lines(page_length + height - 4);
+                       print_page(text, height - 4, width - 2);
+                       print_position(dialog, height, width);
+                       wmove(dialog, cur_y, cur_x);
+                       wrefresh(dialog);
+                       break;
+               case 'J':       /* Next line */
+               case 'j':
+               case KEY_DOWN:
+                       if (!end_reached) {
+                               begin_reached = 0;
+                               scrollok(text, TRUE);
+                               scroll(text);   /* Scroll text region up one line */
+                               scrollok(text, FALSE);
+                               print_line(text, height - 5, width - 2);
+                               wnoutrefresh(text);
+                               print_position(dialog, height, width);
+                               wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
+                               wrefresh(dialog);
+                       }
+                       break;
+               case KEY_NPAGE: /* Next page */
+               case ' ':
+                       if (end_reached)
+                               break;
+
+                       begin_reached = 0;
+                       print_page(text, height - 4, width - 2);
+                       print_position(dialog, height, width);
+                       wmove(dialog, cur_y, cur_x);
+                       wrefresh(dialog);
+                       break;
+               case '0':       /* Beginning of line */
+               case 'H':       /* Scroll left */
+               case 'h':
+               case KEY_LEFT:
+                       if (hscroll <= 0)
+                               break;
+
+                       if (key == '0')
+                               hscroll = 0;
+                       else
+                               hscroll--;
+                       /* Reprint current page to scroll horizontally */
+                       back_lines(page_length);
+                       print_page(text, height - 4, width - 2);
+                       wmove(dialog, cur_y, cur_x);
+                       wrefresh(dialog);
+                       break;
+               case 'L':       /* Scroll right */
+               case 'l':
+               case KEY_RIGHT:
+                       if (hscroll >= MAX_LEN)
+                               break;
+                       hscroll++;
+                       /* Reprint current page to scroll horizontally */
+                       back_lines(page_length);
+                       print_page(text, height - 4, width - 2);
+                       wmove(dialog, cur_y, cur_x);
+                       wrefresh(dialog);
+                       break;
+               case ESC:
+                       break;
+               }
+       }
+
+       delwin(dialog);
+       free(buf);
+       close(fd);
+       return -1;              /* ESC pressed */
+}
+
+/*
+ * Go back 'n' lines in text file. Called by dialog_textbox().
+ * 'page' will be updated to point to the desired line in 'buf'.
+ */
+static void back_lines(int n)
+{
+       int i, fpos;
+
+       begin_reached = 0;
+       /* We have to distinguish between end_reached and !end_reached
+          since at end of file, the line is not ended by a '\n'.
+          The code inside 'if' basically does a '--page' to move one
+          character backward so as to skip '\n' of the previous line */
+       if (!end_reached) {
+               /* Either beginning of buffer or beginning of file reached? */
+               if (page == buf) {
+                       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+                               endwin();
+                               fprintf(stderr, "\nError moving file pointer in "
+                                               "back_lines().\n");
+                               exit(-1);
+                       }
+                       if (fpos > bytes_read) {        /* Not beginning of file yet */
+                               /* We've reached beginning of buffer, but not beginning of
+                                  file yet, so read previous part of file into buffer.
+                                  Note that we only move backward for BUF_SIZE/2 bytes,
+                                  but not BUF_SIZE bytes to avoid re-reading again in
+                                  print_page() later */
+                               /* Really possible to move backward BUF_SIZE/2 bytes? */
+                               if (fpos < BUF_SIZE / 2 + bytes_read) {
+                                       /* No, move less then */
+                                       if (lseek(fd, 0, SEEK_SET) == -1) {
+                                               endwin();
+                                               fprintf(stderr, "\nError moving file pointer in "
+                                                               "back_lines().\n");
+                                               exit(-1);
+                                       }
+                                       page = buf + fpos - bytes_read;
+                               } else {        /* Move backward BUF_SIZE/2 bytes */
+                                       if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
+                                               endwin();
+                                               fprintf(stderr, "\nError moving file pointer "
+                                                               "in back_lines().\n");
+                                               exit(-1);
+                                       }
+                                       page = buf + BUF_SIZE / 2;
+                               }
+                               if ((bytes_read =
+                                    read(fd, buf, BUF_SIZE)) == -1) {
+                                       endwin();
+                                       fprintf(stderr, "\nError reading file in back_lines().\n");
+                                       exit(-1);
+                               }
+                               buf[bytes_read] = '\0';
+                       } else {        /* Beginning of file reached */
+                               begin_reached = 1;
+                               return;
+                       }
+               }
+               if (*(--page) != '\n') {        /* '--page' here */
+                       /* Something's wrong... */
+                       endwin();
+                       fprintf(stderr, "\nInternal error in back_lines().\n");
+                       exit(-1);
+               }
+       }
+       /* Go back 'n' lines */
+       for (i = 0; i < n; i++)
+               do {
+                       if (page == buf) {
+                               if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+                                       endwin();
+                                       fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+                                       exit(-1);
+                               }
+                               if (fpos > bytes_read) {
+                                       /* Really possible to move backward BUF_SIZE/2 bytes? */
+                                       if (fpos < BUF_SIZE / 2 + bytes_read) {
+                                               /* No, move less then */
+                                               if (lseek(fd, 0, SEEK_SET) == -1) {
+                                                       endwin();
+                                                       fprintf(stderr, "\nError moving file pointer "
+                                                                       "in back_lines().\n");
+                                                       exit(-1);
+                                               }
+                                               page = buf + fpos - bytes_read;
+                                       } else {        /* Move backward BUF_SIZE/2 bytes */
+                                               if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
+                                                       endwin();
+                                                       fprintf(stderr, "\nError moving file pointer"
+                                                                       " in back_lines().\n");
+                                                       exit(-1);
+                                               }
+                                               page = buf + BUF_SIZE / 2;
+                                       }
+                                       if ((bytes_read =
+                                            read(fd, buf, BUF_SIZE)) == -1) {
+                                               endwin();
+                                               fprintf(stderr, "\nError reading file in "
+                                                               "back_lines().\n");
+                                               exit(-1);
+                                       }
+                                       buf[bytes_read] = '\0';
+                               } else {        /* Beginning of file reached */
+                                       begin_reached = 1;
+                                       return;
+                               }
+                       }
+               } while (*(--page) != '\n');
+       page++;
+}
+
+/*
+ * Print a new page of text. Called by dialog_textbox().
+ */
+static void print_page(WINDOW * win, int height, int width)
+{
+       int i, passed_end = 0;
+
+       page_length = 0;
+       for (i = 0; i < height; i++) {
+               print_line(win, i, width);
+               if (!passed_end)
+                       page_length++;
+               if (end_reached && !passed_end)
+                       passed_end = 1;
+       }
+       wnoutrefresh(win);
+}
+
+/*
+ * Print a new line of text. Called by dialog_textbox() and print_page().
+ */
+static void print_line(WINDOW * win, int row, int width)
+{
+       int y, x;
+       char *line;
+
+       line = get_line();
+       line += MIN(strlen(line), hscroll);     /* Scroll horizontally */
+       wmove(win, row, 0);     /* move cursor to correct line */
+       waddch(win, ' ');
+       waddnstr(win, line, MIN(strlen(line), width - 2));
+
+       getyx(win, y, x);
+       /* Clear 'residue' of previous line */
+#if OLD_NCURSES
+       {
+               int i;
+               for (i = 0; i < width - x; i++)
+                       waddch(win, ' ');
+       }
+#else
+       wclrtoeol(win);
+#endif
+}
+
+/*
+ * Return current line of text. Called by dialog_textbox() and print_line().
+ * 'page' should point to start of current line before calling, and will be
+ * updated to point to start of next line.
+ */
+static char *get_line(void)
+{
+       int i = 0, fpos;
+       static char line[MAX_LEN + 1];
+
+       end_reached = 0;
+       while (*page != '\n') {
+               if (*page == '\0') {
+                       /* Either end of file or end of buffer reached */
+                       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+                               endwin();
+                               fprintf(stderr, "\nError moving file pointer in "
+                                               "get_line().\n");
+                               exit(-1);
+                       }
+                       if (fpos < file_size) { /* Not end of file yet */
+                               /* We've reached end of buffer, but not end of file yet,
+                                  so read next part of file into buffer */
+                               if ((bytes_read =
+                                    read(fd, buf, BUF_SIZE)) == -1) {
+                                       endwin();
+                                       fprintf(stderr, "\nError reading file in get_line().\n");
+                                       exit(-1);
+                               }
+                               buf[bytes_read] = '\0';
+                               page = buf;
+                       } else {
+                               if (!end_reached)
+                                       end_reached = 1;
+                               break;
+                       }
+               } else if (i < MAX_LEN)
+                       line[i++] = *(page++);
+               else {
+                       /* Truncate lines longer than MAX_LEN characters */
+                       if (i == MAX_LEN)
+                               line[i++] = '\0';
+                       page++;
+               }
+       }
+       if (i <= MAX_LEN)
+               line[i] = '\0';
+       if (!end_reached)
+               page++;         /* move pass '\n' */
+
+       return line;
+}
+
+/*
+ * Print current position
+ */
+static void print_position(WINDOW * win, int height, int width)
+{
+       int fpos, percent;
+
+       if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+               endwin();
+               fprintf(stderr, "\nError moving file pointer in print_position().\n");
+               exit(-1);
+       }
+       wattrset(win, position_indicator_attr);
+       wbkgdset(win, position_indicator_attr & A_COLOR);
+       percent = !file_size ?
+           100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
+       wmove(win, height - 3, width - 9);
+       wprintw(win, "(%3d%%)", percent);
+}
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
new file mode 100644 (file)
index 0000000..f82cebb
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ *  util.c
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/* use colors by default? */
+bool use_colors = 1;
+
+const char *backtitle = NULL;
+
+/*
+ * Attribute values, default is for mono display
+ */
+chtype attributes[] = {
+       A_NORMAL,               /* screen_attr */
+       A_NORMAL,               /* shadow_attr */
+       A_NORMAL,               /* dialog_attr */
+       A_BOLD,                 /* title_attr */
+       A_NORMAL,               /* border_attr */
+       A_REVERSE,              /* button_active_attr */
+       A_DIM,                  /* button_inactive_attr */
+       A_REVERSE,              /* button_key_active_attr */
+       A_BOLD,                 /* button_key_inactive_attr */
+       A_REVERSE,              /* button_label_active_attr */
+       A_NORMAL,               /* button_label_inactive_attr */
+       A_NORMAL,               /* inputbox_attr */
+       A_NORMAL,               /* inputbox_border_attr */
+       A_NORMAL,               /* searchbox_attr */
+       A_BOLD,                 /* searchbox_title_attr */
+       A_NORMAL,               /* searchbox_border_attr */
+       A_BOLD,                 /* position_indicator_attr */
+       A_NORMAL,               /* menubox_attr */
+       A_NORMAL,               /* menubox_border_attr */
+       A_NORMAL,               /* item_attr */
+       A_REVERSE,              /* item_selected_attr */
+       A_BOLD,                 /* tag_attr */
+       A_REVERSE,              /* tag_selected_attr */
+       A_BOLD,                 /* tag_key_attr */
+       A_REVERSE,              /* tag_key_selected_attr */
+       A_BOLD,                 /* check_attr */
+       A_REVERSE,              /* check_selected_attr */
+       A_BOLD,                 /* uarrow_attr */
+       A_BOLD                  /* darrow_attr */
+};
+
+#include "colors.h"
+
+/*
+ * Table of color values
+ */
+int color_table[][3] = {
+       {SCREEN_FG, SCREEN_BG, SCREEN_HL},
+       {SHADOW_FG, SHADOW_BG, SHADOW_HL},
+       {DIALOG_FG, DIALOG_BG, DIALOG_HL},
+       {TITLE_FG, TITLE_BG, TITLE_HL},
+       {BORDER_FG, BORDER_BG, BORDER_HL},
+       {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
+       {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
+       {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
+       {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG,
+        BUTTON_KEY_INACTIVE_HL},
+       {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG,
+        BUTTON_LABEL_ACTIVE_HL},
+       {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
+        BUTTON_LABEL_INACTIVE_HL},
+       {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
+       {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
+       {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
+       {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
+       {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
+       {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
+       {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
+       {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
+       {ITEM_FG, ITEM_BG, ITEM_HL},
+       {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
+       {TAG_FG, TAG_BG, TAG_HL},
+       {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
+       {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
+       {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
+       {CHECK_FG, CHECK_BG, CHECK_HL},
+       {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
+       {UARROW_FG, UARROW_BG, UARROW_HL},
+       {DARROW_FG, DARROW_BG, DARROW_HL},
+};                             /* color_table */
+
+/*
+ * Set window to attribute 'attr'
+ */
+void attr_clear(WINDOW * win, int height, int width, chtype attr)
+{
+       int i, j;
+
+       wattrset(win, attr);
+       for (i = 0; i < height; i++) {
+               wmove(win, i, 0);
+               for (j = 0; j < width; j++)
+                       waddch(win, ' ');
+       }
+       touchwin(win);
+}
+
+void dialog_clear(void)
+{
+       attr_clear(stdscr, LINES, COLS, screen_attr);
+       /* Display background title if it exists ... - SLH */
+       if (backtitle != NULL) {
+               int i;
+
+               wattrset(stdscr, screen_attr);
+               mvwaddstr(stdscr, 0, 1, (char *)backtitle);
+               wmove(stdscr, 1, 1);
+               for (i = 1; i < COLS - 1; i++)
+                       waddch(stdscr, ACS_HLINE);
+       }
+       wnoutrefresh(stdscr);
+}
+
+/*
+ * Do some initialization for dialog
+ */
+void init_dialog(void)
+{
+       initscr();              /* Init curses */
+       keypad(stdscr, TRUE);
+       cbreak();
+       noecho();
+
+       if (use_colors)         /* Set up colors */
+               color_setup();
+
+       dialog_clear();
+}
+
+/*
+ * Setup for color display
+ */
+void color_setup(void)
+{
+       int i;
+
+       if (has_colors()) {     /* Terminal supports color? */
+               start_color();
+
+               /* Initialize color pairs */
+               for (i = 0; i < ATTRIBUTE_COUNT; i++)
+                       init_pair(i + 1, color_table[i][0], color_table[i][1]);
+
+               /* Setup color attributes */
+               for (i = 0; i < ATTRIBUTE_COUNT; i++)
+                       attributes[i] = C_ATTR(color_table[i][2], i + 1);
+       }
+}
+
+/*
+ * End using dialog functions.
+ */
+void end_dialog(void)
+{
+       endwin();
+}
+
+/* Print the title of the dialog. Center the title and truncate
+ * tile if wider than dialog (- 2 chars).
+ **/
+void print_title(WINDOW *dialog, const char *title, int width)
+{
+       if (title) {
+               int tlen = MIN(width - 2, strlen(title));
+               wattrset(dialog, title_attr);
+               mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
+               mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
+               waddch(dialog, ' ');
+       }
+}
+
+/*
+ * Print a string of text in a window, automatically wrap around to the
+ * next line if the string is too long to fit on one line. Newline
+ * characters '\n' are replaced by spaces.  We start on a new line
+ * if there is no room for at least 4 nonblanks following a double-space.
+ */
+void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
+{
+       int newl, cur_x, cur_y;
+       int i, prompt_len, room, wlen;
+       char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
+
+       strcpy(tempstr, prompt);
+
+       prompt_len = strlen(tempstr);
+
+       /*
+        * Remove newlines
+        */
+       for (i = 0; i < prompt_len; i++) {
+               if (tempstr[i] == '\n')
+                       tempstr[i] = ' ';
+       }
+
+       if (prompt_len <= width - x * 2) {      /* If prompt is short */
+               wmove(win, y, (width - prompt_len) / 2);
+               waddstr(win, tempstr);
+       } else {
+               cur_x = x;
+               cur_y = y;
+               newl = 1;
+               word = tempstr;
+               while (word && *word) {
+                       sp = index(word, ' ');
+                       if (sp)
+                               *sp++ = 0;
+
+                       /* Wrap to next line if either the word does not fit,
+                          or it is the first word of a new sentence, and it is
+                          short, and the next word does not fit. */
+                       room = width - cur_x;
+                       wlen = strlen(word);
+                       if (wlen > room ||
+                           (newl && wlen < 4 && sp
+                            && wlen + 1 + strlen(sp) > room
+                            && (!(sp2 = index(sp, ' '))
+                                || wlen + 1 + (sp2 - sp) > room))) {
+                               cur_y++;
+                               cur_x = x;
+                       }
+                       wmove(win, cur_y, cur_x);
+                       waddstr(win, word);
+                       getyx(win, cur_y, cur_x);
+                       cur_x++;
+                       if (sp && *sp == ' ') {
+                               cur_x++;        /* double space */
+                               while (*++sp == ' ') ;
+                               newl = 1;
+                       } else
+                               newl = 0;
+                       word = sp;
+               }
+       }
+}
+
+/*
+ * Print a button
+ */
+void print_button(WINDOW * win, const char *label, int y, int x, int selected)
+{
+       int i, temp;
+
+       wmove(win, y, x);
+       wattrset(win, selected ? button_active_attr : button_inactive_attr);
+       waddstr(win, "<");
+       temp = strspn(label, " ");
+       label += temp;
+       wattrset(win, selected ? button_label_active_attr
+                : button_label_inactive_attr);
+       for (i = 0; i < temp; i++)
+               waddch(win, ' ');
+       wattrset(win, selected ? button_key_active_attr
+                : button_key_inactive_attr);
+       waddch(win, label[0]);
+       wattrset(win, selected ? button_label_active_attr
+                : button_label_inactive_attr);
+       waddstr(win, (char *)label + 1);
+       wattrset(win, selected ? button_active_attr : button_inactive_attr);
+       waddstr(win, ">");
+       wmove(win, y, x + temp + 1);
+}
+
+/*
+ * Draw a rectangular box with line drawing characters
+ */
+void
+draw_box(WINDOW * win, int y, int x, int height, int width,
+        chtype box, chtype border)
+{
+       int i, j;
+
+       wattrset(win, 0);
+       for (i = 0; i < height; i++) {
+               wmove(win, y + i, x);
+               for (j = 0; j < width; j++)
+                       if (!i && !j)
+                               waddch(win, border | ACS_ULCORNER);
+                       else if (i == height - 1 && !j)
+                               waddch(win, border | ACS_LLCORNER);
+                       else if (!i && j == width - 1)
+                               waddch(win, box | ACS_URCORNER);
+                       else if (i == height - 1 && j == width - 1)
+                               waddch(win, box | ACS_LRCORNER);
+                       else if (!i)
+                               waddch(win, border | ACS_HLINE);
+                       else if (i == height - 1)
+                               waddch(win, box | ACS_HLINE);
+                       else if (!j)
+                               waddch(win, border | ACS_VLINE);
+                       else if (j == width - 1)
+                               waddch(win, box | ACS_VLINE);
+                       else
+                               waddch(win, box | ' ');
+       }
+}
+
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes
+ */
+void draw_shadow(WINDOW * win, int y, int x, int height, int width)
+{
+       int i;
+
+       if (has_colors()) {     /* Whether terminal supports color? */
+               wattrset(win, shadow_attr);
+               wmove(win, y + height, x + 2);
+               for (i = 0; i < width; i++)
+                       waddch(win, winch(win) & A_CHARTEXT);
+               for (i = y + 1; i < y + height + 1; i++) {
+                       wmove(win, i, x + width);
+                       waddch(win, winch(win) & A_CHARTEXT);
+                       waddch(win, winch(win) & A_CHARTEXT);
+               }
+               wnoutrefresh(win);
+       }
+}
+
+/*
+ *  Return the position of the first alphabetic character in a string.
+ */
+int first_alpha(const char *string, const char *exempt)
+{
+       int i, in_paren = 0, c;
+
+       for (i = 0; i < strlen(string); i++) {
+               c = tolower(string[i]);
+
+               if (strchr("<[(", c))
+                       ++in_paren;
+               if (strchr(">])", c) && in_paren > 0)
+                       --in_paren;
+
+               if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
+                       return i;
+       }
+
+       return 0;
+}
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
new file mode 100644 (file)
index 0000000..cb2568a
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *  yesno.c -- implements the yes/no box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display termination buttons
+ */
+static void print_buttons(WINDOW * dialog, int height, int width, int selected)
+{
+       int x = width / 2 - 10;
+       int y = height - 2;
+
+       print_button(dialog, " Yes ", y, x, selected == 0);
+       print_button(dialog, "  No  ", y, x + 13, selected == 1);
+
+       wmove(dialog, y, x + 1 + 13 * selected);
+       wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int dialog_yesno(const char *title, const char *prompt, int height, int width)
+{
+       int i, x, y, key = 0, button = 0;
+       WINDOW *dialog;
+
+       /* center dialog box on screen */
+       x = (COLS - width) / 2;
+       y = (LINES - height) / 2;
+
+       draw_shadow(stdscr, y, x, height, width);
+
+       dialog = newwin(height, width, y, x);
+       keypad(dialog, TRUE);
+
+       draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+       wattrset(dialog, border_attr);
+       mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+       for (i = 0; i < width - 2; i++)
+               waddch(dialog, ACS_HLINE);
+       wattrset(dialog, dialog_attr);
+       waddch(dialog, ACS_RTEE);
+
+       print_title(dialog, title, width);
+
+       wattrset(dialog, dialog_attr);
+       print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+       print_buttons(dialog, height, width, 0);
+
+       while (key != ESC) {
+               key = wgetch(dialog);
+               switch (key) {
+               case 'Y':
+               case 'y':
+                       delwin(dialog);
+                       return 0;
+               case 'N':
+               case 'n':
+                       delwin(dialog);
+                       return 1;
+
+               case TAB:
+               case KEY_LEFT:
+               case KEY_RIGHT:
+                       button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button);
+
+                       print_buttons(dialog, height, width, button);
+                       wrefresh(dialog);
+                       break;
+               case ' ':
+               case '\n':
+                       delwin(dialog);
+                       return button;
+               case ESC:
+                       break;
+               }
+       }
+
+       delwin(dialog);
+       return -1;              /* ESC pressed */
+}
index d1ad40531ee5a681b63c3d142f556acac8eb02f3..d63d7fb677e4c97b9a6135993b3370766559b59d 100644 (file)
@@ -325,7 +325,7 @@ static void cprint_init(void)
        memset(args, 0, sizeof(args));
        indent = 0;
        child_count = 0;
-       cprint("./scripts/lxdialog/lxdialog");
+       cprint("./scripts/kconfig/lxdialog/lxdialog");
        cprint("--backtitle");
        cprint(menu_backtitle);
 }
index 1fa4c0b801b34f3264a596540e9ced519d7906d8..656d2c87d6614f13c9a23fc861cce0f356aba25e 100644 (file)
@@ -33,7 +33,7 @@ int file_write_dep(const char *name)
        FILE *out;
 
        if (!name)
-               name = ".config.cmd";
+               name = ".kconfig.d";
        out = fopen("..config.tmp", "w");
        if (!out)
                return 1;
@@ -101,7 +101,7 @@ void str_printf(struct gstr *gs, const char *fmt, ...)
        va_end(ap);
 }
 
-/* Retreive value of growable string */
+/* Retrieve value of growable string */
 const char *str_get(struct gstr *gs)
 {
        return gs->s;
diff --git a/scripts/lxdialog/checklist.c b/scripts/lxdialog/checklist.c
deleted file mode 100644 (file)
index 7aba17c..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- *  checklist.c -- implements the checklist box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
- *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static int list_width, check_x, item_x, checkflag;
-
-/*
- * Print list item
- */
-static void
-print_item (WINDOW * win, const char *item, int status,
-           int choice, int selected)
-{
-    int i;
-
-    /* Clear 'residue' of last item */
-    wattrset (win, menubox_attr);
-    wmove (win, choice, 0);
-    for (i = 0; i < list_width; i++)
-       waddch (win, ' ');
-
-    wmove (win, choice, check_x);
-    wattrset (win, selected ? check_selected_attr : check_attr);
-    if (checkflag == FLAG_CHECK)
-       wprintw (win, "[%c]", status ? 'X' : ' ');
-    else
-       wprintw (win, "(%c)", status ? 'X' : ' ');
-
-    wattrset (win, selected ? tag_selected_attr : tag_attr);
-    mvwaddch(win, choice, item_x, item[0]);
-    wattrset (win, selected ? item_selected_attr : item_attr);
-    waddstr (win, (char *)item+1);
-    if (selected) {
-       wmove (win, choice, check_x+1);
-       wrefresh (win);
-    }
-}
-
-/*
- * Print the scroll indicators.
- */
-static void
-print_arrows (WINDOW * win, int choice, int item_no, int scroll,
-               int y, int x, int height)
-{
-    wmove(win, y, x);
-
-    if (scroll > 0) {
-       wattrset (win, uarrow_attr);
-       waddch (win, ACS_UARROW);
-       waddstr (win, "(-)");
-    }
-    else {
-       wattrset (win, menubox_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-    }
-
-   y = y + height + 1;
-   wmove(win, y, x);
-
-   if ((height < item_no) && (scroll + choice < item_no - 1)) {
-       wattrset (win, darrow_attr);
-       waddch (win, ACS_DARROW);
-       waddstr (win, "(+)");
-    }
-    else {
-       wattrset (win, menubox_border_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-   }
-}
-
-/*
- *  Display the termination buttons
- */
-static void
-print_buttons( WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 11;
-    int y = height - 2;
-
-    print_button (dialog, "Select", y, x, selected == 0);
-    print_button (dialog, " Help ", y, x + 14, selected == 1);
-
-    wmove(dialog, y, x+1 + 14*selected);
-    wrefresh (dialog);
-}
-
-/*
- * Display a dialog box with a list of options that can be turned on or off
- * The `flag' parameter is used to select between radiolist and checklist.
- */
-int
-dialog_checklist (const char *title, const char *prompt, int height, int width,
-       int list_height, int item_no, const char * const * items, int flag)
-       
-{
-    int i, x, y, box_x, box_y;
-    int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
-    WINDOW *dialog, *list;
-
-    checkflag = flag;
-
-    /* Allocate space for storing item on/off status */
-    if ((status = malloc (sizeof (int) * item_no)) == NULL) {
-       endwin ();
-       fprintf (stderr,
-                "\nCan't allocate memory in dialog_checklist().\n");
-       exit (-1);
-    }
-
-    /* Initializes status */
-    for (i = 0; i < item_no; i++) {
-       status[i] = !strcasecmp (items[i * 3 + 2], "on");
-       if ((!choice && status[i]) || !strcasecmp (items[i * 3 + 2], "selected"))
-            choice = i + 1;
-    }
-    if (choice)
-           choice--;
-
-    max_choice = MIN (list_height, item_no);
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    list_width = width - 6;
-    box_y = height - list_height - 5;
-    box_x = (width - list_width) / 2 - 1;
-
-    /* create new window for the list */
-    list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
-
-    keypad (list, TRUE);
-
-    /* draw a box around the list items */
-    draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
-             menubox_border_attr, menubox_attr);
-
-    /* Find length of longest item in order to center checklist */
-    check_x = 0;
-    for (i = 0; i < item_no; i++) 
-       check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4);
-
-    check_x = (list_width - check_x) / 2;
-    item_x = check_x + 4;
-
-    if (choice >= list_height) {
-       scroll = choice - list_height + 1;
-       choice -= scroll;
-    }
-
-    /* Print the list */
-    for (i = 0; i < max_choice; i++) {
-       print_item (list, items[(scroll+i) * 3 + 1],
-                   status[i+scroll], i, i == choice);
-    }
-
-    print_arrows(dialog, choice, item_no, scroll,
-                       box_y, box_x + check_x + 5, list_height);
-
-    print_buttons(dialog, height, width, 0);
-
-    wnoutrefresh (list);
-    wnoutrefresh (dialog);
-    doupdate ();
-
-    while (key != ESC) {
-       key = wgetch (dialog);
-
-       for (i = 0; i < max_choice; i++)
-            if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
-                break;
-
-
-       if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || 
-           key == '+' || key == '-' ) {
-           if (key == KEY_UP || key == '-') {
-               if (!choice) {
-                   if (!scroll)
-                       continue;
-                   /* Scroll list down */
-                   if (list_height > 1) {
-                       /* De-highlight current first item */
-                       print_item (list, items[scroll * 3 + 1],
-                                       status[scroll], 0, FALSE);
-                       scrollok (list, TRUE);
-                       wscrl (list, -1);
-                       scrollok (list, FALSE);
-                   }
-                   scroll--;
-                   print_item (list, items[scroll * 3 + 1],
-                               status[scroll], 0, TRUE);
-                   wnoutrefresh (list);
-
-                   print_arrows(dialog, choice, item_no, scroll,
-                               box_y, box_x + check_x + 5, list_height);
-
-                   wrefresh (dialog);
-
-                   continue;   /* wait for another key press */
-               } else
-                   i = choice - 1;
-           } else if (key == KEY_DOWN || key == '+') {
-               if (choice == max_choice - 1) {
-                   if (scroll + choice >= item_no - 1)
-                       continue;
-                   /* Scroll list up */
-                   if (list_height > 1) {
-                       /* De-highlight current last item before scrolling up */
-                       print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
-                                   status[scroll + max_choice - 1],
-                                   max_choice - 1, FALSE);
-                       scrollok (list, TRUE);
-                       wscrl (list, 1);
-                       scrollok (list, FALSE);
-                   }
-                   scroll++;
-                   print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
-                               status[scroll + max_choice - 1],
-                               max_choice - 1, TRUE);
-                   wnoutrefresh (list);
-
-                   print_arrows(dialog, choice, item_no, scroll,
-                               box_y, box_x + check_x + 5, list_height);
-
-                   wrefresh (dialog);
-
-                   continue;   /* wait for another key press */
-               } else
-                   i = choice + 1;
-           }
-           if (i != choice) {
-               /* De-highlight current item */
-               print_item (list, items[(scroll + choice) * 3 + 1],
-                           status[scroll + choice], choice, FALSE);
-               /* Highlight new item */
-               choice = i;
-               print_item (list, items[(scroll + choice) * 3 + 1],
-                           status[scroll + choice], choice, TRUE);
-               wnoutrefresh (list);
-               wrefresh (dialog);
-           }
-           continue;           /* wait for another key press */
-       }
-       switch (key) {
-       case 'H':
-       case 'h':
-       case '?':
-           fprintf (stderr, "%s", items[(scroll + choice) * 3]);
-           delwin (dialog);
-           free (status);
-           return 1;
-       case TAB:
-       case KEY_LEFT:
-       case KEY_RIGHT:
-           button = ((key == KEY_LEFT ? --button : ++button) < 0)
-                       ? 1 : (button > 1 ? 0 : button);
-
-           print_buttons(dialog, height, width, button);
-           wrefresh (dialog);
-           break;
-       case 'S':
-       case 's':
-       case ' ':
-       case '\n':
-           if (!button) {
-               if (flag == FLAG_CHECK) {
-                   status[scroll + choice] = !status[scroll + choice];
-                   wmove (list, choice, check_x);
-                   wattrset (list, check_selected_attr);
-                   wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
-               } else {
-                   if (!status[scroll + choice]) {
-                       for (i = 0; i < item_no; i++)
-                           status[i] = 0;
-                       status[scroll + choice] = 1;
-                       for (i = 0; i < max_choice; i++)
-                           print_item (list, items[(scroll + i) * 3 + 1],
-                                       status[scroll + i], i, i == choice);
-                   }
-               }
-               wnoutrefresh (list);
-               wrefresh (dialog);
-            
-               for (i = 0; i < item_no; i++) {
-                   if (status[i]) {
-                       if (flag == FLAG_CHECK) {
-                           fprintf (stderr, "\"%s\" ", items[i * 3]);
-                       } else {
-                           fprintf (stderr, "%s", items[i * 3]);
-                       }
-
-                   }
-               }
-            } else
-               fprintf (stderr, "%s", items[(scroll + choice) * 3]);
-           delwin (dialog);
-           free (status);
-           return button;
-       case 'X':
-       case 'x':
-           key = ESC;
-       case ESC:
-           break;
-       }
-
-       /* Now, update everything... */
-       doupdate ();
-    }
-    
-
-    delwin (dialog);
-    free (status);
-    return -1;                 /* ESC pressed */
-}
diff --git a/scripts/lxdialog/inputbox.c b/scripts/lxdialog/inputbox.c
deleted file mode 100644 (file)
index 074d2d6..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- *  inputbox.c -- implements the input box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-char dialog_input_result[MAX_LEN + 1];
-
-/*
- *  Print the termination buttons
- */
-static void
-print_buttons(WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 11;
-    int y = height - 2;
-
-    print_button (dialog, "  Ok  ", y, x, selected==0);
-    print_button (dialog, " Help ", y, x + 14, selected==1);
-
-    wmove(dialog, y, x+1+14*selected);
-    wrefresh(dialog);
-}
-
-/*
- * Display a dialog box for inputing a string
- */
-int
-dialog_inputbox (const char *title, const char *prompt, int height, int width,
-                const char *init)
-{
-    int i, x, y, box_y, box_x, box_width;
-    int input_x = 0, scroll = 0, key = 0, button = -1;
-    char *instr = dialog_input_result;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    /* Draw the input field box */
-    box_width = width - 6;
-    getyx (dialog, y, x);
-    box_y = y + 2;
-    box_x = (width - box_width) / 2;
-    draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
-             border_attr, dialog_attr);
-
-    print_buttons(dialog, height, width, 0);
-
-    /* Set up the initial value */
-    wmove (dialog, box_y, box_x);
-    wattrset (dialog, inputbox_attr);
-
-    if (!init)
-       instr[0] = '\0';
-    else
-       strcpy (instr, init);
-
-    input_x = strlen (instr);
-
-    if (input_x >= box_width) {
-       scroll = input_x - box_width + 1;
-       input_x = box_width - 1;
-       for (i = 0; i < box_width - 1; i++)
-           waddch (dialog, instr[scroll + i]);
-    } else
-       waddstr (dialog, instr);
-
-    wmove (dialog, box_y, box_x + input_x);
-
-    wrefresh (dialog);
-
-    while (key != ESC) {
-       key = wgetch (dialog);
-
-       if (button == -1) {     /* Input box selected */
-           switch (key) {
-           case TAB:
-           case KEY_UP:
-           case KEY_DOWN:
-               break;
-           case KEY_LEFT:
-               continue;
-           case KEY_RIGHT:
-               continue;
-           case KEY_BACKSPACE:
-           case 127:
-               if (input_x || scroll) {
-                   wattrset (dialog, inputbox_attr);
-                   if (!input_x) {
-                       scroll = scroll < box_width - 1 ?
-                           0 : scroll - (box_width - 1);
-                       wmove (dialog, box_y, box_x);
-                       for (i = 0; i < box_width; i++)
-                           waddch (dialog, instr[scroll + input_x + i] ?
-                                   instr[scroll + input_x + i] : ' ');
-                       input_x = strlen (instr) - scroll;
-                   } else
-                       input_x--;
-                   instr[scroll + input_x] = '\0';
-                   mvwaddch (dialog, box_y, input_x + box_x, ' ');
-                   wmove (dialog, box_y, input_x + box_x);
-                   wrefresh (dialog);
-               }
-               continue;
-           default:
-               if (key < 0x100 && isprint (key)) {
-                   if (scroll + input_x < MAX_LEN) {
-                       wattrset (dialog, inputbox_attr);
-                       instr[scroll + input_x] = key;
-                       instr[scroll + input_x + 1] = '\0';
-                       if (input_x == box_width - 1) {
-                           scroll++;
-                           wmove (dialog, box_y, box_x);
-                           for (i = 0; i < box_width - 1; i++)
-                               waddch (dialog, instr[scroll + i]);
-                       } else {
-                           wmove (dialog, box_y, input_x++ + box_x);
-                           waddch (dialog, key);
-                       }
-                       wrefresh (dialog);
-                   } else
-                       flash ();       /* Alarm user about overflow */
-                   continue;
-               }
-           }
-       }
-       switch (key) {
-       case 'O':
-       case 'o':
-           delwin (dialog);
-           return 0;
-       case 'H':
-       case 'h':
-           delwin (dialog);
-           return 1;
-       case KEY_UP:
-       case KEY_LEFT:
-           switch (button) {
-           case -1:
-               button = 1;     /* Indicates "Cancel" button is selected */
-               print_buttons(dialog, height, width, 1);
-               break;
-           case 0:
-               button = -1;    /* Indicates input box is selected */
-               print_buttons(dialog, height, width, 0);
-               wmove (dialog, box_y, box_x + input_x);
-               wrefresh (dialog);
-               break;
-           case 1:
-               button = 0;     /* Indicates "OK" button is selected */
-               print_buttons(dialog, height, width, 0);
-               break;
-           }
-           break;
-       case TAB:
-       case KEY_DOWN:
-       case KEY_RIGHT:
-           switch (button) {
-           case -1:
-               button = 0;     /* Indicates "OK" button is selected */
-               print_buttons(dialog, height, width, 0);
-               break;
-           case 0:
-               button = 1;     /* Indicates "Cancel" button is selected */
-               print_buttons(dialog, height, width, 1);
-               break;
-           case 1:
-               button = -1;    /* Indicates input box is selected */
-               print_buttons(dialog, height, width, 0);
-               wmove (dialog, box_y, box_x + input_x);
-               wrefresh (dialog);
-               break;
-           }
-           break;
-       case ' ':
-       case '\n':
-           delwin (dialog);
-           return (button == -1 ? 0 : button);
-       case 'X':
-       case 'x':
-           key = ESC;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    return -1;                 /* ESC pressed */
-}
diff --git a/scripts/lxdialog/lxdialog.c b/scripts/lxdialog/lxdialog.c
deleted file mode 100644 (file)
index f283a85..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  dialog - Display simple dialog boxes from shell scripts
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void Usage (const char *name);
-
-typedef int (jumperFn) (const char *title, int argc, const char * const * argv);
-
-struct Mode {
-    char *name;
-    int argmin, argmax, argmod;
-    jumperFn *jumper;
-};
-
-jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
-jumperFn j_msgbox, j_infobox;
-
-static struct Mode modes[] =
-{
-    {"--menu", 9, 0, 3, j_menu},
-    {"--checklist", 9, 0, 3, j_checklist},
-    {"--radiolist", 9, 0, 3, j_radiolist},
-    {"--yesno",    5,5,1, j_yesno},
-    {"--textbox",  5,5,1, j_textbox},
-    {"--inputbox", 5, 6, 1, j_inputbox},
-    {"--msgbox", 5, 5, 1, j_msgbox},
-    {"--infobox", 5, 5, 1, j_infobox},
-    {NULL, 0, 0, 0, NULL}
-};
-
-static struct Mode *modePtr;
-
-#ifdef LOCALE
-#include <locale.h>
-#endif
-
-int
-main (int argc, const char * const * argv)
-{
-    int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
-    const char *title = NULL;
-
-#ifdef LOCALE
-    (void) setlocale (LC_ALL, "");
-#endif
-
-#ifdef TRACE
-    trace(TRACE_CALLS|TRACE_UPDATE);
-#endif
-    if (argc < 2) {
-       Usage (argv[0]);
-       exit (-1);
-    }
-
-    while (offset < argc - 1 && !end_common_opts) {    /* Common options */
-       if (!strcmp (argv[offset + 1], "--title")) {
-           if (argc - offset < 3 || title != NULL) {
-               Usage (argv[0]);
-               exit (-1);
-           } else {
-               title = argv[offset + 2];
-               offset += 2;
-           }
-        } else if (!strcmp (argv[offset + 1], "--backtitle")) {
-            if (backtitle != NULL) {
-                Usage (argv[0]);
-                exit (-1);
-            } else {
-                backtitle = argv[offset + 2];
-                offset += 2;
-            }
-       } else if (!strcmp (argv[offset + 1], "--clear")) {
-           if (opt_clear) {            /* Hey, "--clear" can't appear twice! */
-               Usage (argv[0]);
-               exit (-1);
-           } else if (argc == 2) {     /* we only want to clear the screen */
-               init_dialog ();
-               refresh ();     /* init_dialog() will clear the screen for us */
-               end_dialog ();
-               return 0;
-           } else {
-               opt_clear = 1;
-               offset++;
-           }
-       } else                  /* no more common options */
-           end_common_opts = 1;
-    }
-
-    if (argc - 1 == offset) {  /* no more options */
-       Usage (argv[0]);
-       exit (-1);
-    }
-    /* use a table to look for the requested mode, to avoid code duplication */
-
-    for (modePtr = modes; modePtr->name; modePtr++)    /* look for the mode */
-       if (!strcmp (argv[offset + 1], modePtr->name))
-           break;
-
-    if (!modePtr->name)
-       Usage (argv[0]);
-    if (argc - offset < modePtr->argmin)
-       Usage (argv[0]);
-    if (modePtr->argmax && argc - offset > modePtr->argmax)
-       Usage (argv[0]);
-
-
-
-    init_dialog ();
-    retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
-
-    if (opt_clear) {           /* clear screen before exit */
-       attr_clear (stdscr, LINES, COLS, screen_attr);
-       refresh ();
-    }
-    end_dialog();
-
-    exit (retval);
-}
-
-/*
- * Print program usage
- */
-static void
-Usage (const char *name)
-{
-    fprintf (stderr, "\
-\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
-\n  patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
-\n  modified/gutted for use as a Linux kernel config tool by \
-\n  William Roadcap (roadcapw@cfw.com)\
-\n\
-\n* Display dialog boxes from shell scripts *\
-\n\
-\nUsage: %s --clear\
-\n       %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
-\n\
-\nBox options:\
-\n\
-\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
-\n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n  --textbox   <file> <height> <width>\
-\n  --inputbox  <text> <height> <width> [<init>]\
-\n  --yesno     <text> <height> <width>\
-\n", name, name);
-    exit (-1);
-}
-
-/*
- * These are the program jumpers
- */
-
-int
-j_menu (const char *t, int ac, const char * const * av)
-{
-    return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]),
-                       atoi (av[5]), av[6], (ac - 6) / 2, av + 7);
-}
-
-int
-j_checklist (const char *t, int ac, const char * const * av)
-{
-    return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
-       atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
-}
-
-int
-j_radiolist (const char *t, int ac, const char * const * av)
-{
-    return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
-       atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
-}
-
-int
-j_textbox (const char *t, int ac, const char * const * av)
-{
-    return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4]));
-}
-
-int
-j_yesno (const char *t, int ac, const char * const * av)
-{
-    return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4]));
-}
-
-int
-j_inputbox (const char *t, int ac, const char * const * av)
-{
-    int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]),
-                            ac == 6 ? av[5] : (char *) NULL);
-    if (ret == 0)
-        fprintf(stderr, dialog_input_result);
-    return ret;
-}
-
-int
-j_msgbox (const char *t, int ac, const char * const * av)
-{
-    return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1);
-}
-
-int
-j_infobox (const char *t, int ac, const char * const * av)
-{
-    return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0);
-}
-
diff --git a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c
deleted file mode 100644 (file)
index 91d82ba..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- *  menubox.c -- implements the menu box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *  Changes by Clifford Wolf (god@clifford.at)
- *
- *  [ 1998-06-13 ]
- *
- *    *)  A bugfix for the Page-Down problem
- *
- *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
- *        to the first position in the menu box.  Now lxdialog is a bit
- *        smarter and works more like other menu systems (just have a look at
- *        it).
- *
- *    *)  Formerly if I selected something my scrolling would be broken because
- *        lxdialog is re-invoked by the Menuconfig shell script, can't
- *        remember the last scrolling position, and just sets it so that the
- *        cursor is at the bottom of the box.  Now it writes the temporary file
- *        lxdialog.scrltmp which contains this information. The file is
- *        deleted by lxdialog if the user leaves a submenu or enters a new
- *        one, but it would be nice if Menuconfig could make another "rm -f"
- *        just to be sure.  Just try it out - you will recognise a difference!
- *
- *  [ 1998-06-14 ]
- *
- *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
- *        and menus change their size on the fly.
- *
- *    *)  If for some reason the last scrolling position is not saved by
- *        lxdialog, it sets the scrolling so that the selected item is in the
- *        middle of the menu box, not at the bottom.
- *
- * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
- * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
- * This fixes a bug in Menuconfig where using ' ' to descend into menus
- * would leave mis-synchronized lxdialog.scrltmp files lying around,
- * fscanf would read in 'scroll', and eventually that value would get used.
- */
-
-#include "dialog.h"
-
-static int menu_width, item_x;
-
-/*
- * Print menu item
- */
-static void
-print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
-{
-    int j;
-    char menu_item[menu_width+1];
-
-    strncpy(menu_item, item, menu_width);
-    menu_item[menu_width] = 0;
-    j = first_alpha(menu_item, "YyNnMmHh");
-
-    /* Clear 'residue' of last item */
-    wattrset (win, menubox_attr);
-    wmove (win, choice, 0);
-#if OLD_NCURSES
-    {
-        int i;
-        for (i = 0; i < menu_width; i++)
-           waddch (win, ' ');
-    }
-#else
-    wclrtoeol(win);
-#endif
-    wattrset (win, selected ? item_selected_attr : item_attr);
-    mvwaddstr (win, choice, item_x, menu_item);
-    if (hotkey) {
-       wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
-       mvwaddch(win, choice, item_x+j, menu_item[j]);
-    }
-    if (selected) {
-       wmove (win, choice, item_x+1);
-       wrefresh (win);
-    }
-}
-
-/*
- * Print the scroll indicators.
- */
-static void
-print_arrows (WINDOW * win, int item_no, int scroll,
-               int y, int x, int height)
-{
-    int cur_y, cur_x;
-
-    getyx(win, cur_y, cur_x);
-
-    wmove(win, y, x);
-
-    if (scroll > 0) {
-       wattrset (win, uarrow_attr);
-       waddch (win, ACS_UARROW);
-       waddstr (win, "(-)");
-    }
-    else {
-       wattrset (win, menubox_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-    }
-
-   y = y + height + 1;
-   wmove(win, y, x);
-
-   if ((height < item_no) && (scroll + height < item_no)) {
-       wattrset (win, darrow_attr);
-       waddch (win, ACS_DARROW);
-       waddstr (win, "(+)");
-    }
-    else {
-       wattrset (win, menubox_border_attr);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-       waddch (win, ACS_HLINE);
-   }
-
-   wmove(win, cur_y, cur_x);
-}
-
-/*
- * Display the termination buttons.
- */
-static void
-print_buttons (WINDOW *win, int height, int width, int selected)
-{
-    int x = width / 2 - 16;
-    int y = height - 2;
-
-    print_button (win, "Select", y, x, selected == 0);
-    print_button (win, " Exit ", y, x + 12, selected == 1);
-    print_button (win, " Help ", y, x + 24, selected == 2);
-
-    wmove(win, y, x+1+12*selected);
-    wrefresh (win);
-}
-
-/*
- * Display a menu for choosing among a number of options
- */
-int
-dialog_menu (const char *title, const char *prompt, int height, int width,
-               int menu_height, const char *current, int item_no,
-               const char * const * items)
-
-{
-    int i, j, x, y, box_x, box_y;
-    int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
-    WINDOW *dialog, *menu;
-    FILE *f;
-
-    max_choice = MIN (menu_height, item_no);
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    wbkgdset (dialog, dialog_attr & A_COLOR);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    menu_width = width - 6;
-    box_y = height - menu_height - 5;
-    box_x = (width - menu_width) / 2 - 1;
-
-    /* create new window for the menu */
-    menu = subwin (dialog, menu_height, menu_width,
-               y + box_y + 1, x + box_x + 1);
-    keypad (menu, TRUE);
-
-    /* draw a box around the menu items */
-    draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
-             menubox_border_attr, menubox_attr);
-
-    /*
-     * Find length of longest item in order to center menu.
-     * Set 'choice' to default item. 
-     */
-    item_x = 0;
-    for (i = 0; i < item_no; i++) {
-       item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
-       if (strcmp(current, items[i*2]) == 0) choice = i;
-    }
-
-    item_x = (menu_width - item_x) / 2;
-
-    /* get the scroll info from the temp file */
-    if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
-       if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
-            (scroll+max_choice > choice) && (scroll >= 0) &&
-            (scroll+max_choice <= item_no) ) {
-           first_item = scroll;
-           choice = choice - scroll;
-           fclose(f);
-       } else {
-           scroll=0;
-           remove("lxdialog.scrltmp");
-           fclose(f);
-           f=NULL;
-       }
-    }
-    if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
-       if (choice >= item_no-max_choice/2)
-           scroll = first_item = item_no-max_choice;
-       else
-           scroll = first_item = choice - max_choice/2;
-       choice = choice - scroll;
-    }
-
-    /* Print the menu */
-    for (i=0; i < max_choice; i++) {
-       print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
-                    (items[(first_item + i)*2][0] != ':'));
-    }
-
-    wnoutrefresh (menu);
-
-    print_arrows(dialog, item_no, scroll,
-                box_y, box_x+item_x+1, menu_height);
-
-    print_buttons (dialog, height, width, 0);
-    wmove (menu, choice, item_x+1);
-    wrefresh (menu);
-
-    while (key != ESC) {
-       key = wgetch(menu);
-
-       if (key < 256 && isalpha(key)) key = tolower(key);
-
-       if (strchr("ynmh", key))
-               i = max_choice;
-       else {
-        for (i = choice+1; i < max_choice; i++) {
-               j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
-               if (key == tolower(items[(scroll+i)*2+1][j]))
-                       break;
-       }
-       if (i == max_choice)
-                       for (i = 0; i < max_choice; i++) {
-                       j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
-                       if (key == tolower(items[(scroll+i)*2+1][j]))
-                               break;
-               }
-       }
-
-       if (i < max_choice || 
-            key == KEY_UP || key == KEY_DOWN ||
-            key == '-' || key == '+' ||
-            key == KEY_PPAGE || key == KEY_NPAGE) {
-
-            print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
-                       (items[(scroll+choice)*2][0] != ':'));
-
-           if (key == KEY_UP || key == '-') {
-                if (choice < 2 && scroll) {
-                   /* Scroll menu down */
-                    scrollok (menu, TRUE);
-                    wscrl (menu, -1);
-                    scrollok (menu, FALSE);
-
-                    scroll--;
-
-                    print_item (menu, items[scroll * 2 + 1], 0, FALSE,
-                               (items[scroll*2][0] != ':'));
-               } else
-                   choice = MAX(choice - 1, 0);
-
-           } else if (key == KEY_DOWN || key == '+')  {
-
-               print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
-                                (items[(scroll+choice)*2][0] != ':'));
-
-                if ((choice > max_choice-3) &&
-                    (scroll + max_choice < item_no)
-                   ) {
-                   /* Scroll menu up */
-                   scrollok (menu, TRUE);
-                   wscrl (menu, 1);
-                    scrollok (menu, FALSE);
-
-                    scroll++;
-
-                    print_item (menu, items[(scroll+max_choice-1)*2+1],
-                               max_choice-1, FALSE,
-                               (items[(scroll+max_choice-1)*2][0] != ':'));
-                } else
-                    choice = MIN(choice+1, max_choice-1);
-
-           } else if (key == KEY_PPAGE) {
-               scrollok (menu, TRUE);
-                for (i=0; (i < max_choice); i++) {
-                    if (scroll > 0) {
-                       wscrl (menu, -1);
-                       scroll--;
-                       print_item (menu, items[scroll * 2 + 1], 0, FALSE,
-                       (items[scroll*2][0] != ':'));
-                    } else {
-                        if (choice > 0)
-                            choice--;
-                    }
-                }
-                scrollok (menu, FALSE);
-
-            } else if (key == KEY_NPAGE) {
-                for (i=0; (i < max_choice); i++) {
-                    if (scroll+max_choice < item_no) {
-                       scrollok (menu, TRUE);
-                       wscrl (menu, 1);
-                       scrollok (menu, FALSE);
-                       scroll++;
-                       print_item (menu, items[(scroll+max_choice-1)*2+1],
-                                   max_choice-1, FALSE,
-                                   (items[(scroll+max_choice-1)*2][0] != ':'));
-                   } else {
-                       if (choice+1 < max_choice)
-                           choice++;
-                   }
-                }
-
-            } else
-                choice = i;
-
-            print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
-                       (items[(scroll+choice)*2][0] != ':'));
-
-            print_arrows(dialog, item_no, scroll,
-                         box_y, box_x+item_x+1, menu_height);
-
-            wnoutrefresh (dialog);
-            wrefresh (menu);
-
-           continue;           /* wait for another key press */
-        }
-
-       switch (key) {
-       case KEY_LEFT:
-       case TAB:
-       case KEY_RIGHT:
-           button = ((key == KEY_LEFT ? --button : ++button) < 0)
-                       ? 2 : (button > 2 ? 0 : button);
-
-           print_buttons(dialog, height, width, button);
-           wrefresh (menu);
-           break;
-       case ' ':
-       case 's':
-       case 'y':
-       case 'n':
-       case 'm':
-       case '/':
-           /* save scroll info */
-           if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
-               fprintf(f,"%d\n",scroll);
-               fclose(f);
-           }
-           delwin (dialog);
-            fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
-            switch (key) {
-            case 's': return 3;
-            case 'y': return 3;
-            case 'n': return 4;
-            case 'm': return 5;
-            case ' ': return 6;
-            case '/': return 7;
-            }
-           return 0;
-       case 'h':
-       case '?':
-           button = 2;
-       case '\n':
-           delwin (dialog);
-           if (button == 2) 
-               fprintf(stderr, "%s \"%s\"\n", 
-                       items[(scroll + choice) * 2],
-                       items[(scroll + choice) * 2 + 1] +
-                       first_alpha(items[(scroll + choice) * 2 + 1],""));
-           else
-               fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
-
-           remove("lxdialog.scrltmp");
-           return button;
-       case 'e':
-       case 'x':
-           key = ESC;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    remove("lxdialog.scrltmp");
-    return -1;                 /* ESC pressed */
-}
diff --git a/scripts/lxdialog/msgbox.c b/scripts/lxdialog/msgbox.c
deleted file mode 100644 (file)
index 93692e1..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  msgbox.c -- implements the message box and info box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int
-dialog_msgbox (const char *title, const char *prompt, int height, int width,
-               int pause)
-{
-    int i, x, y, key = 0;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 2);
-
-    if (pause) {
-       wattrset (dialog, border_attr);
-       mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-       for (i = 0; i < width - 2; i++)
-           waddch (dialog, ACS_HLINE);
-       wattrset (dialog, dialog_attr);
-       waddch (dialog, ACS_RTEE);
-
-       print_button (dialog, "  Ok  ",
-                     height - 2, width / 2 - 4, TRUE);
-
-       wrefresh (dialog);
-       while (key != ESC && key != '\n' && key != ' ' &&
-               key != 'O' && key != 'o' && key != 'X' && key != 'x')
-           key = wgetch (dialog);
-    } else {
-       key = '\n';
-       wrefresh (dialog);
-    }
-
-    delwin (dialog);
-    return key == ESC ? -1 : 0;
-}
diff --git a/scripts/lxdialog/textbox.c b/scripts/lxdialog/textbox.c
deleted file mode 100644 (file)
index ed23df2..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- *  textbox.c -- implements the text box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void back_lines (int n);
-static void print_page (WINDOW * win, int height, int width);
-static void print_line (WINDOW * win, int row, int width);
-static char *get_line (void);
-static void print_position (WINDOW * win, int height, int width);
-
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
-
-/*
- * Display text from a file in a dialog box.
- */
-int
-dialog_textbox (const char *title, const char *file, int height, int width)
-{
-    int i, x, y, cur_x, cur_y, fpos, key = 0;
-    int passed_end;
-    char search_term[MAX_LEN + 1];
-    WINDOW *dialog, *text;
-
-    search_term[0] = '\0';     /* no search term entered yet */
-
-    /* Open input file for reading */
-    if ((fd = open (file, O_RDONLY)) == -1) {
-       endwin ();
-       fprintf (stderr,
-                "\nCan't open input file in dialog_textbox().\n");
-       exit (-1);
-    }
-    /* Get file size. Actually, 'file_size' is the real file size - 1,
-       since it's only the last byte offset from the beginning */
-    if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
-       exit (-1);
-    }
-    /* Restore file pointer to beginning of file after getting file size */
-    if (lseek (fd, 0, SEEK_SET) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
-       exit (-1);
-    }
-    /* Allocate space for read buffer */
-    if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
-       endwin ();
-       fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
-       exit (-1);
-    }
-    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError reading file in dialog_textbox().\n");
-       exit (-1);
-    }
-    buf[bytes_read] = '\0';    /* mark end of valid data */
-    page = buf;                        /* page is pointer to start of page to be displayed */
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    /* Create window for text region, used for scrolling text */
-    text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
-    wattrset (text, dialog_attr);
-    wbkgdset (text, dialog_attr & A_COLOR);
-
-    keypad (text, TRUE);
-
-    /* register the new window, along with its borders */
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    wbkgdset (dialog, dialog_attr & A_COLOR);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-    print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
-    wnoutrefresh (dialog);
-    getyx (dialog, cur_y, cur_x);      /* Save cursor position */
-
-    /* Print first page of text */
-    attr_clear (text, height - 4, width - 2, dialog_attr);
-    print_page (text, height - 4, width - 2);
-    print_position (dialog, height, width);
-    wmove (dialog, cur_y, cur_x);      /* Restore cursor position */
-    wrefresh (dialog);
-
-    while ((key != ESC) && (key != '\n')) {
-       key = wgetch (dialog);
-       switch (key) {
-       case 'E':               /* Exit */
-       case 'e':
-       case 'X':
-       case 'x':
-           delwin (dialog);
-           free (buf);
-           close (fd);
-           return 0;
-       case 'g':               /* First page */
-       case KEY_HOME:
-           if (!begin_reached) {
-               begin_reached = 1;
-               /* First page not in buffer? */
-               if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                     "\nError moving file pointer in dialog_textbox().\n");
-                   exit (-1);
-               }
-               if (fpos > bytes_read) {        /* Yes, we have to read it in */
-                   if (lseek (fd, 0, SEEK_SET) == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError moving file pointer in "
-                                "dialog_textbox().\n");
-                       exit (-1);
-                   }
-                   if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                       endwin ();
-                       fprintf (stderr,
-                            "\nError reading file in dialog_textbox().\n");
-                       exit (-1);
-                   }
-                   buf[bytes_read] = '\0';
-               }
-               page = buf;
-               print_page (text, height - 4, width - 2);
-               print_position (dialog, height, width);
-               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-               wrefresh (dialog);
-           }
-           break;
-       case 'G':               /* Last page */
-       case KEY_END:
-
-           end_reached = 1;
-           /* Last page not in buffer? */
-           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-               endwin ();
-               fprintf (stderr,
-                     "\nError moving file pointer in dialog_textbox().\n");
-               exit (-1);
-           }
-           if (fpos < file_size) {     /* Yes, we have to read it in */
-               if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                     "\nError moving file pointer in dialog_textbox().\n");
-                   exit (-1);
-               }
-               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                            "\nError reading file in dialog_textbox().\n");
-                   exit (-1);
-               }
-               buf[bytes_read] = '\0';
-           }
-           page = buf + bytes_read;
-           back_lines (height - 4);
-           print_page (text, height - 4, width - 2);
-           print_position (dialog, height, width);
-           wmove (dialog, cur_y, cur_x);       /* Restore cursor position */
-           wrefresh (dialog);
-           break;
-       case 'K':               /* Previous line */
-       case 'k':
-       case KEY_UP:
-           if (!begin_reached) {
-               back_lines (page_length + 1);
-
-               /* We don't call print_page() here but use scrolling to ensure
-                  faster screen update. However, 'end_reached' and
-                  'page_length' should still be updated, and 'page' should
-                  point to start of next page. This is done by calling
-                  get_line() in the following 'for' loop. */
-               scrollok (text, TRUE);
-               wscrl (text, -1);       /* Scroll text region down one line */
-               scrollok (text, FALSE);
-               page_length = 0;
-               passed_end = 0;
-               for (i = 0; i < height - 4; i++) {
-                   if (!i) {
-                       /* print first line of page */
-                       print_line (text, 0, width - 2);
-                       wnoutrefresh (text);
-                   } else
-                       /* Called to update 'end_reached' and 'page' */
-                       get_line ();
-                   if (!passed_end)
-                       page_length++;
-                   if (end_reached && !passed_end)
-                       passed_end = 1;
-               }
-
-               print_position (dialog, height, width);
-               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-               wrefresh (dialog);
-           }
-           break;
-       case 'B':               /* Previous page */
-       case 'b':
-       case KEY_PPAGE:
-           if (begin_reached)
-               break;
-           back_lines (page_length + height - 4);
-           print_page (text, height - 4, width - 2);
-           print_position (dialog, height, width);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case 'J':               /* Next line */
-       case 'j':
-       case KEY_DOWN:
-           if (!end_reached) {
-               begin_reached = 0;
-               scrollok (text, TRUE);
-               scroll (text);  /* Scroll text region up one line */
-               scrollok (text, FALSE);
-               print_line (text, height - 5, width - 2);
-               wnoutrefresh (text);
-               print_position (dialog, height, width);
-               wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-               wrefresh (dialog);
-           }
-           break;
-       case KEY_NPAGE:         /* Next page */
-       case ' ':
-           if (end_reached)
-               break;
-
-           begin_reached = 0;
-           print_page (text, height - 4, width - 2);
-           print_position (dialog, height, width);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case '0':               /* Beginning of line */
-       case 'H':               /* Scroll left */
-       case 'h':
-       case KEY_LEFT:
-           if (hscroll <= 0)
-               break;
-
-           if (key == '0')
-               hscroll = 0;
-           else
-               hscroll--;
-           /* Reprint current page to scroll horizontally */
-           back_lines (page_length);
-           print_page (text, height - 4, width - 2);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case 'L':               /* Scroll right */
-       case 'l':
-       case KEY_RIGHT:
-           if (hscroll >= MAX_LEN)
-               break;
-           hscroll++;
-           /* Reprint current page to scroll horizontally */
-           back_lines (page_length);
-           print_page (text, height - 4, width - 2);
-           wmove (dialog, cur_y, cur_x);
-           wrefresh (dialog);
-           break;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    free (buf);
-    close (fd);
-    return -1;                 /* ESC pressed */
-}
-
-/*
- * Go back 'n' lines in text file. Called by dialog_textbox().
- * 'page' will be updated to point to the desired line in 'buf'.
- */
-static void
-back_lines (int n)
-{
-    int i, fpos;
-
-    begin_reached = 0;
-    /* We have to distinguish between end_reached and !end_reached
-       since at end of file, the line is not ended by a '\n'.
-       The code inside 'if' basically does a '--page' to move one
-       character backward so as to skip '\n' of the previous line */
-    if (!end_reached) {
-       /* Either beginning of buffer or beginning of file reached? */
-       if (page == buf) {
-           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-               endwin ();
-               fprintf (stderr, "\nError moving file pointer in "
-                        "back_lines().\n");
-               exit (-1);
-           }
-           if (fpos > bytes_read) {    /* Not beginning of file yet */
-               /* We've reached beginning of buffer, but not beginning of
-                  file yet, so read previous part of file into buffer.
-                  Note that we only move backward for BUF_SIZE/2 bytes,
-                  but not BUF_SIZE bytes to avoid re-reading again in
-                  print_page() later */
-               /* Really possible to move backward BUF_SIZE/2 bytes? */
-               if (fpos < BUF_SIZE / 2 + bytes_read) {
-                   /* No, move less then */
-                   if (lseek (fd, 0, SEEK_SET) == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError moving file pointer in "
-                                "back_lines().\n");
-                       exit (-1);
-                   }
-                   page = buf + fpos - bytes_read;
-               } else {        /* Move backward BUF_SIZE/2 bytes */
-                   if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
-                       == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError moving file pointer "
-                                "in back_lines().\n");
-                       exit (-1);
-                   }
-                   page = buf + BUF_SIZE / 2;
-               }
-               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                   endwin ();
-                   fprintf (stderr, "\nError reading file in back_lines().\n");
-                   exit (-1);
-               }
-               buf[bytes_read] = '\0';
-           } else {            /* Beginning of file reached */
-               begin_reached = 1;
-               return;
-           }
-       }
-       if (*(--page) != '\n') {        /* '--page' here */
-           /* Something's wrong... */
-           endwin ();
-           fprintf (stderr, "\nInternal error in back_lines().\n");
-           exit (-1);
-       }
-    }
-    /* Go back 'n' lines */
-    for (i = 0; i < n; i++)
-       do {
-           if (page == buf) {
-               if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-                   endwin ();
-                   fprintf (stderr,
-                         "\nError moving file pointer in back_lines().\n");
-                   exit (-1);
-               }
-               if (fpos > bytes_read) {
-                   /* Really possible to move backward BUF_SIZE/2 bytes? */
-                   if (fpos < BUF_SIZE / 2 + bytes_read) {
-                       /* No, move less then */
-                       if (lseek (fd, 0, SEEK_SET) == -1) {
-                           endwin ();
-                           fprintf (stderr, "\nError moving file pointer "
-                                    "in back_lines().\n");
-                           exit (-1);
-                       }
-                       page = buf + fpos - bytes_read;
-                   } else {    /* Move backward BUF_SIZE/2 bytes */
-                       if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
-                                  SEEK_CUR) == -1) {
-                           endwin ();
-                           fprintf (stderr, "\nError moving file pointer"
-                                    " in back_lines().\n");
-                           exit (-1);
-                       }
-                       page = buf + BUF_SIZE / 2;
-                   }
-                   if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                       endwin ();
-                       fprintf (stderr, "\nError reading file in "
-                                "back_lines().\n");
-                       exit (-1);
-                   }
-                   buf[bytes_read] = '\0';
-               } else {        /* Beginning of file reached */
-                   begin_reached = 1;
-                   return;
-               }
-           }
-       } while (*(--page) != '\n');
-    page++;
-}
-
-/*
- * Print a new page of text. Called by dialog_textbox().
- */
-static void
-print_page (WINDOW * win, int height, int width)
-{
-    int i, passed_end = 0;
-
-    page_length = 0;
-    for (i = 0; i < height; i++) {
-       print_line (win, i, width);
-       if (!passed_end)
-           page_length++;
-       if (end_reached && !passed_end)
-           passed_end = 1;
-    }
-    wnoutrefresh (win);
-}
-
-/*
- * Print a new line of text. Called by dialog_textbox() and print_page().
- */
-static void
-print_line (WINDOW * win, int row, int width)
-{
-    int y, x;
-    char *line;
-
-    line = get_line ();
-    line += MIN (strlen (line), hscroll);      /* Scroll horizontally */
-    wmove (win, row, 0);       /* move cursor to correct line */
-    waddch (win, ' ');
-    waddnstr (win, line, MIN (strlen (line), width - 2));
-
-    getyx (win, y, x);
-    /* Clear 'residue' of previous line */
-#if OLD_NCURSES
-    {
-        int i;
-        for (i = 0; i < width - x; i++)
-           waddch (win, ' ');
-    }
-#else
-    wclrtoeol(win);
-#endif
-}
-
-/*
- * Return current line of text. Called by dialog_textbox() and print_line().
- * 'page' should point to start of current line before calling, and will be
- * updated to point to start of next line.
- */
-static char *
-get_line (void)
-{
-    int i = 0, fpos;
-    static char line[MAX_LEN + 1];
-
-    end_reached = 0;
-    while (*page != '\n') {
-       if (*page == '\0') {
-           /* Either end of file or end of buffer reached */
-           if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-               endwin ();
-               fprintf (stderr, "\nError moving file pointer in "
-                        "get_line().\n");
-               exit (-1);
-           }
-           if (fpos < file_size) {     /* Not end of file yet */
-               /* We've reached end of buffer, but not end of file yet,
-                  so read next part of file into buffer */
-               if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-                   endwin ();
-                   fprintf (stderr, "\nError reading file in get_line().\n");
-                   exit (-1);
-               }
-               buf[bytes_read] = '\0';
-               page = buf;
-           } else {
-               if (!end_reached)
-                   end_reached = 1;
-               break;
-           }
-       } else if (i < MAX_LEN)
-           line[i++] = *(page++);
-       else {
-           /* Truncate lines longer than MAX_LEN characters */
-           if (i == MAX_LEN)
-               line[i++] = '\0';
-           page++;
-       }
-    }
-    if (i <= MAX_LEN)
-       line[i] = '\0';
-    if (!end_reached)
-       page++;                 /* move pass '\n' */
-
-    return line;
-}
-
-/*
- * Print current position
- */
-static void
-print_position (WINDOW * win, int height, int width)
-{
-    int fpos, percent;
-
-    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-       endwin ();
-       fprintf (stderr, "\nError moving file pointer in print_position().\n");
-       exit (-1);
-    }
-    wattrset (win, position_indicator_attr);
-    wbkgdset (win, position_indicator_attr & A_COLOR);
-    percent = !file_size ?
-       100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
-    wmove (win, height - 3, width - 9);
-    wprintw (win, "(%3d%%)", percent);
-}
diff --git a/scripts/lxdialog/util.c b/scripts/lxdialog/util.c
deleted file mode 100644 (file)
index e7bce9b..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- *  util.c
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-
-/* use colors by default? */
-bool use_colors = 1;
-
-const char *backtitle = NULL;
-
-const char *dialog_result;
-
-/* 
- * Attribute values, default is for mono display
- */
-chtype attributes[] =
-{
-    A_NORMAL,                  /* screen_attr */
-    A_NORMAL,                  /* shadow_attr */
-    A_NORMAL,                  /* dialog_attr */
-    A_BOLD,                    /* title_attr */
-    A_NORMAL,                  /* border_attr */
-    A_REVERSE,                 /* button_active_attr */
-    A_DIM,                     /* button_inactive_attr */
-    A_REVERSE,                 /* button_key_active_attr */
-    A_BOLD,                    /* button_key_inactive_attr */
-    A_REVERSE,                 /* button_label_active_attr */
-    A_NORMAL,                  /* button_label_inactive_attr */
-    A_NORMAL,                  /* inputbox_attr */
-    A_NORMAL,                  /* inputbox_border_attr */
-    A_NORMAL,                  /* searchbox_attr */
-    A_BOLD,                    /* searchbox_title_attr */
-    A_NORMAL,                  /* searchbox_border_attr */
-    A_BOLD,                    /* position_indicator_attr */
-    A_NORMAL,                  /* menubox_attr */
-    A_NORMAL,                  /* menubox_border_attr */
-    A_NORMAL,                  /* item_attr */
-    A_REVERSE,                 /* item_selected_attr */
-    A_BOLD,                    /* tag_attr */
-    A_REVERSE,                 /* tag_selected_attr */
-    A_BOLD,                    /* tag_key_attr */
-    A_REVERSE,                 /* tag_key_selected_attr */
-    A_BOLD,                    /* check_attr */
-    A_REVERSE,                 /* check_selected_attr */
-    A_BOLD,                    /* uarrow_attr */
-    A_BOLD                     /* darrow_attr */
-};
-
-
-#include "colors.h"
-
-/*
- * Table of color values
- */
-int color_table[][3] =
-{
-    {SCREEN_FG, SCREEN_BG, SCREEN_HL},
-    {SHADOW_FG, SHADOW_BG, SHADOW_HL},
-    {DIALOG_FG, DIALOG_BG, DIALOG_HL},
-    {TITLE_FG, TITLE_BG, TITLE_HL},
-    {BORDER_FG, BORDER_BG, BORDER_HL},
-    {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
-    {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
-    {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
-    {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
-    {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
-    {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
-     BUTTON_LABEL_INACTIVE_HL},
-    {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
-    {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
-    {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
-    {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
-    {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
-    {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
-    {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
-    {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
-    {ITEM_FG, ITEM_BG, ITEM_HL},
-    {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
-    {TAG_FG, TAG_BG, TAG_HL},
-    {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
-    {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
-    {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
-    {CHECK_FG, CHECK_BG, CHECK_HL},
-    {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
-    {UARROW_FG, UARROW_BG, UARROW_HL},
-    {DARROW_FG, DARROW_BG, DARROW_HL},
-};                             /* color_table */
-
-/*
- * Set window to attribute 'attr'
- */
-void
-attr_clear (WINDOW * win, int height, int width, chtype attr)
-{
-    int i, j;
-
-    wattrset (win, attr);
-    for (i = 0; i < height; i++) {
-       wmove (win, i, 0);
-       for (j = 0; j < width; j++)
-           waddch (win, ' ');
-    }
-    touchwin (win);
-}
-
-void dialog_clear (void)
-{
-    attr_clear (stdscr, LINES, COLS, screen_attr);
-    /* Display background title if it exists ... - SLH */
-    if (backtitle != NULL) {
-        int i;
-
-        wattrset (stdscr, screen_attr);
-        mvwaddstr (stdscr, 0, 1, (char *)backtitle);
-        wmove (stdscr, 1, 1);
-        for (i = 1; i < COLS - 1; i++)
-            waddch (stdscr, ACS_HLINE);
-    }
-    wnoutrefresh (stdscr);
-}
-
-/*
- * Do some initialization for dialog
- */
-void
-init_dialog (void)
-{
-    initscr ();                        /* Init curses */
-    keypad (stdscr, TRUE);
-    cbreak ();
-    noecho ();
-
-
-    if (use_colors)    /* Set up colors */
-       color_setup ();
-
-
-    dialog_clear ();
-}
-
-/*
- * Setup for color display
- */
-void
-color_setup (void)
-{
-    int i;
-
-    if (has_colors ()) {       /* Terminal supports color? */
-       start_color ();
-
-       /* Initialize color pairs */
-       for (i = 0; i < ATTRIBUTE_COUNT; i++)
-           init_pair (i + 1, color_table[i][0], color_table[i][1]);
-
-       /* Setup color attributes */
-       for (i = 0; i < ATTRIBUTE_COUNT; i++)
-           attributes[i] = C_ATTR (color_table[i][2], i + 1);
-    }
-}
-
-/*
- * End using dialog functions.
- */
-void
-end_dialog (void)
-{
-    endwin ();
-}
-
-
-/*
- * Print a string of text in a window, automatically wrap around to the
- * next line if the string is too long to fit on one line. Newline
- * characters '\n' are replaced by spaces.  We start on a new line
- * if there is no room for at least 4 nonblanks following a double-space.
- */
-void
-print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
-{
-    int newl, cur_x, cur_y;
-    int i, prompt_len, room, wlen;
-    char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
-
-    strcpy (tempstr, prompt);
-
-    prompt_len = strlen(tempstr);
-       
-    /*
-     * Remove newlines
-     */
-    for(i=0; i<prompt_len; i++) {
-       if(tempstr[i] == '\n') tempstr[i] = ' ';
-    }
-
-    if (prompt_len <= width - x * 2) { /* If prompt is short */
-       wmove (win, y, (width - prompt_len) / 2);
-       waddstr (win, tempstr);
-    } else {
-       cur_x = x;
-       cur_y = y;
-       newl = 1;
-       word = tempstr;
-       while (word && *word) {
-           sp = index(word, ' ');
-           if (sp)
-               *sp++ = 0;
-
-           /* Wrap to next line if either the word does not fit,
-              or it is the first word of a new sentence, and it is
-              short, and the next word does not fit. */
-           room = width - cur_x;
-           wlen = strlen(word);
-           if (wlen > room ||
-              (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
-                    && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
-               cur_y++;
-               cur_x = x;
-           }
-           wmove (win, cur_y, cur_x);
-           waddstr (win, word);
-           getyx (win, cur_y, cur_x);
-           cur_x++;
-           if (sp && *sp == ' ') {
-               cur_x++;        /* double space */
-               while (*++sp == ' ');
-               newl = 1;
-           } else
-               newl = 0;
-           word = sp;
-       }
-    }
-}
-
-/*
- * Print a button
- */
-void
-print_button (WINDOW * win, const char *label, int y, int x, int selected)
-{
-    int i, temp;
-
-    wmove (win, y, x);
-    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-    waddstr (win, "<");
-    temp = strspn (label, " ");
-    label += temp;
-    wattrset (win, selected ? button_label_active_attr
-             : button_label_inactive_attr);
-    for (i = 0; i < temp; i++)
-       waddch (win, ' ');
-    wattrset (win, selected ? button_key_active_attr
-             : button_key_inactive_attr);
-    waddch (win, label[0]);
-    wattrset (win, selected ? button_label_active_attr
-             : button_label_inactive_attr);
-    waddstr (win, (char *)label + 1);
-    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-    waddstr (win, ">");
-    wmove (win, y, x + temp + 1);
-}
-
-/*
- * Draw a rectangular box with line drawing characters
- */
-void
-draw_box (WINDOW * win, int y, int x, int height, int width,
-         chtype box, chtype border)
-{
-    int i, j;
-
-    wattrset (win, 0);
-    for (i = 0; i < height; i++) {
-       wmove (win, y + i, x);
-       for (j = 0; j < width; j++)
-           if (!i && !j)
-               waddch (win, border | ACS_ULCORNER);
-           else if (i == height - 1 && !j)
-               waddch (win, border | ACS_LLCORNER);
-           else if (!i && j == width - 1)
-               waddch (win, box | ACS_URCORNER);
-           else if (i == height - 1 && j == width - 1)
-               waddch (win, box | ACS_LRCORNER);
-           else if (!i)
-               waddch (win, border | ACS_HLINE);
-           else if (i == height - 1)
-               waddch (win, box | ACS_HLINE);
-           else if (!j)
-               waddch (win, border | ACS_VLINE);
-           else if (j == width - 1)
-               waddch (win, box | ACS_VLINE);
-           else
-               waddch (win, box | ' ');
-    }
-}
-
-/*
- * Draw shadows along the right and bottom edge to give a more 3D look
- * to the boxes
- */
-void
-draw_shadow (WINDOW * win, int y, int x, int height, int width)
-{
-    int i;
-
-    if (has_colors ()) {       /* Whether terminal supports color? */
-       wattrset (win, shadow_attr);
-       wmove (win, y + height, x + 2);
-       for (i = 0; i < width; i++)
-           waddch (win, winch (win) & A_CHARTEXT);
-       for (i = y + 1; i < y + height + 1; i++) {
-           wmove (win, i, x + width);
-           waddch (win, winch (win) & A_CHARTEXT);
-           waddch (win, winch (win) & A_CHARTEXT);
-       }
-       wnoutrefresh (win);
-    }
-}
-
-/*
- *  Return the position of the first alphabetic character in a string.
- */
-int
-first_alpha(const char *string, const char *exempt)
-{
-       int i, in_paren=0, c;
-
-       for (i = 0; i < strlen(string); i++) {
-               c = tolower(string[i]);
-
-               if (strchr("<[(", c)) ++in_paren;
-               if (strchr(">])", c) && in_paren > 0) --in_paren;
-
-               if ((! in_paren) && isalpha(c) && 
-                    strchr(exempt, c) == 0)
-                       return i;
-       }
-
-       return 0;
-}
diff --git a/scripts/lxdialog/yesno.c b/scripts/lxdialog/yesno.c
deleted file mode 100644 (file)
index 11fcc25..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *  yesno.c -- implements the yes/no box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display termination buttons
- */
-static void
-print_buttons(WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 10;
-    int y = height - 2;
-
-    print_button (dialog, " Yes ", y, x, selected == 0);
-    print_button (dialog, "  No  ", y, x + 13, selected == 1);
-
-    wmove(dialog, y, x+1 + 13*selected );
-    wrefresh (dialog);
-}
-
-/*
- * Display a dialog box with two buttons - Yes and No
- */
-int
-dialog_yesno (const char *title, const char *prompt, int height, int width)
-{
-    int i, x, y, key = 0, button = 0;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-       waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-       /* truncate long title -- mec */
-       char * title2 = malloc(width-2+1);
-       memcpy( title2, title, width-2 );
-       title2[width-2] = '\0';
-       title = title2;
-    }
-
-    if (title != NULL) {
-       wattrset (dialog, title_attr);
-       mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-       waddstr (dialog, (char *)title);
-       waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    print_buttons(dialog, height, width, 0);
-
-    while (key != ESC) {
-       key = wgetch (dialog);
-       switch (key) {
-       case 'Y':
-       case 'y':
-           delwin (dialog);
-           return 0;
-       case 'N':
-       case 'n':
-           delwin (dialog);
-           return 1;
-
-       case TAB:
-       case KEY_LEFT:
-       case KEY_RIGHT:
-           button = ((key == KEY_LEFT ? --button : ++button) < 0)
-                       ? 1 : (button > 1 ? 0 : button);
-
-           print_buttons(dialog, height, width, button);
-           wrefresh (dialog);
-           break;
-       case ' ':
-       case '\n':
-           delwin (dialog);
-           return button;
-       case ESC:
-           break;
-       }
-    }
-
-    delwin (dialog);
-    return -1;                 /* ESC pressed */
-}
index 3bed09e625c0b52c8d52f762af6ee6dfd7c86cba..f70ff13d481834b14ceb926879a6a3a2e99e1894 100644 (file)
@@ -326,8 +326,8 @@ parse_elf_finish(struct elf_info *info)
        release_file(info->hdr, info->size);
 }
 
-#define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
-#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
+#define CRC_PFX     "__crc_"
+#define KSYMTAB_PFX "__ksymtab_"
 
 void
 handle_modversions(struct module *mod, struct elf_info *info,
@@ -539,10 +539,9 @@ add_header(struct buffer *b, struct module *mod)
        buf_printf(b, "\n");
        buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
        buf_printf(b, "\n");
-       buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */
        buf_printf(b, "struct module __this_module\n");
        buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
-       buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n");
+       buf_printf(b, " .name = KBUILD_MODNAME,\n");
        if (mod->has_init)
                buf_printf(b, " .init = init_module,\n");
        if (mod->has_cleanup)
index f3e7e8e4a500fe8e6ae0438cd09ebd148067b3bd..c201ef001f09f1477f50a3c9268c42b7a6cdb24b 100644 (file)
@@ -84,7 +84,7 @@ clean-dirs += $(objtree)/debian/
 # ---------------------------------------------------------------------------
 .PHONY: tar%pkg
 tar%pkg:
-       $(MAKE)
+       $(MAKE) KBUILD_SRC=
        $(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@
 
 clean-dirs += $(objtree)/tar-install/
index d8fffe6f890657b3b42c32639ad8bc5313880328..88b5281ac41ef75e4bf82b9114eb06f6cdaa54e8 100644 (file)
@@ -1,9 +1,9 @@
 #!/bin/sh
 
 #
-# buildtar 0.0.3
+# buildtar 0.0.4
 #
-# (C) 2004-2005 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
+# (C) 2004-2006 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
 #
 # This script is used to compile a tarball from the currently
 # prepared kernel. Based upon the builddeb script from
@@ -15,9 +15,8 @@ set -e
 #
 # Some variables and settings used throughout the script
 #
-version="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}${EXTRANAME}"
 tmpdir="${objtree}/tar-install"
-tarball="${objtree}/linux-${version}.tar"
+tarball="${objtree}/linux-${KERNELRELEASE}.tar"
 
 
 #
@@ -53,21 +52,17 @@ mkdir -p -- "${tmpdir}/boot"
 #
 # Try to install modules
 #
-if ! make INSTALL_MOD_PATH="${tmpdir}" modules_install; then
-       echo "" >&2
-       echo "Ignoring error at module_install time, since that could be" >&2
-       echo "a result of missing local modutils/module-init-tools," >&2
-       echo "or you just didn't compile in module support at all..." >&2
-       echo "" >&2
+if grep -q '^CONFIG_MODULES=y' "${objtree}/.config"; then
+       make ARCH="${ARCH}" O="${objtree}" KBUILD_SRC= INSTALL_MOD_PATH="${tmpdir}" modules_install
 fi
 
 
 #
 # Install basic kernel files
 #
-cp -v -- System.map "${tmpdir}/boot/System.map-${version}"
-cp -v -- .config "${tmpdir}/boot/config-${version}"
-cp -v -- vmlinux "${tmpdir}/boot/vmlinux-${version}"
+cp -v -- "${objtree}/System.map" "${tmpdir}/boot/System.map-${KERNELRELEASE}"
+cp -v -- "${objtree}/.config" "${tmpdir}/boot/config-${KERNELRELEASE}"
+cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
 
 
 #
@@ -75,17 +70,17 @@ cp -v -- vmlinux "${tmpdir}/boot/vmlinux-${version}"
 #
 case "${ARCH}" in
        i386)
-               [ -f arch/i386/boot/bzImage ] && cp -v -- arch/i386/boot/bzImage "${tmpdir}/boot/vmlinuz-${version}"
+               [ -f "${objtree}/arch/i386/boot/bzImage" ] && cp -v -- "${objtree}/arch/i386/boot/bzImage" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
                ;;
        alpha)
-               [ -f arch/alpha/boot/vmlinux.gz ] && cp -v -- arch/alpha/boot/vmlinux.gz "${tmpdir}/boot/vmlinuz-${version}"
+               [ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
                ;;
        vax)
-               [ -f vmlinux.SYS ] && cp -v -- vmlinux.SYS "${tmpdir}/boot/vmlinux-${version}.SYS"
-               [ -f vmlinux.dsk ] && cp -v -- vmlinux.dsk "${tmpdir}/boot/vmlinux-${version}.dsk"
+               [ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS"
+               [ -f "${objtree}/vmlinux.dsk" ] && cp -v -- "${objtree}/vmlinux.dsk" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.dsk"
                ;;
        *)
-               [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${version}"
+               [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}"
                echo "" >&2
                echo '** ** **  WARNING  ** ** **' >&2
                echo "" >&2
index f2d47ca9c8facb232bc41263d87bdaa667fc1292..67e4b1868e500dcd7331265ffd5027ee52703d3b 100755 (executable)
@@ -45,7 +45,7 @@
 # update usage message;
 # fix some whitespace damage;
 # be smarter about stopping when current version is larger than requested;
-#      Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18.
+#      Randy Dunlap <rdunlap@xenotime.net>, 2004-AUG-18.
 #
 # Add better support for (non-incremental) 2.6.x.y patches;
 # If an ending version number if not specified, the script automatically
@@ -56,7 +56,7 @@
 # patch-kernel does not normally support reverse patching, but does so when
 # applying EXTRAVERSION (x.y) patches, so that moving from 2.6.11.y to 2.6.11.z
 # is easy and handled by the script (reverse 2.6.11.y and apply 2.6.11.z).
-#      Randy Dunlap <rddunlap@osdl.org>, 2005-APR-08.
+#      Randy Dunlap <rdunlap@xenotime.net>, 2005-APR-08.
 
 PNAME=patch-kernel
 
index 64d3f1e9ca85e4a925b2c38680af74c70dc27a53..34f593410d57cb12070a154bc0fa0b272467dfeb 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 3ca5f2b828a0d84780c8ec223b1a62e954a7ff10..a15c54709fdefe69defdd67c49340e2485d65006 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 b038cd0fae2e09f3f1917cad3da24056828858e4..06d54d9d20a5049e25911e33668dc3ed1a2dd9c4 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 fc774436a264d0f21c1b07f142d96331372014f2..3d496eae1b47ee1ce6a5950f2ffe770c495da705 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 1deb59e1b76257dab1129f0050ce0f727aceeb30..71aeb12f07c8d78cc1a2a21bbad97ce180b28576 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 a78b5d59c9fc008f638200a1764c3a1e2e7a646e..d1d0996049e3636f271e36add8c9506eeb5b401c 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 e1326704c0c5b4842f31c43844db1092b92ee7a5..a1bd8040dea441a06a487ef9943a8e31997bb457 100644 (file)
@@ -1994,7 +1994,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 9807c3d7b1a4e4ef24afb00fa81e0cb73fef18dc..e0abb56bbe492084d565a9c56b17c71b8ed47a60 100644 (file)
@@ -407,7 +407,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,